Ask Your Question

Interpretation of IMU data from the gazebo_ros_imu plugin

asked 2012-01-12 01:33:01 -0600

We want to use the gazebo_ros_imu plugin for the simulation of our quadrotor and other vehicles in Gazebo. When looking at the output and source file of the plugin, several questions arise:

  1. When the platform is standing still, the simulated accelerations are all zero apart from the simulated noise. Shouldn't the gravity vector be added to the accelerations measured due to body motion? A real IMU would give a more or less constant gravity vector in body coordinates. Does this behavior mimic the output of the simulated Microstrain 3DM-GX2 IMU?
  2. Accelerations are calculated by a first-order approximation of the linear velocity. Is there a specific reason why the driver does not use the gazebo::Entity::GetRelativeLinearAccel() or gazebo::Entity::GetWorldLinearAccel() functions?
  3. I am not familiar with the Gazebo interface. The Entity class seems to provide two types of access functions for the body states, one in relative (body) coordinates and one in world coordinates. Wouldn't it be more straight-forward to directly use the body vectors instead of the rotated world vectors? I assume the reason is the rpyOffsets parameter and that the accelerations and angular velocities should match the "wrong" orientation. But in reality the things are other way round, namely that offsets in orientation are a result of offsets in the acceleration measurements.

By the way, in my opinion the term "IMU" is misleading for a device providing the orientation of a platform, as a pure IMU by itself only provides accelerations and angular velocity. The roll and pitch angles can be estimated with this information under the assumption that the velocity vector of the platform is more or less constant over time (which does not necessarily hold for flying vehicles). Heading or yaw always needs additional references like earth magnetic field or others. I think "AHRS" (Attitude and Heading Reference System) would fit better for what an IMU is in ROS.

Thanks in advance for some useful answers!

edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted

answered 2012-02-06 04:26:53 -0600

In the meantime we implemented a modified version of the gazebo_ros_imu plugin in our hector_gazebo_plugins package ( The sensor controller can be configured with independent Gaussian noise and a low-frequency drifting behavior for all six IMU channels (angular_velocity and linear_acceleration). Orientation is derived from the simulated acceleration/gravity measurement and an additional error model for the heading.

So here are some answers to my own questions:

  1. An acceleration sensors measures the acceleration acting on a probe mass relative to the sensor's body frame. Gravity is acting on both, the probe mass and the sensor frame and therefore has to be handled separately from other forces. All other external forces are acting on the frame only and therefore produce a measurable relative acceleration. As a result, the sensor output is the sum of all forces minus the gravity (or vice-versa depending on the point of view). When the platform is not accelerated, e.g. standing on the ground, the sensor output corresponds to the inverse gravity vector.

  2. The Entity::GetRelativeLinearAccel() and Entity::GetWorldLinearAccel() member functions are indeed unusable for IMU simulation as their result is dependent on the order in which controllers are executed. Looking at Gazebo's current implementation of the ODEBody::SetForce() and ODEBody::SetTorque() method reveals that forces and torques are accumulated within each simulation step and the getter functions for forces and linear accelerations just return the current value of the accumulator. Forces added at a later time are ignored. Furthermore gravity and contact forces seem to be handled differently and the returned acceleration vector is zero for a platform standing on the ground and during free fall. So looking at the linear velocities and differentiating them manually is a valuable solution for determining the overall acceleration during the previous time step. GetRelativeAngularVel()/GetWorldAngularVel() functions are not affected by this issue, but sometimes return illegal NaN values. Calculating the angular velocity from the quaternion rate between two subsequent time steps works flawlessly.

  3. As expected the return values of Body::GetRelativeXXX() and Body::GetWorldXXX() functions just differ by the true orientation of the platform in the world frame. Our implementation of the hector_gazebo_ros_imu plugin uses the GetRelativeLinearVel() function directly to calculate the accelerations in body coordinates. The roll and pitch components of the orientation quaternion are derived from the "measured" gravity vector affected by noise, offset and drift, much like a real AHRS would do in the static case. Errors in orientation are a consequence of the drift error in gravity measurement and therefore not independent of the orientation like in the standard implementation of the IMU plugin.

edit flag offensive delete link more

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools



Asked: 2012-01-12 01:33:01 -0600

Seen: 2,933 times

Last updated: Feb 06 '12