Robotics StackExchange | Archived questions

robot_pose_ekf : IMU frame and base_footprint rotates too much.

Hello everyone,

I am implementing an IMU (accelerometer, gyroscope and magnetometer) and want to fuse it with my odometry to optimize the odometry I'll then put in AMCL.

I use the robotposeekf package and I put a low covariance on yaw orientation of the IMU to give it a lot of "weight" in the final estimation (given the magnetometer is a precise and absolute sensor) but it seems like when I rotate in place of an angle of 90°, my IMUframe end up 90° away from my IMUbase frame (that is fixed to baselink frame) but my baselink ends up 270 ° away from my odom frame. As seen in this video : here Note that this is my imuframe and imubase frames seen within the odom frame (ixed frame in rviz).

This tftree shows you my current configuration : tf_tree. The basefootprint_odom is the one created from pure odom so I can can compare the two.

My Imu msgs are published in the imu_frame :

header: 
  seq: 15771
  stamp: 
    secs: 1661346327
    nsecs: 523344384
  frame_id: "imu_frame"
...

The IMU tf is broadcast as follows :

    transform.setRotation(imu_quaternion);

    ROS_INFO("Publishing tf\n");

    tf_br.sendTransform(tf::StampedTransform(transform, current_time, "imu_base", "imu_frame"));

    imu_out=*imu;
    imu_out.header.frame_id="imu_base";
    imu_out.orientation.w=-imu_out.orientation.w; //needed so it's imu_base->imu_frame and not the opposite
    imu_out.orientation_covariance=boost::assign::list_of(1e-9)(0)(0)
                                                          (0)(1e-9)(0)
                                                          (0)(0)(1e-6);

    imu_out.angular_velocity_covariance=boost::assign::list_of(1e-3)(0)(0)
                                                              (0)(1e-3)(0)
                                                              (0)(0)(1e-3);

    imu_out.linear_acceleration_covariance=boost::assign::list_of(1e-3)(0)(0)
                                                                 (0)(1e-3)(0)
                                                                 (0)(0)(1e-6);                                                     
    imu_pub.publish(imu_out);

My robotposeekf launch file looks like this :

<launch>

<node pkg="robot_pose_ekf" type="robot_pose_ekf" name="robot_pose_ekf">  
<param name="output_frame" value="odom"/>   
<param name="base_footprint_frame" value="base_footprint"/>   
<param name="freq" value="30.0"/>   
<param name="sensor_timeout" value="1.0"/>    
<param name="odom_used" value="true"/> 
<param name="imu_used" value="true"/>  
<param name="vo_used" value="false"/>

  <remap from="odom" to="/odom" />   
 <remap from="/imu_data" to="listener_cpp/imu/data_raw" /> </node>

</launch>

If anyone has a solution or a suggestion on how to debug this issue, I'd be glad to hear it. Sincerely yours.

EDIT : My tf tree looks like that:

                                          odom

                                             |

                                         base_footprint

                                             |

                                         base_link

                                             |

                                        imu_base

                                             |

                                        imu_frame

With the dynamic tf imubase->imuframe being computed from the orientation of my IMU (with imu_base as my fixed frame). Thomas

Asked by thomzem on 2022-08-24 08:24:37 UTC

Comments

What is imu_frame? Please tell us the transform frame names from odom to imu_base for your robot.

Asked by Mike Scheutzow on 2022-08-28 09:23:50 UTC

Why are you modifying the imu message orientation before publishing it to the imu_data topic? Is there something non-standard about the imu sensor?

Asked by Mike Scheutzow on 2022-08-31 21:16:06 UTC

Actually the orientation needed to be changed because my IMU (3dm-cv7 from Lord Microstrain) returned the orientation of the global frame in the sensor frame instead of the opposite. I just reverse it to have the right message I needed. The same is done with the tf I send but using the transform. inverse() function (prior in my code) . I am curious to know if there is any convention about these IMU relative frames.

Asked by thomzem on 2022-09-01 03:02:39 UTC

Answers

I actually found my error : the imu message I feed the Kalman filter was relative to the "imu_frame" instead of "imu_base". It means that when my Kalman filter uses the IMU message it considers the orientation variation in the imu_frame that is himself rotating around imu_base, hence the orientation going twice as far as it it should.

Asked by thomzem on 2022-09-01 02:55:39 UTC

Comments

If you have gotten the rough odometry results making sense, then the next thing I would check is whether or not the robot_pose_ekf compensates for an imu sensor that is not mounted at the robot's center of rotation.

Asked by Mike Scheutzow on 2022-09-01 06:21:00 UTC