草庐IT

【算法】kalman运动状态估计不准确的思考

RockWang. 2023-09-27 原文

前言

在仿真实验多目标跟踪时,我采用了Kalman做跟踪,在运动状态估计时位置可以很“准确”的估计,但是速度与方向就偏差很大,最近看到了一篇文献详细的介绍了原因,之前考虑到时间间隔太小,噪声又很大的影响,但没有深究。
Observation-Centric SORT: Rethinking SORT for Robust Multi-Object Tracking

1.综述

这篇文章是在SORT的基础上进行的改进,主要指出了基于运动建模的方式的三个缺点,传统的卡尔曼预测方式假设运动在一段时间间隔内是线性的,基于这个假设,在极短的时间间隔内卡尔曼预测的位置是“准确的”,注意是引号,后面会讲。但对于长时间的预测,物体运动很难满足线性的要求,所以长时间的预测用卡尔曼效果并不好。这篇文章主要指出了三个问题:

  1. 首先,尽管高帧率是将物体运动近似为线性的关键,但它也放大了模型对状态估计噪声的敏感性。具体来说,在高帧率视频包括激光雷达数据的连续帧之间,作者证明了物体位移的噪声可以与实际物体位移的大小相同,导致KF估计的物体速度存在显著差异。同时,速度估计中的噪声会通过过渡过程累积到位置估计中。
  2. 其次,在KF更新阶段没有观测值时,KF状态估计的噪声会随着时间的推移而累积。作者发现,误差积累非常快,相对于目标对象被取消跟踪的时间来说。噪声对速度方向的影响往往会使重新关联后的轨迹再次丢失。
  3. 最后,考虑到目标检测的发展,通过“检测得到的目标状态通常比通过固定运动模型估计出的状态具有更低的方差。然而,SORT的设计是通过状态估计而不是观测来延长物体的轨迹。作者的意思是目前检测器发展很快,比如深度学习的各种目标检测模型比状态估计要成熟可靠,所以作者想能不能提高观测的权重来改进卡尔曼以估计为主的模式。

2.理论推导


这是文章中的卡尔曼更新方程,这是我见过表达最清晰的,尤其是update部分采用的 x ^ t ∣ t \widehat{x}_{t|t} x tt代表t时刻对t时刻的状态进行估计,区别于t-1时刻对t时刻估计。

误差分析


上面就是位置估计的公式

这是给出了误差与时间的关系,误差原理大学本科的时候学过,还有点印象:

D ( U − V ) = D ( U ) + D ( V ) + 协方差矩阵 D(U-V)=D(U)+D(V)+协方差矩阵 D(UV)=D(U)+D(V)+协方差矩阵
如果相互独立则
D ( U − V ) = D ( U ) + D ( V ) D(U-V)=D(U)+D(V) D(UV)=D(U)+D(V)
可以看出时间间隔越小误差影响越大,所以验证了可以增加时间间隔来减少误差的影响,但是治标不治本,跟踪还是要首先考虑实时性。

这是位置的误差,与速度相反时间越长误差越大。然后作者分别给出了三个缺点对应的解决方案。正在看…

2.思考

  1. 回到前面提到的“准确”为什么加引号。卡尔曼之所以“准确”是因为观测值的修正,卡尔曼在模型理论值与观测值之间取了一个相对可靠的数据,但是这个数据虽然可靠但是不一定最接近真值,可以说它选择一个在自己的经验内最有把握的,最信赖的数据,至于准不准是次要的,可靠是首要的。所以在观测值丢失后,卡尔曼像盲人凭感觉经验进行估计,短时间内可行,长时间会偏离真值,正如人走路,会时不时看一下路纠正一下。走大路没人时可以玩手机-“无观测预测”,当小路有很多人时需要时刻看路-“观测修正”。但是在小路有很多人时没有观测那么就出问题了——撞树走偏。
  2. 如何有效解决短时间内噪声对速度估计的影响,并保持高帧率的处理速度?
  3. 对于单线激光雷达数据在跟踪时,本身检测的形状也是不稳定的,如果检测稳定需要提供足够的数据或者检测算法有所改进。

