原文链接:https://developers.google.com/tango/apis/java/java-motion-tracking
本文演示如何通过 Java 来使用运动追踪技术。
生命周期
运动追踪系统一般情况下包含三个状态:TangoPoseData.POSE_INITIALIZING, TangoPoseData.POSE_VALID 以及 TangoPoseData.POSE_INVALID。POSE_INITIALIZING 表示系统还未就绪,无 pose 数据可用。POSE_VALID 表示系统运转正常。POSE_INVALID 表示系统异常,需要重新初始化。还有一个状态,POSE_UNKNOWN,表示出上述状态之外的其他状态。
如果 pose 数据变成 POSE_INVALID 状态,运动追踪系统可以通过两种方法来重新初始化。如果系统配置项 config_enable_auto_recovery = true,系统将立即进入 POSE_INITIALIZING 状态。恢复之后,系统使用最近一次POSE_VALID状态的pose作为追踪的起始点。如果TangoConfig.KEY_BOOLEAN_AUTORECOVERY=false,系统将停止工作,并始终返回 POSE_INVALID 状态的 pose 数据,直到 Tango.resetMotionTracking() 方法被调用。与自动恢复不同的是,系统恢复后该方法将重置起始点为故障前的原始点。
更多信息,请参考设备 Pose 原理页面。
配置
要使用运动追踪功能,TangoConfig 中的 KEY_BOOLEAN_MOTIONTRACKING 必须设置为 true。默认的 TangoConfig 中 KEY_BOOLEAN_MOTIONTRACKING = true。
除此之外还得设置 KEY_BOOLEAN_AUTORECOVERY。该项默认为 true。该项表示的意义请查看生命周期章节。
获取 pose 数据
对于基本的运动追踪功能,有两种坐标帧对可供使用:设备帧&服务起始帧,设备帧&前设备帧。对于第一种,设备 pose 数据是相对于运动追踪服务开启时的位置,该模式下 pose 数据可以通过回调和时间戳参数获取。后一种,获取的设备 pose 数据是相对于设备之前某个位置。该模式下只能通过回调获取。
回调方式
在回调方式中,你必须定义对应的坐标帧对,并实现 Tango.OnTangoUpdateListener 接口中的三个方法:onPoseAvailable(),onXyzIjAvailable(),onTangoEvent()。
private void setTangoListeners() {
final ArrayList<TangoCoordinateFramePair> framePairs = new ArrayList<TangoCoordinateFramePair>();
framePairs.add(new TangoCoordinateFramePair(
TangoPoseData.COORDINATE_FRAME_START_OF_SERVICE,
TangoPoseData.COORDINATE_FRAME_DEVICE));
// Listen for new Tango data
mTango.connectListener(framePairs, new OnTangoUpdateListener() {
@Override
public void onPoseAvailable(final TangoPoseData pose) {
// Process pose data from device with respect to start of service
}
@Override
public void onXyzIjAvailable(TangoXyzIjData arg0) {
// We need this callback even if we don't use it
}
@Override
public void onTangoEvent(final TangoEvent event) {
// This callback also has to be here
}
});
}
时间戳方式
这种方式中,你必须先设置合适的帧对。对于简单的运动追踪,使用
TangoPoseData.COORDINATE_FRAME_DEVICE & TangoPoseData.COORDINATE_FRAME_START_OF_SERVICE 就行。
// Define what motion is requested.
TangoCoordinateFramePair frames_of_reference;
frames_of_reference.baseFrame = TangoPoseData.COORDINATE_FRAME_START_OF_SERVICE;
frames_of_reference.targetFrame = TangoPoseData.COORDINATE_FRAME_DEVICE;
然后调用 Tango.getPoseAtTime()。下面的例子中,时间戳参数是 0.0 来获取最近的一次的 pose 数据。如果设置成其他值,将获得对应时刻的封装好的 pose 数据。这里的时间戳是以设备启动时刻为起始点的。
new Thread(new Runnable() {
final int pollingUpdatePeriodMilliseconds = 66;
@Override
public void run() {
while (true) {
try {
Thread.sleep(pollingUpdatePeriodMilliseconds);
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
final TangoPoseData queryPoseStartDevice =
mTango.getPoseAtTime(0.0, frames_of_reference);
} catch (TangoErrorException e) {
e.printStackTrace();
}
}
}
}).start();