Distance Measurement on Mobile App using ARCore

Distance Measurement on Mobile App using ARCore

19 May 2021
Distance Measurement on Mobile App using ARCore 47Billion

We have developed a mobile app based on augmented reality technology and it turns smartphone into a measuring device. 

ARCore SDK has plane detection capability. In order to use the app, the user has to pick two points using the phone camera to measure the distance between them. The user can also use this app to measure the distance between multiple points. 

Augmented reality 

Augmented reality (AR) technology allows us to superimpose digital content over a real-world environment. Google’s ARCore SDK is used for building augmented reality experiences.
 

Three key capabilities of ARCore SDK are used: 

1.   Motion tracking: using this we can track the position of phone relative to the world.
 

2.   Environmental understanding: using this we can detect the size and location of all type of surfaces.
 

3.   Light estimation: using this we can estimate the environment’s current lighting conditions.
 

ARCore tracks the position of the mobile device as it moves, and build its own understanding of the real world. 

Measuring distance using ARCore – Development Details 

In order to write code for calculating the distance between the two points using ARCore, configure Android Studio to use ARCore and then set up basic AR code. Please refer to my previous blog if you are having any issues with configuration.

How to code Augmented Reality Mobile Application with Android ARCore SDK — Part 1 | 47Billion 
 

Here are the terms that we need to understand in ARCore: 

HitResult — On tap, in ARFragment we get object of HitResult. This provides the location of a real-world object.

Anchor — It is a fixed location in the real-world.

TransformableNode — We can interact with this type of node to scale or transform the Anchor

With basic AR Code set up we have to add listener on ARFragment so that whenever user focus camera to any location and tap on that location, we will get HitResult which provides us the location of the selected place in real world.

We can place an anchor using the following code. 

 private fun placeAnchor(hitResult: HitResult, 
                        renderable: Renderable){ 
    val anchor = hitResult.createAnchor() 
    placedAnchors.add(anchor) 
 
    val anchorNode = AnchorNode(anchor).apply { 
        isSmoothed = true 
        setParent(arFragment!!.arSceneView.scene) 
    } 
    placedAnchorNodes.add(anchorNode) 
 
    val node = TransformableNode(arFragment!!.transformationSystem) 
        .apply{ 
            this.rotationController.isEnabled = false 
            this.scaleController.isEnabled = false 
            this.translationController.isEnabled = true 
            this.renderable = renderable 
            setParent(anchorNode) 
        } 
 
    arFragment!!.arSceneView.scene.addOnUpdateListener(this) 
    arFragment!!.arSceneView.scene.addChild(anchorNode) 
    node.select() 
} 

In order to find the distance between two points places two anchors. For that create ArrayList of AnchorNode to save multiple AnchorNodes 

val distanceMeter = 
    calculateDistance(placedAnchorNodes[0].worldPosition, placedAnchorNodes[1].worldPosition) 
private val placedAnchorNodes = ArrayList<AnchorNode>() 

When we tap on the ARFragment it gives HitResult. At that HitResult, we have to create an Anchor, AnchorNode and TransformableNode if we want to drag and adjust the position of Anchor. After having two AnchorNode calculate the distance between them using their worldPosition

val distanceMeter = 
    calculateDistance(placedAnchorNodes[0].worldPosition, placedAnchorNodes[1].worldPosition) 

Using distance formula of coordinate geometry calculate the distance between two points. 

private fun calculateDistance(objectPose0: Vector3, objectPose1: Vector3): Float{ 
    return calculateDistance( 
        objectPose0.x - objectPose1.x, 
        objectPose0.y - objectPose1.y, 
        objectPose0.z - objectPose1.z 
    ) 
} 
 
private fun calculateDistance(x: Float, y: Float, z: Float): Float{ 
    return sqrt(x.pow(2) + y.pow(2) + z.pow(2)) 
} 

Output

Accuracy 

The accuracy of measurement depends on the lighting conditions, the quality of the camera and which object are being measured. 

Physical tape or ruler gives more accurate measurements. With this app, we can provide an approximate estimate. App can be used for large objects like lamp posts or even buildings where tape measures would be difficult to use. 

Share
You can reach us at hello@47billion.com