![](/img/trans.png)
[英]Project Tango native code crash when calling getPoseAtTime()
[英]Project Tango onPoseAvailable() and getPoseAtTime() discrepancies
我看到onPoseAvailable()
回调和Tango.getPoseAtTime()
的姿势之间存在重大差异。 我编写了一个测试程序,其中在onPoseAvailable()
我记录了所提供的姿势,并使用getPoseAtTime()
使用来自2个回调的时间戳来请求姿势。 KEY_BOOLEAN_SMOOTH_POSE
配置为false
。 这是执行此操作的代码( timestamps_
成员变量是LinkedList<Double>
):
@Override
public void onPoseAvailable(TangoPoseData poseData) {
if (poseData != null && poseData.statusCode == TangoPoseData.POSE_VALID) {
Log.v("bug",
String.format("onPoseAvailable t: %f, base: %d, target %d, p: (%f, %f, %f)",
poseData.timestamp,
poseData.baseFrame,
poseData.targetFrame,
poseData.translation[0], poseData.translation[1], poseData.translation[2]));
timestamps_.add(poseData.timestamp);
if (timestamps_.size() > 3)
timestamps_.remove();
}
if (timestamps_.isEmpty())
return;
TangoCoordinateFramePair framePair = new TangoCoordinateFramePair(
TangoPoseData.COORDINATE_FRAME_START_OF_SERVICE,
TangoPoseData.COORDINATE_FRAME_DEVICE);
poseData = tango_.getPoseAtTime(timestamps_.getFirst(), framePair);
if (poseData != null && poseData.statusCode == TangoPoseData.POSE_VALID) {
Log.v("bug",
String.format("getPoseAtTime t: %f, base: %d, target %d, p: (%f, %f, %f)",
poseData.timestamp,
poseData.baseFrame,
poseData.targetFrame,
poseData.translation[0], poseData.translation[1], poseData.translation[2]));
}
}
这是实际日志的摘录(为清晰起见,我对记录的调用进行了去交织):
onPoseAvailable t: 2732.762486, base: 2, target 4, p: (0.280245, 0.412468, 0.562201)
onPoseAvailable t: 2732.802553, base: 2, target 4, p: (0.296951, 0.420919, 0.599938)
onPoseAvailable t: 2732.852638, base: 2, target 4, p: (0.317444, 0.429809, 0.646445)
onPoseAvailable t: 2732.882689, base: 2, target 4, p: (0.330845, 0.434106, 0.676810)
onPoseAvailable t: 2732.932774, base: 2, target 4, p: (0.350995, 0.439777, 0.723639)
onPoseAvailable t: 2732.962825, base: 2, target 4, p: (0.363319, 0.442731, 0.754508)
onPoseAvailable t: 2732.992875, base: 2, target 4, p: (0.373911, 0.445289, 0.784786)
onPoseAvailable t: 2733.032943, base: 2, target 4, p: (0.387709, 0.448182, 0.822682)
onPoseAvailable t: 2733.062994, base: 2, target 4, p: (0.398502, 0.450481, 0.852662)
onPoseAvailable t: 2733.073011, base: 2, target 4, p: (0.401869, 0.451084, 0.862530)
onPoseAvailable t: 2733.103062, base: 2, target 4, p: (0.411136, 0.452486, 0.890441)
getPoseAtTime t: 2732.712401, base: 2, target 4, p: (0.269301, 0.410911, 0.549182)
getPoseAtTime t: 2732.732435, base: 2, target 4, p: (0.277217, 0.415130, 0.567040)
getPoseAtTime t: 2732.762486, base: 2, target 4, p: (0.288928, 0.421914, 0.595162)
getPoseAtTime t: 2732.802553, base: 2, target 4, p: (0.305241, 0.429648, 0.632158)
getPoseAtTime t: 2732.852638, base: 2, target 4, p: (0.324359, 0.437655, 0.680300)
getPoseAtTime t: 2732.882689, base: 2, target 4, p: (0.332997, 0.442538, 0.712727)
getPoseAtTime t: 2732.932774, base: 2, target 4, p: (0.353665, 0.447269, 0.759725)
getPoseAtTime t: 2732.962825, base: 2, target 4, p: (0.369174, 0.451645, 0.790263)
getPoseAtTime t: 2732.992875, base: 2, target 4, p: (0.382584, 0.454754, 0.819555)
getPoseAtTime t: 2733.032943, base: 2, target 4, p: (0.396857, 0.456922, 0.856626)
getPoseAtTime t: 2733.062994, base: 2, target 4, p: (0.409672, 0.460060, 0.888748)
看一下最后一个带有时间戳2733.062994的getPoseAtTime()
条目。 请注意,其位置值与具有相同时间戳记的onPoseAvailable
中的姿势不匹配。 这里不对劲。
我确实认为,样条曲线的位姿拟合不一定需要通过控制点,但是我认为这不是可以接受的解释。 首先,拥有一个为同一测量提供不同值的API并没有多大意义。 但除此之外,实际数字并不支持这一推测。
查看getPoseAtTime()
Y值0.460060。 这在所有onPoseAvailable()
Y值的Y范围之前和之后(实际上是整个日志onPoseAvailable()
都在Y范围之外。 没有合理的插值模型可以产生该值。
我想问题是这里发生了什么? 姿势不一致,因此至少其中之一是错误的(如果不是两个)。 我的猜测是onPoseAvailable()
更可能是正确的。
这是将数位板固定在底座上时,两种姿势方法(Nash释放)的Y位置与时间的关系图:
蓝线是onPoseAvailable()
回调,红线是getPoseAtTime()
轮询。 这些结果有点奇怪。 如果姿势完全不同,我希望轮询值会更平滑,因为可以使用轮询时间之前和之后的样本贡献来过滤轮询值,而回调值将不被过滤或仅使用之前的值进行过滤样品。 但这不是我们所看到的-轮询的值看起来更嘈杂。
这是我上下移动平板电脑时捕获的类似图形。 轮询的值仍然具有更高的频率,并且两个信号之间的跟踪并不特别紧密。
感谢rhashimoto指出这一点!
编辑
我必须编辑我以前的帖子。 我声称使用GetPoseAtTime而不是OnPoseAvailable回调的姿势时,漂移更大。
反之亦然。 使用GetPoseAtTime可以获得更好的结果。
我通过在椅子上旋转360°进行了扫描。 如您在图片中所见,我在办公桌前停下来。
上方的点云使用GetPoseAtTime构成,下方的点云使用OnPoseAvailable回调构成。 两者同时捕获。 GetPoseAtTime的漂移很小,但OnPoseAvailable回调的漂移确实很大。
到目前为止,我发现,GetPoseAtTime使用姿势图并在检测到闭环时纠正姿势。 请参见本文 。 我测试了结果是否变好,是否立即使用可用的点云访问姿势或在合并所有点云时才访问姿势。
结果的确更好。 因此,到目前为止,我的经验是:
扫描结束时,OnPoseAvailabe回调<GetPoseAtTime立即具有可用点云<GetPoseAtTime
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.