A fork of sunnypilot / openpilot that turns a comma 3X into a connected node of the ORBIT platform: live telemetry out, remote commands in, QR pairing to your account — with driving always behind openpilot's own safety gates.
Researcher profile · Research group — SICUEM · Backend + app (ORBIT-IoV) ↗
A full dark "ground-station" redesign of the driver UI — same sunnypilot functionality, ORBIT identity.
| 📡 Telemetry publisher | car state, GPS, radar, model, alerts, camera frames → MQTT, with a 3 s heartbeat |
| 🎮 Remote commands | lane change, speed nudges, steering pulses, emergency brake — bridged via openpilot Params |
| 🔔 On-road command overlay | the driver always sees when the app sends a command; remote braking gets a full red banner |
| 🔗 QR enrollment | scan from the app to claim the device; owner shown in-UI; unlink from app or device |
| 🧠 Jetson edge link | ZeroMQ frames + AI steer-torque, live status panel, selectable torque modes |
| 🚗 Sim + mod menu | MetaDrive bridge with hotkey mod-menu: swap maps, spawn traffic/obstacles — test before the real car |
flowchart LR
subgraph CAR["🚗 comma 3X · this firmware"]
CAN["CAN bus"] --> OP["openpilot / sunnypilot<br/>safety-critical control loop"]
OP --> ORB["orbit/<br/>MQTT telemetry + commands"]
end
subgraph EDGE["🧠 Edge · optional"]
J["NVIDIA Jetson"]
end
subgraph CLOUD["☁️ ORBIT infra · repo ORBIT-IoV"]
BR["Mosquitto<br/>MQTT broker"]
BE["Flask backend<br/>REST + SQLite"]
end
APP["📱 Flutter app"]
ORB -- "telemetry_mqtt/<dongle>/*" --> BR
BR -- "telemetry_config/<dongle>/* (commands)" --> ORB
ORB -- "ZeroMQ (frames / torque)" --> J
BR <--> BE
BR <--> APP
APP -- "REST" --> BE
Backend, app, database and broker live in ORBIT-IoV. The safety-critical loop never leaves the car: remote commands only act through openpilot's actuation and safety gates.
sequenceDiagram
participant D as 🚗 Device
participant BE as ☁️ Backend
participant U as 📱 App
D->>BE: enroll { pairing_code, ttl 600 s } + QR on screen
U->>BE: scan QR → POST /api/devices/claim
BE->>D: enroll_ack { claimed, user_name }
D->>D: ✓ "Vinculado" — owner shown on Home
U-->>BE: unlink (app) → enroll_ack { claimed: false } → QR is back
Lost acks self-heal, codes can be regenerated from the dialog, and unlinking from the app re-opens enrollment on the device automatically.
- Install like any sunnypilot build (getting started).
- Point the device at your ORBIT broker: Settings → ORBIT → Servidor ORBIT → EDITAR. The value is persisted in
/data/orbit_config_mqtt.json(outside the git tree, so it survives OTA updates);orbit/config_mqtt.jsonis only the factory template (broker,broker_port,backend_port). - Pair: Settings → Device → Vincular con ORBIT → scan with the app. Done — telemetry and remote control flow once claimed.
./tools/sim/launch_openpilot.sh # openpilot side
./tools/sim/run_bridge.py --render # MetaDrive side, with on-screen HUDHotkeys in the bridge terminal: m cycle map (loop / roundabout / intersections / highway / ramps) · t toggle traffic · l/k spawn lead / cut-in car · o/p obstacles · c clear. ./tools/sim/preview_map.py --map roundabout previews geometry without openpilot.
📶 MQTT contract — topics & payloads
Telemetry — device → cloud (telemetry_mqtt/<dongle>/<type>)
| Type | Notes |
|---|---|
carState |
speed, cruise, blinkers, blind-spot; also the 3 s presence heartbeat |
carControl · controlsState |
actuators / hud, alerts |
radarState · drivingModelData |
lead(s), lane-line metadata |
liveCalibration · gpsLocationExternal · gpsLocation |
calibration, position |
event · logs · camera/{road,driver,wide} |
alerts, device logs, camera frames |
enroll |
pairing announce while unclaimed |
sicuem_torque |
Jetson AI steer-torque (when a Jetson mode is active) |
Commands — cloud → device (telemetry_config/<dongle>/<cmd>)
| Command | Effect (through openpilot gates) |
|---|---|
left · right |
forced lane change |
control |
forward / break (speed nudge) · tright / tleft (steering pulse) |
speed_up · speed_down · speed_increment |
cruise-speed control |
overtake |
one commanded left lane change (closed-course validation required) |
brutebreak |
emergency brake (bounded intensity) |
intervalos |
periodic longitudinal cut demo |
camera_config · jetson_config · steer_torque_mode |
device configuration |
enroll_ack |
claim / unclaim confirmation ({claimed, user_name, user_email, ts}) |
Every remote command is mirrored to the driver by the on-road ORBIT overlay.
📁 Where the ORBIT code lives
ORBITPILOT/
├── orbit/ # the ORBIT device integration
│ ├── mqtt_envio_general.py # telemetry publisher + heartbeat + QR enroll + connection state
│ ├── mqtt_comandos.py # remote-command subscriber/router + enroll_ack (claim/unclaim)
│ ├── camera_sender.py # camera frame sender (MQTT)
│ ├── zmq_client.py # Jetson ZeroMQ link
│ ├── canales.json # telemetry channel → topic map
│ ├── config_broker.py # broker config: template + /data/orbit_config_mqtt.json (survives OTA)
│ └── config_mqtt.json # factory template: broker host/port + backend port
├── selfdrive/ui/
│ ├── layouts/home.py # ORBIT home (status cards, telemetry pulse, account pill)
│ ├── widgets/orbit_enroll_dialog.py# QR pairing dialog (countdown, regenerate, success state)
│ ├── widgets/orbit_server.py # broker + backend health monitor
│ └── sunnypilot/onroad/orbit_command_overlay.py # on-road remote-command indicator
├── tools/sim/ # MetaDrive bridge + mod menu (maps, traffic, spawns)
├── common/params_keys.h # Orbit*/orbit_* param registrations
└── docs/superpowers/specs/ # design docs (enrollment, migration, jetson mode)
Everything else is upstream openpilot / sunnypilot.
🛠️ Development notes (this fork)
- Working branch:
orbit-master. - Pushing:
originis SSH; always push withgit push --no-verify. The tracked.lfsconfigpoints Git LFS at sunnypilot's upstream GitLab (read-only), so the LFS pre-push hook must be skipped. ORBIT images are plain git blobs via.gitattributes. - Design docs:
docs/superpowers/specs/(QR enrollment, sicuem→orbit migration, comma↔Jetson mode).
📚 Citation
@article{orbit2026,
title = {ORBIT: A Scalable IoV Architecture for Remote Telemetry and Control in Open Autonomous Driving Systems},
author = {Ca{\~n}adas Gallardo, Adri{\'a}n and Bemposta Rosende, Sergio and Garc{\'i}a-Fern{\'a}ndez, Manuel and Aliane, Nourdine and Fern{\'a}ndez-Andr{\'e}s, Javier},
journal = {TBD},
year = {2026},
note = {Universidad Europea de Madrid}
}Alpha-quality research software — not a product. Remote maneuvers run through openpilot's actuation and safety gates and are always announced to the driver on screen, but this firmware has not passed comma's safety validation. Validate every remote-control feature on a closed course first and comply with local laws.
Developed within the SICUEM research group at Universidad Europea de Madrid, on top of openpilot and sunnypilot. Released under the MIT License; the original openpilot notice is reproduced below as required:
openpilot is released under the MIT license. Some parts of the software are released under other licenses as specified.
Any user of this software shall indemnify and hold harmless Comma.ai, Inc. and its directors, officers, employees, agents, stockholders, affiliates, subcontractors and customers from and against all allegations, claims, actions, suits, demands, damages, liabilities, obligations, losses, settlements, judgments, costs and expenses (including without limitation attorneys' fees and costs) which arise out of, relate to or result from any use of this software by user.
THIS IS ALPHA QUALITY SOFTWARE FOR RESEARCH PURPOSES ONLY. THIS IS NOT A PRODUCT. YOU ARE RESPONSIBLE FOR COMPLYING WITH LOCAL LAWS AND REGULATIONS. NO WARRANTY EXPRESSED OR IMPLIED.
For full license terms, see the LICENSE file.







