Argon.js/A-Frame: локальные координаты из getEntityPose() не относятся к refereceFrame

Я пытаюсь использовать argon.js для преобразования координат lla в локальные координаты из предопределенной системы отсчета. Метод, который был рекомендован мне (насколько я понимаю), требует, чтобы я создал цезиевый объект из набора lla, а затем использовал этот элемент ceisum в качестве эталона при создании последующих цезиевых объектов с другими lla.

Я попытался сделать это, используя два метода: первый путем создания эталонной цезиевой сущности в argon.js, а второй - созданием a-frame-сущности с геопозицией, а затем выхватил цезиевую сущность из списка a-frame-сущностей. компоненты. Я использую argon.js, чтобы сделать все последующие преобразования.

В обоих методах я успешно создаю эталонные цезиевые объекты, и мне кажется (по крайней мере, мне), что конвертированные цезиевые объекты включают эталонные объекты в качестве своей системы отсчета. Однако, entityPose преобразованных объектов все еще 0, 0, 0. Я ожидаю, что опорный объект будет 0, 0, 0, и преобразованные объекты будут иметь локальные координаты относительно этого (например, 4, 8, 10), Кроме того, в каждом случае у сущностей есть poseStatus 0, но документация argon.js перечисляет только возможности как KNOWN = 1, FOUND = 2 и LOST = 4.

Я включил свой код ниже, а также некоторые отзывы от инспектора. Возвращаемые объекты очень большие, поэтому я включил только то, что считаю уместным, но, пожалуйста, дайте мне знать, если есть другие атрибуты, которые я должен включить. Также обратите внимание, что код содержит две опции, которые я перечислил выше, а вторая опция закомментирована.

Для некоторой истории см.:

Использование гео-координат вместо декартовой для рисования в аргоне и A-кадре

Argon.js: ошибка: состояние кадра еще не получено

<!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>

Отзыв от инспектора:

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 }

2 ответа

Решение

Насколько я понимаю, проблема в том, что хотя браузер на рабочем столе будет указывать местоположение, поскольку он не будет обеспечивать ориентацию, полная трехмерная поза не может быть получена. Таким образом, объект пользователя определяется на произвольной системе отсчета. Будущий выпуск будет иметь ориентацию, когда он недоступен.

РЕДАКТИРОВАТЬ: искаженный характер проблемы.

Сначала несколько простых вещей. Чтобы ответить на ваш вопрос о Argon.PoseStatus, это битовая маска, поэтому 0 неявно "ничего из вышеперечисленного" (так что, не известно, не просто найдено или потеряно). KNOWN устанавливается, когда поза известна, LOST или FOUND устанавливаются, когда состояние только что изменилось между KNOWN, а не KNOWN.

Таким образом, ваша линия

if (Argon.PoseStatus.KNOWN) {

нужно изменить на

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

если вы хотите убедиться, что мы знаем, где находится пользователь, что вам нужно, если вы хотите делать вещи в локальных координатах.

Это сказало, madRefEntityPose скорее всего не вычисляется (это poseStatus 0), поскольку позиция пользователя еще не определена. Для обоих вариантов.

Теперь по поводу кода. Вариант 1 дает вам объект в фиксированных координатах (эти большие числа, вероятно, являются правильными, они представляют собой значение в метрах положения этой точки на поверхности земли, используя стандартное эллиптическое приближение к Земле в качестве отметки 0). Если бы поза пользователя была известна, я бы ожидал poseStatus быть KNOWNи значения position а также orientation быть чем-то ненулевым.

Вариант 2 немного странный. Вы задаете ему большие числа в качестве позиции объекта, но затем говорите, что они выражаются в координатах предыдущего объекта. Это означает, что вы, вероятно, говорите ему расположить второе существо в космосе на расстоянии, эквивалентном расстоянию от центра Земли...

Напоминаю, что ваша цель - получить позу 2-го очка относительно первого. Для этого вам нужно

  • подождите, пока не станет известна поза пользователя
  • получить позу обеих точек в локальных координатах (как вы делаете для варианта 1)
  • вычтите первую (или ту, которая вам нужна как "локальное происхождение") из второй (и из последующих), чтобы получить небольшие смещения в метрах от последующих точек от первой (назначьте это для madP1Ref).
  • создать объект (как в варианте 2), используя эти маленькие метры (теперь в madP1Ref) так же, как вы делаете там.
Другие вопросы по тегам