0

我现在使用 Google Tango,到目前为止一切正常,但我偶然发现了一些奇怪的事情。

Tango 示例中有一个 ScenePoseCalculator 类。还有一种方法“toOpenGlCameraPose”。使用它时,OpenGL 相机设置不正确。当我向前移动时,相机向后移动。左右也互换了。

但最困难的是正确转换点云。我执行以下操作:

创建一个 Vector3 数组:

Vector3f [] vertices = new Vector3f[mPointCloud.getGeometry().getVertices().capacity()];
    for(int i=0; i<mPointCloud.getGeometry().getVertices().capacity(); i++) {
        vertices[i] = new Vector3f(
            mPointCloud.getGeometry().getVertices().get(i*3), 
            mPointCloud.getGeometry().getVertices().get(i*3+1),
            mPointCloud.getGeometry().getVertices().get(i*3+2));
    }

在 TangoListener 的 PointCloud 回调中,我这样做:

private void updateXYZIJ() {

    try {
        if(pcm.getLatestXyzIj().xyzCount<10) return;

        TangoCoordinateFramePair fp = new TangoCoordinateFramePair(
            TangoPoseData.COORDINATE_FRAME_START_OF_SERVICE,
            TangoPoseData.COORDINATE_FRAME_DEVICE);

        TangoXyzIjData xyzIj = pcm.getLatestXyzIj();
        depthArray = new float[xyzIj.xyzCount * 3];
        xyzIj.xyz.get(depthArray);

        com.projecttango.rajawali.Pose p = 
            ScenePoseCalculator.toDepthCameraOpenGlPose(
                tangoProvider.getTango().getPoseAtTime( 
                    xyzIj.timestamp, fp), this.setupExtrinsics());

        Pose cloudPose = this.rajawaliPoseToJMEPoseCLOUD(p);

        currentPointCloudData = new PointCloudUpdate(
            new Date(),
            depthArray,
            xyzIj.xyzCount,
            xyzIj.ijRows,
            xyzIj.ijCols,
            0,
            cloudPose,
            null
        );

        // inform listeners
        for (PointCloudListener listener : this.pointsListeners) {
            listener.acceptMessage(tangoProvider, this.currentPointCloudData);
        }

    } catch (Exception e) {
        e.printStackTrace();
    }
}

要转换 PointCloud,我会:

this.transformation = new Matrix4f();
    this.transformation.setRotationQuaternion(
        this.referencePose.orientation);
    this.transformation.setTranslation(this.referencePose.place);

absVertices = new Vector3f[vertices.length];
    for(int i=0; i<vertices.length; i++) {

        // Create new Vertex
        absVertices[i]=new Vector3f(
            vertices[i].x,
            vertices[i].y,
            vertices[i].z
        );

        Vector3f v = absVertices[i];

        transformation.rotateVect(absVertices[i]);
        transformation.translateVect(absVertices[i]);
    }

但无论我做什么。我什么都试过了。但它看起来不正确。PointClouds 被装订在一起,或者看起来像是毫无意义的放置。

希望有人知道更多...

4

1 回答 1

1

对于仍在寻找如何做到这一点的每个人,我只是在 jMONkeyEngine3 中管理它。秘诀是,必须使用 Tango 提供的旋转四元数的 INVERSE。

好的,这是它的工作原理:

使用回调获取深度数据:

public void onXyzIjAvailable(TangoXyzIjData xyzIj)

从 xyz 数组创建一个顶点数组:

// Create new array, big enough to hold all vertices
        depthArray = new float[xyzIj.xyzCount * 3];
        xyzIj.xyz.get(depthArray);

        // Create Vertices
        Vector3f[] vertices = new Vector3f[xyzIj.xyzCount];
        for(int i=0; i<xyzIj.xyzCount; i++) {
            vertices[i] = new Vector3f(
                depthArray[i*3],
                depthArray[i*3+1], 
                depthArray[i*3+2]);
        }

使用 Rajawali3d 的 ScenePoseCalculator:

com.projecttango.rajawali.Pose p = ScenePoseCalculator
            .toDepthCameraOpenGlPose(tangoProvider.getTango().getPoseAtTime( 
                  xyzIj.timestamp, framePair_SS_D), this.setupExtrinsics());

必须在此之前订购设备内在函数,但请记住在 TRY/CATCH 外壳中进行。

之后,从 Tango Pose 中获取 Rotation Quaternion 和 Pose Vector3:

Pose cloudPose = this.rajawaliPoseToJMEPoseCLOUD(p);

该方法在这里定义:

private Pose rajawaliPoseToJMEPoseCLOUD(com.projecttango.rajawali.Pose p) {
    Pose pose = new Pose(
        new Vector3f(
            (float)p.getPosition().x, 
            (float)p.getPosition().y, 
            (float)p.getPosition().z),
        new Quaternion(
            (float)p.getOrientation().x,
            (float)p.getOrientation().y,
            (float)p.getOrientation().z,
            (float)p.getOrientation().w
        ));

    return pose;
}

然后将顶点放在一个节点中,并使用相应 XYZIJ-Data 的 Pose Data 转换该节点:

meshNode.setLocalRotation(pcu.referencePose.orientation.inverse());
    meshNode.setLocalTranslation(pcu.referencePose.place);

希望它可以帮助某人。我花了 4 天时间才弄明白 x(

干杯

于 2016-05-13T17:06:11.907 回答