diff --git a/cereal/log.capnp b/cereal/log.capnp index 57b56d5229..4742473318 100644 --- a/cereal/log.capnp +++ b/cereal/log.capnp @@ -684,18 +684,53 @@ struct LiveTracks { oncoming @9 :Bool; } +struct SelfdriveState { + # high level system state + state @0 :OpenpilotState; + enabled @1 :Bool; + active @2 :Bool; + engageable @9 :Bool; # can OP be engaged? + + # UI alerts + alertText1 @3 :Text; + alertText2 @4 :Text; + alertStatus @5 :AlertStatus; + alertSize @6 :AlertSize; + alertType @7 :Text; + alertSound @8 :Car.CarControl.HUDControl.AudibleAlert; + + # configurable driving settings + experimentalMode @10 :Bool; + personality @11 :LongitudinalPersonality; + + enum OpenpilotState @0xdbe58b96d2d1ac61 { + disabled @0; + preEnabled @1; + enabled @2; + softDisabling @3; + overriding @4; # superset of overriding with steering or accelerator + } + + enum AlertStatus @0xa0d0dcd113193c62 { + normal @0; + userPrompt @1; + critical @2; + } + + enum AlertSize @0xe98bb99d6e985f64 { + none @0; + small @1; + mid @2; + full @3; + } +} + struct ControlsState @0x97ff69c53601abf1 { + cumLagMs @15 :Float32; startMonoTime @48 :UInt64; longitudinalPlanMonoTime @28 :UInt64; lateralPlanMonoTime @50 :UInt64; - state @31 :OpenpilotState; - enabled @19 :Bool; - active @36 :Bool; - - experimentalMode @64 :Bool; - personality @66 :LongitudinalPersonality; - longControlState @30 :Car.CarControl.Actuators.LongControlState; vTargetLead @3 :Float32; vCruise @22 :Float32; # actual set speed @@ -706,18 +741,21 @@ struct ControlsState @0x97ff69c53601abf1 { aTarget @35 :Float32; curvature @37 :Float32; # path curvature from vehicle model desiredCurvature @61 :Float32; # lag adjusted curvatures used by lateral controllers - forceDecel @51 :Bool; - # UI alerts + # TODO: remove these, they're now in selfdriveState alertText1 @24 :Text; alertText2 @25 :Text; - alertStatus @38 :AlertStatus; - alertSize @39 :AlertSize; + alertStatus @38 :SelfdriveState.AlertStatus; + alertSize @39 :SelfdriveState.AlertSize; alertType @44 :Text; alertSound @56 :Car.CarControl.HUDControl.AudibleAlert; engageable @41 :Bool; # can OP be engaged? - - cumLagMs @15 :Float32; + forceDecel @51 :Bool; + state @31 :SelfdriveState.OpenpilotState; + enabled @19 :Bool; + active @36 :Bool; + experimentalMode @64 :Bool; + personality @66 :LongitudinalPersonality; lateralControlState :union { indiState @52 :LateralINDIState; @@ -730,27 +768,6 @@ struct ControlsState @0x97ff69c53601abf1 { lqrStateDEPRECATED @55 :LateralLQRState; } - enum OpenpilotState @0xdbe58b96d2d1ac61 { - disabled @0; - preEnabled @1; - enabled @2; - softDisabling @3; - overriding @4; # superset of overriding with steering or accelerator - } - - enum AlertStatus { - normal @0; # low priority alert for user's convenience - userPrompt @1; # mid priority alert that might require user intervention - critical @2; # high priority alert that needs immediate user intervention - } - - enum AlertSize { - none @0; # don't display the alert - small @1; # small box - mid @2; # mid screen - full @3; # full screen - } - struct LateralINDIState { active @0 :Bool; steeringAngleDeg @1 :Float32; @@ -2300,6 +2317,7 @@ struct Event { gpsNMEA @3 :GPSNMEAData; can @5 :List(CanData); controlsState @7 :ControlsState; + selfdriveState @130 :SelfdriveState; gyroscope @99 :SensorEventData; gyroscope2 @100 :SensorEventData; accelerometer @98 :SensorEventData; diff --git a/cereal/services.py b/cereal/services.py index 7d0a7d380a..b50e47be60 100755 --- a/cereal/services.py +++ b/cereal/services.py @@ -24,6 +24,7 @@ _services: dict[str, tuple] = { "deviceState": (True, 2., 1), "can": (True, 100., 2053), # decimation gives ~3 msgs in a full segment "controlsState": (True, 100., 10), + "selfdriveState": (True, 100., 10), "pandaStates": (True, 10., 1), "peripheralState": (True, 2., 1), "radarState": (True, 20., 5), diff --git a/selfdrive/controls/controlsd.py b/selfdrive/controls/controlsd.py index 7c6a3b4a11..cd957c731a 100755 --- a/selfdrive/controls/controlsd.py +++ b/selfdrive/controls/controlsd.py @@ -44,7 +44,7 @@ TESTING_CLOSET = "TESTING_CLOSET" in os.environ IGNORE_PROCESSES = {"loggerd", "encoderd", "statsd"} ThermalStatus = log.DeviceState.ThermalStatus -State = log.ControlsState.OpenpilotState +State = log.SelfdriveState.OpenpilotState PandaType = log.PandaState.PandaType Desire = log.Desire LaneChangeState = log.LaneChangeState @@ -78,7 +78,7 @@ class Controls: self.branch = get_short_branch() # Setup sockets - self.pm = messaging.PubMaster(['controlsState', 'carControl', 'onroadEvents']) + self.pm = messaging.PubMaster(['selfdriveState', 'controlsState', 'carControl', 'onroadEvents']) self.gps_location_service = get_gps_location_service(self.params) self.gps_packets = [self.gps_location_service] @@ -781,6 +781,25 @@ class Controls: self.pm.send('controlsState', dat) + # selfdriveState + ss_msg = messaging.new_message('selfdriveState') + ss_msg.valid = CS.canValid + ss = ss_msg.selfdriveState + if current_alert: + ss.alertText1 = current_alert.alert_text_1 + ss.alertText2 = current_alert.alert_text_2 + ss.alertSize = current_alert.alert_size + ss.alertStatus = current_alert.alert_status + ss.alertType = current_alert.alert_type + ss.alertSound = current_alert.audible_alert + ss.enabled = self.enabled + ss.active = self.active + ss.state = self.state + ss.engageable = not self.events.contains(ET.NO_ENTRY) + ss.experimentalMode = self.experimental_mode + ss.personality = self.personality + self.pm.send('selfdriveState', ss_msg) + # onroadEvents - logged every second or on change if (self.sm.frame % int(1. / DT_CTRL) == 0) or (self.events.names != self.events_prev): ce_send = messaging.new_message('onroadEvents', len(self.events)) diff --git a/selfdrive/controls/lib/events.py b/selfdrive/controls/lib/events.py index fa6528f659..2ef4774e87 100755 --- a/selfdrive/controls/lib/events.py +++ b/selfdrive/controls/lib/events.py @@ -12,8 +12,8 @@ from openpilot.common.git import get_short_branch from openpilot.common.realtime import DT_CTRL from openpilot.selfdrive.locationd.calibrationd import MIN_SPEED_FILTER -AlertSize = log.ControlsState.AlertSize -AlertStatus = log.ControlsState.AlertStatus +AlertSize = log.SelfdriveState.AlertSize +AlertStatus = log.SelfdriveState.AlertStatus VisualAlert = car.CarControl.HUDControl.VisualAlert AudibleAlert = car.CarControl.HUDControl.AudibleAlert EventName = car.CarEvent.EventName @@ -110,8 +110,8 @@ class Alert: def __init__(self, alert_text_1: str, alert_text_2: str, - alert_status: log.ControlsState.AlertStatus, - alert_size: log.ControlsState.AlertSize, + alert_status: log.SelfdriveState.AlertStatus, + alert_size: log.SelfdriveState.AlertSize, priority: Priority, visual_alert: car.CarControl.HUDControl.VisualAlert, audible_alert: car.CarControl.HUDControl.AudibleAlert, diff --git a/selfdrive/controls/tests/test_alerts.py b/selfdrive/controls/tests/test_alerts.py index 38dc045949..d315d70565 100644 --- a/selfdrive/controls/tests/test_alerts.py +++ b/selfdrive/controls/tests/test_alerts.py @@ -12,7 +12,7 @@ from openpilot.selfdrive.controls.lib.events import Alert, EVENTS, ET from openpilot.selfdrive.controls.lib.alertmanager import set_offroad_alert from openpilot.selfdrive.test.process_replay.process_replay import CONFIGS -AlertSize = log.ControlsState.AlertSize +AlertSize = log.SelfdriveState.AlertSize OFFROAD_ALERTS_PATH = os.path.join(BASEDIR, "selfdrive/controls/lib/alerts_offroad.json") diff --git a/selfdrive/controls/tests/test_startup.py b/selfdrive/controls/tests/test_startup.py index 077d289021..bfe117062e 100644 --- a/selfdrive/controls/tests/test_startup.py +++ b/selfdrive/controls/tests/test_startup.py @@ -59,7 +59,7 @@ CX5_FW_VERSIONS = [ (EventName.startupMaster, TOYOTA.TOYOTA_COROLLA, COROLLA_FW_VERSIONS_FUZZY, "toyota"), ]) def test_startup_alert(expected_event, car_model, fw_versions, brand): - controls_sock = messaging.sub_sock("controlsState") + controls_sock = messaging.sub_sock("selfdriveState") pm = messaging.PubMaster(['can', 'pandaStates']) params = Params() @@ -114,7 +114,7 @@ def test_startup_alert(expected_event, car_model, fw_versions, brand): ctrls = messaging.drain_sock(controls_sock) if len(ctrls): - event_name = ctrls[0].controlsState.alertType.split("/")[0] + event_name = ctrls[0].selfdriveState.alertType.split("/")[0] assert EVENT_NAME[expected_event] == event_name, f"expected {EVENT_NAME[expected_event]} for '{car_model}', got {event_name}" break else: diff --git a/selfdrive/controls/tests/test_state_machine.py b/selfdrive/controls/tests/test_state_machine.py index a480aa8d2b..3926b88eb2 100644 --- a/selfdrive/controls/tests/test_state_machine.py +++ b/selfdrive/controls/tests/test_state_machine.py @@ -6,7 +6,7 @@ from openpilot.selfdrive.controls.controlsd import Controls, SOFT_DISABLE_TIME from openpilot.selfdrive.controls.lib.events import Events, ET, Alert, Priority, AlertSize, AlertStatus, VisualAlert, \ AudibleAlert, EVENTS -State = log.ControlsState.OpenpilotState +State = log.SelfdriveState.OpenpilotState # The event types that maintain the current state MAINTAIN_STATES = {State.enabled: (None,), State.disabled: (None,), State.softDisabling: (ET.SOFT_DISABLE,), diff --git a/selfdrive/debug/cycle_alerts.py b/selfdrive/debug/cycle_alerts.py index afd3fb9a25..6ab9ab8733 100755 --- a/selfdrive/debug/cycle_alerts.py +++ b/selfdrive/debug/cycle_alerts.py @@ -57,7 +57,7 @@ def cycle_alerts(duration=200, is_metric=False): 'driverMonitoringState', 'longitudinalPlan', 'livePose', 'managerState'] + cameras) - pm = messaging.PubMaster(['controlsState', 'pandaStates', 'deviceState']) + pm = messaging.PubMaster(['selfdriveState', 'pandaStates', 'deviceState']) events = Events() AM = AlertManager() @@ -100,17 +100,17 @@ def cycle_alerts(duration=200, is_metric=False): print(alert) for _ in range(duration): dat = messaging.new_message() - dat.init('controlsState') - dat.controlsState.enabled = False + dat.init('selfdriveState') + dat.selfdriveState.enabled = False if alert: - dat.controlsState.alertText1 = alert.alert_text_1 - dat.controlsState.alertText2 = alert.alert_text_2 - dat.controlsState.alertSize = alert.alert_size - dat.controlsState.alertStatus = alert.alert_status - dat.controlsState.alertType = alert.alert_type - dat.controlsState.alertSound = alert.audible_alert - pm.send('controlsState', dat) + dat.selfdriveState.alertText1 = alert.alert_text_1 + dat.selfdriveState.alertText2 = alert.alert_text_2 + dat.selfdriveState.alertSize = alert.alert_size + dat.selfdriveState.alertStatus = alert.alert_status + dat.selfdriveState.alertType = alert.alert_type + dat.selfdriveState.alertSound = alert.audible_alert + pm.send('selfdriveState', dat) dat = messaging.new_message() dat.init('deviceState') diff --git a/selfdrive/test/process_replay/migration.py b/selfdrive/test/process_replay/migration.py index 52ed82a7cc..c1f60959e2 100644 --- a/selfdrive/test/process_replay/migration.py +++ b/selfdrive/test/process_replay/migration.py @@ -15,6 +15,7 @@ def migrate_all(lr, old_logtime=False, manager_states=False, panda_states=False, msgs = migrate_gpsLocation(msgs) msgs = migrate_deviceState(msgs) msgs = migrate_carOutput(msgs) + msgs = migrate_selfdriveState(msgs) if manager_states: msgs = migrate_managerState(msgs) if panda_states: @@ -26,6 +27,23 @@ def migrate_all(lr, old_logtime=False, manager_states=False, panda_states=False, return msgs +def migrate_selfdriveState(lr): + ret = [] + for msg in lr: + if msg.which() == 'controlsState': + m = messaging.new_message('selfdriveState') + m.valid = msg.valid + m.logMonoTime = msg.logMonoTime + ss = m.selfdriveState + for field in ("enabled", "active", "state", "engageable", "alertText1", "alertText2", + "alertStatus", "alertSize", "alertType", "alertSound", "experimentalMode", + "personality"): + setattr(ss, field, getattr(msg.controlsState, field)) + ret.append(m.as_reader()) + ret.append(msg) + return ret + + def migrate_managerState(lr): all_msgs = [] for msg in lr: diff --git a/selfdrive/test/process_replay/process_replay.py b/selfdrive/test/process_replay/process_replay.py index 7997612e25..c11f684690 100755 --- a/selfdrive/test/process_replay/process_replay.py +++ b/selfdrive/test/process_replay/process_replay.py @@ -489,7 +489,7 @@ CONFIGS = [ "testJoystick", "liveTorqueParameters", "accelerometer", "gyroscope", "carOutput", "gpsLocationExternal", "gpsLocation", ], - subs=["controlsState", "carControl", "onroadEvents"], + subs=["selfdriveState", "controlsState", "carControl", "onroadEvents"], ignore=["logMonoTime", "controlsState.startMonoTime", "controlsState.cumLagMs"], config_callback=controlsd_config_callback, init_callback=get_car_params_callback, diff --git a/selfdrive/test/process_replay/ref_commit b/selfdrive/test/process_replay/ref_commit index e2bd658ef5..5ed9bddaed 100644 --- a/selfdrive/test/process_replay/ref_commit +++ b/selfdrive/test/process_replay/ref_commit @@ -1 +1 @@ -a8b4c81ec1df5135ae448c8273ce14c1a98b1bfc \ No newline at end of file +ab4983de4477d648e5c36447debfd6735dfc466f \ No newline at end of file diff --git a/selfdrive/test/test_onroad.py b/selfdrive/test/test_onroad.py index 63ef2a7a4c..0d6c0ba214 100644 --- a/selfdrive/test/test_onroad.py +++ b/selfdrive/test/test_onroad.py @@ -416,8 +416,8 @@ class TestOnroad: startup_alert = None for msg in self.lrs[0]: # can't use onroadEvents because the first msg can be dropped while loggerd is starting up - if msg.which() == "controlsState": - startup_alert = msg.controlsState.alertText1 + if msg.which() == "selfdriveState": + startup_alert = msg.selfdriveState.alertText1 break expected = EVENTS[car.CarEvent.EventName.startup][ET.PERMANENT].alert_text_1 assert startup_alert == expected, "wrong startup alert" diff --git a/selfdrive/ui/qt/offroad/settings.cc b/selfdrive/ui/qt/offroad/settings.cc index 1c17fdcdf7..fc92a471d6 100644 --- a/selfdrive/ui/qt/offroad/settings.cc +++ b/selfdrive/ui/qt/offroad/settings.cc @@ -111,8 +111,8 @@ TogglesPanel::TogglesPanel(SettingsWindow *parent) : ListWidget(parent) { void TogglesPanel::updateState(const UIState &s) { const SubMaster &sm = *(s.sm); - if (sm.updated("controlsState")) { - auto personality = sm["controlsState"].getControlsState().getPersonality(); + if (sm.updated("selfdriveState")) { + auto personality = sm["selfdriveState"].getSelfdriveState().getPersonality(); if (personality != s.scene.personality && s.scene.started && isVisible()) { long_personality_setting->setCheckedButton(static_cast(personality)); } diff --git a/selfdrive/ui/qt/onroad/alerts.cc b/selfdrive/ui/qt/onroad/alerts.cc index 0235c5ff42..d5d2e6c0de 100644 --- a/selfdrive/ui/qt/onroad/alerts.cc +++ b/selfdrive/ui/qt/onroad/alerts.cc @@ -19,8 +19,8 @@ void OnroadAlerts::clear() { } OnroadAlerts::Alert OnroadAlerts::getAlert(const SubMaster &sm, uint64_t started_frame) { - const cereal::ControlsState::Reader &cs = sm["controlsState"].getControlsState(); - const uint64_t controls_frame = sm.rcv_frame("controlsState"); + const cereal::SelfdriveState::Reader &cs = sm["selfdriveState"].getSelfdriveState(); + const uint64_t controls_frame = sm.rcv_frame("selfdriveState"); Alert a = {}; if (controls_frame >= started_frame) { // Don't get old alert. @@ -28,26 +28,26 @@ OnroadAlerts::Alert OnroadAlerts::getAlert(const SubMaster &sm, uint64_t started cs.getAlertType().cStr(), cs.getAlertSize(), cs.getAlertStatus()}; } - if (!sm.updated("controlsState") && (sm.frame - started_frame) > 5 * UI_FREQ) { + if (!sm.updated("selfdriveState") && (sm.frame - started_frame) > 5 * UI_FREQ) { const int CONTROLS_TIMEOUT = 5; - const int controls_missing = (nanos_since_boot() - sm.rcv_time("controlsState")) / 1e9; + const int controls_missing = (nanos_since_boot() - sm.rcv_time("selfdriveState")) / 1e9; // Handle controls timeout if (controls_frame < started_frame) { - // car is started, but controlsState hasn't been seen at all + // car is started, but selfdriveState hasn't been seen at all a = {tr("openpilot Unavailable"), tr("Waiting for controls to start"), - "controlsWaiting", cereal::ControlsState::AlertSize::MID, - cereal::ControlsState::AlertStatus::NORMAL}; + "controlsWaiting", cereal::SelfdriveState::AlertSize::MID, + cereal::SelfdriveState::AlertStatus::NORMAL}; } else if (controls_missing > CONTROLS_TIMEOUT && !Hardware::PC()) { // car is started, but controls is lagging or died if (cs.getEnabled() && (controls_missing - CONTROLS_TIMEOUT) < 10) { a = {tr("TAKE CONTROL IMMEDIATELY"), tr("Controls Unresponsive"), - "controlsUnresponsive", cereal::ControlsState::AlertSize::FULL, - cereal::ControlsState::AlertStatus::CRITICAL}; + "controlsUnresponsive", cereal::SelfdriveState::AlertSize::FULL, + cereal::SelfdriveState::AlertStatus::CRITICAL}; } else { a = {tr("Controls Unresponsive"), tr("Reboot Device"), - "controlsUnresponsivePermanent", cereal::ControlsState::AlertSize::MID, - cereal::ControlsState::AlertStatus::NORMAL}; + "controlsUnresponsivePermanent", cereal::SelfdriveState::AlertSize::MID, + cereal::SelfdriveState::AlertStatus::NORMAL}; } } } @@ -55,19 +55,19 @@ OnroadAlerts::Alert OnroadAlerts::getAlert(const SubMaster &sm, uint64_t started } void OnroadAlerts::paintEvent(QPaintEvent *event) { - if (alert.size == cereal::ControlsState::AlertSize::NONE) { + if (alert.size == cereal::SelfdriveState::AlertSize::NONE) { return; } - static std::map alert_heights = { - {cereal::ControlsState::AlertSize::SMALL, 271}, - {cereal::ControlsState::AlertSize::MID, 420}, - {cereal::ControlsState::AlertSize::FULL, height()}, + static std::map alert_heights = { + {cereal::SelfdriveState::AlertSize::SMALL, 271}, + {cereal::SelfdriveState::AlertSize::MID, 420}, + {cereal::SelfdriveState::AlertSize::FULL, height()}, }; int h = alert_heights[alert.size]; int margin = 40; int radius = 30; - if (alert.size == cereal::ControlsState::AlertSize::FULL) { + if (alert.size == cereal::SelfdriveState::AlertSize::FULL) { margin = 0; radius = 0; } @@ -94,15 +94,15 @@ void OnroadAlerts::paintEvent(QPaintEvent *event) { const QPoint c = r.center(); p.setPen(QColor(0xff, 0xff, 0xff)); p.setRenderHint(QPainter::TextAntialiasing); - if (alert.size == cereal::ControlsState::AlertSize::SMALL) { + if (alert.size == cereal::SelfdriveState::AlertSize::SMALL) { p.setFont(InterFont(74, QFont::DemiBold)); p.drawText(r, Qt::AlignCenter, alert.text1); - } else if (alert.size == cereal::ControlsState::AlertSize::MID) { + } else if (alert.size == cereal::SelfdriveState::AlertSize::MID) { p.setFont(InterFont(88, QFont::Bold)); p.drawText(QRect(0, c.y() - 125, width(), 150), Qt::AlignHCenter | Qt::AlignTop, alert.text1); p.setFont(InterFont(66)); p.drawText(QRect(0, c.y() + 21, width(), 90), Qt::AlignHCenter, alert.text2); - } else if (alert.size == cereal::ControlsState::AlertSize::FULL) { + } else if (alert.size == cereal::SelfdriveState::AlertSize::FULL) { bool l = alert.text1.length() > 15; p.setFont(InterFont(l ? 132 : 177, QFont::Bold)); p.drawText(QRect(0, r.y() + (l ? 240 : 270), width(), 600), Qt::AlignHCenter | Qt::TextWordWrap, alert.text1); diff --git a/selfdrive/ui/qt/onroad/alerts.h b/selfdrive/ui/qt/onroad/alerts.h index 1f76ba305b..de38d8ffc3 100644 --- a/selfdrive/ui/qt/onroad/alerts.h +++ b/selfdrive/ui/qt/onroad/alerts.h @@ -17,18 +17,18 @@ protected: QString text1; QString text2; QString type; - cereal::ControlsState::AlertSize size; - cereal::ControlsState::AlertStatus status; + cereal::SelfdriveState::AlertSize size; + cereal::SelfdriveState::AlertStatus status; bool equal(const Alert &other) const { return text1 == other.text1 && text2 == other.text2 && type == other.type; } }; - const QMap alert_colors = { - {cereal::ControlsState::AlertStatus::NORMAL, QColor(0x15, 0x15, 0x15, 0xf1)}, - {cereal::ControlsState::AlertStatus::USER_PROMPT, QColor(0xDA, 0x6F, 0x25, 0xf1)}, - {cereal::ControlsState::AlertStatus::CRITICAL, QColor(0xC9, 0x22, 0x31, 0xf1)}, + const QMap alert_colors = { + {cereal::SelfdriveState::AlertStatus::NORMAL, QColor(0x15, 0x15, 0x15, 0xf1)}, + {cereal::SelfdriveState::AlertStatus::USER_PROMPT, QColor(0xDA, 0x6F, 0x25, 0xf1)}, + {cereal::SelfdriveState::AlertStatus::CRITICAL, QColor(0xC9, 0x22, 0x31, 0xf1)}, }; void paintEvent(QPaintEvent*) override; diff --git a/selfdrive/ui/qt/onroad/annotated_camera.cc b/selfdrive/ui/qt/onroad/annotated_camera.cc index 865b2599cc..3eb74c9bfc 100644 --- a/selfdrive/ui/qt/onroad/annotated_camera.cc +++ b/selfdrive/ui/qt/onroad/annotated_camera.cc @@ -48,7 +48,7 @@ void AnnotatedCameraWidget::updateState(const UIState &s) { speed *= is_metric ? MS_TO_KPH : MS_TO_MPH; speedUnit = is_metric ? tr("km/h") : tr("mph"); - hideBottomIcons = (cs.getAlertSize() != cereal::ControlsState::AlertSize::NONE); + hideBottomIcons = (sm["selfdriveState"].getSelfdriveState().getAlertSize() != cereal::SelfdriveState::AlertSize::NONE); status = s.status; // update engageability/experimental mode button @@ -170,7 +170,7 @@ void AnnotatedCameraWidget::drawLaneLines(QPainter &painter, const UIState *s) { // paint path QLinearGradient bg(0, height(), 0, 0); - if (sm["controlsState"].getControlsState().getExperimentalMode()) { + if (sm["selfdriveState"].getSelfdriveState().getExperimentalMode()) { // The first half of track_vertices are the points for the right side of the path const auto &acceleration = sm["modelV2"].getModelV2().getAcceleration().getX(); const int max_len = std::min(scene.track_vertices.length() / 2, acceleration.size()); @@ -318,7 +318,7 @@ void AnnotatedCameraWidget::paintGL() { } else if (v_ego > 15) { wide_cam_requested = false; } - wide_cam_requested = wide_cam_requested && sm["controlsState"].getControlsState().getExperimentalMode(); + wide_cam_requested = wide_cam_requested && sm["selfdriveState"].getSelfdriveState().getExperimentalMode(); // for replay of old routes, never go to widecam wide_cam_requested = wide_cam_requested && s->scene.calibration_wide_valid; } diff --git a/selfdrive/ui/qt/onroad/buttons.cc b/selfdrive/ui/qt/onroad/buttons.cc index 92bcea11b5..2c2cc672b9 100644 --- a/selfdrive/ui/qt/onroad/buttons.cc +++ b/selfdrive/ui/qt/onroad/buttons.cc @@ -33,7 +33,7 @@ void ExperimentalButton::changeMode() { } void ExperimentalButton::updateState(const UIState &s) { - const auto cs = (*s.sm)["controlsState"].getControlsState(); + const auto cs = (*s.sm)["selfdriveState"].getSelfdriveState(); bool eng = cs.getEngageable() || cs.getEnabled(); if ((cs.getExperimentalMode() != experimental_mode) || (eng != engageable)) { engageable = eng; diff --git a/selfdrive/ui/soundd.py b/selfdrive/ui/soundd.py index 0550a7db9e..4055fcfd35 100644 --- a/selfdrive/ui/soundd.py +++ b/selfdrive/ui/soundd.py @@ -41,10 +41,10 @@ sound_list: dict[int, tuple[str, int | None, float]] = { } def check_controls_timeout_alert(sm): - controls_missing = time.monotonic() - sm.recv_time['controlsState'] + controls_missing = time.monotonic() - sm.recv_time['selfdriveState'] if controls_missing > CONTROLS_TIMEOUT: - if sm['controlsState'].enabled and (controls_missing - CONTROLS_TIMEOUT) < 10: + if sm['selfdriveState'].enabled and (controls_missing - CONTROLS_TIMEOUT) < 10: return True return False @@ -111,8 +111,8 @@ class Soundd: self.current_sound_frame = 0 def get_audible_alert(self, sm): - if sm.updated['controlsState']: - new_alert = sm['controlsState'].alertSound.raw + if sm.updated['selfdriveState']: + new_alert = sm['selfdriveState'].alertSound.raw self.update_alert(new_alert) elif check_controls_timeout_alert(sm): self.update_alert(AudibleAlert.warningImmediate) @@ -136,7 +136,7 @@ class Soundd: # sounddevice must be imported after forking processes import sounddevice as sd - sm = messaging.SubMaster(['controlsState', 'microphone']) + sm = messaging.SubMaster(['selfdriveState', 'microphone']) with self.get_stream(sd) as stream: rk = Ratekeeper(20) diff --git a/selfdrive/ui/tests/test_soundd.py b/selfdrive/ui/tests/test_soundd.py index 468bc92cca..f40af8696a 100644 --- a/selfdrive/ui/tests/test_soundd.py +++ b/selfdrive/ui/tests/test_soundd.py @@ -10,14 +10,14 @@ AudibleAlert = car.CarControl.HUDControl.AudibleAlert class TestSoundd: def test_check_controls_timeout_alert(self): - sm = SubMaster(['controlsState']) - pm = PubMaster(['controlsState']) + sm = SubMaster(['selfdriveState']) + pm = PubMaster(['selfdriveState']) for _ in range(100): - cs = messaging.new_message('controlsState') - cs.controlsState.enabled = True + cs = messaging.new_message('selfdriveState') + cs.selfdriveState.enabled = True - pm.send("controlsState", cs) + pm.send("selfdriveState", cs) time.sleep(0.01) diff --git a/selfdrive/ui/tests/test_ui/run.py b/selfdrive/ui/tests/test_ui/run.py index 5a05b1f28a..0ab11d57b0 100644 --- a/selfdrive/ui/tests/test_ui/run.py +++ b/selfdrive/ui/tests/test_ui/run.py @@ -16,6 +16,7 @@ from cereal.messaging import SubMaster, PubMaster from openpilot.common.params import Params from openpilot.common.transformations.camera import CameraConfig, DEVICE_CAMERAS from openpilot.selfdrive.test.helpers import with_processes +from openpilot.selfdrive.test.process_replay.migration import migrate_selfdriveState from openpilot.tools.lib.logreader import LogReader from openpilot.tools.lib.framereader import FrameReader from openpilot.tools.lib.route import Route @@ -25,7 +26,7 @@ TEST_ROUTE = "a2a0ccea32023010|2023-07-27--13-01-19" STREAMS: list[tuple[VisionStreamType, CameraConfig, bytes]] = [] DATA: dict[str, capnp.lib.capnp._DynamicStructBuilder] = dict.fromkeys( - ["deviceState", "pandaStates", "controlsState", "liveCalibration", + ["deviceState", "pandaStates", "selfdriveState", "liveCalibration", "modelV2", "radarState", "driverMonitoringState", "carState", "driverStateV2", "roadCameraState", "wideRoadCameraState", "driverCameraState"], None) @@ -67,7 +68,7 @@ def setup_onroad(click, pm: PubMaster): time.sleep(0.05) def setup_onroad_wide(click, pm: PubMaster): - DATA['controlsState'].controlsState.experimentalMode = True + DATA['selfdriveState'].selfdriveState.experimentalMode = True DATA["carState"].carState.vEgo = 1 setup_onroad(click, pm) @@ -86,26 +87,26 @@ def setup_driver_camera(click, pm: PubMaster): setup_onroad(click, pm) DATA['deviceState'].deviceState.started = True -def setup_onroad_alert(click, pm: PubMaster, text1, text2, size, status=log.ControlsState.AlertStatus.normal): +def setup_onroad_alert(click, pm: PubMaster, text1, text2, size, status=log.SelfdriveState.AlertStatus.normal): print(f'setup onroad alert, size: {size}') setup_onroad(click, pm) - dat = messaging.new_message('controlsState') - cs = dat.controlsState + dat = messaging.new_message('selfdriveState') + cs = dat.selfdriveState cs.alertText1 = text1 cs.alertText2 = text2 cs.alertSize = size cs.alertStatus = status cs.alertType = "test_onroad_alert" - pm.send('controlsState', dat) + pm.send('selfdriveState', dat) def setup_onroad_alert_small(click, pm: PubMaster): - setup_onroad_alert(click, pm, 'This is a small alert message', '', log.ControlsState.AlertSize.small) + setup_onroad_alert(click, pm, 'This is a small alert message', '', log.SelfdriveState.AlertSize.small) def setup_onroad_alert_mid(click, pm: PubMaster): - setup_onroad_alert(click, pm, 'Medium Alert', 'This is a medium alert message', log.ControlsState.AlertSize.mid) + setup_onroad_alert(click, pm, 'Medium Alert', 'This is a medium alert message', log.SelfdriveState.AlertSize.mid) def setup_onroad_alert_full(click, pm: PubMaster): - setup_onroad_alert(click, pm, 'Full Alert', 'This is a full alert message', log.ControlsState.AlertSize.full) + setup_onroad_alert(click, pm, 'Full Alert', 'This is a full alert message', log.SelfdriveState.AlertSize.full) CASES = { "homescreen": setup_homescreen, @@ -192,7 +193,7 @@ def create_screenshots(): segnum = 2 lr = LogReader(route.qlog_paths()[segnum]) - for event in lr: + for event in migrate_selfdriveState(lr): if event.which() in DATA: DATA[event.which()] = event.as_builder() diff --git a/selfdrive/ui/ui.cc b/selfdrive/ui/ui.cc index 19ea61f15a..8613eb2f2f 100644 --- a/selfdrive/ui/ui.cc +++ b/selfdrive/ui/ui.cc @@ -217,13 +217,13 @@ void ui_update_params(UIState *s) { } void UIState::updateStatus() { - if (scene.started && sm->updated("controlsState")) { - auto controls_state = (*sm)["controlsState"].getControlsState(); - auto state = controls_state.getState(); - if (state == cereal::ControlsState::OpenpilotState::PRE_ENABLED || state == cereal::ControlsState::OpenpilotState::OVERRIDING) { + if (scene.started && sm->updated("selfdriveState")) { + auto ss = (*sm)["selfdriveState"].getSelfdriveState(); + auto state = ss .getState(); + if (state == cereal::SelfdriveState::OpenpilotState::PRE_ENABLED || state == cereal::SelfdriveState::OpenpilotState::OVERRIDING) { status = STATUS_OVERRIDE; } else { - status = controls_state.getEnabled() ? STATUS_ENGAGED : STATUS_DISENGAGED; + status = ss.getEnabled() ? STATUS_ENGAGED : STATUS_DISENGAGED; } } @@ -243,7 +243,7 @@ UIState::UIState(QObject *parent) : QObject(parent) { sm = std::make_unique(std::vector{ "modelV2", "controlsState", "liveCalibration", "radarState", "deviceState", "pandaStates", "carParams", "driverMonitoringState", "carState", "driverStateV2", - "wideRoadCameraState", "managerState", "clocks", + "wideRoadCameraState", "managerState", "selfdriveState", }); Params params; diff --git a/selfdrive/ui/ui.h b/selfdrive/ui/ui.h index 4efdad8ac0..2e3bd3927f 100644 --- a/selfdrive/ui/ui.h +++ b/selfdrive/ui/ui.h @@ -110,7 +110,7 @@ public: UIState(QObject* parent = 0); void updateStatus(); inline bool engaged() const { - return scene.started && (*sm)["controlsState"].getControlsState().getEnabled(); + return scene.started && (*sm)["selfdriveState"].getSelfdriveState().getEnabled(); } void setPrimeType(PrimeType type); diff --git a/tools/cabana/videowidget.cc b/tools/cabana/videowidget.cc index 8d2f8674b3..899023f2c7 100644 --- a/tools/cabana/videowidget.cc +++ b/tools/cabana/videowidget.cc @@ -279,9 +279,9 @@ void Slider::parseQLog(std::shared_ptr qlog) { } } else if (e.which == cereal::Event::Which::CONTROLS_STATE) { capnp::FlatArrayMessageReader reader(e.data); - auto cs = reader.getRoot().getControlsState(); + auto cs = reader.getRoot().getSelfdriveState(); if (cs.getAlertType().size() > 0 && cs.getAlertText1().size() > 0 && - cs.getAlertSize() != cereal::ControlsState::AlertSize::NONE) { + cs.getAlertSize() != cereal::SelfdriveState::AlertSize::NONE) { std::lock_guard lk(mutex); alerts.emplace(e.mono_time, AlertInfo{cs.getAlertStatus(), cs.getAlertText1().cStr(), cs.getAlertText2().cStr()}); } @@ -397,9 +397,9 @@ void InfoLabel::paintEvent(QPaintEvent *event) { } if (alert_info.text1.size() > 0) { QColor color = timeline_colors[(int)TimelineType::AlertInfo]; - if (alert_info.status == cereal::ControlsState::AlertStatus::USER_PROMPT) { + if (alert_info.status == cereal::SelfdriveState::AlertStatus::USER_PROMPT) { color = timeline_colors[(int)TimelineType::AlertWarning]; - } else if (alert_info.status == cereal::ControlsState::AlertStatus::CRITICAL) { + } else if (alert_info.status == cereal::SelfdriveState::AlertStatus::CRITICAL) { color = timeline_colors[(int)TimelineType::AlertCritical]; } color.setAlphaF(0.5); diff --git a/tools/cabana/videowidget.h b/tools/cabana/videowidget.h index 1e793e9d1d..76364083a8 100644 --- a/tools/cabana/videowidget.h +++ b/tools/cabana/videowidget.h @@ -18,7 +18,7 @@ #include "tools/replay/logreader.h" struct AlertInfo { - cereal::ControlsState::AlertStatus status; + cereal::SelfdriveState::AlertStatus status; QString text1; QString text2; }; diff --git a/tools/replay/replay.cc b/tools/replay/replay.cc index 4fea879f8b..b7c55294fd 100644 --- a/tools/replay/replay.cc +++ b/tools/replay/replay.cc @@ -153,15 +153,15 @@ void Replay::buildTimeline() { uint64_t engaged_begin = 0; bool engaged = false; - auto alert_status = cereal::ControlsState::AlertStatus::NORMAL; - auto alert_size = cereal::ControlsState::AlertSize::NONE; + auto alert_status = cereal::SelfdriveState::AlertStatus::NORMAL; + auto alert_size = cereal::SelfdriveState::AlertSize::NONE; uint64_t alert_begin = 0; std::string alert_type; const TimelineType timeline_types[] = { - [(int)cereal::ControlsState::AlertStatus::NORMAL] = TimelineType::AlertInfo, - [(int)cereal::ControlsState::AlertStatus::USER_PROMPT] = TimelineType::AlertWarning, - [(int)cereal::ControlsState::AlertStatus::CRITICAL] = TimelineType::AlertCritical, + [(int)cereal::SelfdriveState::AlertStatus::NORMAL] = TimelineType::AlertInfo, + [(int)cereal::SelfdriveState::AlertStatus::USER_PROMPT] = TimelineType::AlertWarning, + [(int)cereal::SelfdriveState::AlertStatus::CRITICAL] = TimelineType::AlertCritical, }; const auto &route_segments = route_->segments(); @@ -174,7 +174,7 @@ void Replay::buildTimeline() { if (e.which == cereal::Event::Which::CONTROLS_STATE) { capnp::FlatArrayMessageReader reader(e.data); auto event = reader.getRoot(); - auto cs = event.getControlsState(); + auto cs = event.getSelfdriveState(); if (engaged != cs.getEnabled()) { if (engaged) { @@ -185,7 +185,7 @@ void Replay::buildTimeline() { } if (alert_type != cs.getAlertType().cStr() || alert_status != cs.getAlertStatus()) { - if (!alert_type.empty() && alert_size != cereal::ControlsState::AlertSize::NONE) { + if (!alert_type.empty() && alert_size != cereal::SelfdriveState::AlertSize::NONE) { timeline.push_back({toSeconds(alert_begin), toSeconds(e.mono_time), timeline_types[(int)alert_status]}); } alert_begin = e.mono_time; @@ -202,7 +202,7 @@ void Replay::buildTimeline() { if (engaged) { timeline.push_back({toSeconds(engaged_begin), toSeconds(log->events.back().mono_time), TimelineType::Engaged}); } - if (!alert_type.empty() && alert_size != cereal::ControlsState::AlertSize::NONE) { + if (!alert_type.empty() && alert_size != cereal::SelfdriveState::AlertSize::NONE) { timeline.push_back({toSeconds(alert_begin), toSeconds(log->events.back().mono_time), timeline_types[(int)alert_status]}); }