Je travaille actuellement sur un projet pour l'école où j'ai besoin d'implémenter un filtre de Kalman étendu pour un robot ponctuel avec un scanner laser. Le robot peut tourner avec un rayon de braquage de 0 degré et avancer. Tous les mouvements sont linéaires par morceaux (entraînement, rotation, entraînement).
Le simulateur que nous utilisons ne prend pas en charge l'accélération, tout mouvement est instantané.
Nous avons également une carte connue (image png) que nous devons localiser. Nous pouvons ray tracer dans l'image afin de simuler des balayages laser.
Mon partenaire et moi sommes peu confus quant aux modèles de mouvement et de capteur que nous devrons utiliser.
Jusqu'à présent, nous modélisons l'état comme un vecteur .
Nous utilisons les équations de mise à jour comme suit
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;
}
Nous pensions que tout fonctionnait jusqu'à ce que nous remarquions que nous avons oublié d'initialiser P
et que c'était zéro, ce qui signifie qu'aucune correction ne s'est produite. Apparemment, notre propagation était très précise car nous n'avons pas encore introduit de bruit dans le système.
Pour le modèle de mouvement, nous utilisons la matrice suivante pour F:
Comme son jacobien de nos formules de mise à jour. Est-ce correct?
L'autre problème était d'avoir comment initialiser P. Nous avons essayé 1,10,100 et ils placent tous le robot en dehors de la carte à (-90, -70) lorsque la carte n'est que de 50x50.
Le code de notre projet se trouve ici: https://github.com/en4bz/kalman/blob/master/src/kalman.cpp
Tout conseil est grandement appréciée.
ÉDITER:
À ce stade, le filtre s'est stabilisé avec un bruit de mouvement de base, mais aucun mouvement réel. Dès que le robot commence à bouger, le filtre diverge assez rapidement et quitte la carte.
la source
Tout d'abord, vous n'avez rien dit sur le type de localisation que vous utilisez. Est-ce avec des correspondances connues ou inconnues?
Maintenant, pour acquérir le jacobien dans Matlab, vous pouvez faire ce qui suit
Le résultat
Le filtre de Kalman étendu nécessite que le système soit linéaire et que le bruit soit gaussien. Le système signifie ici que les modèles de mouvement et d'observation doivent être linéaires. Les capteurs laser donnent la portée et l'angle vers un point de repère à partir du cadre du robot, de sorte que le modèle de mesure n'est pas linéaire. À propos
P
, si vous supposez qu'il est grand, votre estimateur EKF sera médiocre au début et il s'appuie sur les mesures car le vecteur d'état précédent n'est pas disponible. Cependant, une fois que votre robot commencera à se déplacer et à détecter, l'EKF s'améliorera car il utilise les modèles de mouvement et de mesure pour estimer la pose du robot. Si votre robot ne détecte aucun point de repère, l'incertitude augmente considérablement. En outre, vous devez faire attention à l'angle. En C ++,cos and sin
, l'angle doit être en radian. Il n'y a rien dans votre code concernant ce problème. Si vous supposez le bruit de l'angle en degrés lors de votre calcul en radian, vous pourriez obtenir des résultats étranges car un degré de bruit alors que les calculs en radian sont considérés comme énormes.la source