ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

I've had the same issue with yaw drift (also with the use_mag set to false) and never had much of a chance to dig into it. All IMUs drift over time, but I'm surprised how quickly this one starts to drift even after calibration. Unfortunately robot_pose_ekf doesn't take /cmd_vel as an input to see that the robot is not being commanded to move (rather it depends solely on wheel odometry for that through topic /odom and the IMU /imu) so the ekf doesn't really help.

So far I've had two hacky solutions to solve this problem which are suboptimal: 1) Repetitive calibration: Call rosservice /imu/calibrate which will stop the drifting temporarily. Do this whenever the robot is still (very important!) and on flat ground. I had the robot call this service automatically when it detects drift or after a certain timeout threshold. This works well enough for my use case to get the job done....but slight drift will still happen over time regardless. If you're performing SLAM or static map localization (e.g. AMCL), the robot will correct its position in the map frame anyway automatically....so doesn't matter if odom is a little wacky.

2) Ignore the yaw if you have another sensor measuring yaw: On the base I'm using, there's a very good single-axis gyro which is fused into the wheel odometry by its ROS driver. I would prefer having that yaw versus the drifting one generated through the IMU + robot_pose_ekf -- though I would still like to keep the roll and pitch components from the phidgets. You can either adjust the imu driver code or write a filter node for /imu to change the covariance matrix so the error is high for Z-axis (which corresponds to the yaw component) in the phidgets IMU so that robot_pose_ekf will weight the yaw from the wheel odometry (with the good gyro) more heavily. The other option which doesn't require changing IMU stuff is to write a node that subscribes to the wheel odometry /odom and to the fused result /odom_combined that's generated by robot_pose_ekf (which is incorporated /odom and /imu). You want to then take the x,y,z,roll,pitch components from /odom_combined and then take /yaw from odom and now publish to a new topic...let's say /odom_final...which is the odometry all your nodes should use. The new node should also publish the transform between /odom and /base_footprint....you should make sure that the same transform from robot_pose_ekf is ignored (set it to a garbage frame if you have to).

Sorry that #2 might be confusing, but that's the only thing I could think of so far. I'm hoping to get more cycles to look into the problem further. Perhaps Martin can chime in with more suggestions.

Best of luck!

I've had the same issue with yaw drift (also with the use_mag set to false) and never had much of a chance to dig into it. All IMUs drift over time, but I'm surprised how quickly this one starts to drift even after calibration. Unfortunately robot_pose_ekf doesn't take /cmd_vel as an input to see that the robot is not being commanded to move (rather it depends solely on wheel odometry for that through topic /odom and the IMU /imu) so the ekf doesn't really help.

So far I've had two hacky solutions to solve this problem which are suboptimal: suboptimal:

1) Repetitive calibration: Call rosservice /imu/calibrate which will stop the drifting temporarily. Do this whenever the robot is still (very important!) and on flat ground. I had the robot call this service automatically when it detects drift or after a certain timeout threshold. This works well enough for my use case to get the job done....but slight drift will still happen over time regardless. If you're performing SLAM or static map localization (e.g. AMCL), the robot will correct its position in the map frame anyway automatically....so doesn't matter if odom is a little wacky.

OR

2) Ignore the yaw if you have another sensor measuring yaw: On the base I'm using, there's a very good single-axis gyro which is fused into the wheel odometry by its ROS driver. I would prefer having that yaw versus the drifting one generated through the IMU + robot_pose_ekf -- though I would still like to keep the roll and pitch components from the phidgets. You can either adjust the imu driver code or write a filter node for /imu to change the covariance matrix so the error is high for Z-axis (which corresponds to the yaw component) in the phidgets IMU so that robot_pose_ekf will weight the yaw from the wheel odometry (with the good gyro) more heavily. The other option which doesn't require changing IMU stuff is to write a node that subscribes to the wheel odometry /odom and to the fused result /odom_combined that's generated by robot_pose_ekf (which is incorporated /odom and /imu). You want to then take the x,y,z,roll,pitch components from /odom_combined and then take /yaw from odom and now publish to a new topic...let's say /odom_final...which is the odometry all your nodes should use. The new node should also publish the transform between /odom and /base_footprint....you should make sure that the same transform from robot_pose_ekf is ignored (set it to a garbage frame if you have to).

Sorry that #2 might be confusing, but that's the only thing I could think of so far. I'm hoping to get more cycles to look into the problem further. Perhaps Martin can chime in with more suggestions.

Best of luck!

I've had the same issue with yaw drift (also with the use_mag set to false) and never had much of a chance to dig into it. All IMUs drift over time, but I'm surprised how quickly this one starts to drift even after calibration. Unfortunately robot_pose_ekf doesn't take /cmd_vel as an input to see that the robot is not being commanded to move (rather it depends solely on wheel odometry for that through topic /odom and the IMU /imu) so the ekf doesn't really help.

So far I've had two hacky solutions to solve this problem which are suboptimal:

1) Repetitive calibration: Call rosservice /imu/calibrate which will stop the drifting temporarily. Do this whenever the robot is still (very important!) and on flat ground. I had the robot call this service automatically when it detects drift or after a certain timeout threshold. This works well enough for my use case to get the job done....but slight drift will still happen over time regardless. If you're performing SLAM or static map localization (e.g. AMCL), the robot will correct its position in the map frame anyway automatically....so doesn't matter if odom is a little wacky.

OR

2) Ignore the yaw if you have another sensor measuring yaw: On the base I'm using, there's a very good single-axis gyro which is fused into the wheel odometry by its ROS driver. I would prefer having that yaw versus the drifting one generated through the IMU + robot_pose_ekf -- though I would still like to keep the roll and pitch components from the phidgets. You can either adjust the imu driver code or write a filter node for /imu to change the covariance matrix so the error is high for Z-axis (which corresponds to the yaw component) in the phidgets IMU so that robot_pose_ekf will weight the yaw from the wheel odometry (with the good gyro) more heavily. The other option which doesn't require changing IMU stuff is to write a node that subscribes to the wheel odometry /odom and to the fused result /odom_combined that's generated by robot_pose_ekf (which is incorporated /odom and /imu). You want to then take the x,y,z,roll,pitch components from /odom_combined and then take /yaw yaw from odom /odom and now publish to a new topic...let's say /odom_final...which is the odometry all your nodes should use. The new node should also publish the transform between /odom and /base_footprint....you should make sure that the same transform from robot_pose_ekf is ignored (set it to a garbage frame if you have to).

Sorry that #2 might be confusing, but that's the only thing I could think of so far. I'm hoping to get more cycles to look into the problem further. Perhaps Martin can chime in with more suggestions.

Best of luck!

I've had the same issue with yaw drift (also with the use_mag set to false) and never had much of a chance to dig into it. All IMUs drift over time, but I'm surprised how quickly this one starts to drift even after calibration. Unfortunately robot_pose_ekf doesn't take /cmd_vel as an input to see that the robot is not being commanded to move (rather it depends solely on wheel odometry for that through topic /odom and the IMU /imu) so the ekf doesn't really help.

So far I've had two hacky solutions to solve this problem which are suboptimal:

1) Repetitive calibration: Call rosservice /imu/calibrate which will stop the drifting temporarily. Do this whenever the robot is still (very important!) and on flat ground. I had the robot call this service automatically when it detects drift or after a certain timeout threshold. This works well enough for my use case to get the job done....but slight drift will still happen over time regardless. If you're performing SLAM or static map localization (e.g. AMCL), the robot will correct its position in the map frame anyway automatically....so doesn't matter if odom is a little wacky.

OR

2) Ignore the yaw if you have another sensor measuring yaw: On the base I'm using, there's a very good single-axis gyro which is fused into the wheel odometry by its ROS driver. I would prefer having that yaw versus the drifting one generated through the IMU + robot_pose_ekf -- though I would still like to keep the roll and pitch components from the phidgets. You can either adjust the imu driver code or write a filter node for /imu to change the covariance matrix so the error is high for Z-axis (which corresponds to the yaw component) in the phidgets IMU so that robot_pose_ekf will weight the yaw from the wheel odometry (with the good gyro) more heavily. The other option which doesn't require changing IMU stuff is to write a node that subscribes to both the wheel odometry /odom (/odom) and to the fused result /odom_combined (/odom_combined) that's generated by robot_pose_ekf (which is incorporated incorporates /odom and /imu). You want to then take the x,y,z,roll,pitch components from /odom_combined and then take yaw from /odom and now publish to a new topic...let's say /odom_final...which is the odometry all your nodes should use. The new node should also publish the transform between /odom and /base_footprint....you should make sure that the same transform from robot_pose_ekf is ignored (set it to a garbage frame if you have to).