有关【算法】kalman运动状态估计不准确的思考的更多相关文章

  1. ruby - 在 Ruby 程序执行时阻止 Windows 7 PC 进入休眠状态 - 2

    我需要在客户计算机上运行Ruby应用程序。通常需要几天才能完成(复制大备份文件)。问题是如果启用sleep,它会中断应用程序。否则,计算机将持续运行数周,直到我下次访问为止。有什么方法可以防止执行期间休眠并让Windows在执行后休眠吗?欢迎任何疯狂的想法;-) 最佳答案 Here建议使用SetThreadExecutionStateWinAPI函数,使应用程序能够通知系统它正在使用中,从而防止系统在应用程序运行时进入休眠状态或关闭显示。像这样的东西:require'Win32API'ES_AWAYMODE_REQUIRED=0x0

  2. ruby-on-rails - 跳过状态机方法的所有验证 - 2

    当我的预订模型通过rake任务在状态机上转换时,我试图找出如何跳过对ActiveRecord对象的特定实例的验证。我想在reservation.close时跳过所有验证!叫做。希望调用reservation.close!(:validate=>false)之类的东西。仅供引用,我们正在使用https://github.com/pluginaweek/state_machine用于状态机。这是我的预订模型的示例。classReservation["requested","negotiating","approved"])}state_machine:initial=>'requested

  3. ruby - 字符串文字中的转义状态作为 `String#tr` 的参数 - 2

    对于作为String#tr参数的单引号字符串文字中反斜杠的转义状态,我觉得有些神秘。你能解释一下下面三个例子之间的对比吗?我特别不明白第二个。为了避免复杂化,我在这里使用了'd',在双引号中转义时不会改变含义("\d"="d")。'\\'.tr('\\','x')#=>"x"'\\'.tr('\\d','x')#=>"\\"'\\'.tr('\\\d','x')#=>"x" 最佳答案 在tr中转义tr的第一个参数非常类似于正则表达式中的括号字符分组。您可以在表达式的开头使用^来否定匹配(替换任何不匹配的内容)并使用例如a-f来匹配一

  4. ruby - Net::HTTP 获取源代码和状态 - 2

    我目前正在使用以下方法获取页面的源代码:Net::HTTP.get(URI.parse(page.url))我还想获取HTTP状态,而无需发出第二个请求。有没有办法用另一种方法做到这一点?我一直在查看文档,但似乎找不到我要找的东西。 最佳答案 在我看来,除非您需要一些真正的低级访问或控制,否则最好使用Ruby的内置Open::URI模块:require'open-uri'io=open('http://www.example.org/')#=>#body=io.read[0,50]#=>"["200","OK"]io.base_ur

  5. 区块链之加解密算法&数字证书 - 2

    目录一.加解密算法数字签名对称加密DES(DataEncryptionStandard)3DES(TripleDES)AES(AdvancedEncryptionStandard)RSA加密法DSA(DigitalSignatureAlgorithm)ECC(EllipticCurvesCryptography)非对称加密签名与加密过程非对称加密的应用对称加密与非对称加密的结合二.数字证书图解一.加解密算法加密简单而言就是通过一种算法将明文信息转换成密文信息,信息的的接收方能够通过密钥对密文信息进行解密获得明文信息的过程。根据加解密的密钥是否相同,算法可以分为对称加密、非对称加密、对称加密和非

  6. FOHEART H1数据手套驱动Optitrack光学动捕双手运动(Unity3D) - 2

    本教程将在Unity3D中混合Optitrack与数据手套的数据流,在人体运动的基础上,添加双手手指部分的运动。双手手背的角度仍由Optitrack提供,数据手套提供双手手指的角度。 01  客户端软件分别安装MotiveBody与MotionVenus并校准人体与数据手套。MotiveBodyMotionVenus数据手套使用、校准流程参照:https://gitee.com/foheart_1/foheart-h1-data-summary.git02  数据转发打开MotiveBody软件的Streaming,开始向Unity3D广播数据;MotionVenus中设置->选项选择Unit

  7. ruby-on-rails - 为模型创建状态属性 - 2

    我想为我的Task模型创建一个status属性,该属性将按以下顺序指示它在三部分进度中的位置:打开=>进行中=>完成。它的工作方式类似于亚马逊包裹的交付方式:已订购=>已发货=>已交付。我想知道设置此属性的最佳方法是什么。我可能是错的,但创建三个独立的bool属性似乎有点多余。实现此目标的最佳方法是什么? 最佳答案 Rails4有一个内置的enummacro.它使用单个整数列并映射到键列表。classOrderenumstatus:[:ordered,:shipped,:delivered]end状态映射如下:{ordered:0,

  8. ruby - 是否可以在不实际发送或读取数据的情况下查明 ruby​​ 套接字是否处于 ESTABLISHED 或 CLOSE_WAIT 状态? - 2

    s=Socket.new(Socket::AF_INET,Socket::SOCK_STREAM,0)s.connect(Socket.pack_sockaddr_in('port','hostname'))ssl=OpenSSL::SSL::SSLSocket.new(s,sslcert)ssl.connect从这里开始,如果ssl连接和底层套接字仍然是ESTABLISHED,或者它是否在默认值7200之后进入CLOSE_WAIT,我想检查一个线程几秒钟甚至更糟的是在实际上不需要.write()或.read()的情况下关闭。是用select()、IO.select()还是其他方法完成

  9. ruby - 在 ruby​​ 中生成一个进程,捕获 stdout,stderr,获取退出状态 - 2

    我想从ruby​​rake脚本运行一个可执行文件,比如foo.exe我希望将foo.exe的STDOUT和STDERR输出直接写入我正在运行rake任务的控制台.当进程完成时,我想将退出代码捕获到一个变量中。我如何实现这一目标?我一直在玩backticks、process.spawn、system但我无法获得我想要的所有行为,只有部分更新:我在Windows上,在标准命令提示符下,而不是cygwin 最佳答案 system获取您想要的STDOUT行为。它还返回true作为零退出代码,这可能很有用。$?填充了有关最后一次system调

  10. ruby-on-rails - 状态机、模型验证和 RSpec - 2

    这是我当前的类定义和规范:classEvent:not_starteddoevent:game_starteddotransition:not_started=>:in_progressendevent:game_endeddotransition:in_progress=>:finalendevent:game_postponeddotransition[:not_started,:in_progress]=>:postponedendstate:not_started,:in_progress,:postponeddovalidate:end_time_before_finalen

随机推荐