Skip to main content

Quick Start

1. Start the Runtime Environment

This project uses Docker for containerized deployment. Start it from the project root directory:

chmod +x run.sh
sudo ./run.sh

The following environment variables can be customized:

Environment VariableDescriptionDefault Value
IMAGE_NAMEDocker image nameghrc_2026:v0
CONTAINER_NAMEContainer nameisaac_sim_lerobot
HOST_WORKSPACEHost project directory pathDirectory containing run.sh
CONTAINER_WORKSPACEWorking directory in the container/workspace/GlobalHumanoidRobotChallenge_2026_Baseline
SHM_SIZEShared memory size8g
ISAAC_CACHE_ROOTIsaac Sim cache directory${HOME}/.cache/isaac_sim_container
HF_CACHEHugging Face cache directory${HOME}/.cache/huggingface
HEADLESSWhether to enable headless mode0 (No)

Usage examples:

# Basic startup
./run.sh

# Headless mode (remote server)
./run.sh --headless

# Custom image name
IMAGE_NAME=my_custom_image:v1 ./run.sh

# Custom mount path
HOST_WORKSPACE=/my/project/path ./run.sh

⚠️ Before the first run, make sure Docker and the NVIDIA Container Toolkit have been installed.

2. Features

2.1 Teleoperation (Teleoperate)

Use the keyboard to teleoperate the Walker S2 robot:

# Before starting teleoperation, set teleop.evdev_device_path to the /dev/input/event* device corresponding to your keyboard

# task1
/isaac-sim/python.sh src/lerobot/scripts/lerobot_teleoperate.py \
--robot.type=walker_s2_sim \
--robot.headless=false \
--task=Part_Sorting \
--teleop.type=walker_s2_keyboard \
--teleop.evdev_device_path=/dev/input/event2 \
--display_data=false

# task2
/isaac-sim/python.sh src/lerobot/scripts/lerobot_teleoperate.py \
--robot.type=walker_s2_sim \
--robot.headless=false \
--task=Conveyor_Sorting \
--teleop.type=walker_s2_keyboard \
--teleop.evdev_device_path=/dev/input/event2 \
--display_data=false

# task3
/isaac-sim/python.sh src/lerobot/scripts/lerobot_teleoperate.py \
--robot.type=walker_s2_sim \
--robot.headless=false \
--task=Foam_Inlaying \
--teleop.type=walker_s2_keyboard \
--teleop.evdev_device_path=/dev/input/event2 \
--display_data=false

# task4
/isaac-sim/python.sh src/lerobot/scripts/lerobot_teleoperate.py \
--robot.type=walker_s2_sim \
--robot.headless=false \
--task=Packing_Box \
--teleop.type=walker_s2_keyboard \
--teleop.evdev_device_path=/dev/input/event2 \
--display_data=false
ParameterDescriptionDefault Value
--robot.typeRobot typewalker_s2_sim
--robot.headlessWhether to run in headless modefalse
--taskTask name (Part_Sorting, Conveyor_Sorting, Foam_Inlaying, or Packing_Box)Required
--teleop.typeTeleoperation device typewalker_s2_keyboard
--teleop.evdev_device_pathKeyboard evdev device pathAuto-detected; specifying it is recommended
--display_dataWhether to display camera imagesfalse

2.1.1 Keyboard Mapping

End-effector translation (hold the key for continuous movement)

KeyAction
1Move the end effector along +Y
3Move the end effector along -Y
4Move the end effector along -X
6Move the end effector along +X
7Move the end effector along +Z (up)
9Move the end effector along -Z (down)

End-effector rotation (hold the key for continuous rotation)

KeyAction
yRotate about the Y-axis in the positive direction
uRotate about the Y-axis in the negative direction
vRotate about the X-axis in the positive direction
bRotate about the X-axis in the negative direction
nRotate about the Z-axis in the positive direction
mRotate about the Z-axis in the negative direction

Gripper control

KeyAction
kOpen gripper
lClose gripper

System control

KeyAction
oSwitch the controlled arm (left ↔ right)
0Switch between single-arm control and synchronized dual-arm control
hReturn to the home position
+ / =Increase the movement speed level
-Decrease the movement speed level
qExit teleoperation

2.1.2 Speed Levels

IndexSpeed (m/step)Description
00.010Low speed (default)
10.035Medium speed

2.2 Data Recording (Record)

Record human demonstration data through keyboard teleoperation:

# task1
/isaac-sim/python.sh src/lerobot/scripts/lerobot_record.py \
--robot.type=walker_s2_sim \
--robot.headless=false \
--task=Part_Sorting \
--teleop.type=walker_s2_keyboard \
--teleop.evdev_device_path=/dev/input/event2 \
--dataset.repo_id=your_org/Part_Sorting \
--dataset.root=datasets/Part_Sorting/record/v0 \
--dataset.num_episodes=10 \
--dataset.single_task="Part Sorting" \
--dataset.video=true \
--dataset.fps=30 \
--dataset.episode_time_s=1000000 \
--dataset.push_to_hub=false \
--play_sounds=false

# task2
/isaac-sim/python.sh src/lerobot/scripts/lerobot_record.py \
--robot.type=walker_s2_sim \
--robot.headless=false \
--task=Conveyor_Sorting \
--teleop.type=walker_s2_keyboard \
--teleop.evdev_device_path=/dev/input/event2 \
--dataset.repo_id=your_org/Conveyor_Sorting \
--dataset.root=datasets/Conveyor_Sorting/record/v0 \
--dataset.num_episodes=10 \
--dataset.single_task="Conveyor Sorting" \
--dataset.video=true \
--dataset.fps=30 \
--dataset.episode_time_s=1000000 \
--dataset.push_to_hub=false \
--play_sounds=false

# task3
/isaac-sim/python.sh src/lerobot/scripts/lerobot_record.py \
--robot.type=walker_s2_sim \
--robot.headless=false \
--task=Foam_Inlaying \
--teleop.type=walker_s2_keyboard \
--teleop.evdev_device_path=/dev/input/event2 \
--dataset.repo_id=your_org/Foam_Inlaying \
--dataset.root=datasets/Foam_Inlaying/record/v0 \
--dataset.num_episodes=10 \
--dataset.single_task="Foam Inlaying" \
--dataset.video=true \
--dataset.fps=30 \
--dataset.episode_time_s=1000000 \
--dataset.push_to_hub=false \
--play_sounds=false

# task4
/isaac-sim/python.sh src/lerobot/scripts/lerobot_record.py \
--robot.type=walker_s2_sim \
--robot.headless=false \
--task=Packing_Box \
--teleop.type=walker_s2_keyboard \
--teleop.evdev_device_path=/dev/input/event2 \
--dataset.repo_id=your_org/Packing_Box \
--dataset.root=datasets/Packing_Box/record/v0 \
--dataset.num_episodes=10 \
--dataset.single_task="Packing Box" \
--dataset.video=true \
--dataset.fps=30 \
--dataset.episode_time_s=1000000 \
--dataset.push_to_hub=false \
--play_sounds=false

⚠️ After running the command, Isaac Sim 5.1.0 may take some time to load. If the Isaac Sim window shows 'Not Responding', wait until loading completes. Once it has loaded successfully, you will be prompted to press Enter to begin recording. You can then use keyboard teleoperation to control both arms and manually record demonstrations one episode at a time.

⚠️ Press the left arrow key to discard the current episode. Both arms will return to their initial positions so that the same episode can be recorded again. Press the right arrow key to end the current episode early, save the data, reset the environment, and proceed to the next recording. After all recordings are complete, press Esc to stop recording entirely and save all recorded episodes.

⚠️ The collected data is saved in the directory specified by dataset.root.

ParameterDescriptionDefault Value / Notes
--robot.typeRobot typewalker_s2_sim
--robot.headlessWhether to run in headless modefalse
--taskTask nameRequired
--teleop.typeTeleoperation device typewalker_s2_keyboard
--teleop.evdev_device_pathKeyboard evdev device pathAuto-detected; specifying it is recommended
--dataset.repo_idDataset ID in Hugging Face formatRequired
--dataset.rootLocal save path, used instead of repo_idNone
--dataset.num_episodesNumber of episodes to record50
--dataset.single_taskTask descriptionRequired
--dataset.videoWhether to record videotrue
--dataset.fpsFrame rate30
--dataset.episode_time_sRecording duration per episode, in seconds60
--dataset.push_to_hubWhether to upload to Hugging Facefalse
--play_soundsWhether to play audio cuesfalse

⚠️ The play_sounds parameter must be set to false because the Docker image does not include the audio playback dependencies.

Dataset Structure

datasets/packing_box/
├── data
│ └── chunk-000
│ └── file-000.parquet
├── meta
│ ├── episodes
│ │ └── chunk-000
│ │ └── file-000.parquet
│ ├── info.json
│ ├── stats.json
│ └── tasks.parquet
└── videos
├── observation.images.head_left
│ └── chunk-000
│ └── file-000.mp4
├── observation.images.head_right
│ └── chunk-000
│ └── file-000.mp4
├── observation.images.wrist_left
│ └── chunk-000
│ └── file-000.mp4
└── observation.images.wrist_right
└── chunk-000
└── file-000.mp4

2.3 Dataset Replay (Replay)

Replay a recorded dataset for verification:

# task1
/isaac-sim/python.sh src/lerobot/scripts/lerobot_replay.py \
--robot.type=walker_s2_sim \
--robot.headless=false \
--task=Part_Sorting \
--dataset.repo_id=your_org/your_dataset \
--dataset.root=datasets/Part_Sorting/record/v0 \
--dataset.episode=0 \
--play_sounds=false

# task2
/isaac-sim/python.sh src/lerobot/scripts/lerobot_replay.py \
--robot.type=walker_s2_sim \
--robot.headless=false \
--task=Conveyor_Sorting \
--dataset.repo_id=your_org/your_dataset \
--dataset.root=datasets/Conveyor_Sorting/record/v0 \
--dataset.episode=0 \
--play_sounds=false

# task3
/isaac-sim/python.sh src/lerobot/scripts/lerobot_replay.py \
--robot.type=walker_s2_sim \
--robot.headless=false \
--task=Foam_Inlaying \
--dataset.repo_id=your_org/your_dataset \
--dataset.root=datasets/Foam_Inlaying/record/v0 \
--dataset.episode=0 \
--play_sounds=false

# task4
/isaac-sim/python.sh src/lerobot/scripts/lerobot_replay.py \
--robot.type=walker_s2_sim \
--robot.headless=false \
--task=Packing_Box \
--dataset.repo_id=your_org/your_dataset \
--dataset.root=datasets/Packing_Box/record/v0 \
--dataset.episode=0 \
--play_sounds=false
ParameterDescriptionDefault Value / Notes
--robot.typeRobot typewalker_s2_sim
--taskTask name; it must match the task used for recordingRequired
--dataset.repo_idDataset sourceRequired
--dataset.rootLocal dataset path, used instead of repo_idNone
--dataset.episodeIndex of the episode to replay, starting from 0Required
--play_soundsWhether to play audio cuesfalse

⚠️ The play_sounds parameter must be set to false because the Docker image does not include the audio playback dependencies.

Environment State Restoration Mechanism

During replay, the system automatically restores the poses of environment objects stored in the dataset to the simulation scene:

  1. Data source: The observation.state column contains the robot state in the first 20 dimensions and the environment object poses in the remaining dimensions.
  2. Restoration timing: After robot.connect() and before replay begins.
  • Extract the environment object poses from the first frame, skipping the first 20 robot-state dimensions.
  • Call robot.set_environment_state() to restore the object poses.
  • Advance the physics simulation by 50 steps to allow the objects to stabilize.

Environment state dimension calculation:

TaskDimension FormulaDescription
Part_Sortingnum_parts × 2 × 7Two types of parts
Conveyor_Sortingnum_parts × 2 × 7Two types of parts
Packing_Boxnum_boxes × num_parts × 7Multiple boxes
Foam_Inlaying0No tracked objects

Each object is represented by 7 dimensions:

[x, y, z, qx, qy, qz, qw]