This page documents the WebRTC infrastructure in openpilot, specifically the webrtcd daemon and its integration with the "comma body" robot for teleoperation. The system enables low-latency, bidirectional streaming of video, audio, and cereal messages between an openpilot device and a web browser.
webrtcd is an asyncio-based daemon that serves as a WebRTC gateway. It bridges openpilot's internal msgq messaging system (cereal) and hardware video encoders to a standard WebRTC PeerConnection.
The daemon handles:
PubMaster/SubMaster and WebRTC DataChannels system/webrtc/webrtcd.py84-154The following diagram illustrates the flow of video data from the cameras and control messages from the browser to the robot's actuators.
WebRTC Teleop Data Flow
Sources: system/webrtc/webrtcd.py84-218 system/webrtc/device/video.py11-46 tools/bodyteleop/static/js/webrtc.js111-115
To allow the browser to interact with the vehicle/robot, webrtcd provides bidirectional proxying of cereal messages.
The CerealOutgoingMessageProxy class monitors specific cereal services using a messaging.SubMaster system/webrtc/webrtcd.py84-88 When new messages arrive, it converts the Cap'n Proto structures to JSON and broadcasts them over the WebRTC RTCDataChannel system/webrtc/webrtcd.py110-121
to_json() recursively converts capnp._DynamicStructReader and bytes into JSON-serializable formats system/webrtc/webrtcd.py98-108AsyncTaskRunner, running an async loop calling update() every 10ms system/webrtc/webrtcd.py123-138The CerealIncomingMessageProxy receives JSON strings from the browser, parses them, and publishes them to the local msgq bus using a messaging.PubMaster system/webrtc/webrtcd.py140-154
DynamicPubMaster to lazily create publisher sockets for services requested by the client session system/webrtc/webrtcd.py156-166Sources: system/webrtc/webrtcd.py84-166
Video tracks are implemented in LiveStreamVideoStreamTrack, which inherits from teleoprtc.tracks.TiciVideoStreamTrack system/webrtc/device/video.py11 It maps camera types (driver, wideRoad, road) to corresponding "livestream" cereal sockets system/webrtc/device/video.py12-16 The recv() method extracts the header and data from the cereal message to create an av.Packet system/webrtc/device/video.py35-42
The LivestreamBitrateController monitors network conditions via peer_connection.getStats() system/webrtc/webrtcd.py220 It implements a three-tier bitrate system (Low: 500kbps, Med: 1.5Mbps, High: 5Mbps) system/webrtc/webrtcd.py169-170
loss_rate exceeds high_level (0.1) or stays above med_level (0.05) for 1 second, it drops the bitrate tier and doubles the recovery time (exponential backoff) system/webrtc/webrtcd.py205-211loss_rate is 0 for a sufficient interval, it increases the bitrate tier system/webrtc/webrtcd.py212-217LivestreamEncoderBitrate param system/webrtc/webrtcd.py176Sources: system/webrtc/webrtcd.py168-243 system/webrtc/device/video.py11-46
The bodyteleop tool provides a web interface for remote control of a comma body robot.
The backend uses aiohttp to serve the static UI and act as a signaling proxy for webrtcd tools/bodyteleop/web.py8-12
webrtcd with requested services: driver camera, testJoystick (incoming), and carState (outgoing) tools/bodyteleop/web.py57-67openssl command, as WebRTC requires HTTPS in browsers tools/bodyteleop/web.py23-44RTCPeerConnection to create an offer, sends it to the /offer endpoint, and sets the remote description from the returned answer tools/bodyteleop/static/js/webrtc.js42-71controls.js tools/bodyteleop/static/js/controls.js1-20 and sends them as testJoystick messages over the RTCDataChannel every 50ms tools/bodyteleop/static/js/webrtc.js111-135carState messages to update battery level and ping time visualizations using Chart.js tools/bodyteleop/static/js/webrtc.js139-154Sources: tools/bodyteleop/web.py1-82 tools/bodyteleop/static/js/webrtc.js1-176 tools/bodyteleop/static/js/controls.js1-20
System Entity Mapping
Sources: system/webrtc/webrtcd.py245-285 system/webrtc/device/video.py11 tools/bodyteleop/web.py57-67 tools/bodyteleop/static/js/webrtc.js42-71
Refresh this wiki