Ayush Agarwal*, Ansh Gandhi*, Jeremy A. Collins, Omar Rayyan, Aryan Sarswat, Ranjani Koushik, Masoud Moghani, Ajay Mandlekar, Animesh Garg
This repo contains the official implementation for COBALT: Crowdsourcing Robot Learning via Cloud-Based Teleoperation with Smartphones. COBALT is a platform for collecting robot demonstrations through smartphone-based teleoperation. It enables crowdsourced data collection for robot learning by allowing users to control robots remotely using their mobile devices. It is easily deployable to the cloud.
- Docker Engine
- Google Chrome
COBALT consists of separate backend and frontend services that need to be configured independently.
git submodule update --init --recursiveDefault (no GPU, Robosuite):
cd backend
./setup.sh
python setup_backend.pyOptional IsaacLab setup (GPU required):
cd backend
./setup.sh --with-isaaclab
python setup_backend.pycd ../frontend
python setup_frontend.pyNote: Setup scripts automatically detect your public IP address for nginx configuration. To use a custom domain, pass it as an argument:
python setup_backend.py --domain your-domain.comorpython setup_frontend.py --domain your-domain.com
COBALT uses nginx as a reverse proxy to route requests to different services. Configure your firewall based on your deployment scenario:
# Allow traffic to frontend (optional if using localhost)
sudo ufw allow 80
# Allow traffic to backend
sudo ufw allow 8080
# Allow traffic to be forwarded from nginx to media-server
sudo ufw allow from 172.18.0.0/16 to any port 5001 proto tcp
# Allow UDP connections on these ports for WebRTC communication
sudo ufw allow 49152:65535/udpPort Customization: External ports can be modified in
backend/nginx/backend.conf.templateandfrontend/nginx/frontend.conf. Internal service ports are configured inbackend/docker.envandfrontend/docker.env.
Start both services in separate terminal windows:
Backend Service:
cd backend
sudo TASK=lift SIMULATOR=robosuite docker compose --env-file docker.env upBackend Service (IsaacLab / GPU):
cd backend
sudo TASK=lift SIMULATOR=isaaclab docker compose --env-file docker.env upFrontend Service:
cd frontend
sudo docker compose up- Simulators:
robosuite,isaaclab - Task Lists: See
isaaclab_tasks.jsonandrobosuite_tasks.jsonfor available tasks. For bimanual tasks, you will need two devices to connect to the same session before starting teleoperation. - Upgrade Path: You can start with the default Robosuite setup and run
./setup.sh --with-isaaclablater to add IsaacLab support.
- Download Mobile App
- iOS: Apple Test Flight
- Android: Android APK
- Configure Mobile App:
- Open app settings (gear icon on top-right)
- Set Server IP Address to your host machine's IP
- Set Server Port to
8080 - Select any task (host machine determines actual task)
- Connect Mobile Device:
- Return to main screen
- Tap "Connect"
- Start Video Stream:
- Navigate to
http://localhost:3000in your browser - Enter your host machine's IP address
- Enter the Session ID displayed on your mobile app
- Click "Start Stream"
- Navigate to
To teleoperate with a keyboard, first start the backend service as described above. Then run:
python backend/teleop-server/RobotTeleop/clients/client.pyNotes:
- Keyboard teleop client depends on
pynputandwebsockets(included inbackend/teleop-server/requirements-core.txt). RobotTeleop/clients/keyboard.pyrequires running the keyboard client as root. If needed, usesudo.- Useful client flags:
--host(default:localhost)--port(default:8080)--task(default:test; should match your backend task route)--session_id(attach to an existing session)--sim-type(default:bimanual)
Example (local machine):
python backend/teleop-server/RobotTeleop/clients/client.py --host localhost --port 8080 --task liftCOBALT also supports mixing devices (for example, smartphone + keyboard in bimanual sessions).
To add support for a new robot or simulator, update the extension points below.
- Add a robot implementation under
backend/teleop-server/RobotTeleop/robots/(typically inheriting Teleop/IK/OSC robot interfaces). - Import it in
backend/teleop-server/RobotTeleop/robots/__init__.pyso it registers via the robot metaclass/registry inrobots/interfaces/teleop_robot.py. - Reference the robot class name in the appropriate server config (for example in
base_config_robosuite.py,base_config_isaac.py, or a new config file).
- Implement a simulator under
backend/teleop-server/RobotTeleop/simulators/by inheritingBaseSimulator(simulators/base_simulator.py). - Register it in
simulators/simulator_factory.pyviaSimulatorFactory.register_simulator("<name>", YourSimulatorClass). - Make sure
config.simulator.namematches the registered name.
- Add task definitions in
backend/teleop-server/RobotTeleop/configs/tasks/(JSON). - Update or add a server config in
backend/teleop-server/RobotTeleop/configs/to map:- simulator name
- robot type(s)
- task metadata (
task,num_device, timeout)
- Set environment variables at startup, for example:
SIMULATOR=robosuiteorSIMULATOR=isaaclabTASK=<task_name>
To add new tasks, you will need to add new environments to the underlying packages (e.g. src/robosuite, src/isaaclab, etc.). After doing this, ensure to add the new task to the appropriate tasks JSON file (e.g. backend/teleop-server/RobotTeleop/configs/tasks/robosuite_tasks.json, backend/teleop-server/RobotTeleop/configs/tasks/isaaclab_tasks.json) so that COBALT recognizes the new task.
Merge multiple demonstration files:
cd backend/teleop-server/RobotTeleop/scripts
python post_process_data.py --input-folder <INPUT_FOLDER> --output-file <OUTPUT_FILE>Generate demonstration metrics:
cd backend/teleop-server/RobotTeleop/scripts
python demo_metrics.py --input-file <INPUT_FILE> --output-file <OUTPUT_FILE>For better connectivity across NAT/firewall boundaries, you can set up a TURN server:
cd backend
python coturn/setup_coturn.py
sudo docker run -d --network=host -v $(pwd)/coturn/custom.conf:/etc/coturn/turnserver.conf coturn/coturnCreate frontend/.env:
REACT_APP_TURN_URL=<TURN_URL>
REACT_APP_TURN_USERNAME=<USERNAME>
REACT_APP_TURN_PASSWORD=<PASSWORD>Note: Also add these credentials to the
iceServersconfiguration inVideoChat.tsx
Create backend/media-server/.env:
TURN_SERVER_1_URL=<TURN_URL>
TURN_SERVER_1_USERNAME=<USERNAME>
TURN_SERVER_1_PASSWORD=<PASSWORD>Connection Problems:
- Cause: Blocked ports on host machine
- Solution: Ensure firewall ports are open (see Firewall Configuration)
- Note: Docker does NOT automatically open ports - manual firewall configuration is required
Mobile App Won't Connect:
- Verify host machine IP address is correct
- Check that backend service is running on port 8080 and is accessible from another device
Video Stream Not Loading:
- Confirm frontend service is running
- Check Session ID matches between mobile app and web interface
- Verify media server is accessible (check Docker logs)
Docker Issues:
NVIDIA GPU Driver Error:
Error response from daemon: could not select device driver "nvidia" with capabilities: [[gpu]]
- Cause: NVIDIA Container Toolkit is not installed
- When it appears: IsaacLab mode (
--profile isaaclab) - Solution: Install and configure the toolkit:
# Install the toolkit
sudo apt-get update
sudo apt-get install -y nvidia-container-toolkit
# Configure Docker to use it
sudo nvidia-ctk runtime configure --runtime=docker
sudo systemctl restart dockerLast Updated: May 15, 2026