ARKit Session Paused and Not Resuming

In my ARKit app I am presenting a modal window. When I close the modal and go back to the ARSCNView then I find out that the session is paused due to this code:

 override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)

        // Pause the view's session
        sceneView.session.pause()
    } 

When I close the modal and go back to the ARKit camera view screen this code gets fired:

override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        // Create a session configuration
        let configuration = ARWorldTrackingSessionConfiguration()

        // Run the view's session
        sceneView.session.run(configuration)
    }

But this code never resumes the session. The screen is completely frozen on the last image it read. Any ideas?

I update the viewDidAppear code to be the following. It is still stuck on the camera screen with image frozen.

  override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        // Create a session configuration
        let configuration = ARWorldTrackingSessionConfiguration()

        sceneView.session.delegate = self

        if self.isPaused {
            sceneView.session.run(sceneView.session.configuration!)
        } else {
            // Run the view's session
            sceneView.session.run(configuration)
        }


    }

Not sure why your session isn't resuming, but... this generally isn't a situation you want to be in anyway.

Notice in the readme that ships with Apple's ARKit sample code (attached to the WWDC17 session on ARKit):

Avoid interrupting the AR experience. If the user transitions to another fullscreen UI in your app, the AR view might not be an expected state when coming back.

Use the popover presentation (even on iPhone) for auxiliary view controllers to keep the user in the AR experience while adjusting settings or making a modal selection. In this example, the SettingsViewController and VirtualObjectSelectionViewController classes use popover presentation.

To go into a bit more detail: if you pause the session, it won't be tracking the world while your user is away in a different fullscreen view controller. That means that when you resume, any virtual content placed in the scene won't be in the positions (relative to the camera) where you left it.

ios - ARKit Session Paused and Not Resuming, In my ARKit app I am presenting a modal window. When I close the modal and go back to the ARSCNView then I find out that the session is paused due to this  func pause () Discussion While paused, the session doesn't track device motion or capture scene imagery, nor does it coordinate with its delegate object or update any associated ARSCNView or ARSKView object.

I don't know if the iOS 11 GM Seed or XCode 9 GM Seed versions fixed this today however I can successfully resume a paused ARSCNview with code as in the original question.

sceneView.session.run(sceneView.session.configuration!)

pause(), Pauses processing in the session. SDK. iOS 11.0+. Framework. ARKit While paused, the session doesn't track device motion or capture scene imagery, nor  In my ARKit app I am presenting a modal window. When I close the modal and go back to the ARSCNView then I find out that the session is paused due to this code: override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) // Pause the view's session sceneView.session.pause() }

I get that you have chosen an answer, and that answer is what is recommended by apple, you can restart the AR Session. You can't unpause/resume the Session though, because the device stops it's tracking once you're out of your controller presenting the ARSceneView and will stop keeping track of the position of your device relative to the objects you've placed in the scene.

Anyway, I've managed to restart the session essentially by destroying all aspects of my session and rebuilding them them when my view reappears, or through a button press.

I'll post some sample code here. It's in Objective-C cause my project was written in that, but it might help future people with the same question.

-(void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated]
    [self setupScene];
    [self setupSession];
}

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    [self destroySession];
    [self destroyScene];
}

- (void)setupScene {

// Setup the ARSCNViewDelegate - this gives us callbacks to handle new
// geometry creation
    self.sceneView.delegate = self;

// A dictionary of all the current planes being rendered in the scene
    self.planes = [NSMutableDictionary new];

// Contains a list of all the boxes rendered in the scene
    self.boxes = [NSMutableArray new];

// Show statistics such as fps and timing information
    self.sceneView.showsStatistics = YES;
    self.sceneView.autoenablesDefaultLighting = YES;

    SCNScene *scene = [SCNScene new];

    [self.sceneView setScene:scene];

    self.sceneView.scene.physicsWorld.contactDelegate = self;   
}

- (void)setupSession {

    // Create a session configuration
    ARWorldTrackingConfiguration *configuration = [ARWorldTrackingConfiguration new];
    //ARWorldTrackingSessionConfiguration *configuration = [ARWorldTrackingSessionConfiguration new]; This has been deprecated in favor of the previous line in XCode 9 beta 5. 

    // Specify that we do want to track horizontal planes. Setting this will cause the ARSCNViewDelegate
    // methods to be called when scenes are detected
    //configuration.planeDetection = ARPlaneDetectionHorizontal;

    // Run the view's session
    [self.sceneView.session runWithConfiguration:configuration options:ARSessionRunOptionResetTracking];
}


-(void)destroyScene {
    bottomPlane = nil;
    [self.sceneView setScene:nil];
    [self.sceneView setDebugOptions:nil];
    self.boxes = nil;
    self.planes = nil;
    self.sceneView.delegate = nil;  
}

-(void)destroySession {
    [self.sceneView.session pause];
    [self.sceneView setSession:nil];
}

These destroy methods are used when the view disappears. I am also restarting the AR Session on a button press, but it is not through these methods. It is as follows:

-(void)resetPressed{
    NSLog(@"Reset Pressed");
    [_sceneView.session pause];


    SCNScene *scene = [[SCNScene alloc] init];
    [_sceneView setScene:scene];
    [_sceneView.scene.rootNode enumerateChildNodesUsingBlock:^(SCNNode * _Nonnull child, BOOL * _Nonnull stop) {
        [child removeFromParentNode];
    }];

    ARWorldTrackingConfiguration *configuration = [[ARWorldTrackingSessionConfiguration ARWorldTrackingConfiguration] init];
    [_sceneView.session runWithConfiguration:configuration options:ARSessionRunOptionResetTracking | ARSessionRunOptionRemoveExistingAnchors];
}

Hope it helps.

Best Practices for Continued AR experiences, This article presents the concept of continued experiences for paused AR Limited Tracking – While it is not a temporal interruption of the application itself, tracking ARKit. Upon resuming an interrupted AR session, the DeviceTracker will  // Run your session session.run(configuration) // Pause your session session.pause() // Resume your session session.run(session.configuration) // Change your configuration session.run(otherConfiguration)

Here's an answer working with Swift 4.2 and iOS 12.

To present UI defined in another view controller over your AR scene, create your view controller instance and set it's modalPresentationStyle property to .overCurrentContext:

EXAMPLE:

func showMaterialPicker(completion: (Texture?) -> Void) {

    // create an instance of your view controller, I have convenience functions
    // setup to do this via an extension on UIViewController
    guard let materialPicker = MaterialCategoriesViewController.instance(from: .product) else {
        print("Unable to instantiate MaterialCategoriesViewController, bailing")
        return
    }

    // set presentation style and transition style
    materialPicker.modalPresentationStyle = .overCurrentContext
    materialPicker.modalTransitionStyle = .crossDissolve

    // present the controller
    present(materialPicker, animated: true, completion: nil)
}

Bonus tip:

To make your overlay appear to slide up from the bottom like a drawer, set

materialPicker.modalTransitionStyle = .coverVertical

then constrain your views in your overlay view controller a comfortable height from the bottom and set the background color of the view controllers view to UIColor.clear.

If you want to darken the AR view while your overlay is displayed you can set the background color to a black color with an opacity/alpha value of approximately 0.75.

Something like this:

self.view.backgroundColor = UIColor(red: 0.0, green: 0.0, blue: 0.0, alpha: 0.75)

or in the storyboard:

In the screenshot above I have a tableview pinned to the bottom and sides of the overlay view controllers view, and a height constraint of 300.

When done this way you can still see the AR view behind the overlay view controller and the scene continues to render.

AR Foundation - Pausing & Resuming tracking?, ARKit XR 1.0.0-preview.14 However on iOS this does not work ,as when i try to get access to the ARPlaneManager it comes up with a message An AR Session can be started, paused, resumed, and stopped entirely. To maintain the AR session, Vuforia records the position of targets, anchors and virtual content in the environment which will be ready once the users resume the AR session. For the continuity support to work optimally, it is recommended that users resume the AR session in roughly the same position that it was paused.

ARKit: pausing session does not stop the scene to be called, I pause the session when the user navigates back: override func But as said in ARKit Session Paused and Not Resuming thread, whenever i change the tab to  Cannot resume downloading the file: File Name. It’s possible that the address of the file is not valid anymore or your session has expired. IDM will open a web page in your browser in captured

Building a Portal App in ARKit: Adding Objects, On failure, the session is paused and it does not receive sensor data. Show a “​Session resumed” message on the screen for 3 seconds. It is good practice to pause the ARKit session when the view controller is not visible (in the ViewWillDisappear method: SceneView.Session.Pause(); Summary. The above code results in a simple ARKit application. More complex examples would expect the view controller hosting the augmented reality session to implement IARSCNViewDelegate, and additional methods be implemented.

How to use GIFs with ARKit (Tutorial), Unfortunately, it's not as simple as applying a GIF file as a material on a .com/​questions/44979559/arkit-session-paused-and-not-resuming. An ARSession object coordinates the major processes that ARKit performs on your behalf to create an augmented reality experience. These processes include reading data from the device's motion sensing hardware, controlling the device's built-in camera, and performing image analysis on captured camera images.

Comments
  • Thanks @rickster! Makes sense now. I would make sure that the user does not leave the AR experience and use popover presentation.
  • I'm seeing the session frozen even when using the popover presentation. Possible bug? forums.developer.apple.com/thread/81943
  • The accepted answer also says they were unable to reproduce the issue and goes into more detail. Could this answer be edited to add value to OP and others with this issue?
  • This worked great for me! First self.sceneView.session.pause() then sceneView.session.run(sceneView.session.configuration!)
  • This is what I have been doing. But somehow the second time around the ARSession is created if keeps missing frames for long periods of time. The camera state stays indefinitely at ARTrackingStateLimited.
  • I don't quite understand how are you addressing the change in the world centre coordinates. Most likely the world will not be with the same centre the second time you run the session. So all loaded nodes will be misplaced. Can you offer me a solution for this issue, because all I can come up with is some ImageRecognition software that can translate the change of world centres somehow, and give a translation matrix from there. Any better suggestions?
  • @dvp.petrov i am not addressing the change in coordinates. I was simply addressing the issue in the question, which was that when the OP returned to the AR View Controller the AR session was paused and doesn't move. I was simply offering a way on restarting the session once you go back to that view controller. With regards to your question, I guess you could save the positions of all the nodes you've added and re-add them once you're back, but there is no guarantee that the device will be in the same physical location at that point.
  • @AlanS - I am curious if the second time you run your ARSession it is as stable as the first time around? In my second run I have it forever as ARTrackingStateReasonInitializing and it never becomes ARTrackingStateReasonNone.
  • Finally! After two days, I can say that this did it! I was actually having a bit different issue. When I presented a NewViewController OVER the SceneViewController, that NewViewController froze. I tried pausing, resuming the session, removing the scene completely and reinitializing on viewWillAppear - nothing worked. Only I came across this post by @digitalHound and used the newViewController.modalPresentationStyle = .overCurrentContext I was able to solve the issue! Thank you again @digitalHound
  • @kalafun : Hi guys. Me too facing the same issue. My new view controller completely freezes when I push it on top of the sceneViewController. I tried presenting it with the suggestion above, but still doesn't work. Do you recommend anything else?