轨迹误差评估指标[APE/RPE]和EVO[TUM/KITTI]
Reference:
在实际工程中,我们经常需要评估一个算法的估计轨迹与真实轨迹的差异来评价算法的精度。真实轨迹往往通过某些更高精度的系统获得,而估计轨迹则是由待评价的算法计算得到的。考虑一条估计轨迹 T e s t i , i T_{esti,i} Testi,i 和真实轨迹 T g t , i T_{gt,i} Tgt,i,其中 i = 1 , ⋅ ⋅ ⋅ , N i=1,\cdot\cdot\cdot,N i=1,⋅⋅⋅,N,那么我们可以定义一些误差指标来描述它们之间的差别。
《视觉SLAM十四讲》上的命名感觉跟 EVO 稍微有一点点区别,比如绝对轨迹误差(Absolute Trajectory Error, ATE):
A
T
E
a
l
l
=
1
N
∑
i
=
1
N
∥
log
(
T
g
t
,
i
−
1
T
esti
,
i
)
∨
∥
2
2
,
\mathrm{ATE}_{\mathrm{all}}=\sqrt{\frac{1}{N} \sum_{i=1}^N\left\|\log \left(T_{\mathrm{gt}, i}^{-1} T_{\text {esti }, i}\right)^{\vee}\right\|_2^2},
ATEall=N1i=1∑N
log(Tgt,i−1Testi ,i)∨
22,这玩意儿应该就是 EVO 中的 绝对位姿误差(Absolute Pose Error, APE),后面这个概念统称 APE。
这个公式实际上是每个位姿李代数的均方根误差(Root-Mean-Squared Error, RMSE)。这种误差可以刻画两条轨迹的旋转和平移误差。同时,也有的地方仅考虑平移误差,从而可以定义绝对平移误差(Absolute Translational Error, ATE):
A
T
E
trans
=
1
N
∑
i
=
1
N
∥
trans
(
T
g
t
,
i
−
1
T
est
,
i
)
∥
2
2
\mathrm{ATE}_{\text {trans }}=\sqrt{\frac{1}{N} \sum_{i=1}^N\left\|\operatorname{trans}\left(\boldsymbol{T}_{\mathrm{gt}, i}^{-1} \boldsymbol{T}_{\text {est }, i}\right)\right\|_2^2}
ATEtrans =N1i=1∑N
trans(Tgt,i−1Test ,i)
22其中 trans 表示取括号内部变量的平移部分。因为从整条轨迹上看,旋转出现误差后,随后的轨迹在瓶以上也会出现误差,所以两种指标在实际中都适用。
RPE 定义的是相对的误差。例如,考虑
i
i
i 时刻到
i
+
Δ
t
i+\Delta t
i+Δt 时刻的运动,那么相对位姿误差(Relative Pose Error, RPE)可定义为:
R
P
E
all
=
1
N
−
Δ
t
∑
i
=
1
N
−
Δ
t
∥
log
(
(
T
g
t
,
i
−
1
T
g
t
,
i
+
Δ
t
)
)
−
1
(
T
esti
,
i
−
1
T
esti
,
i
+
Δ
t
)
)
∨
∥
2
2
,
\mathrm{RPE}_{\text {all }}=\sqrt{\left.\frac{1}{N-\Delta t} \sum_{i=1}^{N-\Delta t} \| \log \left(\left(T_{\mathrm{gt}, i}^{-1} T_{\mathrm{gt}, i+\Delta t}\right)\right)^{-1}\left(T_{\text {esti }, i}^{-1} T_{\text {esti }, i+\Delta t}\right)\right)^{\vee} \|_2^2,}
RPEall =N−Δt1i=1∑N−Δt∥log((Tgt,i−1Tgt,i+Δt))−1(Testi ,i−1Testi ,i+Δt))∨∥22,同样地,也可只取平移部分:
R
P
E
trans
=
1
N
−
Δ
t
∑
i
=
1
N
−
Δ
t
∥
trans
(
(
T
g
t
,
i
−
1
T
g
t
,
i
+
Δ
t
)
)
−
1
(
T
esti
,
i
−
1
T
esti
,
i
+
Δ
t
)
)
∥
2
2
\mathrm{RPE}_{\text {trans }}=\sqrt{\left.\frac{1}{N-\Delta t} \sum_{i=1}^{N-\Delta t} \| \operatorname{trans}\left(\left(\boldsymbol{T}_{\mathrm{gt}, i}^{-1} \boldsymbol{T}_{\mathrm{gt}, i+\Delta t}\right)\right)^{-1}\left(T_{\text {esti }, i}^{-1} T_{\text {esti }, i+\Delta t}\right)\right) \|_2^2}
RPEtrans =N−Δt1i=1∑N−Δt∥trans((Tgt,i−1Tgt,i+Δt))−1(Testi ,i−1Testi ,i+Δt))∥22
TUM 数据集格式:timestamp tx ty tz qx qy qz qw

