Skip to content

Commit 3b60fbd

Browse files
authored
Isaac Sim: add TRON1, split launchers, and fix issues (#1)
* include isaac sim, policy checkpoints, and cloud support * fix isaac sim, separate launch files, refactor lowstate node * add tron usd * fix lint
1 parent 1eb8296 commit 3b60fbd

15 files changed

Lines changed: 2035 additions & 211 deletions

File tree

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@ Thumbs.db
2323
# Logs
2424
*.log
2525

26+
# Isaac Sim heavy binary assets — populate manually from go2_isaac_sim/standalone
27+
# (Modern_Apartment.usdz ~101M, human.usdz ~20M, USD configuration dirs ~46M)
28+
isaac_sim/assets/human/
29+
isaac_sim/assets/environment/
30+
2631
# Isaac Sim venv
2732
isaac_sim/env_isaacsim/
2833
isaac_sim/__pycache__/

README.md

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ This repo provides two simulation environments:
77
| Simulator | Directory | Robots | Description |
88
|-----------|-----------|--------|-------------|
99
| **Gazebo** | `gazebo_sim/` | Go2 | Lightweight sim with lidar-based obstacle avoidance |
10-
| **Isaac Sim** | `isaac_sim/` | Go2, G1 | High-fidelity NVIDIA sim with cameras, LiDAR, IMU |
10+
| **Isaac Sim** | `isaac_sim/` | Go2, G1, TRON1 | High-fidelity NVIDIA sim with cameras, LiDAR, IMU |
1111

1212
---
1313

@@ -89,11 +89,13 @@ uv run src/run.py go2_sim_autonomy
8989

9090
### Features
9191

92-
- **Isaac Sim**: Realistic physics simulation of Unitree Go2 and G1
92+
- **Isaac Sim**: Realistic physics simulation of Unitree Go2, G1, and TRON1
9393
- **Cameras**: RealSense depth + RGB, Go2 front camera
9494
- **LiDAR**: Unitree L1 and Velodyne VLP-16 (2D scan)
9595
- **IMU**: Simulated IMU sensor
9696
- **ROS 2 Integration**: Full topic publishing (images, point clouds, odometry, TF, joint states)
97+
- **Lowstate publisher**: mock `/lowstate`, `/lf/lowstate` with battery drain/charge sim
98+
- **Optional scenery**: apartment environment, human pedestrian, AprilTag charging dock
9799

98100
### Prerequisites
99101

@@ -158,10 +160,21 @@ ros2 launch isaac_sim isaac_sim_launch.py
158160
# G1 humanoid
159161
ros2 launch isaac_sim isaac_sim_launch.py robot_type:=g1
160162

163+
# TRON1 bipedal wheelfoot
164+
ros2 launch isaac_sim isaac_sim_launch.py robot_type:=tron1
165+
161166
# Without sensor nodes (if OM1-ros2-sdk is not built)
162167
ros2 launch isaac_sim isaac_sim_launch.py launch_sensors:=false
163168
```
164169

170+
If you start `run.py` separately (e.g. directly in the Isaac Sim venv), use the
171+
support-nodes launcher instead — it brings up only the bridge nodes, lowstate,
172+
and topic relays:
173+
174+
```bash
175+
ros2 launch isaac_sim isaac_sim_launch_support_nodes.py
176+
```
177+
165178
**Terminal 2 — Zenoh bridge:**
166179

167180
```bash
@@ -191,7 +204,7 @@ uv run src/run.py go2_sim_autonomy
191204

192205
| Argument | Default | Description |
193206
|----------|---------|-------------|
194-
| `robot_type` | `go2` | `go2` or `g1` |
207+
| `robot_type` | `go2` | `go2`, `g1`, or `tron1` |
195208
| `policy_dir` | auto | Path to policy directory |
196209
| `launch_sensors` | `true` | Launch sensor nodes from OM1-ros2-sdk |
197210

@@ -201,7 +214,7 @@ These are passed directly if running `run.py` manually (advanced usage):
201214

202215
| Argument | Default | Description |
203216
|----------|---------|-------------|
204-
| `--robot_type` | `go2` | `go2` or `g1` |
217+
| `--robot_type` | `go2` | `go2`, `g1`, or `tron1` |
205218
| `--policy_dir` | auto | Path to policy directory |
206219

207220
---
@@ -218,10 +231,12 @@ OM1-sim/
218231
│ ├── champ_base/ # CHAMP base package
219232
│ └── champ_msgs/ # CHAMP message definitions
220233
├── isaac_sim/ # Isaac Sim simulation
221-
│ ├── launch/ # ROS2 launch file (isaac_sim_launch.py)
234+
│ ├── launch/ # isaac_sim_launch.py (all-in-one)
235+
│ │ # + isaac_sim_launch_support_nodes.py
222236
│ ├── run.py # Main simulation script
223237
│ ├── utils.py # ROS2 OmniGraph utilities
224-
│ ├── assets/ # Robot USD models (Go2, G1)
238+
│ ├── lowstate_node.py # Mock LowState publisher with battery sim
239+
│ ├── assets/ # Robot USD models (Go2, G1, TRON1)
225240
│ └── checkpoints/ # Pre-trained locomotion policies
226241
├── om_api/ # OpenMind message definitions (shared)
227242
├── unitree_api/ # Unitree API messages (shared)

isaac_sim/CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,10 @@ install(
88
DESTINATION share/${PROJECT_NAME}
99
)
1010

11+
install(PROGRAMS
12+
lowstate_node.py
13+
DESTINATION lib/${PROJECT_NAME}
14+
RENAME lowstate_node
15+
)
16+
1117
ament_package()

isaac_sim/assets/apriltags.png

7.39 KB
Loading
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/home/shaohong/Projects/tron1-rl-isaaclab/exts/bipedal_locomotion/bipedal_locomotion/assets/usd/WF_TRON1A/configuration
420 KB
Binary file not shown.
726 KB
Binary file not shown.
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# TRON1 WheelFoot (WF_TRON1A) deployment configuration
2+
# 8 DOF: 6 leg joints (position control) + 2 wheel joints (velocity control)
3+
# Joint order: abad_L, abad_R, hip_L, hip_R, knee_L, knee_R, wheel_L, wheel_R
4+
5+
step_dt: 0.02
6+
decimation: 4
7+
history_length: 10
8+
9+
# No joint reordering needed - sim order matches SDK order
10+
joint_ids_map: null
11+
12+
# 8 joints total
13+
stiffness: [40.0, 40.0, 40.0, 40.0, 40.0, 40.0, 0.0, 0.0]
14+
damping: [2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 0.8, 0.8]
15+
default_joint_pos: [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
16+
17+
# Leg joints are first 6, wheel joints are last 2
18+
num_leg_joints: 6
19+
num_wheel_joints: 2
20+
21+
commands:
22+
base_velocity:
23+
ranges:
24+
lin_vel_x: [-0.7, 0.7]
25+
lin_vel_y: [-0.5, 0.5]
26+
ang_vel_z: [-3.14159, 3.14159]
27+
28+
actions:
29+
leg:
30+
scale: 0.25
31+
use_default_offset: true
32+
wheel:
33+
scale: 1.0
34+
35+
observations:
36+
base_ang_vel:
37+
scale: [0.25, 0.25, 0.25]
38+
projected_gravity:
39+
scale: [1.0, 1.0, 1.0]
40+
joint_pos_rel:
41+
# Only 6 leg joints (no wheels)
42+
scale: [1.0, 1.0, 1.0, 1.0, 1.0, 1.0]
43+
joint_vel_rel:
44+
# All 8 joints
45+
scale: [0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05]
46+
last_action:
47+
# All 8 actions
48+
scale: [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0]

isaac_sim/launch/isaac_sim_launch.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -148,12 +148,13 @@ def generate_launch_description():
148148
],
149149
)
150150

