alka - init

This commit is contained in:
Rick Lan
2025-03-31 11:59:01 +08:00
parent c7b91221ff
commit 0545016dde
21 changed files with 62 additions and 16 deletions

View File

@@ -10,7 +10,8 @@ $Cxx.namespace("cereal");
# DO rename the structs
# DON'T change the identifier (e.g. @0x81c2f05a394cf4af)
struct CustomReserved0 @0x81c2f05a394cf4af {
struct DpControlsState @0x81c2f05a394cf4af {
alkaActive @0 :Bool;
}
struct CustomReserved1 @0xaedffd8f31e7b55d {

View File

@@ -2576,7 +2576,7 @@ struct Event {
# DO change the name of the field and struct
# DON'T change the ID (e.g. @107)
# DON'T change which struct it points to
customReserved0 @107 :Custom.CustomReserved0;
dpControlsState @107 :Custom.DpControlsState;
customReserved1 @108 :Custom.CustomReserved1;
customReserved2 @109 :Custom.CustomReserved2;
customReserved3 @110 :Custom.CustomReserved3;

View File

@@ -91,6 +91,7 @@ _services: dict[str, tuple] = {
"customReservedRawData0": (True, 0.),
"customReservedRawData1": (True, 0.),
"customReservedRawData2": (True, 0.),
"dpControlsState": (False, 100., 10),
}
SERVICE_LIST = {name: Service(*vals) for
idx, (name, vals) in enumerate(_services.items())}

View File

@@ -119,4 +119,5 @@ inline static std::unordered_map<std::string, uint32_t> keys = {
{"Version", PERSISTENT},
{"dp_device_last_log", CLEAR_ON_MANAGER_START},
{"dp_device_reset_conf", CLEAR_ON_MANAGER_START},
{"dp_lat_alka", PERSISTENT},
};

View File

@@ -60,7 +60,7 @@ class CarController(CarControllerBase):
# Below are the HUD messages. We copy the stock message and modify
if self.CP.carFingerprint != CAR.NISSAN_ALTIMA:
if self.frame % 2 == 0:
can_sends.append(nissancan.create_lkas_hud_msg(self.packer, CS.lkas_hud_msg, CC.enabled, hud_control.leftLaneVisible, hud_control.rightLaneVisible,
can_sends.append(nissancan.create_lkas_hud_msg(self.packer, CS.lkas_hud_msg, CC.latActive, hud_control.leftLaneVisible, hud_control.rightLaneVisible,
hud_control.leftLaneDepart, hud_control.rightLaneDepart))
if self.frame % 50 == 0:

View File

@@ -20,4 +20,5 @@ CarControlT = capnp.lib.capnp._StructModule
CarParamsT = capnp.lib.capnp._StructModule
class DPFlags:
LateralALKA = 1
pass

View File

@@ -266,7 +266,7 @@ class CarController(CarControllerBase):
if self.frame % 20 == 0 or send_ui:
can_sends.append(toyotacan.create_ui_command(self.packer, steer_alert, pcm_cancel_cmd, hud_control.leftLaneVisible,
hud_control.rightLaneVisible, hud_control.leftLaneDepart,
hud_control.rightLaneDepart, CC.enabled, CS.lkas_hud))
hud_control.rightLaneDepart, lat_active, CS.lkas_hud))
if (self.frame % 100 == 0 or send_ui) and (self.CP.enableDsu or self.CP.flags & ToyotaFlags.DISABLE_RADAR.value):
can_sends.append(toyotacan.create_fcw_command(self.packer, fcw_alert))

View File

@@ -76,6 +76,8 @@ class ToyotaFlags(IntFlag):
RAISED_ACCEL_LIMIT = 1024
SECOC = 2048
ALKA = 2 ** 12
class Footnote(Enum):
CAMRY = CarFootnote(
"openpilot operates above 28mph for Camry 4CYL L, 4CYL LE and 4CYL SE which don't have Full-Speed Range Dynamic Radar Cruise Control.",

View File

@@ -9,3 +9,5 @@ class ALTERNATIVE_EXPERIENCE:
DISABLE_STOCK_AEB = 2
RAISE_LONGITUDINAL_LIMITS_TO_ISO_MAX = 8
ALLOW_AEB = 16
ALKA = 2 ** 10

View File

@@ -641,8 +641,9 @@ bool longitudinal_brake_checks(int desired_brake, const LongitudinalLimits limit
bool steer_torque_cmd_checks(int desired_torque, int steer_req, const TorqueSteeringLimits limits) {
bool violation = false;
uint32_t ts = microsecond_timer_get();
bool alka = (alternative_experience & ALT_EXP_ALKA) != 0;
if (controls_allowed) {
if (controls_allowed || alka) {
// *** global torque limit check ***
violation |= max_limit_check(desired_torque, limits.max_steer, -limits.max_steer);
@@ -669,7 +670,7 @@ bool steer_torque_cmd_checks(int desired_torque, int steer_req, const TorqueStee
}
// no torque if controls is not allowed
if (!controls_allowed && (desired_torque != 0)) {
if (!(controls_allowed || alka) && (desired_torque != 0)) {
violation = true;
}
@@ -711,7 +712,7 @@ bool steer_torque_cmd_checks(int desired_torque, int steer_req, const TorqueStee
}
// reset to 0 if either controls is not allowed or there's a violation
if (violation || !controls_allowed) {
if (violation || !(controls_allowed || alka)) {
valid_steer_req_count = 0;
invalid_steer_req_count = 0;
desired_torque_last = 0;
@@ -727,7 +728,9 @@ bool steer_torque_cmd_checks(int desired_torque, int steer_req, const TorqueStee
bool steer_angle_cmd_checks(int desired_angle, bool steer_control_enabled, const AngleSteeringLimits limits) {
bool violation = false;
if (controls_allowed && steer_control_enabled) {
bool alka = (alternative_experience & ALT_EXP_ALKA) != 0;
if ((controls_allowed || alka) && steer_control_enabled) {
// convert floating point angle rate limits to integers in the scale of the desired angle on CAN,
// add 1 to not false trigger the violation. also fudge the speed by 1 m/s so rate limits are
// always slightly above openpilot's in case we read an updated speed in between angle commands
@@ -814,7 +817,7 @@ bool steer_angle_cmd_checks(int desired_angle, bool steer_control_enabled, const
}
// No angle control allowed when controls are not allowed
violation |= !controls_allowed && steer_control_enabled;
violation |= !(controls_allowed || alka) && steer_control_enabled;
return violation;
}

View File

@@ -242,8 +242,9 @@ static bool honda_tx_hook(const CANPacket_t *to_send) {
}
// STEER: safety check
bool alka = (alternative_experience & ALT_EXP_ALKA) != 0;
if ((addr == 0xE4) || (addr == 0x194)) {
if (!controls_allowed) {
if (!(controls_allowed || alka)) {
bool steer_applied = GET_BYTE(to_send, 0) | GET_BYTE(to_send, 1);
if (steer_applied) {
tx = false;

View File

@@ -255,6 +255,8 @@ extern struct sample_t angle_meas; // last 6 steer angles/curvatures
// This flag allows AEB to be commanded from openpilot.
#define ALT_EXP_ALLOW_AEB 16
#define ALT_EXP_ALKA 1024
extern int alternative_experience;
// time since safety mode has been changed

View File

@@ -99,6 +99,9 @@ class Car:
with car.CarParams.from_bytes(cached_params_raw) as _cached_params:
cached_params = _cached_params
if self.params.get_bool("dp_lat_alka"):
dp_params |= structs.DPFlags.LateralALKA
self.CI = get_car(*self.can_callbacks, obd_callback(self.params), experimental_long_allowed, num_pandas, dp_params, cached_params)
self.RI = interfaces[self.CI.CP.carFingerprint].RadarInterface(self.CI.CP)
self.CP = self.CI.CP
@@ -115,6 +118,9 @@ class Car:
if not disengage_on_accelerator:
self.CP.alternativeExperience |= ALTERNATIVE_EXPERIENCE.DISABLE_DISENGAGE_ON_GAS
if dp_params & structs.DPFlags.LateralALKA:
self.CP.alternativeExperience |= ALTERNATIVE_EXPERIENCE.ALKA
openpilot_enabled_toggle = self.params.get_bool("OpenpilotEnabledToggle")
controller_available = self.CI.CC is not None and openpilot_enabled_toggle and not self.CP.dashcamOnly

View File

@@ -38,7 +38,7 @@ class Controls:
self.sm = messaging.SubMaster(['liveParameters', 'liveTorqueParameters', 'modelV2', 'selfdriveState',
'liveCalibration', 'livePose', 'longitudinalPlan', 'carState', 'carOutput',
'driverMonitoringState', 'onroadEvents', 'driverAssistance'], poll='selfdriveState')
self.pm = messaging.PubMaster(['carControl', 'controlsState'])
self.pm = messaging.PubMaster(['carControl', 'controlsState', 'dpControlsState'])
self.steer_limited_by_controls = False
self.desired_curvature = 0.0
@@ -56,6 +56,9 @@ class Controls:
elif self.CP.lateralTuning.which() == 'torque':
self.LaC = LatControlTorque(self.CP, self.CI)
self.alka_enabled = self.params.get_bool("dp_lat_alka")
self.alka_active = False
def update(self):
self.sm.update(15)
if self.sm.updated["liveCalibration"]:
@@ -88,7 +91,9 @@ class Controls:
# Check which actuators can be enabled
standstill = abs(CS.vEgo) <= max(self.CP.minSteerSpeed, MIN_LATERAL_CONTROL_SPEED) or CS.standstill
CC.latActive = self.sm['selfdriveState'].active and not CS.steerFaultTemporary and not CS.steerFaultPermanent and not standstill
self.alka_active = self.alka_enabled and CS.cruiseState.available and not standstill and CS.gearShifter != car.CarState.GearShifter.reverse
lat_active = self.sm['selfdriveState'].active or self.alka_active
CC.latActive = lat_active and not CS.steerFaultTemporary and not CS.steerFaultPermanent and not standstill
CC.longActive = CC.enabled and not any(e.overrideLongitudinal for e in self.sm['onroadEvents']) and self.CP.openpilotLongitudinalControl
actuators = CC.actuators
@@ -169,6 +174,13 @@ class Controls:
# TODO: both controlsState and carControl valids should be set by
# sm.all_checks(), but this creates a circular dependency
# dpControlsState
dat = messaging.new_message('dpControlsState')
dat.valid = True
ncs = dat.dpControlsState
ncs.alkaActive = self.alka_active
self.pm.send('dpControlsState', dat)
# controlsState
dat = messaging.new_message('controlsState')
dat.valid = CS.canValid

View File

@@ -58,6 +58,8 @@ class SelfdriveD:
self.car_events = CarSpecificEvents(self.CP)
self.disengage_on_accelerator = not (self.CP.alternativeExperience & ALTERNATIVE_EXPERIENCE.DISABLE_DISENGAGE_ON_GAS)
self.alka = (self.CP.alternativeExperience & ALTERNATIVE_EXPERIENCE.ALKA)
# Setup sockets
self.pm = messaging.PubMaster(['selfdriveState', 'onroadEvents'])
@@ -113,7 +115,7 @@ class SelfdriveD:
self.experimental_mode = False
self.personality = self.read_personality_param()
self.recalibrating_seen = False
self.state_machine = StateMachine()
self.state_machine = StateMachine(self.alka)
self.rk = Ratekeeper(100, print_delay_threshold=None)
# Determine startup event

View File

@@ -9,10 +9,11 @@ ACTIVE_STATES = (State.enabled, State.softDisabling, State.overriding)
ENABLED_STATES = (State.preEnabled, *ACTIVE_STATES)
class StateMachine:
def __init__(self):
def __init__(self, alka = False):
self.current_alert_types = [ET.PERMANENT]
self.state = State.disabled
self.soft_disable_timer = 0
self.alka = alka
def update(self, events: Events):
# decrement the soft disable timer at every step, as it's reset on
@@ -92,7 +93,7 @@ class StateMachine:
# Check if openpilot is engaged and actuators are enabled
enabled = self.state in ENABLED_STATES
active = self.state in ACTIVE_STATES
if active:
if active or self.alka:
self.current_alert_types.append(ET.WARNING)
return enabled, active

View File

@@ -106,6 +106,11 @@ void DPPanel::add_lateral_toggles() {
QString::fromUtf8("🐉 ") + tr("Lateral Ctrl"),
"",
},
{
"dp_lat_alka",
tr("Always-on Lane Keeping Assist (ALKA)"),
"",
},
};
QWidget *label = nullptr;

View File

@@ -47,7 +47,7 @@ void OnroadWindow::updateState(const UIState &s) {
alerts->updateState(s);
nvg->updateState(s);
QColor bgColor = bg_colors[s.status];
QColor bgColor = bg_colors[s.scene.alka_active && s.status == STATUS_DISENGAGED? STATUS_ALKA : s.status];
if (bg != bgColor) {
// repaint border
bg = bgColor;

View File

@@ -60,6 +60,7 @@ static void update_state(UIState *s) {
scene.light_sensor = -1;
}
scene.started = sm["deviceState"].getDeviceState().getStarted() && scene.ignition;
scene.alka_active = sm["dpControlsState"].getDpControlsState().getAlkaActive();
}
void ui_update_params(UIState *s) {
@@ -94,6 +95,7 @@ UIState::UIState(QObject *parent) : QObject(parent) {
"modelV2", "controlsState", "liveCalibration", "radarState", "deviceState",
"pandaStates", "carParams", "driverMonitoringState", "carState", "driverStateV2",
"wideRoadCameraState", "managerState", "selfdriveState", "longitudinalPlan",
"dpControlsState",
});
prime_state = new PrimeState(this);
language = QString::fromStdString(Params().get("LanguageSetting"));

View File

@@ -42,12 +42,14 @@ typedef enum UIStatus {
STATUS_DISENGAGED,
STATUS_OVERRIDE,
STATUS_ENGAGED,
STATUS_ALKA,
} UIStatus;
const QColor bg_colors [] = {
[STATUS_DISENGAGED] = QColor(0x17, 0x33, 0x49, 0xc8),
[STATUS_OVERRIDE] = QColor(0x91, 0x9b, 0x95, 0xf1),
[STATUS_ENGAGED] = QColor(0x17, 0x86, 0x44, 0xf1),
[STATUS_ALKA] = QColor(0x7A, 0x89, 0xA0, 0xf1),
};
typedef struct UIScene {
@@ -60,6 +62,7 @@ typedef struct UIScene {
float light_sensor = -1;
bool started, ignition, is_metric;
uint64_t started_frame;
bool alka_active;
} UIScene;
class UIState : public QObject {

View File

@@ -41,6 +41,7 @@ def manager_init() -> None:
("OpenpilotEnabledToggle", "1"),
("LongitudinalPersonality", str(log.LongitudinalPersonality.standard)),
("DisableLogging", "0"),
("dp_lat_alka", "0"),
]
if params.get_bool("RecordFrontLock"):