Skip to content

Commit 37a7768

Browse files
erez-tomcopybara-github
authored andcommitted
Switch egocentric computations from numpy to MuJoCo sensors.
PiperOrigin-RevId: 446252430 Change-Id: Icf97a9829fb5cd033340e22897ee555588f93967
1 parent 20cef21 commit 37a7768

1 file changed

Lines changed: 67 additions & 45 deletions

File tree

dm_control/locomotion/soccer/observables.py

Lines changed: 67 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -104,44 +104,54 @@ def _add_player_observables_on_other(self, player, other, prefix):
104104
"""
105105
if player is other:
106106
raise ValueError('Cannot add egocentric observables of player on itself.')
107-
# Origin callable in xpos, xvel for `player`.
108-
xpos_xyz_callable = lambda p: p.bind(player.walker.root_body).xpos
109-
xvel_xyz_callable = lambda p: p.bind(player.walker.root_body).cvel[3:]
110-
# Egocentric observation of other's position, orientation and
111-
# linear velocities.
112-
def _cvel_observation(physics, other=other):
113-
# Velocitmeter reads in local frame but we need world frame observable
114-
# for egocentric transformation.
115-
return physics.bind(other.walker.root_body).cvel[3:]
116-
117-
def _egocentric_end_effectors_xpos(physics, other=other):
118-
origin_xpos = xpos_xyz_callable(physics)
119-
egocentric_end_effectors_xpos = []
120-
for end_effector_body in other.walker.end_effectors:
121-
xpos = physics.bind(end_effector_body).xpos
122-
delta = xpos - origin_xpos
123-
ego_xpos = player.walker.transform_vec_to_egocentric_frame(
124-
physics, delta)
125-
egocentric_end_effectors_xpos.append(ego_xpos)
126-
return np.concatenate(egocentric_end_effectors_xpos)
127-
128-
player.walker.observables.add_egocentric_vector(
129-
'{}_ego_linear_velocity'.format(prefix),
130-
base_observable.Generic(_cvel_observation),
131-
origin_callable=xvel_xyz_callable)
132-
player.walker.observables.add_egocentric_vector(
133-
'{}_ego_position'.format(prefix),
134-
other.walker.observables.position,
135-
origin_callable=xpos_xyz_callable)
136-
player.walker.observables.add_egocentric_xmat(
137-
'{}_ego_orientation'.format(prefix),
138-
other.walker.observables.orientation)
139107

108+
sensors = []
109+
for effector in other.walker.end_effectors:
110+
name = effector.name + '_' + prefix + '_end_effector'
111+
sensors.append(player.walker.mjcf_model.sensor.add(
112+
'framepos', name=name,
113+
objtype=effector.tag, objname=effector,
114+
reftype='body', refname=player.walker.root_body))
115+
def _egocentric_end_effectors_xpos(physics):
116+
return np.reshape(physics.bind(sensors).sensordata, -1)
140117
# Adds end effectors of the other agents in the player's egocentric frame.
118+
name = '{}_ego_end_effectors_pos'.format(prefix)
141119
player.walker.observables.add_observable(
142-
'{}_ego_end_effectors_pos'.format(prefix),
120+
name,
143121
base_observable.Generic(_egocentric_end_effectors_xpos))
144122

123+
ego_linvel_name = '{}_ego_linear_velocity'.format(prefix)
124+
ego_linvel_sensor = player.walker.mjcf_model.sensor.add(
125+
'framelinvel', name=ego_linvel_name,
126+
objtype='body', objname=other.walker.root_body,
127+
reftype='body', refname=player.walker.root_body)
128+
player.walker.observables.add_observable(
129+
ego_linvel_name,
130+
base_observable.MJCFFeature('sensordata', ego_linvel_sensor))
131+
132+
ego_pos_name = '{}_ego_position'.format(prefix)
133+
ego_pos_sensor = player.walker.mjcf_model.sensor.add(
134+
'framepos', name=ego_pos_name,
135+
objtype='body', objname=other.walker.root_body,
136+
reftype='body', refname=player.walker.root_body)
137+
player.walker.observables.add_observable(
138+
ego_pos_name,
139+
base_observable.MJCFFeature('sensordata', ego_pos_sensor))
140+
141+
sensors_rot = []
142+
obsname = '{}_ego_orientation'.format(prefix)
143+
for direction in ['x', 'y', 'z']:
144+
sensorname = obsname + '_' + direction
145+
sensors_rot.append(player.walker.mjcf_model.sensor.add(
146+
'frame'+direction+'axis', name=sensorname,
147+
objtype='body', objname=other.walker.root_body,
148+
reftype='body', refname=player.walker.root_body))
149+
def _egocentric_orientation(physics):
150+
return np.reshape(physics.bind(sensors_rot).sensordata, -1)
151+
player.walker.observables.add_observable(
152+
obsname,
153+
base_observable.Generic(_egocentric_orientation))
154+
145155
# Adds end effectors of the other agents in the other's egocentric frame.
146156
# A is seeing B's hand extended to B's right.
147157
player.walker.observables.add_observable(
@@ -155,21 +165,33 @@ def _add_player_observables_on_ball(self, player, ball):
155165
player: A `Walker` instance, the player we are adding observations for.
156166
ball: A `SoccerBall` instance.
157167
"""
158-
# Origin callables for egocentric transformations.
159-
xpos_xyz_callable = lambda p: p.bind(player.walker.root_body).xpos
160-
xvel_xyz_callable = lambda p: p.bind(player.walker.root_body).cvel[3:]
161-
162168
# Add egocentric ball observations.
163-
player.walker.observables.add_egocentric_vector(
164-
'ball_ego_angular_velocity', ball.observables.angular_velocity)
165-
player.walker.observables.add_egocentric_vector(
169+
player.walker.ball_ego_angvel_sensor = player.walker.mjcf_model.sensor.add(
170+
'frameangvel', name='ball_ego_angvel',
171+
objtype='body', objname=ball.root_body,
172+
reftype='body', refname=player.walker.root_body)
173+
player.walker.observables.add_observable(
174+
'ball_ego_angular_velocity',
175+
base_observable.MJCFFeature('sensordata',
176+
player.walker.ball_ego_angvel_sensor))
177+
178+
player.walker.ball_ego_pos_sensor = player.walker.mjcf_model.sensor.add(
179+
'framepos', name='ball_ego_pos',
180+
objtype='body', objname=ball.root_body,
181+
reftype='body', refname=player.walker.root_body)
182+
player.walker.observables.add_observable(
166183
'ball_ego_position',
167-
ball.observables.position,
168-
origin_callable=xpos_xyz_callable)
169-
player.walker.observables.add_egocentric_vector(
184+
base_observable.MJCFFeature('sensordata',
185+
player.walker.ball_ego_pos_sensor))
186+
187+
player.walker.ball_ego_linvel_sensor = player.walker.mjcf_model.sensor.add(
188+
'framelinvel', name='ball_ego_linvel',
189+
objtype='body', objname=ball.root_body,
190+
reftype='body', refname=player.walker.root_body)
191+
player.walker.observables.add_observable(
170192
'ball_ego_linear_velocity',
171-
ball.observables.linear_velocity,
172-
origin_callable=xvel_xyz_callable)
193+
base_observable.MJCFFeature('sensordata',
194+
player.walker.ball_ego_linvel_sensor))
173195

174196
def _add_player_proprio_observables(self, player):
175197
"""Add proprioceptive observables to the given player.

0 commit comments

Comments
 (0)