Georg commited on
Commit
cd29740
·
1 Parent(s): c525614

Implement camera and environment reset functions in mujoco_server.py

Browse files

- Added _reset_camera_for_current_robot to configure camera settings based on the active robot.
- Introduced _reset_active_environment to reset the simulation environment and camera together.
- Updated _handle_gym_ws_message to call _reset_active_environment on specific message types.
- Refactored reset logic in handle_ws_message to utilize the new reset functions, improving code organization and maintainability.

Files changed (1) hide show
  1. mujoco_server.py +39 -21
mujoco_server.py CHANGED
@@ -122,6 +122,36 @@ cam.lookat = np.array([0, 0, 0.8])
122
  # Camera follow mode
123
  camera_follow = True
124
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
125
  MODEL_ROOT = Path(_nova_sim_dir) / "robots"
126
 
127
  def discover_scene_files(robot: str) -> list[str]:
@@ -736,6 +766,7 @@ def _handle_gym_ws_message(ws, data):
736
  "info": _serialize_value(info),
737
  },
738
  }
 
739
  elif msg_type == "step":
740
  action = payload.get("action", [])
741
  render = bool(payload.get("render", False))
@@ -755,9 +786,12 @@ def _handle_gym_ws_message(ws, data):
755
  if frame_jpeg:
756
  response["data"]["frame_jpeg"] = frame_jpeg
757
  elif msg_type == "configure":
758
- robot = payload.get("robot", "ur5")
759
  scene = payload.get("scene")
760
  session.configure(robot, scene)
 
 
 
761
  response = {
762
  "type": "gym_configured",
763
  "data": {"robot": session.robot, "scene": session.scene},
@@ -990,29 +1024,14 @@ def handle_ws_message(ws, data):
990
  env.set_command(vx, vy, vyaw)
991
 
992
  elif msg_type == 'reset':
993
- with mujoco_lock:
994
- if env is not None:
995
- env.reset()
996
- cam.azimuth = 135
997
- cam.elevation = -20
998
- if current_robot == "g1":
999
- cam.distance = 3.0
1000
- cam.lookat = np.array([0.0, 0.0, 0.8])
1001
- elif current_robot in ("ur5", "ur5_t_push"):
1002
- cam.distance = 1.8
1003
- cam.lookat = np.array([0.3, 0.0, 0.6])
1004
- cam.azimuth = 150
1005
- cam.elevation = -25
1006
- else:
1007
- cam.distance = 2.5
1008
- cam.lookat = np.array([0.0, 0.0, 0.4])
1009
 
1010
  elif msg_type == 'switch_robot':
1011
  payload = data.get('data', {})
1012
  robot = payload.get('robot', 'g1')
1013
  scene = payload.get('scene')
1014
  print(f"Robot switch requested: {robot} / scene: {scene}")
1015
- needs_robot_switch = {"robot": robot, "scene": scene}
1016
 
1017
  elif msg_type == 'configure':
1018
  payload = data.get('data', {})
@@ -1020,7 +1039,7 @@ def handle_ws_message(ws, data):
1020
  scene = payload.get('scene')
1021
  if robot:
1022
  print(f"Configure requested: {robot} / scene: {scene}")
1023
- needs_robot_switch = {"robot": robot, "scene": scene}
1024
 
1025
  elif msg_type == 'camera':
1026
  payload = data.get('data', {})
@@ -3207,8 +3226,7 @@ def switch_robot_endpoint():
3207
  scene = payload.get('scene')
3208
  if not robot:
3209
  return jsonify({"error": "robot is required"}), 400
3210
- global needs_robot_switch
3211
- needs_robot_switch = {"robot": robot, "scene": scene}
3212
  return jsonify({"status": "pending", "robot": robot, "scene": scene}), 202
3213
 
3214
 
 
122
  # Camera follow mode
123
  camera_follow = True
124
 
125
+ def _reset_camera_for_current_robot() -> None:
126
+ """Reset the orbit camera to the defaults for the active robot."""
127
+ cam.azimuth = 135
128
+ cam.elevation = -20
129
+ if current_robot == "g1":
130
+ cam.distance = 3.0
131
+ cam.lookat = np.array([0.0, 0.0, 0.8])
132
+ elif current_robot in ("ur5", "ur5_t_push"):
133
+ cam.distance = 1.8
134
+ cam.lookat = np.array([0.3, 0.0, 0.6])
135
+ cam.azimuth = 150
136
+ cam.elevation = -25
137
+ else:
138
+ cam.distance = 2.5
139
+ cam.lookat = np.array([0.0, 0.0, 0.4])
140
+
141
+
142
+ def _reset_active_environment() -> None:
143
+ """Reset the primary simulation environment and associated camera."""
144
+ with mujoco_lock:
145
+ if env is not None:
146
+ env.reset()
147
+ _reset_camera_for_current_robot()
148
+
149
+
150
+ def _schedule_robot_switch(robot: str, scene: Optional[str]) -> None:
151
+ """Schedule a robot/scene switch for the simulation loop."""
152
+ global needs_robot_switch
153
+ needs_robot_switch = {"robot": robot, "scene": scene}
154
+
155
  MODEL_ROOT = Path(_nova_sim_dir) / "robots"
156
 
157
  def discover_scene_files(robot: str) -> list[str]:
 
766
  "info": _serialize_value(info),
767
  },
768
  }
769
+ _reset_active_environment()
770
  elif msg_type == "step":
771
  action = payload.get("action", [])
772
  render = bool(payload.get("render", False))
 
786
  if frame_jpeg:
787
  response["data"]["frame_jpeg"] = frame_jpeg
788
  elif msg_type == "configure":
789
+ robot = payload.get("robot")
790
  scene = payload.get("scene")
791
  session.configure(robot, scene)
792
+ if robot:
793
+ print(f"Configure requested (gym): {robot} / scene: {scene}")
794
+ _schedule_robot_switch(robot, scene)
795
  response = {
796
  "type": "gym_configured",
797
  "data": {"robot": session.robot, "scene": session.scene},
 
1024
  env.set_command(vx, vy, vyaw)
1025
 
1026
  elif msg_type == 'reset':
1027
+ _reset_active_environment()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1028
 
1029
  elif msg_type == 'switch_robot':
1030
  payload = data.get('data', {})
1031
  robot = payload.get('robot', 'g1')
1032
  scene = payload.get('scene')
1033
  print(f"Robot switch requested: {robot} / scene: {scene}")
1034
+ _schedule_robot_switch(robot, scene)
1035
 
1036
  elif msg_type == 'configure':
1037
  payload = data.get('data', {})
 
1039
  scene = payload.get('scene')
1040
  if robot:
1041
  print(f"Configure requested: {robot} / scene: {scene}")
1042
+ _schedule_robot_switch(robot, scene)
1043
 
1044
  elif msg_type == 'camera':
1045
  payload = data.get('data', {})
 
3226
  scene = payload.get('scene')
3227
  if not robot:
3228
  return jsonify({"error": "robot is required"}), 400
3229
+ _schedule_robot_switch(robot, scene)
 
3230
  return jsonify({"status": "pending", "robot": robot, "scene": scene}), 202
3231
 
3232