Skip to content

Commit 8067b49

Browse files
committed
add imu projected_gravity
1 parent b257249 commit 8067b49

File tree

4 files changed

+52
-3
lines changed

4 files changed

+52
-3
lines changed

source/isaaclab/isaaclab/envs/mdp/observations.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,21 @@ def imu_orientation(env: ManagerBasedEnv, asset_cfg: SceneEntityCfg = SceneEntit
270270
return asset.data.quat_w
271271

272272

273+
def imu_projected_gravity(env: ManagerBasedEnv, asset_cfg: SceneEntityCfg = SceneEntityCfg("imu")) -> torch.Tensor:
274+
"""Imu sensor orientation w.r.t the env.scene.origin.
275+
276+
Args:
277+
env: The environment.
278+
asset_cfg: The SceneEntity associated with an Imu sensor.
279+
280+
Returns:
281+
Gravity projected on imu_frame, shape of torch.tensor is (num_env,3).
282+
"""
283+
284+
asset: Imu = env.scene[asset_cfg.name]
285+
return asset.data.projected_gravity_b
286+
287+
273288
def imu_ang_vel(env: ManagerBasedEnv, asset_cfg: SceneEntityCfg = SceneEntityCfg("imu")) -> torch.Tensor:
274289
"""Imu sensor angular velocity w.r.t. environment origin expressed in the sensor frame.
275290

source/isaaclab/isaaclab/sensors/imu/imu.py

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,11 @@ def reset(self, env_ids: Sequence[int] | None = None):
9696
if env_ids is None:
9797
env_ids = slice(None)
9898
# reset accumulative data buffers
99+
self._data.pos_w[env_ids] = 0.0
99100
self._data.quat_w[env_ids] = 0.0
101+
self._data.quat_w[env_ids, 0] = 1.0
102+
self._data.projected_gravity_b[env_ids] = 0.0
103+
self._data.projected_gravity_b[env_ids, 2] = -1.0
100104
self._data.lin_vel_b[env_ids] = 0.0
101105
self._data.ang_vel_b[env_ids] = 0.0
102106
self._data.lin_acc_b[env_ids] = 0.0
@@ -135,6 +139,12 @@ def _initialize_impl(self):
135139
else:
136140
raise RuntimeError(f"Failed to find a RigidBodyAPI for the prim paths: {self.cfg.prim_path}")
137141

142+
# Get world gravity
143+
gravity = self._physics_sim_view.get_gravity()
144+
gravity_dir = torch.tensor((gravity[0], gravity[1], gravity[2]), device=self.device)
145+
gravity_dir = math_utils.normalize(gravity_dir.unsqueeze(0)).squeeze(0)
146+
self.GRAVITY_VEC_W = gravity_dir.repeat(self.num_instances, 1)
147+
138148
# Create internal buffers
139149
self._initialize_buffers_impl()
140150

@@ -167,16 +177,18 @@ def _update_buffers_impl(self, env_ids: Sequence[int]):
167177
lin_acc_w = (lin_vel_w - self._prev_lin_vel_w[env_ids]) / self._dt + self._gravity_bias_w[env_ids]
168178
ang_acc_w = (ang_vel_w - self._prev_ang_vel_w[env_ids]) / self._dt
169179
# stack data in world frame and batch rotate
170-
dynamics_data = torch.stack((lin_vel_w, ang_vel_w, lin_acc_w, ang_acc_w), dim=0)
171-
dynamics_data_rot = math_utils.quat_apply_inverse(self._data.quat_w[env_ids].repeat(4, 1), dynamics_data).chunk(
172-
4, dim=0
180+
dynamics_data = torch.stack((lin_vel_w, ang_vel_w, lin_acc_w, ang_acc_w, self.GRAVITY_VEC_W[env_ids]), dim=0)
181+
dynamics_data_rot = math_utils.quat_apply_inverse(self._data.quat_w[env_ids].repeat(5, 1), dynamics_data).chunk(
182+
5, dim=0
173183
)
174184
# store the velocities.
175185
self._data.lin_vel_b[env_ids] = dynamics_data_rot[0]
176186
self._data.ang_vel_b[env_ids] = dynamics_data_rot[1]
177187
# store the accelerations
178188
self._data.lin_acc_b[env_ids] = dynamics_data_rot[2]
179189
self._data.ang_acc_b[env_ids] = dynamics_data_rot[3]
190+
# store projected gravity
191+
self._data.projected_gravity_b[env_ids] = dynamics_data_rot[4]
180192

181193
self._prev_lin_vel_w[env_ids] = lin_vel_w
182194
self._prev_ang_vel_w[env_ids] = ang_vel_w
@@ -187,6 +199,7 @@ def _initialize_buffers_impl(self):
187199
self._data.pos_w = torch.zeros(self._view.count, 3, device=self._device)
188200
self._data.quat_w = torch.zeros(self._view.count, 4, device=self._device)
189201
self._data.quat_w[:, 0] = 1.0
202+
self._data.projected_gravity_b = torch.zeros(self._view.count, 3, device=self._device)
190203
self._data.lin_vel_b = torch.zeros_like(self._data.pos_w)
191204
self._data.ang_vel_b = torch.zeros_like(self._data.pos_w)
192205
self._data.lin_acc_b = torch.zeros_like(self._data.pos_w)

source/isaaclab/isaaclab/sensors/imu/imu_data.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,12 @@ class ImuData:
2525
Shape is (N, 4), where ``N`` is the number of environments.
2626
"""
2727

28+
projected_gravity_b: torch.Tensor = None
29+
"""Gravity direction unit vector projected on the imu frame.
30+
31+
Shape is (N,3), where ``N`` is the number of environments.
32+
"""
33+
2834
lin_vel_b: torch.Tensor = None
2935
"""IMU frame angular velocity relative to the world expressed in IMU frame.
3036

source/isaaclab/test/sensors/test_imu.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,14 @@ def test_single_dof_pendulum(setup_sim):
353353
if idx < 2:
354354
continue
355355

356+
# compare imu projected gravity
357+
gravity_dir_w = torch.tensor((0.0, 0.0, -1.0), device=scene.device).repeat(2, 1)
358+
gravity_dir_b = math_utils.quat_apply_inverse(imu_data.quat_w, gravity_dir_w)
359+
torch.testing.assert_close(
360+
imu_data.projected_gravity_b,
361+
gravity_dir_b,
362+
)
363+
356364
# compare imu angular velocity with joint velocity
357365
torch.testing.assert_close(
358366
joint_vel,
@@ -495,6 +503,13 @@ def test_offset_calculation(setup_sim):
495503
rtol=1e-4,
496504
atol=1e-4,
497505
)
506+
# check the projected gravity
507+
torch.testing.assert_close(
508+
scene.sensors["imu_robot_base"].data.projected_gravity_b,
509+
scene.sensors["imu_robot_imu_link"].data.projected_gravity_b,
510+
rtol=1e-4,
511+
atol=1e-4,
512+
)
498513

499514

500515
def test_env_ids_propagation(setup_sim):

0 commit comments

Comments
 (0)