Skip to content

Commit fdf9787

Browse files
tuned the ready state for more stability. integrated in a test the NN based walking policy that is deployed through onnx. in the process broke old walk engine so it can be used for more navigation. the ONNX walk policy has a few test and has great perfornmance across the board. added some performance notes.
1 parent 2d1522b commit fdf9787

File tree

17 files changed

+1030
-357
lines changed

17 files changed

+1030
-357
lines changed

.idea/workspace.xml

Lines changed: 227 additions & 252 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

MUJOCO_LOG.TXT

Lines changed: 0 additions & 6 deletions
This file was deleted.

mjx_notes.txt

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
cd ~/ros2_ws/src/mujoco_playground/mujoco_playground/_src/locomotion/bez2
2+
mjx-testspeed --mjcf=xmls/scene_mjx_feetonly_flat_terrain.xml --base_path=.
3+
4+
5+
6+
berk
7+
Total JIT time: 31.45 s
8+
Total simulation time: 1.16 s
9+
Total steps per second: 880664
10+
Total realtime factor: 1761.33 x
11+
Total time per step: 1.14 µs
12+
13+
14+
g1
15+
Total JIT time: 49.57 s
16+
Total simulation time: 1.84 s
17+
Total steps per second: 556957
18+
Total realtime factor: 1113.91 x
19+
Total time per step: 1.80 µs
20+
21+
bez2 only head
22+
23+
Total JIT time: 21.88 s
24+
Total simulation time: 5.00 s
25+
Total steps per second: 204634
26+
Total realtime factor: 409.27 x
27+
Total time per step: 4.89 µs
28+
29+
bez2 only feet box
30+
Total JIT time: 21.48 s
31+
Total simulation time: 0.99 s
32+
Total steps per second: 1038202
33+
Total realtime factor: 2076.40 x
34+
Total time per step: 0.96 µs
35+
36+
bez2 only feet mesh
37+
Total JIT time: 31.45 s
38+
Total simulation time: 2.58 s
39+
Total steps per second: 397097
40+
Total realtime factor: 794.19 x
41+
Total time per step: 2.52 µ
42+
43+
bez2 only feet convex mesh
44+
Total JIT time: 33.26 s
45+
Total simulation time: 1.29 s
46+
Total steps per second: 791963
47+
Total realtime factor: 1583.93 x
48+
Total time per step: 1.26 µs
49+
50+
go1 feet only
51+
52+
Total JIT time: 16.25 s
53+
Total simulation time: 0.64 s
54+
Total steps per second: 1608187
55+
Total realtime factor: 6432.75 x
56+
Total time per step: 0.62 µs
57+
58+
go1 scene_mjx_fullcollisions_flat_terrain.xml
59+
60+
Total JIT time: 32.26 s
61+
Total simulation time: 3.62 s
62+
Total steps per second: 282638
63+
Total realtime factor: 1130.55 x
64+
Total time per step: 3.54 µs
65+
66+
go1 scene_mjx_flat_terrain.xml
67+
68+
Total JIT time: 20.63 s
69+
Total simulation time: 1.23 s
70+
Total steps per second: 835247
71+
Total realtime factor: 3340.99 x
72+
Total time per step: 1.20 µs
73+
74+
op3 feet only
75+
76+
Total JIT time: 33.70 s
77+
Total simulation time: 1.38 s
78+
Total steps per second: 740388
79+
Total realtime factor: 2961.55 x
80+
Total time per step: 1.35 µs
81+
82+
bez2 dof 20
83+
84+
time to jit: 0:02:13.416952
85+
time to train: 0:53:36.504378
86+
87+
bez2 dof 12
88+
89+
time to jit: 0:02:13.416952
90+
time to train: 0:53:36.504378

requirements.txt

Lines changed: 12 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,12 @@
1-
construct==2.10.67
2-
cv_bridge==3.2.1
3-
fast_simplification==0.1.12
4-
filterpy==1.4.5
5-
gdown==4.5.4
6-
geometry_msgs==4.9.0
7-
ischedule==1.2.7
8-
launch_ros==0.19.10
9-
matplotlib==3.5.1
10-
mujoco==3.3.5
11-
mujoco_mjx==3.3.5
12-
nav_msgs==4.9.0
13-
numpy==2.3.2
14-
open3d==0.17.0
15-
opencv_python==4.10.0.84
16-
pandas==2.3.2
17-
pinocchio==0.4.3
18-
placo==0.9.14
19-
protobuf==3.20.2
20-
protobuf==3.12.4
21-
psutil==5.9.8
22-
psutil==5.9.0
23-
pybullet==3.2.7
24-
pygame==2.5.2
25-
pyserial==3.5
26-
pytest==7.4.4
27-
pytest==6.2.5
28-
pyvista==0.46.3
29-
PyYAML==6.0.2
30-
PyYAML==5.4.1
31-
PyYAML==6.0.2
32-
rclpy==3.3.17
33-
rosgraph_msgs==1.2.2
34-
scipy==1.8.0
35-
segment_anything==1.0
36-
self==2020.12.3
37-
sensor_msgs==4.9.0
38-
setuptools==71.0.0
39-
setuptools==59.6.0
40-
std_msgs==4.9.0
41-
std_srvs==4.9.0
42-
tf==1.1.0
43-
tf2_py==0.25.16
44-
tf2_ros_py==0.25.16
45-
timeout_decorator==0.5.0
46-
#torch==2.3.1
47-
transforms3d==0.4.2
48-
trimesh==4.5.3
49-
# pipreqs .
1+
torch==2.8.0
2+
torchvision==0.23.0
3+
opencv-python==4.12.0.88
4+
placo==0.9.16
5+
matplotlib==3.10.7
6+
pandas==2.3.3
7+
tqdm==4.67.1
8+
ultralytics==8.3.187
9+
seaborn==0.13.2
10+
gitpython>=3.1.30
11+
pillow>=10.3.0
12+
setuptools>=70.0.0

soccer_control/soccer_pycontrol/config/bez2/bez2_sim_mujoco.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ replan_timesteps: 10 # Replanning each n timesteps
3535
# Posture parameters
3636
walk_com_height: 0.24 # Constant height for the CoM [m]
3737
walk_foot_height: 0.05 # Height of foot rising while walking [m]
38-
walk_trunk_pitch: 0.2 # Trunk pitch angle [rad]
38+
walk_trunk_pitch: 0.15 # Trunk pitch angle [rad]
3939
walk_foot_rise_ratio: 0.2 # Time ratio for the foot swing plateau (0.0 to 1.0)
4040

4141
# Feet parameters

soccer_control/soccer_pycontrol/soccer_pycontrol/model/motor_control.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,19 @@ def get_qdot(self, name: str):
102102
"""
103103
addr = self.model.jnt_dofadr[self.dofs_to_index[name]]
104104
return self.data.qvel[addr]
105+
def get_q_legs(self):
106+
names = ["left_hip_yaw", "left_hip_roll", "left_hip_pitch", "left_knee", "left_ankle_pitch", "left_ankle_roll", "right_hip_yaw", "right_hip_roll", "right_hip_pitch", "right_knee", "right_ankle_pitch", "right_ankle_roll"]
107+
index = []
108+
for name in names:
109+
index.append(self.get_q(name))
110+
return index
111+
112+
def get_qvel_legs(self):
113+
names = ["left_hip_yaw", "left_hip_roll", "left_hip_pitch", "left_knee", "left_ankle_pitch", "left_ankle_roll", "right_hip_yaw", "right_hip_roll", "right_hip_pitch", "right_knee", "right_ankle_pitch", "right_ankle_roll"]
114+
index = []
115+
for name in names:
116+
index.append(self.get_qdot(name))
117+
return index
105118

106119
def set_q(self, name: str, value: float):
107120
"""
@@ -170,6 +183,10 @@ def set_motor(self) -> None:
170183
indexes = list(self.ctrl_dofs_to_index.values())
171184
self.data.ctrl[indexes] = self.get_angles()
172185

186+
def set_motor_head(self) -> None:
187+
indexes = self.get_dof_indexes(["head_yaw", "head_pitch"])
188+
self.data.ctrl[indexes] = self.get_angles()[:2]
189+
173190
def get_dof_indexes(self, names: List[str]) -> list:
174191
index = []
175192
for name in names:

soccer_control/soccer_pycontrol/soccer_pycontrol/walk_engine/navigator.py

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ def __init__(
3535
sim: bool = True,
3636
):
3737

38+
self.dx = 0
39+
self.dy = 0
40+
self.dtheta = 0
3841
self.world = world
3942
self.bez = bez
4043
self.imu_feedback_enabled = imu_feedback_enabled
@@ -59,7 +62,7 @@ def __init__(
5962
) # TODO could also mod if balance is decreasing
6063

6164
self.nav_yaw_pid = PID(
62-
Kp=0.2,
65+
Kp=0.5,
6366
Kd=0,
6467
Ki=0,
6568
setpoint=0,
@@ -109,18 +112,18 @@ def walk_pose(self, target_goal: Transformation):
109112
self.nav_yaw_pid.reset()
110113
self.nav_yaw_pid.setpoint = target_goal.orientation_euler[0]
111114

112-
dx, dy = find_new_vel(goal_loc=target_goal.position[:2])
115+
self.dx, self.dy = find_new_vel(goal_loc=target_goal.position[:2])
113116
# he = self.heading_error(target_goal.orientation_euler[0], pose.orientation_euler[0])
114117
# dtheta = math.copysign(0.5, he)
115-
self.foot_step_planner.setup_walk(dx, dy)
118+
# self.foot_step_planner.setup_walk(dx, dy)
116119
self.walker.t = 0
117120
# TODO fix and add to a nav could add a funct for pybullet or python
118121
# TODO could have a balancing mode by default could use the COM
119122
# TODO for ball could just remove
120123

121124
if (
122125
position_error(pose.position[:2], target_goal.position[:2]) > self.error_tol
123-
or abs(heading_error(target_goal.orientation_euler[0], pose.orientation_euler[0])) > self.error_tol
126+
# or abs(heading_error(target_goal.orientation_euler[0], pose.orientation_euler[0])) > self.error_tol
124127
): # self.bez.sensors.get_pose() #TODO about 20% or 40% error
125128
pose = (
126129
self.bez.sensors.get_pose()
@@ -139,12 +142,12 @@ def walk_pose(self, target_goal: Transformation):
139142
# TODO make a 2d unit test
140143
self.nav_x_pid.setpoint = goal.position[0]
141144
self.nav_y_pid.setpoint = goal.position[1]
142-
dx = self.nav_x_pid.update(0)
143-
dy = self.nav_y_pid.update(0)
144-
dtheta = self.nav_yaw_pid.update(pose.orientation_euler[0])
145-
# print(f"dx: {round(dx, 3)} dy: {round(dy, 3)} dtheta: {round(dtheta, 3)} err_x: {round(x_error, 3)} err_y: {round(y_error, 3)} err_theta: {round(head_error, 3)}")
146-
self.foot_step_planner.configure_planner(dx, dy, dtheta)
147-
self.walker.walk_loop() # TODO move main loop out of here
145+
self.dx = self.nav_x_pid.update(0)
146+
self.dy = self.nav_y_pid.update(0)
147+
self.dtheta = self.nav_yaw_pid.update(pose.orientation_euler[0])
148+
# print(f"dx: {round(self.dx, 3)} dy: {round(self.dy, 3)} dtheta: {round(self.dtheta, 3)} err_x: {round(x_error, 3)} err_y: {round(y_error, 3)} err_theta: {round(head_error, 3)}")
149+
# self.foot_step_planner.configure_planner(dx, dy, dtheta)
150+
# self.walker.walk_loop() # TODO move main loop out of here
148151
else:
149152
self.ready()
150153
self.walker.enable_walking = False
@@ -162,8 +165,8 @@ def walk_ball(self, target_goal: Transformation, ball_pixel):
162165
self.nav_yaw_pid.reset()
163166
self.nav_yaw_pid.setpoint = 0 # TODO add yaw modes
164167

165-
dx, dy = find_new_vel(goal_loc=target_goal.position[:2])
166-
self.foot_step_planner.setup_walk(dx, dy)
168+
self.dx, self.dy = find_new_vel(goal_loc=target_goal.position[:2])
169+
# self.foot_step_planner.setup_walk(dx, dy)
167170
self.walker.t = 0
168171
# TODO fix and add to a nav could add a funct for pybullet or python
169172
# TODO could have a balancing mode by default could use the COM
@@ -178,13 +181,13 @@ def walk_ball(self, target_goal: Transformation, ball_pixel):
178181
# TODO replace with pure pursuit
179182
# TODO make a 2d unit test
180183

181-
dx = self.nav_x_pid.update(0)
182-
dy = self.nav_y_pid.update(0)
184+
self.dx = self.nav_x_pid.update(0)
185+
self.dy = self.nav_y_pid.update(0)
183186

184-
dtheta = self.nav_yaw_pid.update(self.bez.sensors.get_pose().orientation_euler[0])
187+
self.dtheta = self.nav_yaw_pid.update(self.bez.sensors.get_pose().orientation_euler[0])
185188
# print(round(dx, 3), " ", round(dy, 3), " ", round(dtheta, 3), " ", round(x_error, 3), " ", round(y_error, 3), " ", round(head_error, 3))
186-
self.foot_step_planner.configure_planner(dx, dy, dtheta)
187-
189+
# self.foot_step_planner.configure_planner(self.dx, self.dy, self.dtheta)
190+
#
188191
self.walker.walk_loop(target_goal.position, ball_pixel)
189192
# else:
190193
# self.ready()

soccer_control/soccer_pycontrol/soccer_pycontrol/walk_engine/walker.py

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ def __init__(self, bez: Bez, planner: FootStepPlanner, imu_feedback_enabled: boo
3232
Kd=0,
3333
Ki=-0.03,
3434
setpoint=2.4,
35-
output_limits=(0.4, 1.3),
35+
output_limits=(0.1, 1.3),
3636
)
3737

3838
def reset_walk(self):
@@ -42,13 +42,13 @@ def reset_walk(self):
4242
# TODO could make input a vector
4343

4444
def walk_loop(self, target_goal=[0, 0], ball_pixel=[0, 0]): # TODO set default to something better
45-
self.foot_step_planner.plan_steps(self.t)
46-
self.bez.motor_control.set_angles_from_placo(self.foot_step_planner.robot)
45+
# self.foot_step_planner.plan_steps(self.t)
46+
# self.bez.motor_control.set_angles_from_placo(self.foot_step_planner.robot)
4747

48-
if self.imu_feedback_enabled and self.bez.sensors.imu_ready:
49-
[_, pitch, roll] = self.bez.sensors.get_imu()
50-
# print(pitch," ", roll)
51-
self.stabilize_walk(pitch, roll)
48+
# if self.imu_feedback_enabled and self.bez.sensors.imu_ready:
49+
# [_, pitch, roll] = self.bez.sensors.get_imu()
50+
# # print(pitch," ", roll)
51+
# self.stabilize_walk(pitch, roll)
5252

5353
# self.foot_step_planner.head_movement(target_goal)
5454
if ball_pixel != self.last_ball:
@@ -57,7 +57,7 @@ def walk_loop(self, target_goal=[0, 0], ball_pixel=[0, 0]): # TODO set default
5757
self.last_ball = ball_pixel
5858
self.ball_dx = self.ball_x_pid.update(3.2 - ball_pixel[0] / 100.0)
5959
self.ball_dy = self.ball_y_pid.update(ball_pixel[1] / 100.0)
60-
# print(f"{ball_pixel}, {self.ball_dx}, {self.ball_dy}")
60+
print(f"{ball_pixel}, {self.ball_dx}, {self.ball_dy}")
6161
self.bez.motor_control.set_head_target_angles([-self.ball_dx, self.ball_dy])
6262
# self.bez.motor_control.configuration["head_pitch"] = self.ball_dy
6363

@@ -92,7 +92,8 @@ def walk_loop(self, target_goal=[0, 0], ball_pixel=[0, 0]): # TODO set default
9292
# self.bez.motor_control.set_left_leg_target_angles([0, 0, 0, 0, 0, 0])
9393
# self.bez.motor_control.set_head_target_angles(
9494
# [0, 0])
95-
self.bez.motor_control.set_motor()
95+
96+
self.bez.motor_control.set_motor_head()
9697

9798
self.t = self.foot_step_planner.step(self.t)
9899

0 commit comments

Comments
 (0)