[train] 更新新MJCF与第一版完整训练框架
This commit is contained in:
@@ -1,111 +0,0 @@
|
||||
"""Main entry point: wheeled-legged robot simulation.
|
||||
|
||||
Controls:
|
||||
Mode: wheel (default) - differential drive + posture hold
|
||||
trot - quadruped gait with wheel assist
|
||||
mpc - convex MPC locomotion (torque control)
|
||||
|
||||
Keyboard (in MuJoCo viewer):
|
||||
W/S: vel_x ±0.1
|
||||
A/D: yaw_rate ±0.2
|
||||
Q/E: height ±0.02
|
||||
1: wheel mode
|
||||
2: trot mode
|
||||
3: MPC mode
|
||||
4: prone toggle
|
||||
Z: reset commands
|
||||
"""
|
||||
|
||||
import time
|
||||
import numpy as np
|
||||
import mujoco.viewer as mjv
|
||||
|
||||
from robot import Robot
|
||||
from controller import Controller
|
||||
from gui import GUI
|
||||
from config import CTRL_DECIMATION
|
||||
|
||||
|
||||
def main():
|
||||
robot = Robot()
|
||||
robot.reset()
|
||||
ctrl = Controller(robot)
|
||||
gui = GUI(ctrl)
|
||||
|
||||
step = 0
|
||||
sim_steps_per_ctrl = CTRL_DECIMATION
|
||||
|
||||
def key_callback(keycode):
|
||||
"""Called from MuJoCo render thread - only modify ctrl directly, not tkinter."""
|
||||
try:
|
||||
c = chr(keycode).lower()
|
||||
except (ValueError, OverflowError):
|
||||
return
|
||||
if c == 'w':
|
||||
ctrl.vel_x = min(ctrl.vel_x + 0.1, 1.5)
|
||||
elif c == 's':
|
||||
ctrl.vel_x = max(ctrl.vel_x - 0.1, -1.5)
|
||||
elif c == 'a':
|
||||
ctrl.yaw_rate = min(ctrl.yaw_rate + 0.2, 2.0)
|
||||
elif c == 'd':
|
||||
ctrl.yaw_rate = max(ctrl.yaw_rate - 0.2, -2.0)
|
||||
elif c == 'q':
|
||||
ctrl.height = min(ctrl.height + 0.02, 0.45)
|
||||
elif c == 'e':
|
||||
ctrl.height = max(ctrl.height - 0.02, 0.15)
|
||||
elif c == '1':
|
||||
ctrl.mode = "wheel"; ctrl.prone = False
|
||||
elif c == '2':
|
||||
ctrl.mode = "trot"; ctrl.prone = False
|
||||
elif c == '3':
|
||||
ctrl.mode = "mpc"; ctrl.prone = False
|
||||
elif c == '4':
|
||||
ctrl.prone = not ctrl.prone
|
||||
elif c == 'z':
|
||||
ctrl.vel_x = 0.0; ctrl.vel_y = 0.0; ctrl.yaw_rate = 0.0
|
||||
|
||||
with mjv.launch_passive(robot.model, robot.data, key_callback=key_callback) as viewer:
|
||||
viewer.cam.distance = 2.5
|
||||
viewer.cam.elevation = -20
|
||||
viewer.cam.azimuth = 135
|
||||
|
||||
last_time = robot.data.time
|
||||
|
||||
while viewer.is_running() and not gui.closed:
|
||||
t_start = time.perf_counter()
|
||||
|
||||
# Detect viewer reset (Backspace) - time jumps back to 0
|
||||
if robot.data.time < last_time:
|
||||
robot.reset()
|
||||
last_time = robot.data.time
|
||||
|
||||
# Get state and compute control
|
||||
state = robot.get_state()
|
||||
leg_targets, wheel_targets = ctrl.compute(state, robot.dt * sim_steps_per_ctrl)
|
||||
|
||||
# Apply control and step simulation
|
||||
# MPC mode sets ctrl directly via set_ctrl_mit, skip set_ctrl
|
||||
if ctrl.mode != "mpc":
|
||||
robot.set_ctrl(leg_targets, wheel_targets)
|
||||
for _ in range(sim_steps_per_ctrl):
|
||||
robot.step()
|
||||
|
||||
viewer.sync()
|
||||
step += 1
|
||||
|
||||
# Update GUI every 25 steps (~10 Hz)
|
||||
if step % 25 == 0:
|
||||
state = robot.get_state()
|
||||
gui.update_status(state, step)
|
||||
if not gui.tick():
|
||||
break
|
||||
|
||||
# Real-time sync
|
||||
elapsed = time.perf_counter() - t_start
|
||||
target_dt = robot.dt * sim_steps_per_ctrl
|
||||
if elapsed < target_dt:
|
||||
time.sleep(target_dt - elapsed)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user