crld
crld

Reputation: 103

Argon.js/A-Frame: local coordinates from getEntityPose() are not relative to refereceFrame

I am attempting to use argon.js to convert lla coordinates to local coordinates from a predefined reference frame. The method that has been recommended to me (as I understand it) requires that I create a cesium entity from a set of lla's, and then use that ceisum entity as a reference when creating subsequent cesium entities with other lla's.

I have tried to do this using two methods: the first by creating the reference cesium entity in argon.js, and the second by creating an a-frame entity with a geopose, and then grabbing the cesium entity from a-frame entity's list of components. I use argon.js to make all subsequent conversions.

In both methods, I am having success creating the reference cesium entities, and it appears (to me, at least) that the converted cesium entities include the reference entities as their reference frame. However, the entityPose of the converted entities are still 0, 0, 0. My expectation is that the reference entity would be 0, 0, 0, and the converted entities would have local coordinates relative to that (e.g. 4, 8, 10). Additionally, in each case the entities have a poseStatus of 0 but the argon.js documentation only lists the possibilities as KNOWN = 1, FOUND = 2, and LOST = 4.

I have included my code below, as well as some feedback from the inspector. The objects that are returned are very large so I have only included what I think is relevant but please let me know if there are other attributes I should include. Also note, the code contains the two options I listed above with the second option commented out.

For some history see:

Using Geo-coordintes Instead of Cartesian to Draw in Argon and A-Frame

Argon.js: Error: A frame state has not yet been received

<!DOCTYPE html>
<html>
  <head>
    <title>Hello world</title>
    <script src="/socket.io/socket.io.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/geolocator/2.1.0/geolocator.js"></script>
    <script src="arframe/main/resources/js/aframe.js"></script>
    <script src="arframe/main/resources/js/argon.min.js"></script>
    <script src="arframe/main/build.js"></script>
    <script src="arframe/main/resources/js/CSS3DArgonRenderer.js"></script>
    <script src="arframe/main/resources/js/CSS3DArgonHUD.js"></script>
    <script src="arframe/main/resources/js/aframe-look-at-component.js"></script>
  </head>
   <body>

<h1>Hello world</h1>

<ar-scene>
  <!--OPTION 2-->
  <!-- <a-entity id='madRefFrame' referenceframe='lla: -84.31169 33.756128'></a-entity> -->
</ar-scene>

<script>

  // OPTION 1
  var app = Argon.init();

  // OPTION 2
  //var scene = document.querySelector('ar-scene');
  //var app = scene.argonApp;

  var Cesium = Argon.Cesium;
  var Cartesian3 = Cesium.Cartesian3;
  var ConstantPositionProperty = Cesium.ConstantPositionProperty;
  var ReferenceFrame = Cesium.ReferenceFrame;
  var ReferenceEntity = Cesium.ReferenceEntity;

  app.context.setDefaultReferenceFrame(app.context.localOriginEastUpSouth);

  app.updateEvent.addEventListener(function (frame) {

    if (Argon.PoseStatus.KNOWN) {

      // OPTION 1
      var madRefData = { lla : { x : -84.31169, y : 33.756128, z : 299 }};
      var madRef = Cartesian3.fromDegrees(madRefData.lla.x, madRefData.lla.y, madRefData.lla.z);
      var options = { position: new ConstantPositionProperty(madRef, ReferenceFrame.FIXED),
                      orientation:  Cesium.Quaternion.IDENTITY
                    };
      var madRefEntity = new Cesium.Entity(options);

      console.log('madRefEntity');
      console.log(madRefEntity);

      var madRefEntityPose = app.context.getEntityPose(madRefEntity);

      console.log('madRefEntityPose');
      console.log(madRefEntityPose);

      // OPTION 2
      // var madRefEL = document.querySelector('#madRefFrame');
      // var madRefFrame = madRefEL.components['referenceframe'];
      // var madRefEntity = madRefFrame.cesiumEntity;
      // 
      // console.log('madRefEntity');
      // console.log(madRefEntity);
      // 
      // var madRefEntityPose = app.context.getEntityPose(madP1Entity);
      // 
      // console.log('madRefEntityPose');
      // console.log(madRefEntityPose);

      // USED IN OPTIONS 1 AND 2
      var madP1Data = { lla : { x : -84.31169, y : 33.755602, z : 297 }};
      var madP1Ref = Cartesian3.fromDegrees(madP1Data.lla.x, madP1Data.lla.y, madP1Data.lla.z);
      var options = { position: new ConstantPositionProperty(madP1Ref, madRefEntity),
                      orientation:  Cesium.Quaternion.IDENTITY
                    };
      var madP1Entity = new Cesium.Entity(options);

      console.log('madP1Entity');
      console.log(madP1Entity);

      var madP1EntityPose = app.context.getEntityPose(madP1Entity);

      console.log('madP1EntityPose');
      console.log(madP1EntityPose);

    } else {
      // if we don't know the user pose we can't do anything
      console.log("we don't know.");
      return;
    };

  });

