Issue with IMU Returning Incorrect Linear Acceleration Measurements
Hi everyone,
I’m encountering an issue with the IMU where the linear acceleration measurements seem incorrect. Specifically, when comparing the IMU readings (with the sensor placed at the drone’s center of mass) to the theoretical acceleration (calculated as force/mass), the results don’t match.
The blue curve in the graph below shows the calculated acceleration based on the forces applied to the drone, while the red curve represents the IMU output.
IMU Implementation
The IMU is added during class instantiation using the self._add_imus
method. Here’s how the IMU is implemented:
from omni.isaac.sensor import IMUSensor
def add_imu_sensor(parent_path: str, physics_dt: float, imu: Dict[str, Any]) -> IMUSensor:
return IMUSensor(
prim_path=parent_path + imu["Parent"] + imu["Name"],
dt=physics_dt,
translation=imu["Translation"]
)
def _add_imus(self, imu_configs: Dict[str, Any], wrapper: ROSWrapper) -> None:
# Given the IMU configs, add the IMU sensors to the world
for i, imu_config in imu_configs.items():
imu_config["Name"] = "/imu_" + str(i)
imu_sensor = add_imu_sensor(self.parent, self.physics_dt, imu_config)
self.imus.append(imu_sensor)
# Attach a publisher
wrapper.add_publisher("/" + self.name + "/" + imu_config["Topic"], "imu")
# Bind IMU data acquisition and publishing callback after the physics step
self._world.add_physics_callback(
f"pub_imu_{self.name}",
callback_fn=lambda step_size: self.update_imu_data(wrapper, step_size),
)
def update_imu_data(self, wrapper: ROSWrapper, step_size: int = 0) -> None:
for imu in self.imus:
frame = imu.get_current_frame()
frame = imu.measure(wrapper.state[imu.prim_path], step_size)
wrapper.publish_imu("/" + self.name + "/" + imu.name, frame)
Force and Torque Application
For context, this is how I’m applying forces and moments to the center of mass of the drone during each physics callback:
# Get the handle of the rigid body to apply torque to
rb = self._world.dc_interface.get_rigid_body(self._stage_prefix + body_part)
# Apply the torque to the rigid body (in the body frame)
self._world.dc_interface.apply_body_torque(rb, carb._carb.Float3(torque), False)
# Get the handle of the rigid body to apply force to
rb = self._world.dc_interface.get_rigid_body(self._stage_prefix + body_part)
# Apply the force to the rigid body (in the body frame)
self._world.dc_interface.apply_body_force(
rb, carb._carb.Float3(force), carb._carb.Float3(pos), False
)
Observations
When I calculate acceleration by manually differentiating the linear velocity obtained from the dynamic control interface, I get correct results:
linear_vel = self._world.dc_interface.get_rigid_body_linear_velocity(body)
Additional IMU Issue
Additionally, I’ve noticed that the IMU attitude only updates during each render step rather than every physics step. Although the IMU returns measurements at the desired rate, the data only changes during each render step. Interestingly, the angular velocity and linear acceleration do not exhibit this behavior.
Question
Is there an issue with how I’m using the IMU, or could this be a bug in the IMU implementation? Any guidance or advice would be greatly appreciated.
Thank you for your help!
Best regards,
Justin