Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

move car.capnp to opendbc #33722

Merged
merged 10 commits into from
Oct 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
722 changes: 0 additions & 722 deletions cereal/car.capnp

This file was deleted.

1 change: 1 addition & 0 deletions cereal/car.capnp
24 changes: 10 additions & 14 deletions selfdrive/car/card.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
from openpilot.selfdrive.pandad import can_capnp_to_list, can_list_to_can_capnp
from openpilot.selfdrive.car.cruise import VCruiseHelper
from openpilot.selfdrive.car.car_specific import MockCarState
from openpilot.selfdrive.car.helpers import convert_carControl, convert_to_capnp

REPLAY = "REPLAY" in os.environ

Expand Down Expand Up @@ -63,8 +62,7 @@ def can_send(msgs: list[CanData]) -> None:
class Car:
CI: CarInterfaceBase
RI: RadarInterfaceBase
CP: structs.CarParams
CP_capnp: car.CarParams
CP: car.CarParams

def __init__(self, CI=None, RI=None) -> None:
self.can_sock = messaging.sub_sock('can', timeout=20)
Expand Down Expand Up @@ -144,9 +142,7 @@ def __init__(self, CI=None, RI=None) -> None:
self.params.put("CarParamsPrevRoute", prev_cp)

# Write CarParams for controls and radard
# convert to pycapnp representation for caching and logging
self.CP_capnp = convert_to_capnp(self.CP)
cp_bytes = self.CP_capnp.to_bytes()
cp_bytes = self.CP.to_bytes()
self.params.put("CarParams", cp_bytes)
self.params.put_nonblocking("CarParamsCache", cp_bytes)
self.params.put_nonblocking("CarParamsPersistent", cp_bytes)
Expand All @@ -160,19 +156,19 @@ def __init__(self, CI=None, RI=None) -> None:
# card is driven by can recv, expected at 100Hz
self.rk = Ratekeeper(100, print_delay_threshold=None)

def state_update(self) -> tuple[car.CarState, structs.RadarData | None]:
def state_update(self) -> tuple[car.CarState, structs.RadarDataT | None]:
"""carState update loop, driven by can"""

can_strs = messaging.drain_sock_raw(self.can_sock, wait_for_one=True)
can_list = can_capnp_to_list(can_strs)

# Update carState from CAN
CS = convert_to_capnp(self.CI.update(can_list))
CS = self.CI.update(can_list)
if self.CP.carName == 'mock':
CS = self.mock_carstate.update(CS)

# Update radar tracks from CAN
RD: structs.RadarData | None = self.RI.update(can_list)
RD: structs.RadarDataT | None = self.RI.update(can_list)

self.sm.update(0)

Expand All @@ -192,20 +188,20 @@ def state_update(self) -> tuple[car.CarState, structs.RadarData | None]:

return CS, RD

def state_publish(self, CS: car.CarState, RD: structs.RadarData | None):
def state_publish(self, CS: car.CarState, RD: structs.RadarDataT | None):
"""carState and carParams publish loop"""

# carParams - logged every 50 seconds (> 1 per segment)
if self.sm.frame % int(50. / DT_CTRL) == 0:
cp_send = messaging.new_message('carParams')
cp_send.valid = True
cp_send.carParams = self.CP_capnp
cp_send.carParams = self.CP
self.pm.send('carParams', cp_send)

# publish new carOutput
co_send = messaging.new_message('carOutput')
co_send.valid = self.sm.all_checks(['carControl'])
co_send.carOutput.actuatorsOutput = convert_to_capnp(self.last_actuators_output)
co_send.carOutput.actuatorsOutput = self.last_actuators_output
self.pm.send('carOutput', co_send)

# kick off controlsd step while we actuate the latest carControl packet
Expand All @@ -219,7 +215,7 @@ def state_publish(self, CS: car.CarState, RD: structs.RadarData | None):
if RD is not None:
tracks_msg = messaging.new_message('liveTracks')
tracks_msg.valid = len(RD.errors) == 0
tracks_msg.liveTracks = convert_to_capnp(RD)
tracks_msg.liveTracks = RD
self.pm.send('liveTracks', tracks_msg)

