Skip to content

z4ziggy/z4rtc

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

23 Commits
 
 
 
 
 
 
 
 

Repository files navigation

z4rtc - Unitree G1/Go2 WebRTC Controller

A full-featured command-line controller for the Unitree Go2 (and experimental G1) robots. Communicates directly over WebRTC via the robot's built-in data channel, with no middleware required.

Work in progress. Expect rough edges and breaking changes. Contributions and bug reports are welcome.

Features

  • Interactive REPL - tab-completed shell for live robot control
  • Single-shot CLI - scriptable one-liner commands (z4rtc.py stand_up)
  • 149 commands - locomotion, poses, tricks, configuration, services, sensors
  • 50 subscribable topics - IMU, motor state, battery, GNSS, odometry, and more
  • 40 USLAM sub-commands - mapping, navigation, patrol, localization
  • Video streaming - H.264 live view or recording via ffplay/mpv/vlc
  • Photo capture - single frame grab with auto-open (feh/eog/xdg-open)
  • Audio I/O - listen to robot mic, upload audio files, megaphone broadcast
  • LiDAR viewer - live 3D point cloud in browser (Three.js + WebSocket)
  • SLAM & navigation - lidar control, mapping, obstacle avoidance, patrol routes
  • GPT streaming - real-time GPT responses with token-by-token display
  • Pet mode - AI personality, pet background images, natural language commands
  • Map download - retrieve map.pcd, map.pgm, map.txt from the robot
  • Cloud mode - connect via Unitree cloud (email/password auth + TURN)
  • G1 support - experimental humanoid mode with arm control
  • Auto-discovery - finds robots on the LAN via UDP multicast

Requirements

Python packages

pip install -r requirements.txt

System dependencies (optional, for media features)

# Debian/Ubuntu
sudo apt install ffmpeg mpv alsa-utils

# ffplay (part of ffmpeg), mpv, or vlc needed for video
# aplay needed for audio listening
# feh, eog, or xdg-open for photo viewing

Installation

No build step. Just make the script executable:

chmod +x z4rtc.py

Or run it directly with python3 z4rtc.py.

CLI Flags

Flag Arguments Description
--ip <addr> Robot IP address (auto-discovers if omitted)
--g1 G1 humanoid robot mode
--user <email> Cloud login email
--pass <password> Cloud login password
--sn <serial> Robot serial number (cloud, optional)
--debug Verbose debug output

Usage

Interactive mode (REPL)

./z4rtc.py                        # Auto-discover robot and open REPL
./z4rtc.py --ip 192.168.1.100     # Connect to a known IP

Once connected, type any command at the go2> prompt. Tab completion is supported.

Single-shot commands

./z4rtc.py stand_up                          # Stand the robot up
./z4rtc.py --ip 10.0.0.15 move 0.5 0 0       # Walk forward at 0.5 m/s
./z4rtc.py sub low_state 5                   # Subscribe `low_state` topic for 5 seconds
./z4rtc.py video_show                        # Open live video stream
./z4rtc.py photo snapshot.jpg                # Capture a photo
./z4rtc.py light_color red                   # Solid red LED
./z4rtc.py light_color blue 5 500            # Blue flashing for 5s

If no --ip flag is given, auto-discovery runs silently before the command.

Cloud mode

./z4rtc.py --user you@email.com --pass yourpass              # Auto-detect robot
./z4rtc.py --user you@email.com --pass yourpass --sn ABC123  # Specific robot

G1 humanoid mode

./z4rtc.py --g1 --ip 10.0.0.15 wave

Info Commands (no robot needed)

Command Description
help Full command reference
apis All API commands with topics and payloads
subs All subscribable topics
topics All topic names

Command Reference

Motion

Command Arguments Description
move <vx> <vy> <vyaw> Set velocity (m/s, m/s, rad/s)
euler <roll> <pitch> <yaw> Set body orientation (radians)
body_height <meters> Adjust body height
foot_raise_height <meters> Adjust step height
switch_gait 0-4 Gait (idle/trot/trot_run/climb/rev_climb)
speed_level -1/0/1 Slow / normal / fast
continuous_gait 0/1 Continuous gait mode
economic_gait 0/1 Energy-saving gait
pose 0/1 Lock current pose

Postures (no arguments)

stand_up, stand_down, balance_stand, sit, rise_sit, recovery_stand, damp, stop_move

Tricks (no arguments)

hello, stretch, wiggle_hips, wallow, content, heart, scrape, trigger, dance1, dance2, dance3, dance4, front_flip, back_flip, left_flip, right_flip, front_jump, front_pounce, moon_walk, bound, lead_follow, standup, cross_walk, static_walk, trot_run, one_sided_step

Video & Audio

Command Arguments Description
video_show Live video stream (ffplay/mpv/vlc)
video_save [file] [secs] Record video to file
photo [file] Capture single frame (auto-opens viewer)
audio_listen Stream robot mic to speakers
audio_save [file] [secs] Record robot audio
audio_upload <file> Upload WAV/MP3 to robot
megaphone_play <file> Broadcast audio through robot speakers
audio_play <id> Play uploaded audio by ID
audio_volume_set 0-10 Set volume
audio_play_mode_set <mode> Play mode (single_cycle/no_cycle/list_loop)

LED

Command Arguments Description
light_color <color> [time] [flash_cycle] LED color (white/red/yellow/blue/green/cyan/purple)
light_set 0-10 Set brightness
light_get Get current light config

Examples: light_color red (constant red), light_color blue 5 500 (blue flashing for 5s)

SLAM & Navigation

Command Arguments Description
lidar_on Enable lidar
lidar_off Disable lidar
lidar_show Live 3D LiDAR point cloud in browser
lidar_stop Stop LiDAR viewer
slam_start Start SLAM mapping
slam_stop Stop SLAM mapping
obstacles_on Enable obstacle avoidance
obstacles_off Disable obstacle avoidance
get_map_file Download map files (map.pcd/pgm/txt)
uslam_cmd <cmd> USLAM command (40 sub-commands)

USLAM sub-commands include mapping, localization, navigation, and patrol control. Run ./z4rtc.py help to see all 40 sub-commands with descriptions.

Configuration & Services

Command Arguments Description
config_get <name> Read a config key
config_set <json> Write a config key
config_delete <name> Delete a config key
config_meta <name> Get config metadata
service_list List running services
service_start <name> Start a service
service_stop <name> Stop a service
motion_switch <mode> Switch motion mode (Go2: mcf, Go2-W: ai-w)
traffic_save on/off Toggle traffic saving

Bash Runner (diagnostics)

Command Description
run_hw_version Get hardware version
run_pkg_version Get firmware version
run_self_test Run self-diagnostic
run_ip_address Get robot IP
run_rf_power Get RC RF power
run_calibrate_save Save joint calibration
run_get_sn Get robot serial number
run_start_sport Start sport mode
run_error_code Get basic service error code
run_test_success Run success diagnostic
run_test_error Run error diagnostic

Pet / AI (Go2 AI edition)

Command Arguments Description
pet_switch Toggle pet mode
pet_ask <text> Natural language command
pet_background [file] Get pet environment image (base64 JPEG)
pet_role_list List available AI personalities
gpt_req <text> Streaming GPT request

Virtual Joystick

Command Arguments Description
joy <lx> <ly> <rx> <ry> [keys] Virtual joystick input (requires switch_joystick 1)

Keys: R1=1 L1=2 Start=4 Select=8 R2=16 L2=32 A=256 B=512 X=1024 Y=2048

Low-Level Protocol Access

Command Arguments Description
msg <topic> [json] Fire-and-forget message
req <topic> [json] Request with auto-subscribe
raw <json> Send arbitrary JSON directly (no envelope)
rtc_inner_req [json] Bridge internal request

msg and req wrap your payload in a {"type", "topic", "data"} envelope automatically. raw bypasses this and sends your JSON as-is — useful when the standard envelope doesn't match what the robot expects, without needing to add a new command for every edge case.

msg rt/utlidar/switch on                          # Wrapped: {"type":"msg","topic":"...","data":"on"}
req rt/api/sport/request '{"api_id": 1001}'       # Wrapped: {"type":"req","topic":"...","data":{...}}
raw '{"type":"req","topic":"rt/api/sport/request","data":{"header":{"identity":{"api_id":1001}}}}'
raw '{"type":"rtc_inner_req","topic":"","data":{"req_type":"custom","instruction":"test"}}'

Subscriptions

Command Arguments Description
sub <topic> [seconds] Subscribe to topic (default 10s)
unsub <topic> Unsubscribe
quiet Toggle message display (interactive only)

Popular topics: low_state, sport_state, multiple_state, robot_pose, bms_state, wireless_controller

Run ./z4rtc.py subs for the full list of 50 subscribable topics.

Discovery

z4rtc finds your robot automatically via UDP multicast (231.1.1.1 and 239.255.1.1). If multiple robots are found, use --ip to specify which one.

Architecture

Single-file, zero-middleware WebRTC controller:

  • ICE/WebRTC - uses aiortc with monkey-patched shared ICE credentials
  • SDP exchange - port 9991 (fw >= 1.1.11) with port 8081 fallback
  • H.264 video - Annex B stream piped to external player or saved via ffmpeg
  • Encryption - RSA + AES-ECB for SDP; AES-GCM for cloud telemetry
  • Protocol - binary-framed JSON over WebRTC data channel with chunk reassembly
  • REPL - readline with tab completion; restores terminal state on exit

License

See LICENSE for details.

Copyright

Copyright (c) 2026 Ziggy (Elia Yehuda) - @z4ziggy


Made with ❤ using Claude Code

About

A full-featured command-line controller for the Unitree G1/Go2 robots, using WebRTC.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages