我目前正在为一个学校项目工作,该项目需要为带有激光扫描仪的点机器人实现扩展的卡尔曼滤波器。机器人可以以0度转弯半径旋转并向前行驶。所有运动都是分段线性的(驱动,旋转,驱动)。
我们使用的模拟器不支持加速,所有运动都是瞬时的。
我们还需要定位一个已知的地图(png图像)。我们可以在图像中进行光线跟踪以模拟激光扫描。
我和我的搭档对我们需要使用的运动和传感器模型几乎不感到困惑。
到目前为止,我们将状态建模为向量。
我们使用更新公式如下
void kalman::predict(const nav_msgs::Odometry msg){
this->X[0] += linear * dt * cos( X[2] ); //x
this->X[1] += linear * dt * sin( X[2] ); //y
this->X[2] += angular * dt; //theta
this->F(0,2) = -linear * dt * sin( X[2] ); //t+1 ?
this->F(1,2) = linear * dt * cos( X[2] ); //t+1 ?
P = F * P * F.t() + Q;
this->linear = msg.twist.twist.linear.x;
this->angular = msg.twist.twist.angular.z;
return;
}
我们以为一切正常,直到我们注意到我们忘记初始化P
并且它为零,这意味着没有更正发生。显然,由于我们尚未将噪声引入系统,因此传播非常准确。
对于运动模型,我们对F使用以下矩阵:
作为我们的更新公式的雅可比行列式。它是否正确?
对于传感器模型,我们通过对机器人,和位置以及地图中的光线跟踪进行有限差分来逼近Jacobian(H)。我们与电讯局长交谈,电讯局长说这会奏效,但我仍不确定会否。我们的教授不在了,所以我们不能遗憾地问他。我们每个校正步骤使用3次激光测量,因此H为3x3。ÿ θ
关于如何初始化P的另一个问题。我们尝试了1,10,100,并且当地图仅为50x50时,它们都将机器人放置在地图的外部(-90,-70)。
我们项目的代码可以在这里找到:https : //github.com/en4bz/kalman/blob/master/src/kalman.cpp
任何意见是极大的赞赏。
编辑:
在这一点上,我已经使滤波器在基本运动噪声的作用下稳定下来,但没有实际运动。一旦机器人开始移动,过滤器就会迅速发散并离开地图。