Sorry that #2 might be confusing, but that's the only thing I could think of so far. I'm hoping to get more cycles to look into the problem further. Perhaps Martin can chime in with more suggestions.

Best of luck!

I've had the same issue with yaw drift (also with the use_mag set to false) and never had much of a chance to dig into it. All IMUs drift over time, but I'm surprised how quickly this one starts to drift even after calibration. Unfortunately robot_pose_ekf doesn't take /cmd_vel as an input to see that the robot is not being commanded to move (rather it depends solely on wheel odometry for that through topic /odom and the IMU /imu) so the ekf doesn't really help.

So far I've had two hacky solutions to solve this problem which are suboptimal:

1) Repetitive calibration: Call rosservice /imu/calibrate which will stop the drifting temporarily. Do this whenever the robot is still (very important!) and on flat ground. I had the robot call this service automatically when it detects drift or after a certain timeout threshold. This works well enough for my use case to get the job done....but slight drift will still happen over time regardless. If you're performing SLAM or static map localization (e.g. AMCL), the robot will correct its position in the map frame anyway automatically....so doesn't matter if odom is a little wacky.

OR

2) Ignore the yaw if you have another sensor measuring yaw: On the base I'm using, there's a very good single-axis gyro which is fused into the wheel odometry by its ROS driver. I would prefer having that yaw versus the drifting one generated through the IMU + robot_pose_ekf -- though I would still like to keep the roll and pitch components from the phidgets. You can either adjust the imu driver code or write a filter node for /imu to change the covariance matrix so the error is high for Z-axis (which corresponds to the yaw component) in the phidgets IMU so that robot_pose_ekf will weight the yaw from the wheel odometry (with the good gyro) more heavily. The other option which doesn't require changing IMU stuff is to write a node that subscribes to both the wheel odometry (/odom) and to the fused result (/odom_combined) that's generated by robot_pose_ekf (which incorporates /odom and /imu). You want to then take the x,y,z,roll,pitch components from /odom_combined and then take yaw from /odom and now publish to a new topic...let's say /odom_final...which is the odometry all your nodes should use. The new node should also publish the transform between /odom and /base_footprint....you should make sure that the same transform from robot_pose_ekf is ignored (set it to a garbage frame if you have to).

Sorry that #2 might be confusing, but that's the only thing I could think of so far. I'm hoping to get more cycles to look into the problem further. Perhaps Martin @Martin Gunther can chime in with more suggestions.

Best of luck!

I've had the same issue with yaw drift (also with the use_mag set to false) and never had much of a chance to dig into it. All IMUs drift over time, but I'm surprised how quickly this one starts to drift even after calibration. Unfortunately robot_pose_ekf doesn't take /cmd_vel as an input to see that the robot is not being commanded to move (rather it depends solely on wheel odometry for that through topic /odom and the IMU /imu) so the ekf doesn't really help.

So far I've had two hacky solutions to solve this problem which are suboptimal:

1) Repetitive calibration: Call rosservice /imu/calibrate which will stop the drifting temporarily. Do this whenever the robot is still (very important!) and on flat ground. I had the robot call this service automatically when it detects drift or after a certain timeout threshold. This works well enough for my use case to get the job done....but slight drift will still happen over time regardless. If you're performing SLAM or static map localization (e.g. AMCL), the robot will correct its position in the map frame anyway automatically....so doesn't matter if odom is a little wacky.

OR

