This commit is contained in:
royjr
2026-07-25 04:37:27 -04:00
parent 2f1d422990
commit f57f1bd19d
4 changed files with 34 additions and 13 deletions
+15 -7
View File
@@ -26,7 +26,7 @@ from openpilot.common.file_chunker import open_file_chunked, get_manifest_path
from openpilot.selfdrive.modeld.constants import ModelConstants, Plan
from openpilot.selfdrive.modeld.helpers import usbgpu_present, modeld_pkl_path, get_tg_input_devices, load_oob
from openpilot.selfdrive.modeld.usbgpu_link import wait_usbgpu_link
from openpilot.tools.wgpu.zmq import ZmqPubMaster, ZmqSubMaster
from openpilot.tools.wgpu.zmq import WGPU_CAR_PARAMS, ZmqPubMaster, ZmqSubMaster, ZmqSubSocket
from openpilot.sunnypilot.livedelay.helpers import get_lat_delay
from openpilot.sunnypilot.modeld_v2.modeld_base import ModelStateBase
@@ -181,6 +181,18 @@ def main(demo=False, remote_addr: str | None = None, big_model: bool = False):
config_realtime_process(7, 54)
remote_CP = None
if remote_addr is not None:
# Do not attach to VisionIPC until all startup prerequisites are available.
# Otherwise its notification queue grows while waiting for the infrequent
# bridged carParams message and reconnect starts tens of seconds behind.
cloudlog.warning("waiting for remote carParams")
car_params_socket = ZmqSubSocket(WGPU_CAR_PARAMS, remote_addr, conflate=True)
raw_car_params = car_params_socket.receive()
assert raw_car_params is not None
remote_CP = messaging.log_from_bytes(raw_car_params, car.CarParams)
cloudlog.info("modeld got remote CarParams: %s", remote_CP.brand)
# visionipc clients
while True:
available_streams = VisionIpcClient.available_streams("camerad", block=False)
@@ -215,8 +227,6 @@ def main(demo=False, remote_addr: str | None = None, big_model: bool = False):
output_services = ["modelV2", "drivingModelData", "cameraOdometry", "modelDataV2SP"]
pm = ZmqPubMaster(output_services) if remote_addr is not None else PubMaster(output_services)
services = ["deviceState", "carState", "roadCameraState", "liveCalibration", "driverMonitoringState", "carControl", "liveDelay"]
if remote_addr is not None:
services.append("carParams")
sm = ZmqSubMaster(services, remote_addr) if remote_addr is not None else SubMaster(services)
publish_state = PublishState()
@@ -238,10 +248,8 @@ def main(demo=False, remote_addr: str | None = None, big_model: bool = False):
if demo:
CP = get_demo_car_params()
elif remote_addr is not None:
cloudlog.warning("waiting for remote carParams")
while not sm.seen["carParams"]:
sm.update(100)
CP = sm["carParams"]
assert remote_CP is not None
CP = remote_CP
else:
CP = messaging.log_from_bytes(params.get("CarParams", block=True), car.CarParams)
cloudlog.info("modeld got CarParams: %s", CP.brand)
+7 -5
View File
@@ -58,11 +58,13 @@ python3 -m openpilot.tools.wgpu.host COMMA_IP
Add `--big-model` after `COMMA_IP` to use the locally compiled big model.
The first remote `carParams` packet can take up to 50 seconds. Stop either side
with Ctrl+C. A host disconnect automatically stops remote publication and
restores local `modeld` after a one-second timeout; the device helper then stays
running and waits for the next host session. Stop the device helper itself with
Ctrl+C before changing branches or rebooting.
The device helper sends cached `carParams` over a dedicated startup channel, so
the host does not attach to the camera streams and accumulate stale frames while
waiting for the periodic state bridge. Stop either side with Ctrl+C. A host
disconnect automatically stops remote publication and restores local `modeld`
after a one-second timeout; the device helper then stays running and waits for
the next host session. Stop the device helper itself with Ctrl+C before changing
branches or rebooting.
While WGPU is active, model lag does not create an engagement-blocking alert.
The fixed-column diagnostics panel at the top-right of the mici onroad UI shows
+9 -1
View File
@@ -7,7 +7,7 @@ from pathlib import Path
import openpilot.cereal.messaging as messaging
from openpilot.common.params import Params
from openpilot.tools.wgpu.zmq import ZmqSubSocket
from openpilot.tools.wgpu.zmq import WGPU_CAR_PARAMS, ZmqPubMaster, ZmqSubSocket
MODEL_OUTPUTS = "modelV2,drivingModelData,cameraOdometry,modelDataV2SP"
@@ -77,14 +77,22 @@ def main() -> None:
try:
forward = subprocess.Popen([str(BRIDGE)])
params.put_bool("WgpuReady", True, block=True)
car_params_pub = ZmqPubMaster([WGPU_CAR_PARAMS])
remote_model = ZmqSubSocket("modelV2", args.host, conflate=True)
remote_status = ZmqSubSocket(WGPU_STATUS, args.host, conflate=True)
car_params = params.get("CarParams") or params.get("CarParamsPersistent")
while True:
# Keep local modeld publishing while a host connects and warms up.
print(f"forwarding camera/state to {args.host}; waiting for a fresh remote model")
model_name = None
while True:
if car_params is None:
car_params = params.get("CarParams") or params.get("CarParamsPersistent")
if car_params is not None:
# This dedicated conflated startup channel lets remote modeld obtain CP
# before it connects to VisionIPC and accumulates stale frame metadata.
car_params_pub.send_raw(WGPU_CAR_PARAMS, car_params)
received, model_age = receive_model(remote_model)
model_name = receive_model_name(remote_status) or model_name
if received and 0 <= model_age < REMOTE_MODEL_TIMEOUT and model_name is not None:
+3
View File
@@ -5,6 +5,9 @@ import zmq
import openpilot.cereal.messaging as messaging
WGPU_CAR_PARAMS = "wgpuCarParams"
def service_port(endpoint: str) -> int:
# Keep this in sync with cereal/messaging/bridge_zmq.cc.
value = 0xcbf29ce484222325