Georg commited on
Commit ·
3305880
1
Parent(s): 6aec869
Refactor UR5 environment for enhanced Nova state management and UI adjustments
Browse files- Updated the UR5 environment to include new attributes for storing Nova joint snapshots and TCP positions, improving state management.
- Modified the shutdown process to optionally preserve the Nova state, enhancing the robustness of the environment during transitions.
- Implemented methods to store and apply the last Nova state, ensuring smoother operation and better integration with user commands.
- Adjusted the UI overlay positioning in mujoco_server.py for improved visual alignment.
- mujoco_server.py +1 -1
- robots/ur5/ur5_env.py +41 -3
mujoco_server.py
CHANGED
|
@@ -1333,7 +1333,7 @@ def index():
|
|
| 1333 |
.overlay-tiles {
|
| 1334 |
position: absolute;
|
| 1335 |
right: 20px;
|
| 1336 |
-
bottom:
|
| 1337 |
top: auto;
|
| 1338 |
width: 240px;
|
| 1339 |
display: none;
|
|
|
|
| 1333 |
.overlay-tiles {
|
| 1334 |
position: absolute;
|
| 1335 |
right: 20px;
|
| 1336 |
+
bottom: 50px;
|
| 1337 |
top: auto;
|
| 1338 |
width: 240px;
|
| 1339 |
display: none;
|
robots/ur5/ur5_env.py
CHANGED
|
@@ -154,6 +154,9 @@ class UR5Env(gym.Env):
|
|
| 154 |
self._use_nova_jogging = False
|
| 155 |
self._last_nova_sequence = None
|
| 156 |
self._latest_nova_joints = None
|
|
|
|
|
|
|
|
|
|
| 157 |
self._active_jog = None # Internal jogging state
|
| 158 |
|
| 159 |
self._nova_stream_interval_sec = 0.2
|
|
@@ -167,6 +170,8 @@ class UR5Env(gym.Env):
|
|
| 167 |
|
| 168 |
# Remember the requested Nova configuration so we can toggle it later
|
| 169 |
self._nova_api_config = dict(nova_api_config) if nova_api_config else None
|
|
|
|
|
|
|
| 170 |
self._nova_user_enabled = False
|
| 171 |
if self._nova_api_config:
|
| 172 |
enabled = self.set_nova_enabled(True)
|
|
@@ -301,7 +306,7 @@ class UR5Env(gym.Env):
|
|
| 301 |
self._shutdown_nova()
|
| 302 |
return False
|
| 303 |
|
| 304 |
-
def _shutdown_nova(self) -> None:
|
| 305 |
"""Stop any active Nova clients and reset Nova-dependent flags."""
|
| 306 |
if self._nova_jogger is not None:
|
| 307 |
try:
|
|
@@ -323,6 +328,35 @@ class UR5Env(gym.Env):
|
|
| 323 |
self._latest_nova_joints = None
|
| 324 |
self._last_nova_sequence = None
|
| 325 |
self._nova_user_enabled = False
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 326 |
|
| 327 |
def set_nova_enabled(self, enabled: bool) -> bool:
|
| 328 |
"""Enable or disable Nova integration according to the stored configuration."""
|
|
@@ -331,11 +365,14 @@ class UR5Env(gym.Env):
|
|
| 331 |
print("[Nova] Cannot enable Nova API: configuration unavailable.")
|
| 332 |
self._nova_user_enabled = False
|
| 333 |
return False
|
|
|
|
| 334 |
success = self._configure_nova_api(self._nova_api_config)
|
| 335 |
self._nova_user_enabled = success
|
| 336 |
return success
|
| 337 |
|
| 338 |
-
self.
|
|
|
|
|
|
|
| 339 |
self._nova_user_enabled = False
|
| 340 |
return True
|
| 341 |
|
|
@@ -966,5 +1003,6 @@ class UR5Env(gym.Env):
|
|
| 966 |
)
|
| 967 |
self._target_euler = np.array([roll, pitch, yaw], dtype=np.float32)
|
| 968 |
|
| 969 |
-
|
|
|
|
| 970 |
return self._latest_nova_joints is not None
|
|
|
|
| 154 |
self._use_nova_jogging = False
|
| 155 |
self._last_nova_sequence = None
|
| 156 |
self._latest_nova_joints = None
|
| 157 |
+
self._nova_last_joint_snapshot = None
|
| 158 |
+
self._nova_last_tcp_position = None
|
| 159 |
+
self._nova_last_tcp_euler = None
|
| 160 |
self._active_jog = None # Internal jogging state
|
| 161 |
|
| 162 |
self._nova_stream_interval_sec = 0.2
|
|
|
|
| 170 |
|
| 171 |
# Remember the requested Nova configuration so we can toggle it later
|
| 172 |
self._nova_api_config = dict(nova_api_config) if nova_api_config else None
|
| 173 |
+
self._target_pos = None
|
| 174 |
+
self._target_euler = None
|
| 175 |
self._nova_user_enabled = False
|
| 176 |
if self._nova_api_config:
|
| 177 |
enabled = self.set_nova_enabled(True)
|
|
|
|
| 306 |
self._shutdown_nova()
|
| 307 |
return False
|
| 308 |
|
| 309 |
+
def _shutdown_nova(self, preserve_snapshot: bool = False) -> None:
|
| 310 |
"""Stop any active Nova clients and reset Nova-dependent flags."""
|
| 311 |
if self._nova_jogger is not None:
|
| 312 |
try:
|
|
|
|
| 328 |
self._latest_nova_joints = None
|
| 329 |
self._last_nova_sequence = None
|
| 330 |
self._nova_user_enabled = False
|
| 331 |
+
if not preserve_snapshot:
|
| 332 |
+
self._nova_last_joint_snapshot = None
|
| 333 |
+
self._nova_last_tcp_position = None
|
| 334 |
+
self._nova_last_tcp_euler = None
|
| 335 |
+
|
| 336 |
+
def _store_nova_snapshot(self) -> None:
|
| 337 |
+
if self._latest_nova_joints is not None:
|
| 338 |
+
self._nova_last_joint_snapshot = self._latest_nova_joints.copy()
|
| 339 |
+
if self._target_pos is not None:
|
| 340 |
+
self._nova_last_tcp_position = self._target_pos.copy()
|
| 341 |
+
if self._target_euler is not None:
|
| 342 |
+
self._nova_last_tcp_euler = self._target_euler.copy()
|
| 343 |
+
|
| 344 |
+
def _apply_last_nova_state_to_internal(self) -> None:
|
| 345 |
+
applied = False
|
| 346 |
+
if self._nova_last_joint_snapshot is not None:
|
| 347 |
+
self.data.qpos[:6] = self._nova_last_joint_snapshot.copy()
|
| 348 |
+
self.data.ctrl[:6] = self._nova_last_joint_snapshot.copy()
|
| 349 |
+
self._joint_targets = self._nova_last_joint_snapshot.copy()
|
| 350 |
+
applied = True
|
| 351 |
+
if self._nova_last_tcp_position is not None:
|
| 352 |
+
self._target_pos = self._nova_last_tcp_position.copy()
|
| 353 |
+
self.data.mocap_pos[0] = self._target_pos
|
| 354 |
+
applied = True
|
| 355 |
+
if self._nova_last_tcp_euler is not None:
|
| 356 |
+
self._target_euler = self._nova_last_tcp_euler.copy()
|
| 357 |
+
applied = True
|
| 358 |
+
if applied:
|
| 359 |
+
mujoco.mj_forward(self.model, self.data)
|
| 360 |
|
| 361 |
def set_nova_enabled(self, enabled: bool) -> bool:
|
| 362 |
"""Enable or disable Nova integration according to the stored configuration."""
|
|
|
|
| 365 |
print("[Nova] Cannot enable Nova API: configuration unavailable.")
|
| 366 |
self._nova_user_enabled = False
|
| 367 |
return False
|
| 368 |
+
self._shutdown_nova()
|
| 369 |
success = self._configure_nova_api(self._nova_api_config)
|
| 370 |
self._nova_user_enabled = success
|
| 371 |
return success
|
| 372 |
|
| 373 |
+
self._store_nova_snapshot()
|
| 374 |
+
self._shutdown_nova(preserve_snapshot=True)
|
| 375 |
+
self._apply_last_nova_state_to_internal()
|
| 376 |
self._nova_user_enabled = False
|
| 377 |
return True
|
| 378 |
|
|
|
|
| 1003 |
)
|
| 1004 |
self._target_euler = np.array([roll, pitch, yaw], dtype=np.float32)
|
| 1005 |
|
| 1006 |
+
self._update_nova_interpolation(time.time())
|
| 1007 |
+
self._store_nova_snapshot()
|
| 1008 |
return self._latest_nova_joints is not None
|