2) Ignore the yaw if you have another sensor measuring yaw: On the base I'm using, there's a very good single-axis gyro which is fused into the wheel odometry by its ROS driver. I would prefer having that yaw versus the drifting one generated through the IMU + robot_pose_ekf -- though I would still like to keep the roll and pitch components from the phidgets. You can either adjust the imu driver code or write a filter node for /imu to change the covariance matrix so the error is high for Z-axis (which corresponds to the yaw component) in the phidgets IMU so that robot_pose_ekf will weight the yaw from the wheel odometry (with the good gyro) more heavily. The other option which doesn't require changing IMU stuff is to write a node that subscribes to both the wheel odometry (/odom) and to the fused result (/odom_combined) that's generated by robot_pose_ekf (which incorporates /odom and /imu). You want to then take the x,y,z,roll,pitch components from /odom_combined and then take yaw from /odom and now publish to a new topic...let's say /odom_final...which is the odometry all your nodes should use. The new node should also publish the transform between /odom and /base_footprint....you should make sure that the same transform from robot_pose_ekf is ignored (set it to a garbage frame if you have to).

Sorry that #2 might be confusing, but that's the only thing I could think of so far. I'm hoping to get more cycles to look into the problem further. Perhaps @Martin Gunther @Martin-Gunther can chime in with more suggestions.

Best of luck!

I've had the same issue with yaw drift (also with the use_mag set to false) and never had much of a chance to dig into it. All IMUs drift over time, but I'm surprised how quickly this one starts to drift even after calibration. Unfortunately robot_pose_ekf doesn't take /cmd_vel as an input to see that the robot is not being commanded to move (rather it depends solely on wheel odometry for that through topic /odom and the IMU /imu) so the ekf doesn't really help.

So far I've had two hacky solutions to solve this problem which are suboptimal:

1) Repetitive calibration: Call rosservice /imu/calibrate which will stop the drifting temporarily. Do this whenever the robot is still (very important!) and on flat ground. I had the robot call this service automatically when it detects drift or after a certain timeout threshold. This works well enough for my use case to get the job done....but slight drift will still happen over time regardless. If you're performing SLAM or static map localization (e.g. AMCL), the robot will correct its position in the map frame anyway automatically....so doesn't matter if odom is a little wacky.

OR

2) Ignore the yaw if you have another sensor measuring yaw: On the base I'm using, there's a very good single-axis gyro which is fused into the wheel odometry by its ROS driver. I would prefer having that yaw versus the drifting one generated through the IMU + robot_pose_ekf -- though I would still like to keep the roll and pitch components from the phidgets. You can either adjust the imu driver code or write a filter node for /imu to change the covariance matrix so the error is high for Z-axis (which corresponds to the yaw component) in the phidgets IMU so that robot_pose_ekf will weight the yaw from the wheel odometry (with the good gyro) more heavily. The other option which doesn't require changing IMU stuff is to write a node that subscribes to both the wheel odometry (/odom) and to the fused result (/odom_combined) that's generated by robot_pose_ekf (which incorporates /odom and /imu). You want to then take the x,y,z,roll,pitch components from /odom_combined and then take yaw from /odom and now publish to a new topic...let's say /odom_final...which is the odometry all your nodes should use. The new node should also publish the transform between /odom and /base_footprint....you should make sure that the same transform from robot_pose_ekf is ignored (set it to a garbage frame if you have to).

Sorry that #2 might be confusing, but that's the only thing I could think of so far. I'm hoping to get more cycles to look into the problem further. Perhaps @Martin-Gunther @Martin\ Gunther can chime in with more suggestions.

Best of luck!

I've had the same issue with yaw drift (also with the use_mag set to false) and never had much of a chance to dig into it. All IMUs drift over time, but I'm surprised how quickly this one starts to drift even after calibration. Unfortunately robot_pose_ekf doesn't take /cmd_vel as an input to see that the robot is not being commanded to move (rather it depends solely on wheel odometry for that through topic /odom and the IMU /imu) so the ekf doesn't really help.

So far I've had two hacky solutions to solve this problem which are suboptimal:

1) Repetitive calibration: Call rosservice /imu/calibrate which will stop the drifting temporarily. Do this whenever the robot is still (very important!) and on flat ground. I had the robot call this service automatically when it detects drift or after a certain timeout threshold. This works well enough for my use case to get the job done....but slight drift will still happen over time regardless. If you're performing SLAM or static map localization (e.g. AMCL), the robot will correct its position in the map frame anyway automatically....so doesn't matter if odom is a little wacky.

OR

2) Ignore the yaw if you have another sensor measuring yaw: On the base I'm using, there's a very good single-axis gyro which is fused into the wheel odometry by its ROS driver. I would prefer having that yaw versus the drifting one generated through the IMU + robot_pose_ekf -- though I would still like to keep the roll and pitch components from the phidgets. You can either adjust the imu driver code or write a filter node for /imu to change the covariance matrix so the error is high for Z-axis (which corresponds to the yaw component) in the phidgets IMU so that robot_pose_ekf will weight the yaw from the wheel odometry (with the good gyro) more heavily. The other option which doesn't require changing IMU stuff is to write a node that subscribes to both the wheel odometry (/odom) and to the fused result (/odom_combined) that's generated by robot_pose_ekf (which incorporates /odom and /imu). You want to then take the x,y,z,roll,pitch components from /odom_combined and then take yaw from /odom and now publish to a new topic...let's say /odom_final...which is the odometry all your nodes should use. The new node should also publish the transform between /odom and /base_footprint....you should make sure that the same transform from robot_pose_ekf is ignored (set it to a garbage frame if you have to).

Sorry that #2 might be confusing, but that's the only thing I could think of so far. I'm hoping to get more cycles to look into the problem further. Perhaps @Martin\ Gunther Martin can chime in with more suggestions.suggestions -- can't seem to reference him though so he won't see this message :(

Best of luck!

I've had the same issue with of yaw drift with this IMU (also with the use_mag 'use_mag' set to false) and never had much of a chance to dig into it. All IMUs drift over time, but I'm surprised how quickly this one starts to drift even after calibration. Unfortunately robot_pose_ekf doesn't take /cmd_vel as an input to see that the robot is not being commanded to move (rather it depends solely on wheel odometry for that through topic /odom and the IMU /imu) so the ekf doesn't really help.

So far I've had two hacky solutions to solve this problem which are suboptimal:

1) Repetitive calibration: Call rosservice /imu/calibrate which will stop the drifting temporarily. Do this whenever the robot is still (very important!) and on flat ground. I had the robot call this service automatically when it detects drift or after a certain timeout threshold. This works well enough for my use case to get the job done....but slight drift will still happen over time regardless. If you're performing SLAM or static map localization (e.g. AMCL), the robot will correct its position in the map frame anyway automatically....so doesn't matter if odom is a little wacky.

OR

2) Ignore the yaw if you have another sensor measuring yaw: On the base I'm using, there's a very good single-axis gyro which is fused into the wheel odometry by its ROS driver. I would prefer having that yaw versus the drifting one generated through the IMU + robot_pose_ekf -- though I would still like to keep the roll and pitch components from the phidgets. You can either adjust the imu driver code or write a filter node for /imu to change the covariance matrix so the error is high for Z-axis (which corresponds to the yaw component) in the phidgets IMU so that robot_pose_ekf will weight the yaw from the wheel odometry (with the good gyro) more heavily. The other option which doesn't require changing IMU stuff is to write a node that subscribes to both the wheel odometry (/odom) and to the fused result (/odom_combined) that's generated by robot_pose_ekf (which incorporates /odom and /imu). You want to then take the x,y,z,roll,pitch components from /odom_combined and then take yaw from /odom and now publish to a new topic...let's say /odom_final...which is the odometry all your nodes should use. The new node should also publish the transform between /odom and /base_footprint....you should make sure that the same transform from robot_pose_ekf is ignored (set it to a garbage frame if you have to).

Sorry that #2 might be confusing, but that's the only thing I could think of so far. I'm hoping to get more cycles to look into the problem further. Perhaps Martin can chime in with more suggestions -- can't seem to reference him though so he won't see this message :(

Best of luck!

I've had the same issue of yaw drift with this IMU (also with 'use_mag' set to false) and never had much of a chance to dig into it. All IMUs drift over time, but I'm surprised how quickly this one starts to drift even after calibration. Unfortunately robot_pose_ekf doesn't take /cmd_vel as an input to see that the robot is not being commanded to move (rather it depends solely on wheel odometry for that through topic /odom and the IMU /imu) so the ekf doesn't really help.

So far I've had two two..scratch that...THREE hacky solutions to solve this problem which are suboptimal:

