mirror of
https://github.com/sunnypilot/sunnypilot.git
synced 2026-08-17 16:13:45 +08:00
egpu
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import glob
|
||||
import json
|
||||
import os
|
||||
import sys, subprocess
|
||||
import time
|
||||
from SCons.Script import Action, Value
|
||||
from openpilot.common.file_chunker import chunk_file, get_chunk_targets, get_existing_chunks
|
||||
from openpilot.common.transformations.camera import _ar_ox_fisheye, _os_fisheye
|
||||
@@ -26,18 +26,7 @@ tinygrad_files = ["#"+x for x in glob.glob(env.Dir("#tinygrad_repo").relpath + "
|
||||
def estimate_pickle_max_size(onnx_size):
|
||||
return 1.2 * onnx_size + 10 * 1024 * 1024 # 20% + 10MB is plenty
|
||||
|
||||
# get fastest TG config
|
||||
# probe in subprocess so usbgpu locks gets released on process exit
|
||||
def probe_devices():
|
||||
return set(subprocess.run(
|
||||
[sys.executable, '-c', 'from tinygrad import Device\nprint("\\n".join(Device.get_available_devices()))'],
|
||||
capture_output=True, text=True, check=True).stdout.strip().splitlines())
|
||||
|
||||
available = probe_devices()
|
||||
if 'CUDA' in available:
|
||||
tg_backend = 'CUDA'
|
||||
tg_flags = f'DEV={tg_backend}'
|
||||
elif 'QCOM' in available:
|
||||
if arch == 'comma_arm64':
|
||||
tg_backend = 'QCOM'
|
||||
tg_flags = f'DEV={tg_backend} IMAGE=1 FLOAT16=1 NOLOCALS=1 JIT_BATCH_SIZE=0 OPENPILOT_HACKS=1'
|
||||
else:
|
||||
@@ -54,9 +43,9 @@ tg_devices = { # which device to put jit inputs to at runtime
|
||||
},
|
||||
}
|
||||
|
||||
USBGPU = usbgpu_present() # or release # TODO always build big model on release
|
||||
USBGPU = usbgpu_present()
|
||||
if USBGPU:
|
||||
usbgpu_tg_flags = f'DEBUG=2 DEV=USB+AMD:LLVM WARP_DEV={tg_backend} FLOAT16=1 JIT_BATCH_SIZE=0 GMMU=0'
|
||||
usbgpu_tg_flags = f'DEBUG=2 DEV=USB+AMD:LLVM WARP_DEV={tg_backend} FLOAT16=1 JIT_BATCH_SIZE=0 GMMU=0 TC_OPT=2'
|
||||
# the USB+AMD GPU takes an exclusive flock; serialize all targets that touch it
|
||||
usbgpu_lock = File("models/.usb_gpu.lock").abspath
|
||||
|
||||
@@ -97,12 +86,26 @@ for usbgpu in [False, True] if USBGPU else [False]:
|
||||
f'--output {target_pkl_path} --frame-skip {frame_skip}')
|
||||
onnx_sizes_sum = sum(os.path.getsize(f) for f in driving_onnx_deps)
|
||||
chunk_targets = get_chunk_targets(target_pkl_path, estimate_pickle_max_size(onnx_sizes_sum))
|
||||
def do_compile(target, source, env, command=cmd, pkl=target_pkl_path, chunks=chunk_targets):
|
||||
from openpilot.system.hardware.chestnut.flash import link_up
|
||||
# chestnut can enumerate before its PCIe link is up due to varying 12V power behavior across cars
|
||||
for _ in range(10):
|
||||
if link_up():
|
||||
break
|
||||
time.sleep(1)
|
||||
else:
|
||||
print("Chestnut not ready, skipping big model build")
|
||||
return
|
||||
if ret := env.Execute(command):
|
||||
return ret
|
||||
chunk_file(pkl, chunks)
|
||||
def do_chunk(target, source, env, pkl=target_pkl_path, chunks=chunk_targets):
|
||||
chunk_file(pkl, chunks)
|
||||
actions = Action(do_compile, " [USBGPU] $TARGET") if usbgpu else [cmd, Action(do_chunk, " [CHUNK] $TARGET")]
|
||||
node = lenv.Command(
|
||||
chunk_targets,
|
||||
tinygrad_files + compile_modeld_script + driving_onnx_deps + [Value(chunk_targets), chunker_file],
|
||||
[cmd, Action(do_chunk, " [CHUNK] $TARGET")],
|
||||
actions,
|
||||
)
|
||||
if usbgpu:
|
||||
lenv.SideEffect(usbgpu_lock, node)
|
||||
|
||||
@@ -7,7 +7,7 @@ import tempfile
|
||||
from pathlib import Path
|
||||
|
||||
from openpilot.common.file_chunker import get_manifest_path
|
||||
from openpilot.common.hardware.usb import CHESTNUT_VENDOR_ID, CHESTNUT_PRODUCT_ID, USB_DEVICES_PATH
|
||||
from openpilot.common.hardware.usb import CHESTNUT_FW_VERSION, CHESTNUT_USB_IDS, USB_DEVICES_PATH
|
||||
|
||||
MODELS_DIR = Path(__file__).resolve().parent / 'models'
|
||||
TG_INPUT_DEVICES_PATH = MODELS_DIR / 'tg_input_devices.json'
|
||||
@@ -49,7 +49,8 @@ def usbgpu_present() -> bool:
|
||||
for d in USB_DEVICES_PATH.glob("*"):
|
||||
try:
|
||||
usb_id = (int((d / "idVendor").read_text(), 16), int((d / "idProduct").read_text(), 16))
|
||||
if usb_id == (CHESTNUT_VENDOR_ID, CHESTNUT_PRODUCT_ID):
|
||||
product = (d / "product").read_text().strip()
|
||||
if usb_id in CHESTNUT_USB_IDS and product == f"custom {CHESTNUT_FW_VERSION}-CLEAN":
|
||||
return True
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
#!/usr/bin/env python3
|
||||
from functools import cached_property
|
||||
import os
|
||||
os.environ['GMMU'] = '0' # for usbgpu fast loading, noop for qcom
|
||||
from tinygrad.tensor import Tensor
|
||||
from tinygrad.device import Device
|
||||
import struct
|
||||
import threading
|
||||
import time
|
||||
import numpy as np
|
||||
@@ -9,7 +12,9 @@ import openpilot.cereal.messaging as messaging
|
||||
from openpilot.cereal import log
|
||||
from opendbc.car.structs import car
|
||||
from openpilot.cereal.messaging import PubMaster, SubMaster
|
||||
from msgq.visionipc import VisionIpcClient, VisionStreamType, VisionBuf
|
||||
from openpilot.cereal.services import SERVICE_LIST
|
||||
from openpilot.cereal.visionipc import VisionStreamType
|
||||
from msgq.visionipc import VisionIpcClient, VisionBuf
|
||||
from opendbc.car.car_helpers import get_demo_car_params
|
||||
from openpilot.common.swaglog import cloudlog
|
||||
from openpilot.common.params import Params
|
||||
@@ -64,6 +69,50 @@ def get_action_from_model(model_output: dict[str, np.ndarray], prev_action: log.
|
||||
shouldStop=bool(stop))
|
||||
|
||||
|
||||
class ChestnutState:
|
||||
# only modeld can access chestnut
|
||||
def __init__(self, pm: PubMaster):
|
||||
self.pm = pm
|
||||
self.valid = True
|
||||
|
||||
@cached_property
|
||||
def power_limit(self) -> int:
|
||||
smu = Device["AMD"].iface.dev_impl.smu
|
||||
return smu._send_msg(smu.smu_mod.PPSMC_MSG_GetPptLimit, 0, read_back_arg=True, timeout=100)
|
||||
|
||||
def send(self) -> None:
|
||||
msg = messaging.new_message('chestnutState')
|
||||
state = msg.chestnutState
|
||||
valid = False
|
||||
if "AMD" in Device._opened_devices:
|
||||
try:
|
||||
smu = Device["AMD"].iface.dev_impl.smu
|
||||
smu._send_msg(smu.smu_mod.PPSMC_MSG_TransferTableSmu2Dram, smu.smu_mod.TABLE_SMU_METRICS, timeout=100)
|
||||
metrics = smu.read_table(smu.smu_mod.SmuMetricsExternal_t, smu.smu_mod.TABLE_SMU_METRICS).SmuMetrics
|
||||
state.tempC = metrics.AvgTemperature[smu.smu_mod.TEMP_HOTSPOT]
|
||||
state.memoryTempC = metrics.AvgTemperature[smu.smu_mod.TEMP_MEM]
|
||||
state.powerDrawW = metrics.AverageSocketPower
|
||||
state.powerLimitW = self.power_limit
|
||||
state.gpuUsagePercent = metrics.AverageGfxActivity
|
||||
state.gpuClockMhz = metrics.AverageGfxclkFrequencyPostDs
|
||||
state.fanSpeedRpm = metrics.AvgFanRpm
|
||||
valid = True
|
||||
except Exception:
|
||||
if self.valid:
|
||||
cloudlog.exception("chestnut state read failed")
|
||||
try:
|
||||
# ASM runs on USB-C power, these still read without a gpu
|
||||
asm = Device["AMD"].iface.pci_dev.usb
|
||||
state.pcieLtssm = asm.read(0xB450, 1)[0]
|
||||
state.supplyVoltage, state.supplyCurrent = struct.unpack('<Hh', bytes(asm.usb.control_read(0xC0, 5))[:4])
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
self.valid = valid
|
||||
msg.valid = valid
|
||||
self.pm.send('chestnutState', msg)
|
||||
|
||||
|
||||
class FrameMeta:
|
||||
frame_id: int = 0
|
||||
timestamp_sof: int = 0
|
||||
@@ -87,6 +136,7 @@ class ModelState:
|
||||
self.output_slices = metadata['output_slices']
|
||||
|
||||
self.prev_desire = np.zeros(ModelConstants.DESIRE_LEN, dtype=np.float32)
|
||||
self.usbgpu = usbgpu
|
||||
|
||||
self.frame_skip = ModelConstants.MODEL_RUN_FREQ // ModelConstants.MODEL_CONTEXT_FREQ
|
||||
self.input_queues, self.npy = make_input_queues(self.input_shapes, self.frame_skip, device=self.QUEUE_DEV)
|
||||
@@ -127,6 +177,10 @@ class ModelState:
|
||||
**{k: self.input_queues[k] for k in POLICY_INPUTS if k in self.input_queues}, warped=warped
|
||||
)
|
||||
model_output = outs.numpy()[0]
|
||||
if self.usbgpu and not np.all(np.isfinite(model_output)):
|
||||
# TODO remove with prev_feat
|
||||
cloudlog.error("model output not finite, dropping frame")
|
||||
return None
|
||||
outputs_dict = self.parser.parse_outputs(self.slice_outputs(model_output, self.output_slices))
|
||||
self.npy['prev_feat'][:] = model_output[self.output_slices['hidden_state']]
|
||||
|
||||
@@ -149,6 +203,8 @@ def main(demo=False):
|
||||
cloudlog.warning("modeld init")
|
||||
|
||||
USBGPU = usbgpu_present() and usbgpu_compiled()
|
||||
if USBGPU:
|
||||
os.environ['HCQDEV_WAIT_TIMEOUT_MS'] = '3000'
|
||||
params = Params()
|
||||
params.put_bool("UsbGpuLoading", USBGPU)
|
||||
params.remove("UsbGpuActive")
|
||||
@@ -159,12 +215,12 @@ def main(demo=False):
|
||||
while True:
|
||||
available_streams = VisionIpcClient.available_streams("camerad", block=False)
|
||||
if available_streams:
|
||||
use_extra_client = VisionStreamType.VISION_STREAM_WIDE_ROAD in available_streams and VisionStreamType.VISION_STREAM_ROAD in available_streams
|
||||
main_wide_camera = VisionStreamType.VISION_STREAM_ROAD not in available_streams
|
||||
use_extra_client = VisionStreamType.VISION_STREAM_WIDE_ROAD in available_streams and VisionStreamType.VISION_STREAM_NARROW_ROAD in available_streams
|
||||
main_wide_camera = VisionStreamType.VISION_STREAM_NARROW_ROAD not in available_streams
|
||||
break
|
||||
time.sleep(.1)
|
||||
|
||||
vipc_client_main_stream = VisionStreamType.VISION_STREAM_WIDE_ROAD if main_wide_camera else VisionStreamType.VISION_STREAM_ROAD
|
||||
vipc_client_main_stream = VisionStreamType.VISION_STREAM_WIDE_ROAD if main_wide_camera else VisionStreamType.VISION_STREAM_NARROW_ROAD
|
||||
vipc_client_main = VisionIpcClient("camerad", vipc_client_main_stream, True)
|
||||
vipc_client_extra = VisionIpcClient("camerad", VisionStreamType.VISION_STREAM_WIDE_ROAD, False)
|
||||
cloudlog.warning(f"vision stream set up, main_wide_camera: {main_wide_camera}, use_extra_client: {use_extra_client}")
|
||||
@@ -204,11 +260,13 @@ def main(demo=False):
|
||||
cloudlog.warning(f"models loaded in {time.monotonic() - st:.1f}s, modeld starting")
|
||||
|
||||
# messaging
|
||||
pm = PubMaster(["modelV2", "drivingModelData", "cameraOdometry"])
|
||||
sm = SubMaster(["deviceState", "carState", "roadCameraState", "liveCalibration", "driverMonitoringState", "carControl", "liveDelay"])
|
||||
pub_socks = ["modelV2", "drivingModelData", "cameraOdometry"] + (["chestnutState"] if USBGPU else [])
|
||||
pm = PubMaster(pub_socks)
|
||||
sm = SubMaster(["deviceState", "carState", "narrowRoadCameraState", "extrinsicsCalibration", "driverMonitoringState", "carControl", "lateralDelay"])
|
||||
|
||||
publish_state = PublishState()
|
||||
params = Params()
|
||||
chestnut_state = ChestnutState(pm) if USBGPU else None
|
||||
|
||||
# setup filter to track dropped frames
|
||||
frame_dropped_filter = FirstOrderFilter(0., 10., 1. / ModelConstants.MODEL_RUN_FREQ)
|
||||
@@ -218,7 +276,7 @@ def main(demo=False):
|
||||
|
||||
model_transform_main = np.zeros((3, 3), dtype=np.float32)
|
||||
model_transform_extra = np.zeros((3, 3), dtype=np.float32)
|
||||
live_calib_seen = False
|
||||
extrinsics_calibration_seen = False
|
||||
buf_main, buf_extra = None, None
|
||||
meta_main = FrameMeta()
|
||||
meta_extra = FrameMeta()
|
||||
@@ -272,16 +330,18 @@ def main(demo=False):
|
||||
sm.update(0)
|
||||
desire = DH.desire
|
||||
is_rhd = sm["driverMonitoringState"].isRHD
|
||||
frame_id = sm["roadCameraState"].frameId
|
||||
frame_id = sm["narrowRoadCameraState"].frameId
|
||||
v_ego = max(sm["carState"].vEgo, 0.)
|
||||
lat_delay = sm["liveDelay"].lateralDelay + LAT_SMOOTH_SECONDS
|
||||
if sm.updated["liveCalibration"] and sm.seen['roadCameraState'] and sm.seen['deviceState']:
|
||||
device_from_calib_euler = np.array(sm["liveCalibration"].rpyCalib, dtype=np.float32)
|
||||
dc = DEVICE_CAMERAS[(str(sm['deviceState'].deviceType), str(sm['roadCameraState'].sensor))]
|
||||
model_transform_main = get_warp_matrix(device_from_calib_euler, dc.ecam.intrinsics if main_wide_camera else dc.fcam.intrinsics, False).astype(np.float32)
|
||||
lat_delay = sm["lateralDelay"].lateralDelay + LAT_SMOOTH_SECONDS
|
||||
if sm.updated["extrinsicsCalibration"] and sm.seen['narrowRoadCameraState'] and sm.seen['deviceState']:
|
||||
device_from_calib_euler = np.array(sm["extrinsicsCalibration"].rpyCalib, dtype=np.float32)
|
||||
dc = DEVICE_CAMERAS[(str(sm['deviceState'].deviceType), str(sm['narrowRoadCameraState'].sensor))]
|
||||
main_intrinsics = dc.wide_road.intrinsics if main_wide_camera else dc.narrow_road.intrinsics
|
||||
model_transform_main = get_warp_matrix(device_from_calib_euler, main_intrinsics, False).astype(np.float32)
|
||||
has_wide_camera = use_extra_client or main_wide_camera
|
||||
model_transform_extra = get_warp_matrix(device_from_calib_euler, dc.ecam.intrinsics if has_wide_camera else dc.fcam.intrinsics, True).astype(np.float32)
|
||||
live_calib_seen = True
|
||||
extra_intrinsics = dc.wide_road.intrinsics if has_wide_camera else dc.narrow_road.intrinsics
|
||||
model_transform_extra = get_warp_matrix(device_from_calib_euler, extra_intrinsics, True).astype(np.float32)
|
||||
extrinsics_calibration_seen = True
|
||||
|
||||
traffic_convention = np.zeros(2)
|
||||
traffic_convention[int(is_rhd)] = 1
|
||||
@@ -336,7 +396,8 @@ def main(demo=False):
|
||||
prev_action = action
|
||||
fill_model_msg(modelv2_send, model_output, action,
|
||||
publish_state, meta_main.frame_id, meta_extra.frame_id, frame_id,
|
||||
frame_drop_ratio, meta_main.timestamp_eof, model_execution_time, live_calib_seen)
|
||||
frame_drop_ratio, meta_main.timestamp_eof, model_execution_time, extrinsics_calibration_seen)
|
||||
modelv2_send.modelV2.big = model.usbgpu
|
||||
|
||||
desire_state = modelv2_send.modelV2.meta.desireState
|
||||
l_lane_change_prob = desire_state[log.Desire.laneChangeLeft]
|
||||
@@ -347,12 +408,15 @@ def main(demo=False):
|
||||
modelv2_send.modelV2.meta.laneChangeDirection = DH.lane_change_direction
|
||||
|
||||
fill_driving_model_data(drivingdata_send, modelv2_send)
|
||||
fill_pose_msg(posenet_send, model_output, meta_main.frame_id, vipc_dropped_frames, meta_main.timestamp_eof, live_calib_seen)
|
||||
fill_pose_msg(posenet_send, model_output, meta_main.frame_id, vipc_dropped_frames, meta_main.timestamp_eof, extrinsics_calibration_seen)
|
||||
pm.send('modelV2', modelv2_send)
|
||||
pm.send('drivingModelData', drivingdata_send)
|
||||
pm.send('cameraOdometry', posenet_send)
|
||||
last_vipc_frame_id = meta_main.frame_id
|
||||
|
||||
if chestnut_state is not None and run_count % round(ModelConstants.MODEL_RUN_FREQ / SERVICE_LIST['chestnutState'].frequency) == 0:
|
||||
chestnut_state.send()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
|
||||
@@ -25,16 +25,7 @@ def get_camera_configs():
|
||||
|
||||
CAMERA_CONFIGS = get_camera_configs()
|
||||
|
||||
def probe_devices():
|
||||
return set(subprocess.run(
|
||||
[sys.executable, '-c', 'from tinygrad import Device\nprint("\\n".join(Device.get_available_devices()))'],
|
||||
capture_output=True, text=True, check=True).stdout.strip().splitlines())
|
||||
|
||||
available = probe_devices()
|
||||
if 'CUDA' in available:
|
||||
tg_backend = 'CUDA'
|
||||
tg_flags = f'DEV={tg_backend}'
|
||||
elif 'QCOM' in available:
|
||||
if arch == 'comma_arm64':
|
||||
tg_backend = 'QCOM'
|
||||
tg_flags = f'DEV={tg_backend} IMAGE=1 FLOAT16=1 NOLOCALS=1 JIT_BATCH_SIZE=0 OPENPILOT_HACKS=1'
|
||||
else:
|
||||
@@ -53,7 +44,7 @@ script_deps = [File("compile_modeld.py"), upstream_compile_script]
|
||||
|
||||
USBGPU = usbgpu_present()
|
||||
if USBGPU:
|
||||
usbgpu_tg_flags = f'DEBUG=2 DEV=USB+AMD:LLVM WARP_DEV={tg_backend} FLOAT16=1 JIT_BATCH_SIZE=0 GMMU=0'
|
||||
usbgpu_tg_flags = f'DEBUG=2 DEV=USB+AMD:LLVM WARP_DEV={tg_backend} FLOAT16=1 JIT_BATCH_SIZE=0 GMMU=0 TC_OPT=2'
|
||||
usbgpu_lock = File("models/.usb_gpu.lock").abspath
|
||||
|
||||
def compile_combined(model_type, onnx_args, output_name):
|
||||
|
||||
@@ -12,7 +12,6 @@ from openpilot.common.hardware import TICI
|
||||
os.environ['DEV'] = 'QCOM' if TICI else 'CPU'
|
||||
|
||||
from openpilot.selfdrive.modeld.helpers import usbgpu_present, load_oob
|
||||
from openpilot.selfdrive.modeld.usbgpu_link import wait_usbgpu_link
|
||||
|
||||
USBGPU = usbgpu_present()
|
||||
if USBGPU:
|
||||
@@ -23,6 +22,7 @@ import numpy as np
|
||||
import openpilot.cereal.messaging as messaging
|
||||
from openpilot.cereal import log
|
||||
from opendbc.car.structs import car
|
||||
from openpilot.cereal.services import SERVICE_LIST
|
||||
from setproctitle import setproctitle
|
||||
from openpilot.cereal.messaging import PubMaster, SubMaster
|
||||
from msgq.visionipc import VisionIpcClient, VisionStreamType, VisionBuf
|
||||
@@ -42,6 +42,7 @@ from openpilot.system import sentry
|
||||
from openpilot.system.camerad.cameras.nv12_info import get_nv12_info
|
||||
from openpilot.selfdrive.controls.lib.desire_helper import DesireHelper
|
||||
from openpilot.selfdrive.controls.lib.drive_helpers import get_accel_from_plan, smooth_value
|
||||
from openpilot.selfdrive.modeld.modeld import ChestnutState
|
||||
|
||||
from openpilot.sunnypilot.modeld_v2.fill_model_msg import fill_model_msg, fill_pose_msg, PublishState, get_curvature_from_output
|
||||
from openpilot.sunnypilot.modeld_v2.constants import Plan
|
||||
@@ -317,7 +318,11 @@ def main(demo=False):
|
||||
config_realtime_process(7, 54)
|
||||
|
||||
if USBGPU:
|
||||
wait_usbgpu_link()
|
||||
os.environ['HCQDEV_WAIT_TIMEOUT_MS'] = '3000'
|
||||
|
||||
params = Params()
|
||||
params.put_bool("UsbGpuLoading", USBGPU)
|
||||
params.remove("UsbGpuActive")
|
||||
|
||||
# visionipc clients
|
||||
while True:
|
||||
@@ -343,15 +348,30 @@ def main(demo=False):
|
||||
cloudlog.warning(f"connected extra cam with buffer size: {vipc_client_extra.buffer_len} ({vipc_client_extra.width} x {vipc_client_extra.height})")
|
||||
|
||||
cloudlog.warning("loading model")
|
||||
model = ModelState(cam_w=vipc_client_main.width, cam_h=vipc_client_main.height)
|
||||
cloudlog.warning("models loaded, modeld starting")
|
||||
st = time.monotonic()
|
||||
|
||||
model = None
|
||||
if USBGPU:
|
||||
import threading
|
||||
def load(): nonlocal model; model = ModelState(cam_w=vipc_client_main.width, cam_h=vipc_client_main.height)
|
||||
t = threading.Thread(target=load, daemon=True)
|
||||
t.start()
|
||||
t.join(60)
|
||||
assert model, "eGPU timeout (60s)"
|
||||
params.put_bool("UsbGpuActive", True)
|
||||
else:
|
||||
model = ModelState(cam_w=vipc_client_main.width, cam_h=vipc_client_main.height)
|
||||
|
||||
params.put_bool("UsbGpuLoading", False)
|
||||
cloudlog.warning(f"models loaded in {time.monotonic() - st:.1f}s, modeld starting")
|
||||
|
||||
# messaging
|
||||
pm = PubMaster(["modelV2", "drivingModelData", "cameraOdometry", "modelDataV2SP"])
|
||||
pub_socks = ["modelV2", "drivingModelData", "cameraOdometry", "modelDataV2SP"] + (["chestnutState"] if USBGPU else [])
|
||||
pm = PubMaster(pub_socks)
|
||||
sm = SubMaster(["deviceState", "carState", "roadCameraState", "liveCalibration", "driverMonitoringState", "carControl", "liveDelay"])
|
||||
|
||||
publish_state = PublishState()
|
||||
params = Params()
|
||||
chestnut_state = ChestnutState(pm) if USBGPU else None
|
||||
|
||||
params.put_bool("UsbGpuPresent", USBGPU)
|
||||
params.put_bool("UsbGpuCompiled", USBGPU)
|
||||
@@ -509,6 +529,8 @@ def main(demo=False):
|
||||
pm.send('modelDataV2SP', mdv2sp_send)
|
||||
last_vipc_frame_id = meta_main.frame_id
|
||||
|
||||
if chestnut_state is not None and run_count % round(model.constants.MODEL_FREQ / SERVICE_LIST['chestnutState'].frequency) == 0:
|
||||
chestnut_state.send()
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
|
||||
Reference in New Issue
Block a user