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
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
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 theimu_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