-
Notifications
You must be signed in to change notification settings - Fork 2k
Remote Teleoperation over WebRTC #1385
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
for more information, see https://pre-commit.ci
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR adds support for remote teleoperation over WebRTC via a LiveKit server, enabling leader and follower roles to run in separate locations.
- Introduces
LiveKitService
to manage WebRTC connections and data/video channels. - Implements
RemoteRobot
andRemoteTeleoperator
classes for sending actions and publishing observations remotely. - Updates the main teleoperation loop to send observations back to remote teleoperators when applicable.
Reviewed Changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated 2 comments.
Show a summary per file
File | Description |
---|---|
lerobot/teleoperate.py | Hook into RemoteTeleoperator to publish observations |
lerobot/common/transport/livekit_service.py | Added LiveKitService for WebRTC connection management |
lerobot/common/teleoperators/utils.py | Registered so100_remote_leader in factory |
lerobot/common/teleoperators/so100_leader/so100_remote_leader.py | New remote leader subclass |
lerobot/common/teleoperators/so100_leader/config_so100_leader.py | Config subclass for remote leader |
lerobot/common/teleoperators/so100_leader/init.py | Exposed SO100RemoteLeader in package |
lerobot/common/teleoperators/remote_teleoperator.py | Core RemoteTeleoperator implementation |
lerobot/common/teleoperators/config.py | Added RemoteTeleoperatorConfig |
lerobot/common/robots/utils.py | Registered so100_remote_follower in factory |
lerobot/common/robots/so100_follower/so100_remote_follower.py | New remote follower subclass |
lerobot/common/robots/so100_follower/config_so100_follower.py | Config subclass for remote follower |
lerobot/common/robots/so100_follower/init.py | Exposed SO100RemoteFollower in package |
lerobot/common/robots/remote_robot.py | Core RemoteRobot implementation |
lerobot/common/robots/config.py | Added RemoteRobotConfig |
Comments suppressed due to low confidence (1)
lerobot/common/teleoperators/remote_teleoperator.py:200
- The new
publish_observation
method introduces complex JSON and video-publishing logic without accompanying unit or integration tests; consider adding tests to cover serialization, topic dispatching, and video-track handling.
def publish_observation(self, observation: dict[str, Any]) -> None:
def __init__(self, config: SO100RemoteFollowerConfig): | ||
super().__init__(config) | ||
self.config = config | ||
self.cameras = {} #make_cameras_from_configs(config.cameras) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Commented-out camera initialization suggests incomplete implementation; either integrate make_cameras_from_configs(config.cameras)
or remove the dead code to clarify intent and avoid confusion.
self.cameras = {} #make_cameras_from_configs(config.cameras) | |
self.cameras = make_cameras_from_configs(config.cameras) |
Copilot uses AI. Check for mistakes.
# if teleop is a RemoteTeleoperator, send the observations to the remote teleoperator | ||
if isinstance(teleop, RemoteTeleoperator): | ||
observation = robot.get_observation() | ||
teleop.publish_observation(observation) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Calling publish_observation
(which uses blocking sync methods) inside the main loop can introduce latency and drop below target FPS; consider offloading observation publishing to a separate thread or using an asynchronous approach.
teleop.publish_observation(observation) | |
observation_queue.put(observation) |
Copilot uses AI. Check for mistakes.
Remote Teleoperation Over WebRTC
This PR adds the capability for the leader & follower to be in different locations, streaming data between using LiveKit WebRTC server. All actions/observations/videos are streamed over a single connection, enabling easy remote teleoperation from anywhere.
RemoteRobot
andRemoteTeleoperator
classesSO100RemoteLeader
andSO100RemoteTeleoperator
RemoteRobot - an instance of a robot that's not physically connected to computer. The send_action() method will send the desired action over LiveKit as a data message.
RemoteTeleoperator - an instance of a teleoperator that's not physically connected to computer. It will subscribe to action data topic and return the received action command in the get_action() method. It also has a new method
publish_observation
which will publish both the robot state & video to LiveKit.When running the local leader with
display_data=true
the received video streams and observations will be rendered in Rerun.To test, you can use either the OSS LiveKit server or use a free account on LiveKit cloud:
Run local leader with RemoteRobot:
Run local follower with RemoteTeleoperator: