-
Notifications
You must be signed in to change notification settings - Fork 155
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
reverse rotation in IMU linear acceleration calculation #38
base: kinetic-devel
Are you sure you want to change the base?
reverse rotation in IMU linear acceleration calculation #38
Conversation
Thanks, I will check it next week, but I am quite sure that the current implementation is correct according to our conventions, because we also use the simulated sensor output in fusion algorithms like with hector_localization. There has been some confusion about this topic in the past: #8, #11 I assume that the inverted sign of the acceleration vector output compared to other implementations is what caused the confusion about the rotation. There are pros and cons, but actually the way it is now is more consistent with the sign of the angular velocity, which also describes how the body moves within the inertial frame and not how a probe mass would move within the body/IMU frame. So indeed, if the gravity pulls the robot downwards the accelerometer measures and acceleration upwards, because it cannot distinguish these two cases. It simply depends on the point of view. If the sign of the linear acceleration vector does not comply with some conventions, I am willing to change it and adapt other code using it, but at first sight it seems to be consistent with upcoming REP-145, too. I will verify that an IMU mounted upside down has no negative impact, but to me math::Vector3 gravity = world->GetPhysicsEngine()->GetGravity();
math::Vector3 temp = link->GetWorldLinearVel(); // get velocity in world frame
if (dt > 0.0) accel = rot.RotateVectorReverse((temp - velocity) / dt - gravity);
\---------\|/--------/
Acceleration of the body in world frame
\-------------\|/--------------/
Subtract the gravity vector in world frame
(gravity downwards == body acceleration upwards)
\-----------------------\|/----------------------------/
Rotate the resulting vector from world to body frame
|
Yeah, I was wondering whether this might be a matter of convention rather than a bug. To be more specific, the problematic behavior that we've noticed is with ekf_localization. If we configure that node to have as its only input the angular velocities and linear accelerations from an upside-down IMU, then the pose estimates that are produced don't make sense, with the behavior dependent on the orientation of the robot in the world. Perhaps the fix here instead belongs in our configuration of |
Is it possible that this plugin works properly only when the link associated with the IMU plugin is not rotated with respect to its parent link? I've boiled my problem down to a fairly simply case. Here's some URDF:
Call that file
Now you have a box with an IMU attached and are plotting the X and Y linear acceleration values. We want to perturb the box. Right-click it in the Gazebo UI and select "Apply Force/Torque". In "Force->X", fill in a large value, like 1000N. Then click "Apply Force" a few times. The box will move each time, and you should see a response in the X acceleration in Now rotate and try again: select the rotation tool in the Gazebo UI and rotate the box by 45 degrees. Then apply the 1000N force in X again. You should see the same response in X acceleration. That's also as expected. Delete the box in the Gazebo UI. Now edit the URDF to roll the IMU by pi, then spawn it again. Now repeat the experiment described above. In this situation, I observe that:
Can you comment on what's happening here? |
After further experimentation with my simple example, I believe that:
I wonder whether this behavior is related to the fixed joint lumping that happens when Gazebo parses URDF. For now we can get by with not rotating our IMU, but it would be nice to understand what is happening here, and eventually to be able to mount an IMU at an arbitrary location on a vehicle. |
The urdf parser in sdformat plays a role in this when there is a fixed joint reduction, as it changes the |
I have not looked at @gerkey's example yet, but in general hector IMU should respect the There was a bug for angular velocities (#23) which has been fixed in d5fcb4a. The reporter mentions that linear_acceleration values are visualized correctly for an IMU mounted upside down. Indeed it is strange that the Hector plugin uses At the moment I would assume that the output values are correct if there is either no rotation or the IMU is mounted upside down as in #23, but the rotation offset is applied wrongly in all other cases. My best guess is that the multiplication |
I'm working with a Gazebo model in which the link to which I'm attaching a hector IMU is rotated to have Z down. In that situation, I find that the linear acceleration data from this plugin becomes pretty wrong. It seems to be that it's no longer in a body-fixed frame (e.g., with only diff-drive commands, I get non-zero Y accelerations depending on which direction the vehicle is pointing in the world).
After looking at the code with @scpeters, it seems that this rotation is going the wrong direction. At least, after reversing it as I've done here, I get sensible accel data irrespective of how I mount the IMU on the model and which direction the vehicle is oriented in the world.
I can appreciate that this is a pretty fundamental change and I'm not sure how to best go about testing it, but I'm happy to help.