1) Repetitive calibration: Call rosservice /imu/calibrate which will stop the drifting temporarily. Do this whenever the robot is still (very important!) and on flat ground. I had the robot call this service automatically when it detects drift or after a certain timeout threshold. This works well enough for my use case to get the job done....but slight drift will still happen over time regardless. If you're performing SLAM or static map localization (e.g. AMCL), the robot will correct its position in the map frame anyway automatically....so doesn't matter if odom is a little wacky.

OR

2) Ignore the yaw if you have another sensor measuring yaw: On the base I'm using, there's a very good single-axis gyro which is fused into the wheel odometry by its ROS driver. I would prefer having that yaw versus the drifting one generated through the IMU + robot_pose_ekf -- though I would still like to keep the roll and pitch components from the phidgets. You can either adjust the imu driver code or write a filter node for /imu to change the covariance matrix so the error is high for Z-axis (which corresponds to the yaw component) in the phidgets IMU so that robot_pose_ekf will weight the yaw from the wheel odometry (with the good gyro) more heavily. The other option which doesn't require changing IMU stuff is to write a node that subscribes to both the wheel odometry (/odom) and to the fused result (/odom_combined) that's generated by robot_pose_ekf (which incorporates /odom and /imu). You want to then take the x,y,z,roll,pitch x,y,z,roll,pitch, linV, angV.x, angV.y components from /odom_combined and then take yaw and angV.z from /odom and now publish to a new topic...let's say /odom_final...which is the odometry all your nodes should use. The new node should also publish the transform between /odom and /base_footprint....you should make sure that the same transform from robot_pose_ekf is ignored (set (you can do this by remapping tf to tf_garbage in robot_pose_ekf).

OR 3) Just thought of this one and it to a garbage frame if doesn't require having another gyro. Write a filter node just like in option 2 that takes as input the command velocity (/cmd_vel), the raw wheel odometry (/odom), and the ekf smoothed odometry (/odom_combined). If the latest commanded velocity is 0, you have to).can assume the robot is not moving and that the yaw should be whatever it was when the robot last stopped. If the robot is moving, you can trust the IMU value. Combine this with option 1 where you call the calibrate service whenever the robot is not moving and all should be well. So in summary, when cmd_vel is 0, yaw = lastYaw, cmdVel != 0, yaw = imuYaw. Populate an odometry message with this yaw and the appropriate angular velocity about the z axis along with the other values from /odom_combined excluding yaw and z-axis rotational velocity and publish them to a new topic /odom_final.

Sorry that #2 might be and #3 are confusing, but that's they're the only thing solutions I could think conjure of so far. Also note that you'll have to convert r,p,y to quaternion notation for nav_msgs/Odometry. I'm hoping to get more cycles to look into the problem further. further -- at the very least write the filter I described in step 3. Perhaps Martin can chime in with more suggestions -- can't seem to reference him though so he won't see this message :(

Best of luck!

I've had the same issue of yaw drift with this IMU (also with 'use_mag' set to false) and never had much of a chance to dig into it. All IMUs drift over time, but I'm surprised how quickly this one starts to drift even after calibration. Unfortunately robot_pose_ekf doesn't take /cmd_vel as an input to see that the robot is not being commanded to move (rather it depends solely on wheel odometry for that through topic /odom and the IMU /imu) so the ekf doesn't really help.

So far I've had two..scratch that...THREE hacky solutions to solve this problem which are suboptimal:

1) Repetitive calibration: Call rosservice /imu/calibrate which will stop the drifting temporarily. Do this whenever the robot is still (very important!) and on flat ground. I had the robot call this service automatically when it detects drift or after a certain timeout threshold. This works well enough for my use case to get the job done....but slight drift will still happen over time regardless. If you're performing SLAM or static map localization (e.g. AMCL), the robot will correct its position in the map frame anyway automatically....so doesn't matter if odom is a little wacky.

OR

2) Ignore the yaw if you have another sensor measuring yaw: On the base I'm using, there's a very good single-axis gyro which is fused into the wheel odometry by its ROS driver. I would prefer having that yaw versus the drifting one generated through the IMU + robot_pose_ekf -- though I would still like to keep the roll and pitch components from the phidgets. You can either adjust the imu driver code or write a filter node for /imu to change the covariance matrix so the error is high for Z-axis (which corresponds to the yaw component) in the phidgets IMU so that robot_pose_ekf will weight the yaw from the wheel odometry (with the good gyro) more heavily. The other option which doesn't require changing IMU stuff is to write a node that subscribes to both the wheel odometry (/odom) and to the fused result (/odom_combined) that's generated by robot_pose_ekf (which incorporates /odom and /imu). You want to then take the x,y,z,roll,pitch, linV, angV.x, angV.y components from /odom_combined and then take yaw and angV.z from /odom and now publish to a new topic...let's say /odom_final...which is the odometry all your nodes should use. The new node should also publish the transform between /odom and /base_footprint....you should make sure that the same transform from robot_pose_ekf is ignored (you can do this by remapping tf to tf_garbage in robot_pose_ekf).

OR

3) Just thought of this one and it doesn't require having another gyro. Write a filter node just like in option 2 that takes as input the command velocity (/cmd_vel), the raw wheel odometry (/odom), and the ekf smoothed odometry (/odom_combined). If the latest commanded velocity is 0, you can assume the robot is not moving and that the yaw should be whatever it was when the robot last stopped. If the robot is moving, you can trust the IMU value. Combine this with option 1 where you call the calibrate service whenever the robot is not moving and all should be well. So in summary, when cmd_vel is 0, yaw = lastYaw, cmdVel != 0, yaw = imuYaw. Populate an odometry message with this yaw and the appropriate angular velocity about the z axis along with the other values from /odom_combined excluding yaw and z-axis rotational velocity and publish them to a new topic /odom_final.

Sorry that #2 and #3 are confusing, but they're the only solutions I could conjure of so far. Also note that you'll have to convert r,p,y to quaternion notation for nav_msgs/Odometry. I'm hoping to get more cycles to look into the problem further -- at the very least write the filter I described in step 3. Perhaps Martin can chime in with more suggestions -- can't seem to reference him though so he won't see this message :(

Best of luck!

I've had the same issue of yaw drift with this IMU (also with 'use_mag' set to false) and never had much of a chance to dig into it. All IMUs drift over time, but I'm surprised how quickly this one starts to drift even after calibration. Unfortunately robot_pose_ekf doesn't take /cmd_vel as an input to see that the robot is not being commanded to move (rather it depends solely on wheel odometry for that through topic /odom and the IMU /imu) so the ekf doesn't really help.

So far I've had two..scratch that...THREE hacky solutions to solve this problem which are suboptimal:

1) Repetitive calibration: Call rosservice /imu/calibrate which will stop the drifting temporarily. Do this whenever the robot is still (very important!) and on flat ground. I had the robot call this service automatically when it detects drift or after a certain timeout threshold. This works well enough for my use case to get the job done....but slight drift will still happen over time regardless. If you're performing SLAM or static map localization (e.g. AMCL), the robot will correct its position in the map frame anyway automatically....so doesn't matter if odom is a little wacky.

OR

2) Ignore the yaw if you have another sensor measuring yaw: On the base I'm using, there's a very good single-axis gyro which is fused into the wheel odometry by its ROS driver. I would prefer having that yaw versus the drifting one generated through the IMU + robot_pose_ekf -- though I would still like to keep the roll and pitch components from the phidgets. You can either adjust the imu driver code or write a filter node for /imu to change the covariance matrix so the error is high for Z-axis (which corresponds to the yaw component) in the phidgets IMU so that robot_pose_ekf will weight the yaw from the wheel odometry (with the good gyro) more heavily. The other option which doesn't require changing IMU stuff is to write a node that subscribes to both the wheel odometry (/odom) and to the fused result (/odom_combined) that's generated by robot_pose_ekf (which incorporates /odom and /imu). You want to then take the x,y,z,roll,pitch, linV, angV.x, angV.y components from /odom_combined and then take yaw and angV.z from /odom and now publish to a new topic...let's say /odom_final...which is the odometry all your nodes should use. The new node should also publish the transform between /odom and /base_footprint....you should make sure that the same transform from robot_pose_ekf is ignored (you can do this by remapping tf to tf_garbage in robot_pose_ekf).

OR

3) Just thought of this one and it doesn't require having another gyro. Write a filter node just like in option 2 that takes as input the command velocity (/cmd_vel), the raw wheel odometry (/odom), and the ekf smoothed odometry (/odom_combined). If the latest commanded velocity is 0, you can assume the robot is not moving and that the yaw should be whatever it was when the robot last stopped. If the robot is moving, you can trust the IMU value. Combine this with option 1 where you call the calibrate service whenever the robot is not moving and all should be well. So in summary, when cmd_vel is 0, yaw = lastYaw, cmdVel != 0, yaw = imuYaw. Populate an odometry message with this yaw and the appropriate angular velocity about the z axis angVel.z along with the other values from /odom_combined excluding yaw and z-axis rotational velocity angVel.z and publish them to a new topic /odom_final.

Sorry that #2 and #3 are confusing, but they're the only solutions I could conjure of so far. Also note that you'll have to convert r,p,y to quaternion notation for nav_msgs/Odometry. I'm hoping to get more cycles to look into the problem further -- at the very least write the filter I described in step 3. Perhaps Martin can chime in with more suggestions -- can't seem to reference him though so he won't see this message :(

Best of luck!

I've had the same issue of yaw drift with this IMU (also with 'use_mag' set to false) and never had much of a chance to dig into it. All IMUs drift over time, but I'm surprised how quickly this one starts to drift even after calibration. Unfortunately robot_pose_ekf doesn't take /cmd_vel as an input to see that the robot is not being commanded to move (rather it depends solely on wheel odometry for that through topic /odom and the IMU /imu) so the ekf doesn't really help.

So far I've had two..scratch that...THREE hacky solutions to solve this problem which are suboptimal:

1) Repetitive calibration: Call rosservice /imu/calibrate which will stop the drifting temporarily. Do this whenever the robot is still (very important!) and on flat ground. I had the robot call this service automatically when it detects drift or after a certain timeout threshold. This works well enough for my use case to get the job done....but slight drift will still happen over time regardless. If you're performing SLAM or static map localization (e.g. AMCL), the robot will correct its position in the map frame anyway automatically....so doesn't matter if odom is a little wacky.

OR

2) Ignore the yaw if you have another sensor measuring yaw: On the base I'm using, there's a very good single-axis gyro which is fused into the wheel odometry by its ROS driver. I would prefer having that yaw versus the drifting one generated through the IMU + robot_pose_ekf -- though I would still like to keep the roll and pitch components from the phidgets. You can either adjust the imu driver code or write a filter node for /imu to change the covariance matrix so the error is high for Z-axis (which corresponds to the yaw component) in the phidgets IMU so that robot_pose_ekf will weight the yaw from the wheel odometry (with the good gyro) more heavily. The other option which doesn't require changing IMU stuff is to write a node that subscribes to both the wheel odometry (/odom) and to the fused result (/odom_combined) that's generated by robot_pose_ekf (which incorporates /odom and /imu). You want to then take the x,y,z,roll,pitch, linV, angV.x, angV.y components from /odom_combined and then take yaw and angV.z from /odom and now publish to a new topic...let's say /odom_final...which is the odometry all your nodes should use. The new node should also publish the transform between /odom and /base_footprint....you should make sure that the same transform from robot_pose_ekf is ignored (you can do this by remapping tf to tf_garbage in robot_pose_ekf).

OR

3) Just thought of this one and it doesn't require having another gyro. Write a filter node just like in option 2 that takes as input the command velocity (/cmd_vel), the raw wheel odometry (/odom), and the ekf smoothed odometry (/odom_combined). If the latest commanded velocity is 0, you can assume the robot is not moving and that the yaw should be whatever it was when the robot last stopped. If the robot is moving, you can trust the IMU value. Combine this with option 1 where you call the calibrate service whenever the robot is not moving and all should be well. So in summary, when cmd_vel is 0, yaw = lastYaw, cmdVel != 0, yaw = imuYaw. Populate an odometry message with this yaw and the angVel.z along with the other values from /odom_combined excluding yaw and angVel.z and publish them to a new topic /odom_final.

Sorry that #2 and #3 are confusing, but they're the only solutions I could conjure of so far. Also note that you'll have to convert r,p,y to quaternion notation for nav_msgs/Odometry. I'm hoping to get more cycles to look into the problem further -- at the very least write the filter I described in step 3. Perhaps Martin can chime in with more suggestions -- can't seem to reference him though so he won't see this message :(

Best of luck!