KITTI 数据集格式:一行
12
12
12 个数据,表示 Pose(R+t),可能还有另一个文件存放 timestamp

使用示例如下:
evo_ape kitti ground_truth.txt laser_odom.txt -r full --plot --plot_mode xyz
evo_rpe kitti ground_truth.txt laser_odom.txt -r trans_part --delta 100 --plot --plot_mode xyz
evo_ape 的默认形式是 -r trans_part,即计算的是这里的 ATE,想要计算 APE,可以使用 -r full。
-r 用法:
可以先使用 EVO 仓库中自带的数据尝试
cd test/data
evo_traj kitti KITTI_00_ORB.txt KITTI_00_SPTAM.txt --ref=KITTI_00_gt.txt -p --plot_mode=xz
其中:
evo_ape kitti KITTI_00_gt.txt KITTI_00_ORB.txt -va --plot --plot_mode xz --save_plot ./tra1plot --save_results ./tra1.zip
其中:
evo_rpe tum fr2_desk_groundtruth.txt fr2_desk_ORB.txt -va --plot --plot_mode xyz
evo_traj - 用于分析,绘制或导出一个或多个轨迹的工具
evo_res - 用于比较evo_ape或evo_rpe一个或多个结果文件的evo_rpe
evo_fig - 用于重新打开序列化图的(实验性)工具(使用–serialize_plot保存)
evo_config - 全局设置和配置文件操作的工具
evo_traj 主要是用来画轨迹、输出轨迹文件、转换数据格式等功能。
绘制单个轨迹:
evo_traj euroc ground_truth.csv --plot
绘制多个轨迹:
evo_traj kitti KITTI_00_ORB.txt KITTI_00_SPTAM.txt --ref=KITTI_00_gt.txt -p --plot_mode=xz
轨迹尺度缩放
单目相机会存在尺度的不确定性,evo_traj 支持使用 -s或–correct_scale 参数进行Sim(3)上的对齐(旋转、平移与尺度缩放,能非常方便的用于 RTK/GNSS 对轮齿脉冲的标定)
格式转换
如将 EuRoC 转成 TUM 格式,输出为 data.tum:
evo_traj euroc data.csv --save_as_tum
我在Ruby程序中有两个URI。一个肯定是绝对URI,另一个可能是绝对URI或相对URI。我想在第一个的上下文中将第二个转换为绝对URI,所以如果第一个是http://pupeno.com/blog第二个是/about,结果应该是http://pupeno.com/about.有什么想法吗? 最佳答案 Ruby的内置URI和Addressablegem,做这个简短的工作。我更喜欢Addressable,因为它功能更全面,但URI是内置的。require'uri'URI.join('http://pupeno.com/blog','/
我有一个Builder类,可让您添加到其中一个实例变量:classBuilderdefinitialize@lines=[]enddeflinesblock_given??yield(self):@linesenddefadd_line(text)@lines现在,我该如何改变它my_builder=Builder.newmy_builder.lines{|b|b.add_line"foo"b.add_line"bar"}pmy_builder.lines#=>["foo","bar"]进入这个?my_builder=Builder.newmy_builder.lines{add_li
在我的代码中,我使用自动加载进行惰性评估,这样我可以更快地加载程序并在需要时加载文件,我没有看到很多人使用它,但在Thin项目中我注意到自动加载已被广泛使用,反正只是想知道使用它是否有任何风险。 最佳答案 autoload是notthreadsafe并将在未来的Ruby版本中弃用。这是proofbyMatz(ruby的创造者)。 关于ruby-使用autoload与ruby中的require进行惰性评估?,我们在StackOverflow上找到一个类似的问题:
文章目录前言约束硬约束的轨迹优化Corridor-BasedTrajectoryOptimizationBezierCurveOptimizationOtherOptions软约束的轨迹优化Distance-BasedTrajectoryOptimization优化方法前言可以看看我的这几篇Blog1,Blog2,Blog3。上次基于MinimumSnap的轨迹生成,有许多优点,比如:轨迹让机器人可以在某个时间点抵达某个航点。任何一个时刻,都能数学上求出期望的机器人的位置、速度、加速度、导数。MinimumSnap可以把问题转换为凸优化问题。缺点:MnimumSnap可以控制轨迹一定经过中间的
我已经熟悉并使用Ant&Maven,此时我想扩展到另一个工具,我在“Buildr”和“Gradle”之间做出决定。我非常感谢那些使用过其中一种或两种工具的人的见解/反馈,因为坦率地说,在这一点上,对我来说唯一真正的区别似乎是ruby与groovy(我对两者都感到满意并喜欢)。我也希望能回答以下问题:我知道Buildr允许下载和提取不在maven类型存储库中的依赖项,Gradle是否提供相同的功能?Buildr/Gradle能否用于构建其他语言的源代码——即groovy、ruby、actionscript/flex、c系列等?Buildr/Gradle与Hudson或Jenkins的
如果我有如下的ActiveRecord模型classFooself.allowed_typesdefself.allowed_types#somecodethatreturnsanenumerableendend这不起作用,因为在评估验证时尚未定义allowed_types方法。我能想到的所有修复基本上都是围绕将方法定义移到验证之上,以便在需要时可用。我明白这可能更像是一个编码风格问题(我希望我的所有验证都在模型顶部,方法在底部)但我觉得应该有某种解决方案,可能涉及初始模型加载的惰性评估?我想做的事有可能吗?我应该只在验证之上定义方法,还是有更好的验证解决方案来实现我想要的。
我的理解是ruby返回函数中评估的最后一条语句。如果函数以if语句结束,结果为falsedefthing(input)item=input=="hi"ifitem[]endendputsthing("hi").class#>Arrayputsthing("nothi").class#>NilClass我喜欢这个功能(如果语句为false,则返回nil),但为什么不返回false(从赋值给item)? 最佳答案 如果您的if语句没有运行任何代码,则返回nil,否则返回已运行代码的值。Irb是试验这些东西的好工具。irb(main)
实现后NullObjectPattern在Rails应用程序中(也在RubyTapas第112集中描述)我重构了一些代码,但有一个语法结构似乎不再起作用。我曾经写过像current_user||这样的语句redirect_out,如果设置了current_user,它会返回它,如果它是nil,它会重定向出去,但现在current_user可能是Null::User,因此是“真实的”,并且该片段永远不会重定向。我尝试定义||运算符,但没有成功。有什么方法可以将此语法用于空(但“真实”)对象? 最佳答案 我认为您只是半途采用了该模式,并
目录1. 研究范围定义2. 流程中台市场分析3. 厂商评估:微宏科技4. 入选证书 1. 研究范围定义近年来,随着外部市场环境快速变化、客户需求愈发多样,企业逐渐意识到,自身业务需要更加敏捷、高效,具备根据市场需求快速迭代的能力。业务流程的自动化能够帮助企业实现业务的敏捷高效,因此受到越来越多企业的关注。企业的“自动化武器库”品类丰富,包括低/零代码平台、RPA、BPM、AI等。企业可以使用多项自动化工具,但结果往往是各项自动化工具处于各自的“自动化烟囱”之中,仅能实现碎片式自动化。例如,某企业的IT团队可能在使用低代码平台、财务团队可能在使用RPA、呼叫中心则可能在使用聊天机器人。自动
假设我有一个XML::Element...我想做类似的事情:my_xml_element.send("parent.next_sibling.next_sibling") 最佳答案 在你的情况下,最好使用instance_eval"Test".instance_eval{chop!.chop!}#=>"Te"对于您的代码:my_xml_element.instance_eval{parent.next_sibling.next_sibling} 关于Ruby:如何评估每个发送命令的多个方