Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
96 commits
Select commit Hold shift + click to select a range
63adbdd
feat: forward joystick mode sdp offer through athena
stefpi Mar 11, 2026
16a2fbf
feat: add getNotCar dispatcher
stefpi Mar 11, 2026
b346efb
fix: context manager with statement
stefpi Mar 11, 2026
8cb630a
track fix/datachannel-double-counting
stefpi Mar 12, 2026
d7883cd
feat: (v1) bring back comma body face
stefpi Mar 13, 2026
5299b70
feat: raylib face instead of gif, animation harness and barebones pai…
stefpi Mar 13, 2026
b591fb6
feat: 10mbps bitrate for connect webrtc livestream
stefpi Mar 13, 2026
b83e436
feat: FaceAnimations, new faces and reactivity, battery indicator
stefpi Mar 13, 2026
6bb0a22
fix: asleep animation, body_sidebar
stefpi Mar 13, 2026
f3c0b98
fix: home click and release, battery status
stefpi Mar 13, 2026
d2ed390
fix: cleaner transition into driving mode
stefpi Mar 13, 2026
a7e54c1
fix: add CORS headers to webrtcd
stefpi Mar 13, 2026
d0db6a1
fix: simple CORS header for local direct connection, logging in get_s…
stefpi Mar 13, 2026
e2df6b4
fix: add back CORS middleware block
stefpi Mar 13, 2026
e6bb701
fix: inquisitive and responsive turning faces
stefpi Mar 13, 2026
2e41637
fix: swap right and left move animations
stefpi Mar 13, 2026
0694182
feat: add support for all 3 cameras
stefpi Mar 13, 2026
8e15567
feat: optional wait for joystick bodyview, wink animation, status in …
stefpi Mar 14, 2026
f65e11d
clean: remove old bodyteleop
stefpi Mar 14, 2026
6e589eb
fix: change notCar dispatcher to use persistent car params
stefpi Mar 14, 2026
29eba8b
fix: proper exceptions when webrtcd is not running
stefpi Mar 14, 2026
93de8e1
fix: check resp.ok from webrtcd
stefpi Mar 14, 2026
dd13a9b
fix: remove wink all the time
stefpi Mar 16, 2026
02cc1c9
fix: remove redudant and breaking body active check
stefpi Mar 16, 2026
4f44844
fix: remove sdp codec overwite and only accept H264 requests
stefpi Mar 17, 2026
19e459c
feat: body layout refactoring and adding mici layout
stefpi Mar 17, 2026
8a5df0a
fix: body face change on ignition
stefpi Mar 17, 2026
819da5a
fix: make pairing button on MICI bigger
stefpi Mar 17, 2026
ebb6ea0
feat: ignore unnecessary processe in body so that they don't complain…
stefpi Mar 18, 2026
0ea0244
fix: reverse direction of input on body injection test
stefpi Mar 18, 2026
63e743d
faster tuning branch on opendbc
stefpi Mar 18, 2026
7ba69d0
fix: better pairing screens and pairing info
stefpi Mar 18, 2026
580231a
feat: allow multiple webrtc connections
stefpi Mar 18, 2026
9193437
fix: reduce cpu load on body by not running unnecessary processes for…
stefpi Mar 18, 2026
0fd56b4
reduce removed processes on body to just driver monitoring model
stefpi Mar 18, 2026
cd0f864
turn ir lights off on comma body
stefpi Mar 18, 2026
f4b74b5
remove purple IR tint on driver camera
stefpi Mar 18, 2026
66e7041
remove IR defiltering attempt, but keep IR lights off on body
stefpi Mar 18, 2026
bd00bca
add back 1 webrtc connection at a time
stefpi Mar 18, 2026
f13156a
reduce comma body init time to 2 seconds
stefpi Mar 18, 2026
2ef2046
clean: remove zmq whitelist util
stefpi Mar 18, 2026
15354e3
joystickdebug set to false on webrtc disconnection and return to home…
stefpi Mar 18, 2026
bb59973
disconnect transition to home screen functionality moved to mici
stefpi Mar 18, 2026
059f3a4
move joystickdebug set true to webrtcd
stefpi Mar 18, 2026
3bf7b1d
submodule: add teleortpc_repo fix/data-channel-doublecounting branch …
stefpi Mar 18, 2026
ff0514d
pair button bigger and starting animation on sleepy
stefpi Mar 18, 2026
151488a
remove branch name if notCar
stefpi Mar 18, 2026
ef8341d
stay on home page if offroad
stefpi Mar 18, 2026
cee8c5e
change body pair button to connect and clean up body pairing
stefpi Mar 18, 2026
4dd127c
better connect screen for mici
stefpi Mar 18, 2026
30cac11
add ENV support for different connect URLS (PROD, DEV, PREVIEW)
stefpi Mar 19, 2026
2d3dff5
bypass private network restrictions on chrome
stefpi Mar 19, 2026
8750fa2
self signed ssl for webrtc from https deployments
stefpi Mar 19, 2026
14a56cb
auto close ssl cert trust page
stefpi Mar 19, 2026
a035b7f
http+https webrtc, remove PORT from pairing QR
stefpi Mar 19, 2026
2407fe4
lower GOP size on streamencoder
stefpi Mar 20, 2026
a0bfdae
feat: 2-way audio and sound effects routed through soundd + better la…
stefpi Mar 20, 2026
6bc0534
messaging subsocket for webrtc microphone on soundd
stefpi Mar 20, 2026
9b28efe
Merge branch 'master' into good-remote-body
stefpi Mar 23, 2026
24e0807
distinguish between v1 and v2
stefpi Mar 24, 2026
6ee901b
convert 3 livestream to 1 encoder with on the fly switching
stefpi Mar 24, 2026
94ec2bb
fix params, send selected camera on /stream response
stefpi Mar 24, 2026
c50ada6
decode bug on Params
stefpi Mar 24, 2026
001ecfd
fix stationary face animation
stefpi Mar 25, 2026
adb5c1a
stats: add frame timing data to metadata when stats are enabled on da…
stefpi Mar 25, 2026
173c277
bump opendbc
stefpi Mar 25, 2026
76cddb0
bump opendbc and panda to correct commits
stefpi Mar 25, 2026
002961c
refactor body UI code
stefpi Mar 25, 2026
aacc243
better customization for bodyview debug script
stefpi Mar 25, 2026
ef109f7
bump panda commit
stefpi Mar 25, 2026
73b20b2
Merge branch 'master' into good-remote-body
stefpi Mar 25, 2026
f30b91e
update commit on teleoprtc_repo
stefpi Mar 25, 2026
1525369
only ignore driverMonitoringState on notCar
stefpi Mar 25, 2026
9227eae
remove old data channel sound bite request
stefpi Mar 25, 2026
a10504e
fix linting errors
stefpi Mar 25, 2026
12d5a46
fix unsupported operand type error
stefpi Mar 25, 2026
2ef6ab2
bump teleoprtc commit
stefpi Mar 25, 2026
bb998d7
bump teleoprtc commit
stefpi Mar 25, 2026
f3396e5
update git modules
stefpi Mar 25, 2026
51715da
fix ci CP is none error
stefpi Mar 26, 2026
4febc0d
cleanup
stefpi Mar 26, 2026
4413ae6
cleanups and small refactors
stefpi Mar 26, 2026
fc9ec7e
fix is_body call
stefpi Mar 26, 2026
6baf5bd
bump commit opendbc_repo
stefpi Mar 26, 2026
3eb44a4
implement shane's comments
stefpi Mar 26, 2026
23e38f7
fix button touch valid
sshane Mar 26, 2026
3bab051
replace IP with env variable for https URL
stefpi Mar 27, 2026
8eb532d
connect qr points to body url
stefpi Mar 27, 2026
42c2855
fix bug and remove unused code body_pairing
stefpi Mar 27, 2026
af4936c
show connect host name properly for hacakthon
stefpi Mar 27, 2026
a234f75
fix connect button on tici visibility
stefpi Mar 27, 2026
95f9c60
hide tici pairing screen on connection
stefpi Mar 27, 2026
625dd5b
tici move connect/disconnect event reaction
stefpi Mar 27, 2026
4271e90
fix pairing button on tici
stefpi Mar 27, 2026
58ae7db
Merge branch 'master' into good-remote-body
stefpi Apr 3, 2026
7a3f526
bump commits
stefpi Apr 3, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
[submodule "panda"]
path = panda
url = ../../commaai/panda.git
branch = body-hoverboard
[submodule "opendbc"]
path = opendbc_repo
url = ../../commaai/opendbc.git
branch = body
[submodule "msgq"]
path = msgq_repo
url = ../../commaai/msgq.git
Expand All @@ -13,6 +15,7 @@
[submodule "teleoprtc_repo"]
path = teleoprtc_repo
url = ../../commaai/teleoprtc
branch = fix/datachannel-double-counting
[submodule "tinygrad"]
path = tinygrad_repo
url = https://github.com/tinygrad/tinygrad.git
6 changes: 6 additions & 0 deletions cereal/log.capnp
Original file line number Diff line number Diff line change
Expand Up @@ -2515,6 +2515,10 @@ struct AudioFeedback {
blockNum @1 :UInt16;
}

struct SoundRequest {
sound @0 :Car.CarControl.HUDControl.AudibleAlert;
}

struct Touch {
sec @0 :Int64;
usec @1 :Int64;
Expand Down Expand Up @@ -2618,6 +2622,8 @@ struct Event {
userBookmark @93 :UserBookmark;
bookmarkButton @148 :UserBookmark;
audioFeedback @149 :AudioFeedback;
soundRequest @150 :SoundRequest;
webrtcAudioData @151 :AudioData;

lateralManeuverPlan @150 :LateralManeuverPlan;

Expand Down
2 changes: 2 additions & 0 deletions cereal/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ def __init__(self, should_log: bool, frequency: float, decimation: Optional[int]
"rawAudioData": (False, 20.),
"bookmarkButton": (True, 0., 1),
"audioFeedback": (True, 0., 1),
"soundRequest": (False, 0.),
"webrtcAudioData": (False, 0.),
"roadEncodeData": (False, 20., None, QueueSize.BIG),
"driverEncodeData": (False, 20., None, QueueSize.BIG),
"wideRoadEncodeData": (False, 20., None, QueueSize.BIG),
Expand Down
4 changes: 4 additions & 0 deletions common/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@

API_HOST = os.getenv('API_HOST', 'https://api.commadotai.com')

CONNECT_HOST = os.getenv('CONNECT_HOST', 'https://connect.comma.ai')
CONNECT_HOST_DISPLAY = CONNECT_HOST.removeprefix("https://").removeprefix("http://")
CONNECT_CLIENT = os.getenv('CONNECT_CLIENT', 'no domain name set')

# name: jwt signature algorithm
KEYS = {"id_rsa": "RS256",
"id_ecdsa": "ES256"}
Expand Down
1 change: 1 addition & 0 deletions common/params_keys.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
{"LastUpdateTime", {PERSISTENT, TIME}},
{"LastUpdateUptimeOnroad", {PERSISTENT, FLOAT, "0.0"}},
{"LiveDelay", {PERSISTENT, BYTES}},
{"LivestreamCamera", {CLEAR_ON_MANAGER_START, STRING, "driver"}},
{"LiveParameters", {PERSISTENT, JSON}},
{"LiveParametersV2", {PERSISTENT, BYTES}},
{"LiveTorqueParameters", {PERSISTENT | DONT_LOG, BYTES}},
Expand Down
2 changes: 1 addition & 1 deletion msgq_repo
Submodule msgq_repo updated 3 files
+2 −0 SConscript
+6 −0 SConstruct
+8 −0 codecov.yml
2 changes: 1 addition & 1 deletion rednose_repo
93 changes: 93 additions & 0 deletions selfdrive/debug/bodyview.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
#!/usr/bin/env python3
"""Launch the comma UI, but simulating a comma body."""
import argparse
import os
import time
import threading


import pyray as rl
from cereal import car, log, messaging
from openpilot.common.params import Params


def send_messages():
pm = messaging.PubMaster(['deviceState', 'pandaStates', 'carParams', 'carState', 'selfdriveState'])

car_params_msg = messaging.new_message('carParams')
car_params_msg.carParams.brand = "body"
car_params_msg.carParams.notCar = True

device_state_msg = messaging.new_message('deviceState')
device_state_msg.deviceState.started = False

panda_msg = messaging.new_message('pandaStates', 1)
panda_msg.pandaStates[0].ignitionLine = True
panda_msg.pandaStates[0].pandaType = log.PandaState.PandaType.uno

car_state_msg = messaging.new_message('carState')
car_state_msg.carState.charging = True
car_state_msg.carState.fuelGauge = 0.80

selfdrive_state_msg = messaging.new_message('selfdriveState')
selfdrive_state_msg.selfdriveState.enabled = True

while True:
pm.send('carParams', car_params_msg)
pm.send('deviceState', device_state_msg)
pm.send('pandaStates', panda_msg)
pm.send('carState', car_state_msg)
pm.send('selfdriveState', selfdrive_state_msg)
time.sleep(0.01)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can use Ratekeeper if this needs to strictly be 100hz



def main():
parser = argparse.ArgumentParser(description="Launch body view UI")
parser.add_argument("--big", action="store_true", help="Launch in big UI mode (comma 3X)")
parser.add_argument("--joystick", action="store_true", help="Wait for joystick_control before going onroad")
parser.add_argument("--monitor", type=int, default=None, help="Pin window to specified monitor index (e.g. 0, 1)")
args = parser.parse_args()

if args.big:
os.environ["BIG"] = "1"
from openpilot.system.ui.lib.application import gui_app

if args.monitor is not None:
# Pin window to specified monitor after init
monitor_index = args.monitor
_orig_init_window = gui_app.init_window
def _init_window_on_monitor(*a, **kw):
_orig_init_window(*a, **kw)
pos = rl.get_monitor_position(monitor_index)
rl.set_window_position(int(pos.x), int(pos.y))
gui_app.init_window = _init_window_on_monitor

# Set CarParamsPersistent so ui_state.CP.notCar is True on startup
params = Params()
CP = car.CarParams.new_message(notCar=True, brand="body", wheelbase=1, steerRatio=10)
params.put("CarParamsPersistent", CP.to_bytes())
params.put_bool("JoystickDebugMode", True)

if args.joystick:
params.put_bool("IsOffroad", True)

# Wait for joystick_control to start before going "onroad"
sm = messaging.SubMaster(['testJoystick'])
print("Waiting for joystick_control to start (run: python tools/joystick/joystick_control.py --keyboard) ...")
while sm.recv_frame['testJoystick'] == 0:
params.put_bool("IsOffroad", True)
sm.update(100)
print("Joystick connected, starting body view.")
params.remove("IsOffroad")

# Start message sender in background
t = threading.Thread(target=send_messages, daemon=True)
t.start()

# Import after env is set so BIG_UI picks it up
from openpilot.selfdrive.ui.ui import main as ui_main
ui_main()


if __name__ == "__main__":
main()
15 changes: 13 additions & 2 deletions selfdrive/pandad/pandad.cc
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,7 @@ void process_peripheral_state(Panda *panda, PubMaster *pm, bool no_fan_control)

{
sm.update(0);

if (sm.updated("deviceState") && !no_fan_control) {
// Fan speed
uint16_t fan_speed = sm["deviceState"].getDeviceState().getFanSpeedPercentDesired();
Expand Down Expand Up @@ -341,9 +342,19 @@ void process_peripheral_state(Panda *panda, PubMaster *pm, bool no_fan_control)
}

if (ir_pwr != prev_ir_pwr || sm.frame % 100 == 0) {
int16_t ir_panda = util::map_val(ir_pwr, 0, 100, 0, MAX_IR_PANDA_VAL);
std::string cp_bytes = params.get("CarParams");
if (cp_bytes.size() > 0) {
AlignedBuffer aligned_buf;
capnp::FlatArrayMessageReader cmsg(aligned_buf.align(cp_bytes.data(), cp_bytes.size()));
cereal::CarParams::Reader CP = cmsg.getRoot<cereal::CarParams>();
if (CP.getNotCar()) {
ir_pwr = 0;
}
}

int16_t ir_panda = util::map_val(ir_pwr, 0, 100, 0, MAX_IR_PANDA_VAL);
panda->set_ir_pwr(ir_panda);
Hardware::set_ir_power(ir_pwr);
Hardware::set_ir_power(ir_pwr);
prev_ir_pwr = ir_pwr;
}
}
Expand Down
4 changes: 3 additions & 1 deletion selfdrive/selfdrived/selfdrived.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ def __init__(self, CP=None):
self.car_state_sock = messaging.sub_sock('carState', timeout=20)

ignore = self.sensor_packets + self.gps_packets + ['alertDebug', 'lateralManeuverPlan']
if self.CP.notCar:
ignore += ['driverMonitoringState']
if SIMULATION:
ignore += ['driverCameraState', 'managerState']
if REPLAY:
Expand Down Expand Up @@ -192,7 +194,7 @@ def update_events(self, CS):

if self.CP.notCar:
# wait for everything to init first
if self.sm.frame > int(5. / DT_CTRL) and self.initialized:
if self.sm.frame > int(2. / DT_CTRL) and self.initialized:
# body always wants to enable
self.events.add(EventName.pcmEnable)

Expand Down
Empty file added selfdrive/ui/body/__init__.py
Empty file.
Loading
Loading