151-
go2_lowstate_node = TimerAction(
151+
# Use the Isaac-Sim-specific lowstate node, not gazebo's go2_lowstate_node.
152+
lowstate_node = TimerAction(
152153
period=15.0,
153154
actions=[
154155
Node(
155-
package="go2_sim",
156-
executable="go2_lowstate_node",
156+
package="isaac_sim",
157+
executable="lowstate_node",
157158
name="go2_lowstate_node",
158159
output="screen",
159160
),
@@ -211,7 +212,7 @@ def generate_launch_description():
211212
# Bridge nodes (after 15s delay for Isaac Sim startup)
212213
go2_remapping_node,
213214
go2_sport_node,
214-
go2_lowstate_node,
215+
lowstate_node,
215216
]
216217
+ sensor_entities
217218
)
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
"""
2+
Bridge nodes launcher for use when Isaac Sim is already running.
3+
4+
Counterpart to isaac_sim_launch.py, which spawns Isaac Sim itself plus these
5+
nodes. Use this one if you start run.py separately.
6+
7+
om_path is not launched here — it comes from OM1-ros2-sdk's sensor_launch.py
8+
that the all-in-one launcher invokes. Uncomment the block below to run it
9+
standalone.
10+
"""
11+
12+
from launch import LaunchDescription
13+
from launch.actions import DeclareLaunchArgument
14+
from launch.conditions import IfCondition
15+
from launch.substitutions import LaunchConfiguration
16+
from launch_ros.actions import Node
17+
18+
19+
def generate_launch_description():
20+
use_sim_time = LaunchConfiguration("use_sim_time")
21+
22+
declare_use_sim_time = DeclareLaunchArgument(
23+
"use_sim_time",
24+
default_value="true",
25+
description="Use simulation (Isaac Sim) clock if true",
26+
)
27+
declare_rviz = DeclareLaunchArgument(
28+
"rviz", default_value="false", description="Launch rviz2"
29+
)
30+
31+
go2_sport_node = Node(
32+
package="go2_sim",
33+
executable="go2_sport_node",
34+
name="go2_sport_node",
35+
output="screen",
36+
parameters=[{"use_sim_time": use_sim_time}],
37+
)
38+
39+
go2_remapping_node = Node(
40+
package="go2_sim",
41+
executable="go2_remapping_node",
42+
name="go2_remapping_node",
43+
output="screen",
44+
parameters=[{"use_sim_time": use_sim_time}],
45+
)
46+
47+
# Use the Isaac-Sim-specific lowstate node, not gazebo's go2_lowstate_node.
48+
lowstate_node = Node(
49+
package="isaac_sim",
50+
executable="lowstate_node",
51+
name="go2_lowstate_node",
52+
output="screen",
53+
parameters=[{"use_sim_time": use_sim_time}],
54+
)
55+
56+
# om_path_node = Node(
57+
# package="om_path",
58+
# executable="om_path",
59+
# name="om_path",
60+
# output="screen",
61+
# parameters=[
62+
# {"use_sim_time": use_sim_time},
63+
# {"use_sim": True},
64+
# ],
65+
# )
66+
67+
# Republish renamed topics so consumers using either naming work.
68+
relay_color_image = Node(
69+
package="topic_tools",
70+
executable="relay",
71+
name="relay_color_image",
72+
arguments=[
73+
"/camera/realsense2_camera_node/color/image_raw",
74+
"/camera/realsense2_camera_node/color/image_isaac_sim_raw",
75+
],
76+
output="screen",
77+
parameters=[{"use_sim_time": use_sim_time}],
78+
)
79+
relay_depth_image = Node(
80+
package="topic_tools",
81+
executable="relay",
82+
name="relay_depth_image",
83+
arguments=[
84+
"/camera/realsense2_camera_node/depth/image_rect_raw",
85+
"/camera/realsense2_camera_node/depth/image_rect_isaac_sim_raw",
86+
],
87+
output="screen",
88+
parameters=[{"use_sim_time": use_sim_time}],
89+
)
90+
relay_unitree_lidar = Node(
91+
package="topic_tools",
92+
executable="relay",
93+
name="relay_unitree_lidar",
94+
arguments=["/unitree_lidar/points", "/unitree_lidar"],
95+
output="screen",
96+
parameters=[{"use_sim_time": use_sim_time}],
97+
)
98+
relay_go2_camera = Node(
99+
package="topic_tools",
100+
executable="relay",
101+
name="relay_go2_camera",
102+
arguments=["/camera/image_raw", "/camera/go2/image_raw"],
103+
output="screen",
104+
parameters=[{"use_sim_time": use_sim_time}],
105+
)
106+
107+
rviz2 = Node(
108+
package="rviz2",
109+
executable="rviz2",
110+
name="rviz2",
111+
output="screen",
112+
condition=IfCondition(LaunchConfiguration("rviz")),
113+
)
114+
115+
return LaunchDescription(
116+
[
117+
declare_use_sim_time,
118+
declare_rviz,
119+
go2_sport_node,
120+
go2_remapping_node,
121+
lowstate_node,
122+
relay_color_image,
123+
relay_depth_image,
124+
relay_unitree_lidar,
125+
relay_go2_camera,
126+
rviz2,
127+
]
128+
)

0 commit comments

Comments
 (0)