</script>
</body>
</html>

Feedback from inspector:

A-Frame Version: 0.3.2 
three Version: ^0.76.1 
WebVR Polyfill Version: 0.9.15
Reality changed to: {"uri":"reality:empty","title":"Reality","providedReferenceFrames":["FIXED"]}
THREE.CSS3DArgonRenderer 76CSS3D
THREE.CSS3DArgonHUD 76CSS3D
THREE.WebGLRenderer 76
Reality changed to: {"uri":"reality:empty","title":"Reality","providedReferenceFrames":["FIXED"]}
reference frame changed to FOUND

madRefEntity
Object { _availability: undefined, 
       _id: "ae5fe824-12ea-4d7f-87e8-0eee0ca31008", 
       // METHOD 2
       // _id: "madRefFrame"
       _parent: undefined, 
       _propertyNames: Array[19], 
       ...
       _position:Object
        _definitionChanged:Object
        _referenceFrame:0
        _value:Object
          x:526169.6230387943
          y:-5282445.040716821
          z:3524154.8442182266
          // METHOD 2
          //x:526144.9834483624
          //y:-5282197.673182507
          //z:3523988.702129788
       ...
     }

madRefEntityPose
Object { position : { x: 0, y: 0, z: 0 },
       orientation: { w: 1, x: 0, y: 0, z: 0 },
       time: {dayNumber: 2457689, secondsOfDay : 81280.139927485},
       poseStatus: 0 }

madRefP1Entity
Object { _availability: undefined, 
      _id: "9ded96ab-961c-4ba3-b766-8c37e919877f", 
      ...
      _parent: undefined,
      _position: object
       _referenceFrame: object
         _id: "ae5fe824-12ea-4d7f-87e8-0eee0ca31008",
      // METHOD 2
      // _id: "madRefFrame"
         _orientation: object 
          _value: Object
           _w: 1,
           _x: 0,
           _y: 0
           _z: 0
         ...
         _position: Object
          _value:Object
            x:526169.6230387943
            y:-5282445.040716821
            z:3524154.8442182266
            // METHOD 2
            //x:526144.9834483624
            //y:-5282197.673182507
            //z:3523988.702129788
          ...
        ...
      ...
      _value:Object
        x:526172.6715934229
        y:-5282475.646478866
        z:3524105.2236363157
      ...
    }

madRefEntityPose
madRefEntityPose = { position : { x: 0, y: 0, z: 0 },
                  orientation: { w: 1, x: 0, y: 0, z: 0 },
                  time: {dayNumber: 2457689, secondsOfDay : 81281.12722016001},
                  poseStatus: 0 }

Upvotes: 0

Views: 384

Answers (2)

crld
crld

Reputation: 103

As I understand it, the issue is that while a desktop browser will give a location, since it will not provide an orientation, a full 3D pose cannot be obtained. Therefore, the user entity is defined against an arbitrary reference frame. A future release will assume an orientation when one is not available.

EDIT: mischaracterized nature of issue.

Upvotes: 1

Blair MacIntyre
Blair MacIntyre

Reputation: 463

A few simple things, first. To answer your question about Argon.PoseStatus, it is a bitmask, so 0 is implicitly "none of the above" (so, not known, not just been found or lost). KNOWN is set when the pose is known, LOST or FOUND are set when the state has just changed between KNOWN and not KNOWN.

Thus, your line

if (Argon.PoseStatus.KNOWN) {

needs to change to

if (userPose.poseStatus & Argon.PoseStatus.KNOWN) {

if you want to make sure we know where the user is located, which you need if you want to do things in local coordinates.

That said, madRefEntityPose is likely not being computed (it's poseStatus is 0) because the user's position is not yet determined. For both options.

Now, regarding the code. Option 1 gives you the entity in FIXED coordinates (those large numbers are likely correct, they are the value in meters of the position of that point on the surface of the earth, using the standard elliptical approximation to the earth as elevation 0). If the user's pose was known, I would expect the poseStatus to be KNOWN, and the values of position and orientation to be something non-zero.

Option 2 is a bit weird. You are giving it the big numbers as the position of the entity, but then saying they are being expressed in the coordinates of the previous entity. Which means you are probably telling it to position the second entity out in outer space, by the distance equivalent to the distance from the center of the earth ...

I recall that your goal is to get the pose of the 2nd point relative to the first. To do that, you need to

  • wait until the user's pose is known
  • get the pose of both points in local coordinates (as you are doing for Option 1)
  • subtract the first (or whichever one you want as your "local origin") from the second (and from the subsequent ones) to give you small meters-based offsets of the subsequent points from the first one (assign this to madP1Ref).
  • create an entity (like in Option 2) using those small meters (now in madP1Ref) just like you are doing there.

Upvotes: 1

Related Questions