Skip to content

Commit 55a9df6

Browse files
committed
fix(env): multirobotwrapper in absolute mode
1 parent 5211c59 commit 55a9df6

1 file changed

Lines changed: 27 additions & 7 deletions

File tree

python/rcs/envs/base.py

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,8 @@ def __init__(
421421
self.lead_env: gym.Env | None = None
422422
self.sim: simulation.Sim | None = None
423423

424+
self._rel_env: dict[str, bool] = {}
425+
424426
# make sure all envs are the same type (sim/real)
425427
for env in self.envs:
426428
if self.PLATFORM is None:
@@ -430,12 +432,26 @@ def __init__(
430432
assert (
431433
self.envs[env].get_wrapper_attr("PLATFORM") == self.PLATFORM
432434
), "all envs must have the same platform!"
435+
self._rel_env[env] = self._env_relative(self.envs[env]) # type: ignore
436+
433437
self._runs_in_sim = self.PLATFORM == RobotPlatform.SIMULATION
434438
if self._runs_in_sim:
435439
self._inject_main_greenlet()
436440
assert isinstance(self.lead_env, SimEnv), "something is wrong with the env, the base should be type SimEnv"
437441
self.sim = self.lead_env.get_wrapper_attr("sim")
438442

443+
def _env_relative(self, env: gym.Wrapper):
444+
max_depth = 100
445+
while True:
446+
if isinstance(env, RelativeActionSpace):
447+
return True
448+
if isinstance(env, SimEnv | HardwareEnv):
449+
return False
450+
if max_depth < 0:
451+
return False
452+
max_depth -= 1
453+
env = env.env # type: ignore
454+
439455
def _inject_main_greenlet(self):
440456
main_gr = getcurrent()
441457
for env_item in self.envs.values():
@@ -444,15 +460,19 @@ def _inject_main_greenlet(self):
444460
), "something is wrong with the env, the base should be type SimEnv"
445461
env_item.unwrapped.main_greenlet = main_gr
446462

447-
def _translate_pose(self, key, dic, to_world=True):
463+
def _translate_pose(self, key, dic, to_world=True, relative=True):
448464
r2w = self.robot_to_shared_base_frame.get(key, common.Pose())
449465
if not to_world:
450466
r2w = r2w.inverse()
451467
if "tquat" in dic:
452-
p = r2w * common.Pose(translation=dic["tquat"][:3], quaternion=dic["tquat"][3:]) * r2w.inverse()
468+
p = r2w * common.Pose(translation=dic["tquat"][:3], quaternion=dic["tquat"][3:])
469+
if relative:
470+
p *= r2w.inverse()
453471
dic["tquat"] = np.concatenate([p.translation(), p.rotation_q()])
454472
if "xyzrpy" in dic:
455-
p = r2w * common.Pose(translation=dic["xyzrpy"][:3], rpy_vector=dic["xyzrpy"][3:]) * r2w.inverse()
473+
p = r2w * common.Pose(translation=dic["xyzrpy"][:3], rpy_vector=dic["xyzrpy"][3:])
474+
if relative:
475+
p *= r2w.inverse()
456476
dic["xyzrpy"] = p.xyzrpy()
457477

458478
return dic
@@ -470,7 +490,7 @@ def make_step_gr(env_to_step):
470490
step_greenlets[key] = gr
471491

472492
# Translate action
473-
act = self._translate_pose(key, action[key], to_world=False)
493+
act = self._translate_pose(key, action[key], to_world=False, relative=self._rel_env[key])
474494

475495
# Switch to robot greenlet. It will run until RobotSimWrapper.step switches back.
476496
gr.switch(act)
@@ -493,10 +513,10 @@ def make_step_gr(env_to_step):
493513
ob, r, t, tr, info[key] = step_greenlets[key].switch()
494514
else:
495515
# HARDWARE path
496-
act = self._translate_pose(key, action[key], to_world=False)
516+
act = self._translate_pose(key, action[key], to_world=False, relative=self._rel_env[key])
497517
ob, r, t, tr, info[key] = env.step(act)
498518

499-
obs[key] = self._translate_pose(key, ob, to_world=True)
519+
obs[key] = self._translate_pose(key, ob, to_world=True, relative=False)
500520
reward += float(r)
501521
terminated = terminated or t
502522
truncated = truncated or tr
@@ -539,7 +559,7 @@ def make_reset_gr(env_to_reset, s, o):
539559
# HARDWARE path
540560
ob, i = env.reset(seed=seed_[key], options=options_[key])
541561

542-
obs[key] = self._translate_pose(key, ob, to_world=True)
562+
obs[key] = self._translate_pose(key, ob, to_world=True, relative=False)
543563
info[key] = i
544564

545565
return obs, info

0 commit comments

Comments
 (0)