def controls_update(self, CS: car.CarState, CC: car.CarControl):
Expand All @@ -235,7 +231,7 @@ def controls_update(self, CS: car.CarState, CC: car.CarControl):
if self.sm.all_alive(['carControl']):
# send car controls over can
now_nanos = self.can_log_mono_time if REPLAY else int(time.monotonic() * 1e9)
self.last_actuators_output, can_sends = self.CI.apply(convert_carControl(CC), now_nanos)
self.last_actuators_output, can_sends = self.CI.apply(CC, now_nanos)
self.pm.send('sendcan', can_list_to_can_capnp(can_sends, msgtype='sendcan', valid=CS.canValid))

self.CC_prev = CC
Expand Down
74 changes: 0 additions & 74 deletions selfdrive/car/helpers.py

This file was deleted.

15 changes: 7 additions & 8 deletions selfdrive/car/tests/test_car_interfaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
from opendbc.car.fingerprints import all_known_cars
from opendbc.car.fw_versions import FW_VERSIONS, FW_QUERY_CONFIGS
from opendbc.car.mock.values import CAR as MOCK
from openpilot.selfdrive.car.card import convert_carControl, convert_to_capnp
from openpilot.selfdrive.controls.lib.latcontrol_angle import LatControlAngle
from openpilot.selfdrive.controls.lib.latcontrol_pid import LatControlPID
from openpilot.selfdrive.controls.lib.latcontrol_torque import LatControlTorque
Expand Down Expand Up @@ -41,6 +40,7 @@ def test_car_interfaces(self, car_name, data):

car_params = CarInterface.get_params(car_name, args['fingerprints'], args['car_fw'],
experimental_long=args['experimental_long'], docs=False)
car_params = car_params.as_reader()
car_interface = CarInterface(car_params, CarController, CarState)
assert car_params
assert car_interface
Expand Down Expand Up @@ -72,15 +72,15 @@ def test_car_interfaces(self, car_name, data):
# Run car interface
now_nanos = 0
CC = car.CarControl.new_message(**cc_msg)
CC = convert_carControl(CC.as_reader())
CC = CC.as_reader()
for _ in range(10):
car_interface.update([])
car_interface.apply(CC, now_nanos)
now_nanos += DT_CTRL * 1e9 # 10 ms

CC = car.CarControl.new_message(**cc_msg)
CC.enabled = True
CC = convert_carControl(CC.as_reader())
CC = CC.as_reader()
for _ in range(10):
car_interface.update([])
car_interface.apply(CC, now_nanos)
Expand All @@ -89,11 +89,10 @@ def test_car_interfaces(self, car_name, data):
# Test controller initialization
# TODO: wait until card refactor is merged to run controller a few times,
# hypothesis also slows down significantly with just one more message draw
car_params_capnp = convert_to_capnp(car_params).as_reader()
LongControl(car_params_capnp)
LongControl(car_params)
if car_params.steerControlType == CarParams.SteerControlType.angle:
LatControlAngle(car_params_capnp, car_interface)
LatControlAngle(car_params, car_interface)
elif car_params.lateralTuning.which() == 'pid':
LatControlPID(car_params_capnp, car_interface)
LatControlPID(car_params, car_interface)
elif car_params.lateralTuning.which() == 'torque':
LatControlTorque(car_params_capnp, car_interface)
LatControlTorque(car_params, car_interface)
17 changes: 7 additions & 10 deletions selfdrive/car/tests/test_models.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import capnp
import copy
import dataclasses
import os
import pytest
import random
Expand All @@ -20,7 +18,6 @@
from opendbc.car.honda.values import CAR as HONDA, HondaFlags
from opendbc.car.values import Platform
from opendbc.car.tests.routes import non_tested_cars, routes, CarTestRoute
from openpilot.selfdrive.car.card import convert_to_capnp
from openpilot.selfdrive.selfdrived.events import ET
from openpilot.selfdrive.selfdrived.selfdrived import SelfdriveD
from openpilot.selfdrive.pandad import can_capnp_to_list
Expand Down Expand Up @@ -187,15 +184,15 @@ def tearDownClass(cls):
del cls.can_msgs

def setUp(self):
self.CI = self.CarInterface(copy.deepcopy(self.CP), self.CarController, self.CarState)
self.CI = self.CarInterface(self.CP.copy(), self.CarController, self.CarState)
assert self.CI

Params().put_bool("OpenpilotEnabledToggle", self.openpilot_enabled)

# TODO: check safetyModel is in release panda build
self.safety = libpanda_py.libpanda

cfg = car.CarParams.SafetyConfig(**dataclasses.asdict(self.CP.safetyConfigs[-1]))
cfg = self.CP.safetyConfigs[-1]
set_status = self.safety.set_safety_hooks(cfg.safetyModel.raw, cfg.safetyParam)
self.assertEqual(0, set_status, f"failed to set safetyModel {cfg}")
self.safety.init_tests()
Expand All @@ -220,7 +217,7 @@ def test_car_interface(self):
# TODO: also check for checksum violations from can parser
can_invalid_cnt = 0
can_valid = False
CC = structs.CarControl()
CC = structs.CarControl().as_reader()

for i, msg in enumerate(self.can_msgs):
CS = self.CI.update(can_capnp_to_list((msg.as_builder().to_bytes(),)))
Expand Down Expand Up @@ -312,17 +309,17 @@ def test_car_controller(car_control):

# Make sure we can send all messages while inactive
CC = structs.CarControl()
test_car_controller(CC)
test_car_controller(CC.as_reader())

# Test cancel + general messages (controls_allowed=False & cruise_engaged=True)
self.safety.set_cruise_engaged_prev(True)
CC = structs.CarControl(cruiseControl=structs.CarControl.CruiseControl(cancel=True))
test_car_controller(CC)
test_car_controller(CC.as_reader())

# Test resume + general messages (controls_allowed=True & cruise_engaged=True)
self.safety.set_controls_allowed(True)
CC = structs.CarControl(cruiseControl=structs.CarControl.CruiseControl(resume=True))
test_car_controller(CC)
test_car_controller(CC.as_reader())

# Skip stdout/stderr capture with pytest, causes elevated memory usage
@pytest.mark.nocapture
Expand Down Expand Up @@ -409,7 +406,7 @@ def test_panda_safety_carstate(self):
selfdrived = SelfdriveD(CP=self.CP)
selfdrived.initialized = True
for idx, can in enumerate(self.can_msgs):
CS = convert_to_capnp(self.CI.update(can_capnp_to_list((can.as_builder().to_bytes(), ))))
CS = self.CI.update(can_capnp_to_list((can.as_builder().to_bytes(), ))).as_reader()
for msg in filter(lambda m: m.src in range(64), can.can):
to_send = libpanda_py.make_CANPacket(msg.address, msg.src % 4, msg.dat)
ret = self.safety.safety_rx_hook(to_send)
Expand Down
2 changes: 0 additions & 2 deletions selfdrive/controls/lib/tests/test_latcontrol.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
from opendbc.car.honda.values import CAR as HONDA
from opendbc.car.toyota.values import CAR as TOYOTA
from opendbc.car.nissan.values import CAR as NISSAN
from openpilot.selfdrive.car.card import convert_to_capnp
from openpilot.selfdrive.controls.lib.latcontrol_pid import LatControlPID
from openpilot.selfdrive.controls.lib.latcontrol_torque import LatControlTorque
from openpilot.selfdrive.controls.lib.latcontrol_angle import LatControlAngle
Expand All @@ -21,7 +20,6 @@ def test_saturation(self, car_name, controller):
CarInterface, CarController, CarState, RadarInterface = interfaces[car_name]
CP = CarInterface.get_non_essential_params(car_name)
CI = CarInterface(CP, CarController, CarState)
CP = convert_to_capnp(CP)
VM = VehicleModel(CP)

controller = controller(CP.as_reader(), CI)
Expand Down
3 changes: 1 addition & 2 deletions selfdrive/controls/lib/tests/test_vehicle_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,13 @@

from opendbc.car.honda.interface import CarInterface
from opendbc.car.honda.values import CAR
from openpilot.selfdrive.car.card import convert_to_capnp
from openpilot.selfdrive.controls.lib.vehicle_model import VehicleModel, dyn_ss_sol, create_dyn_state_matrices


class TestVehicleModel:
def setup_method(self):
CP = CarInterface.get_non_essential_params(CAR.HONDA_CIVIC)
self.VM = VehicleModel(convert_to_capnp(CP))
self.VM = VehicleModel(CP)

def test_round_trip_yaw_rate(self):
# TODO: fix VM to work at zero speed
Expand Down
11 changes: 8 additions & 3 deletions selfdrive/debug/format_fingerprints.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,16 @@
import jinja2
import os

from cereal import car
from openpilot.common.basedir import BASEDIR
from opendbc.car.interfaces import get_interface_attr

Ecu = car.CarParams.Ecu

CARS = get_interface_attr('CAR')
FW_VERSIONS = get_interface_attr('FW_VERSIONS')
FINGERPRINTS = get_interface_attr('FINGERPRINTS')
ECU_NAME = {v: k for k, v in Ecu.schema.enumerants.items()}

FINGERPRINTS_PY_TEMPLATE = jinja2.Template("""
{%- if FINGERPRINTS[brand] %}
Expand Down Expand Up @@ -45,7 +49,7 @@
{% for car, _ in FW_VERSIONS[brand].items() %}
CAR.{{car.name}}: {
{% for key, fw_versions in FW_VERSIONS[brand][car].items() %}
(Ecu.{{key[0]}}, 0x{{"%0x" | format(key[1] | int)}}, \
(Ecu.{{ECU_NAME[key[0]]}}, 0x{{"%0x" | format(key[1] | int)}}, \
{% if key[2] %}0x{{"%0x" | format(key[2] | int)}}{% else %}{{key[2]}}{% endif %}): [
{% for fw_version in (fw_versions + extra_fw_versions.get(car, {}).get(key, [])) | unique | sort %}
{{fw_version}},
Expand All @@ -67,8 +71,9 @@ def format_brand_fw_versions(brand, extra_fw_versions: None | dict[str, dict[tup
comments = [line for line in f.readlines() if line.startswith("#") and "noqa" not in line]

with open(fingerprints_file, "w") as f:
f.write(FINGERPRINTS_PY_TEMPLATE.render(brand=brand, comments=comments, FINGERPRINTS=FINGERPRINTS,
FW_VERSIONS=FW_VERSIONS, extra_fw_versions=extra_fw_versions))
f.write(FINGERPRINTS_PY_TEMPLATE.render(brand=brand, comments=comments, ECU_NAME=ECU_NAME,
FINGERPRINTS=FINGERPRINTS, FW_VERSIONS=FW_VERSIONS,
extra_fw_versions=extra_fw_versions))


if __name__ == "__main__":
Expand Down
3 changes: 1 addition & 2 deletions selfdrive/modeld/modeld.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
from openpilot.common.transformations.camera import DEVICE_CAMERAS
from openpilot.common.transformations.model import get_warp_matrix
from openpilot.system import sentry
from openpilot.selfdrive.car.card import convert_to_capnp
from openpilot.selfdrive.controls.lib.desire_helper import DesireHelper
from openpilot.selfdrive.modeld.runners import ModelRunner, Runtime
from openpilot.selfdrive.modeld.parse_model_outputs import Parser
Expand Down Expand Up @@ -184,7 +183,7 @@ def main(demo=False):


if demo:
CP = convert_to_capnp(get_demo_car_params())
CP = get_demo_car_params()
else:
CP = messaging.log_from_bytes(params.get("CarParams", block=True), car.CarParams)
cloudlog.info("modeld got CarParams: %s", CP.carName)
Expand Down
Loading
Loading