Pavel Zdenek
Pavel Zdenek

Reputation: 7293

How to determine that ARObjectAnchor was removed from the scene?

I am trying to use ARKit for validating the position of a toy. I have an ARObject scan resource, and placing the toy in camera view works pretty well. In other words, didAdd and didUpdate of SCNScene and ARSession are called as expected in a reasonable time after the toy is placed in camera view. But when i move the toy away from the camera view, didRemove does not get called, neither for SCNScene nor for ARSession.

I did read advocations of this behaviour, saying "well ARKit can't know if it was really removed and it still may be just around the corner" but it is rather impractical assumption. The whole Apple documentation about this function is "ARKit may automatically remove anchors" but doesn't say a word about when and why. I know about isTracked but ARObjectAnchor seems to be the only ARAnchor subclass that does not implement ARTrackable.

The only desperate hack i can think of is some kind of fuzzy timeout for when didUpdate stops getting called, because that's the only effect of removing the object AFAIK. Did i overlook something in ARWorldTrackingConfiguration? Please?

Upvotes: 3

Views: 714

Answers (2)

Pavel Zdenek
Pavel Zdenek

Reputation: 7293

Interpretation of informations from Apple TSI (id 731233593 if anyone wants to refer to this issue in his own TSI):

ARObjectAnchors are not necessarily removed when the object goes offscreen. It is not a behaviour that should be relied on. This applies to AR(SCNView|Session)Delegate.didRemove callbacks and to the content of ARFrame.anchors. The callbacks are definitely called only if the client code removes the relevant anchor programmatically. I was unable to squeeze a better explanation of the official doc line "ARKit may automatically remove anchors" despite asking explicitly. "You shouldn’t worry about why this happened."

Timing out on didAdd or didUpdate callbacks is an official method. The evidence is Apple's official project for creating object scans, file Controllers/TestRun.swift method startNoDetectionTimer. Using 5 seconds timeout.

Demands of ARObjectAnchor to implement ARTrackable are encouraged to fill an enhancement request at Feedback Assistant. I personally was encouraged to investigate alternatives and found that CoreML is unexpectedly friendly and fits my use case much better.

Thanks @Andy for pushing me this far.

Upvotes: 0

Andy Jazz
Andy Jazz

Reputation: 58583

To find an anchor by name give it a descriptive name using init(name:transform:) initialiser:

let anchor = ARAnchor.init(name: "ObjAnchor", transform: mtx) as! ARObjectAnchor

self.sceneView.session.currentFrame?.anchors.filter { 
     $0.name == "ObjAnchor"
}

or:

self.sceneView.session.currentFrame?.anchors.contains { 
    $0.isKind(of: ARObjectAnchor.self)
}

Upvotes: 1

Related Questions