简体   繁体   English

无法找到如何转换探戈点云

[英]Can't find out how to transform Tango Point Cloud

I work with the Google Tango right now and so far everything worked fine, but I stumbled upon a few strange things. 我目前正在使用Google Tango,到目前为止一切正常,但是我偶然发现了一些奇怪的东西。

There is a class ScenePoseCalculator in the Tango Examples. 探戈示例中有一个ScenePoseCalculator类。 And there is a method "toOpenGlCameraPose". 并且有一种方法“ toOpenGlCameraPose”。 When using this, the OpenGL camera however is not set up correctly. 使用此功能时,但是OpenGL相机未正确设置。 When I move forward, the camera moves backwards. 当我向前移动时,相机向后移动。 Left and right are swapped as well. 左右互换。

But the most difficult thing is to transform the PointCloud correctly. 但是最困难的事情是正确转换PointCloud。 I do the following: 我执行以下操作:

Create an Vector3-Array: 创建一个Vector3-Array:

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));
    }

In the PointCloud Callback of the TangoListener I do: 在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();
    }
}

To transform the PointCloud I do: 要转换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]);
    }

But whatever I do. 但是,无论我做什么。 I've tried everything. 我已经尝试了一切。 But it won't look right. 但这看起来不正确。 The PointClouds get stapled over each other or look like they where placed without any sense. PointCloud相互装订在一起,或者看起来毫无意义地放置在它们之间。

Hope someone knows more... 希望有人知道更多...

For everyone still looking to find out how to do this, I just managed it in jMOnkeyEngine3. 对于仍然希望了解如何执行此操作的每个人,我只是在jMOnkeyEngine3中对其进行了管理。 The secret is, one has to use the INVERSE of the rotation Quaternion which the Tango delivers. 秘诀是,必须使用探戈提供的旋转四元数的INVERSE。

Okay, here is how it works: 好的,这是它的工作方式:

Getting depth data with the Callback: 通过回调获取深度数据:

public void onXyzIjAvailable(TangoXyzIjData xyzIj)

Create an Array of vertices from the xyz-Array: 从xyz-Array创建一个顶点数组:

// 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]);
        }

Use the ScenePoseCalculator from Rajawali3d: 使用Rajawali3d中的ScenePoseCalculator:

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

Device intrinsics must be ordered before that, but remember to do it in an TRY/CATCH enclosure. 在此之前必须订购设备内部函数,但请记住在TRY / CATCH机柜中进行配置。

After that, get Rotation Quaternion and Pose Vector3 from the Tango Pose: 之后,从Tango Pose获取Rotation Quaternion和Pose Vector3:

Pose cloudPose = this.rajawaliPoseToJMEPoseCLOUD(p);

That method is defined here: 该方法在这里定义:

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;
}

Then Put the vertices in a node and transform that node with the Pose Data of the according XYZIJ-Data: 然后将顶点放在一个节点中,并使用根据XYZIJ-Data的姿势数据对该节点进行变换:

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

Hope it helps someone. 希望它可以帮助某人。 Took me 4 days to figure it out x( 花了我4天的时间弄清楚x(

Cheers 干杯

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM