Compare commits

...

73 Commits

Author SHA1 Message Date
Your Name
9eee0333ec wip 2024-02-13 14:42:24 -06:00
Your Name
dc1ee37053 wip 2024-02-13 04:20:54 -06:00
Your Name
05c45829f8 wip 2024-02-13 04:13:20 -06:00
Your Name
808fc67534 wip 2024-02-13 04:10:41 -06:00
Your Name
ee9802a513 wip 2024-02-13 04:08:13 -06:00
Your Name
dc9dfa03e9 wip 2024-02-13 04:05:51 -06:00
Your Name
17bc9cf1f3 wip 2024-02-13 04:03:52 -06:00
Your Name
b8aecdb78c wip 2024-02-13 04:02:33 -06:00
Your Name
e2ebe7048c wip 2024-02-13 04:00:11 -06:00
Your Name
794b1d8bdd wip 2024-02-13 03:51:28 -06:00
Your Name
fccc1221f6 wip 2024-02-13 03:29:32 -06:00
Your Name
4bbc34c365 wip 2024-02-13 03:27:24 -06:00
Your Name
589c5dfc82 wip 2024-02-13 03:17:31 -06:00
Your Name
ff80bfe06a wip 2024-02-13 03:13:35 -06:00
Your Name
f1c84854ed wip 2024-02-13 03:11:19 -06:00
Your Name
d6404224fa wip 2024-02-13 03:05:30 -06:00
Your Name
9fd53b7ec1 wip 2024-02-13 03:03:26 -06:00
Your Name
a82120e55e wip 2024-02-13 03:00:54 -06:00
Your Name
99006f0f6c wip 2024-02-13 02:55:03 -06:00
Your Name
0f5573f493 wip 2024-02-13 02:51:20 -06:00
Your Name
73315b7009 wip 2024-02-13 02:02:10 -06:00
Your Name
821d9c5807 wip 2024-02-13 01:59:03 -06:00
Your Name
ebad1a29b2 wip 2024-02-13 01:47:19 -06:00
Your Name
00bef387df wip 2024-02-13 01:28:39 -06:00
Your Name
13db24e327 wip 2024-02-13 01:26:47 -06:00
Your Name
7f7d487723 wip 2024-02-13 01:26:25 -06:00
Your Name
50dd50f0a7 wip 2024-02-13 01:21:51 -06:00
Your Name
3fc6fa0b52 wip 2024-02-13 00:49:09 -06:00
Your Name
412553e741 wip 2024-02-13 00:46:23 -06:00
Your Name
0f7641ea39 wip 2024-02-13 00:35:55 -06:00
Your Name
b98b001ceb wip 2024-02-13 00:25:34 -06:00
Your Name
af0fc9daec wip 2024-02-13 00:22:00 -06:00
Your Name
e10db32b69 wip 2024-02-12 23:34:32 -06:00
Your Name
e034f72f3d wip 2024-02-12 23:10:07 -06:00
Your Name
2803846987 wip 2024-02-12 23:06:10 -06:00
Your Name
9634f1b2e6 wip 2024-02-12 22:48:35 -06:00
Your Name
8f817dffd6 wip 2024-02-12 22:34:07 -06:00
concordia
a380603637 wip 2024-02-12 18:11:57 -06:00
Your Name
9e67df39d3 wip 2024-02-12 14:41:19 -06:00
Your Name
2236323030 wip 2024-02-12 14:36:04 -06:00
concordia
829b75411b wip 2024-02-10 14:46:06 -06:00
Your Name
da6553c24d wip 2024-02-09 17:24:49 -06:00
Your Name
4948aecc6e wip 2024-02-09 16:29:56 -06:00
Your Name
be628a964e wip 2024-02-09 10:13:44 -06:00
Your Name
52c28f6710 wip 2024-02-08 14:55:48 -06:00
Your Name
8d971f0671 wip 2024-02-08 14:50:44 -06:00
Your Name
88785baa11 wip 2024-02-08 14:36:45 -06:00
Your Name
b5fd185742 wip 2024-02-08 14:28:00 -06:00
Your Name
ad5e06b0ad wip 2024-02-08 14:08:25 -06:00
Your Name
96aa4c3e93 wip 2024-02-08 13:03:21 -06:00
Your Name
5307871310 wip 2024-02-08 12:56:22 -06:00
concordia
90b8e9f072 wip 2024-02-08 12:46:30 -06:00
Your Name
7853d218a3 wip 2024-02-06 01:08:15 -06:00
Your Name
f931d2982e wip 2024-02-06 00:13:57 -06:00
concordia
38a3903009 wip 2024-02-06 00:04:33 -06:00
Your Name
2964ede91a wip 2024-02-05 16:25:47 -06:00
Your Name
7949e90b75 wip 2024-02-05 03:05:34 -06:00
Your Name
a7e39e1ccf wip 2024-02-05 02:59:27 -06:00
Your Name
26af5117de wip 2024-02-05 02:59:08 -06:00
Your Name
a8a7c6a20c wip 2024-02-05 02:45:55 -06:00
Your Name
7fb4b58320 wip 2024-02-05 02:36:26 -06:00
Your Name
377c6e3021 wip 2024-02-05 02:27:20 -06:00
Your Name
9213866846 wip 2024-02-05 02:21:21 -06:00
Your Name
67178ebc4b wip 2024-02-05 02:05:53 -06:00
Your Name
746d9fc631 wip 2024-02-05 01:50:34 -06:00
Your Name
e55aa65d18 wip 2024-02-05 01:43:52 -06:00
Your Name
a4f130ba44 wip 2024-02-05 01:22:54 -06:00
Your Name
a81f6285c1 wip 2024-02-05 01:15:52 -06:00
Your Name
072ed7e50f wip 2024-02-05 00:47:17 -06:00
Your Name
425594dd0c wip 2024-02-05 00:25:42 -06:00
Your Name
b7cb5c8893 wip 2024-02-04 23:36:57 -06:00
Your Name
705a30835a wip 2024-02-04 23:34:58 -06:00
Your Name
76f2507503 iwip 2024-02-04 22:15:38 -06:00
54 changed files with 3563 additions and 274 deletions

1
.gitattributes vendored Normal file
View File

@@ -0,0 +1 @@
*.onnx filter=lfs diff=lfs merge=lfs -text

View File

@@ -1,14 +1,33 @@
This is oscarpilot. It is a mod of frogpilot. This is oscarpilot. It is a mod of frogpilot.
- increased driver monitor timeouts to 30 sec warn / 60 second fatal This is for private use by Brian Hanson. If you come across this you are not intended to use it. Unathorized use of this software
- changed some default settings, notably farmville model default is at your own risk.
Released under the MIT license. Some parts of the software are released under other licenses as specified.
Any user of this software shall indemnify and hold harmless Comma.ai, Inc, all developers of openpilot or its forks, and its directors, officers, employees, agents, stockholders, affiliates, subcontractors and customers from and against all allegations, claims, actions, suits, demands, damages, liabilities, obligations, losses, settlements, judgments, costs and expenses (including without limitation attorneys fees and costs) which arise out of, relate to or result from any use of this software by user.
THIS IS ALPHA QUALITY SOFTWARE FOR RESEARCH PURPOSES ONLY. THIS IS NOT A PRODUCT. YOU ARE RESPONSIBLE FOR COMPLYING WITH LOCAL LAWS AND REGULATIONS. NO WARRANTY EXPRESSED OR IMPLIED.
Changes from frogpilot 2024-01-15:
- changed some default settings, notably defaults: farmville model, disabled turn intentions
- disabled lane change assist - disabled lane change assist
- disabled activation / deactivation sounds in custom sound theme - disabled activation / deactivation sounds in custom sound theme
- small edits to theme
This is for private use by Brian Hanson. If you come across this you are not intended to use it. Unathorized use of this software - increased driver monitor timeouts to 10 sec warn / 60 second terminate.
is at your own risk. To the greatest extent possible, by using this software, you agree to free Brian Hanson, frogpilot, and openpilot - Justification:
of any liability by your unauthorized choice to use this software, and you use at your own risk. - Many people will turn off the moinitor altogether if given the choice. There has to be a good middle ground.
- The monitor's primary responsibility should be to detect when the driver has fallen asleep perhaps, which shouldn't
ever happen, but if it does will certainly result in the death of the driver and possibly others. This is critical
enough that the car should make very lound angry noises after a threshold which only should happen if the driver
has flat out stopped paying attention to driving. The shreeking and continuing to drive is preferable to a car
stopping in traffic with its hazards off, as a result the car should keep driving for a reasonable amount of time
that the driver would be reawoken.
Goals:
- Conditional experimental mode: override speed on stock ACC, set to experimental mode, revert to last speed when recovered. Last speed updated to car speed limit on change.
![openpilot on the comma 3X](https://i.imgur.com/6l2qbf5.png) ![openpilot on the comma 3X](https://i.imgur.com/6l2qbf5.png)

1
commit_and_push Normal file
View File

@@ -0,0 +1 @@
git add -A; git commit -m "wip"; bash push_github

View File

@@ -244,6 +244,10 @@ std::unordered_map<std::string, uint32_t> keys = {
{"Compass", PERSISTENT}, {"Compass", PERSISTENT},
{"ConditionalExperimental", PERSISTENT}, {"ConditionalExperimental", PERSISTENT},
{"CurrentRandomEvent", PERSISTENT}, {"CurrentRandomEvent", PERSISTENT},
{"CSLCAvailable", PERSISTENT},
{"CSLCEnabled", PERSISTENT},
{"CSLCSetSpeed", PERSISTENT},
{"CSLCTempSpeed", PERSISTENT},
{"CurveSensitivity", PERSISTENT}, {"CurveSensitivity", PERSISTENT},
{"CustomColors", PERSISTENT}, {"CustomColors", PERSISTENT},
{"CustomIcons", PERSISTENT}, {"CustomIcons", PERSISTENT},
@@ -327,6 +331,7 @@ std::unordered_map<std::string, uint32_t> keys = {
{"ReverseCruise", PERSISTENT}, {"ReverseCruise", PERSISTENT},
{"RoadEdgesWidth", PERSISTENT}, {"RoadEdgesWidth", PERSISTENT},
{"RoadName", PERSISTENT}, {"RoadName", PERSISTENT},
{"oscar_debug", PERSISTENT},
{"RoadNameUI", PERSISTENT}, {"RoadNameUI", PERSISTENT},
{"RotatingWheel", PERSISTENT}, {"RotatingWheel", PERSISTENT},
{"SchedulePending", PERSISTENT}, {"SchedulePending", PERSISTENT},

0
foo Normal file
View File

2457
hyundai_can_full.dbc Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,12 @@
#!/usr/bin/bash #!/usr/bin/bash
cd /data/openpilot
sudo bash /data/openpilot/shell/start_service.sh
# Blank the UI (assuming framebuffer device is /dev/fb0)
# This command clears the framebuffer, effectively blanking the screen
export PASSIVE="0" export PASSIVE="0"
exec ./launch_chffrplus.sh exec ./launch_chffrplus.sh

40
notes Normal file
View File

@@ -0,0 +1,40 @@
hyundai/interface ENABLE_BUTTONS = (Buttons.RES_ACCEL, Buttons.SET_DECEL, Buttons.CANCEL)
Goals:
1 - get current dash speed via calculate_speed_limit_canfd
2 - issue set decel button via LFA button (proof of concept)
3 - chirp when speed limit changes
4 - Use LFA button to set speed of cruise to desired speed - 0-36 speed limit +3, 36-59 + 5, >= 60 +7
5 - On experimental mode engage, adjust cruise speed to experimental model speed
- Verify pause lateral under 30 is enabled
Wishlist:
- When car reports seeing lanes, turn lane keep over to car, resume when car can't see lanes or turn signal is activated
- Get hyundai speed limit reader merged into frogpilot
- Get stock experimental mode controller merged into frogpilot
Pie in the sky:
- Roll up windows on power off (debug dump canbus)
OPKR features:
- Auto Resume at Stop
- Button Spam CC
- auto select speedometer on boot
- Accelerated Departure by Cruise Gap: Cruise gap automatically changed to step 1 for faster departure, sets back to orignal gap selection after few second.
- Weather radar screen (accessible by wheel)
- weather forecast screen (also by wheel)
- auto consent to carplay on car start
- auto hvac to comfortable on drve mode
ret.cruiseState.standstill cp_scc.vl["SCC11"]["SCCInfoDisplay"] == 4.
Interesting can messages
SG_ C_SunRoofOpenState
CR_Datc_DrTempDispF
2-9 test notes
- Only the icon with the lane lines is showing after recent lkas mods - can we show amber?
- pressing lkas distance does in fact cancel cruise, if only for a second. that means that it response to the cancel button - and possibly resume too?
- test: set cluster speed directly
- test: simulate down button on wheel
- we should put a splash screen of the pacman ghost over the main startup display, and only reveal the interface when we tap on it
- Fix: read speed limit from car computer, flicker LKAS button when it is out of range

View File

@@ -273,7 +273,8 @@ static bool hyundai_tx_hook(CANPacket_t *to_send) {
bool allowed_resume = (button == 1) && controls_allowed; bool allowed_resume = (button == 1) && controls_allowed;
bool allowed_cancel = (button == 4) && cruise_engaged_prev; bool allowed_cancel = (button == 4) && cruise_engaged_prev;
if (!(allowed_resume || allowed_cancel)) { bool allowed_cslc = (button == 1 || button == 2) && controls_allowed;
if (!(allowed_resume || allowed_cancel || allowed_cslc)) {
tx = false; tx = false;
} }
} }

View File

@@ -247,8 +247,9 @@ static bool hyundai_canfd_tx_hook(CANPacket_t *to_send) {
int button = GET_BYTE(to_send, 2) & 0x7U; int button = GET_BYTE(to_send, 2) & 0x7U;
bool is_cancel = (button == HYUNDAI_BTN_CANCEL); bool is_cancel = (button == HYUNDAI_BTN_CANCEL);
bool is_resume = (button == HYUNDAI_BTN_RESUME); bool is_resume = (button == HYUNDAI_BTN_RESUME);
bool is_cslc = (button == HYUNDAI_BTN_RESUME || button == HYUNDAI_BTN_SET);
bool allowed = (is_cancel && cruise_engaged_prev) || (is_resume && controls_allowed); bool allowed = (is_cancel && cruise_engaged_prev) || (is_resume && controls_allowed) || (is_cslc && controls_allowed);
if (!allowed) { if (!allowed) {
tx = false; tx = false;
} }

1
push_github Normal file
View File

@@ -0,0 +1 @@
GIT_SSH_COMMAND='ssh -i ~/.ssh/id_rsa_brianhansonxyzgithub -o IdentitiesOnly=yes' git push github oscarpilot

Binary file not shown.

Before

Width:  |  Height:  |  Size: 108 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

@@ -0,0 +1,210 @@
from cereal import car
from openpilot.common.conversions import Conversions as CV
from openpilot.common.numpy_fast import clip
from openpilot.common.realtime import DT_CTRL
from opendbc.can.packer import CANPacker
from openpilot.selfdrive.car import apply_driver_steer_torque_limits, common_fault_avoidance
from openpilot.selfdrive.car.hyundai import hyundaicanfd, hyundaican
from openpilot.selfdrive.car.hyundai.hyundaicanfd import CanBus
from openpilot.selfdrive.car.hyundai.values import HyundaiFlags, Buttons, CarControllerParams, CANFD_CAR, CAR
VisualAlert = car.CarControl.HUDControl.VisualAlert
LongCtrlState = car.CarControl.Actuators.LongControlState
# EPS faults if you apply torque while the steering angle is above 90 degrees for more than 1 second
# All slightly below EPS thresholds to avoid fault
MAX_ANGLE = 85
MAX_ANGLE_FRAMES = 89
MAX_ANGLE_CONSECUTIVE_FRAMES = 2
def process_hud_alert(enabled, fingerprint, hud_control):
sys_warning = (hud_control.visualAlert in (VisualAlert.steerRequired, VisualAlert.ldw))
# initialize to no line visible
# TODO: this is not accurate for all cars
sys_state = 1
if hud_control.leftLaneVisible and hud_control.rightLaneVisible or sys_warning: # HUD alert only display when LKAS status is active
sys_state = 3 if enabled or sys_warning else 4
elif hud_control.leftLaneVisible:
sys_state = 5
elif hud_control.rightLaneVisible:
sys_state = 6
# initialize to no warnings
left_lane_warning = 0
right_lane_warning = 0
if hud_control.leftLaneDepart:
left_lane_warning = 1 if fingerprint in (CAR.GENESIS_G90, CAR.GENESIS_G80) else 2
if hud_control.rightLaneDepart:
right_lane_warning = 1 if fingerprint in (CAR.GENESIS_G90, CAR.GENESIS_G80) else 2
return sys_warning, sys_state, left_lane_warning, right_lane_warning
class CarController:
def __init__(self, dbc_name, CP, VM):
self.CP = CP
self.CAN = CanBus(CP)
self.params = CarControllerParams(CP)
self.packer = CANPacker(dbc_name)
self.angle_limit_counter = 0
self.frame = 0
self.accel_last = 0
self.apply_steer_last = 0
self.car_fingerprint = CP.carFingerprint
self.last_button_frame = 0
def update(self, CC, CS, now_nanos, sport_plus):
actuators = CC.actuators
hud_control = CC.hudControl
# steering torque
new_steer = int(round(actuators.steer * self.params.STEER_MAX))
apply_steer = apply_driver_steer_torque_limits(new_steer, self.apply_steer_last, CS.out.steeringTorque, self.params)
# >90 degree steering fault prevention
self.angle_limit_counter, apply_steer_req = common_fault_avoidance(abs(CS.out.steeringAngleDeg) >= MAX_ANGLE, CC.latActive,
self.angle_limit_counter, MAX_ANGLE_FRAMES,
MAX_ANGLE_CONSECUTIVE_FRAMES)
if not CC.latActive:
apply_steer = 0
# Hold torque with induced temporary fault when cutting the actuation bit
torque_fault = CC.latActive and not apply_steer_req
self.apply_steer_last = apply_steer
# accel + longitudinal
if sport_plus:
accel = clip(actuators.accel, CarControllerParams.ACCEL_MIN, CarControllerParams.ACCEL_MAX_PLUS)
else:
accel = clip(actuators.accel, CarControllerParams.ACCEL_MIN, CarControllerParams.ACCEL_MAX)
stopping = actuators.longControlState == LongCtrlState.stopping
set_speed_in_units = hud_control.setSpeed * (CV.MS_TO_KPH if CS.is_metric else CV.MS_TO_MPH)
# HUD messages
sys_warning, sys_state, left_lane_warning, right_lane_warning = process_hud_alert(CC.enabled, self.car_fingerprint,
hud_control)
can_sends = []
# *** common hyundai stuff ***
# tester present - w/ no response (keeps relevant ECU disabled)
if self.frame % 100 == 0 and not (self.CP.flags & HyundaiFlags.CANFD_CAMERA_SCC.value) and self.CP.openpilotLongitudinalControl:
# for longitudinal control, either radar or ADAS driving ECU
addr, bus = 0x7d0, 0
if self.CP.flags & HyundaiFlags.CANFD_HDA2.value:
addr, bus = 0x730, self.CAN.ECAN
can_sends.append([addr, 0, b"\x02\x3E\x80\x00\x00\x00\x00\x00", bus])
# for blinkers
if self.CP.flags & HyundaiFlags.ENABLE_BLINKERS:
can_sends.append([0x7b1, 0, b"\x02\x3E\x80\x00\x00\x00\x00\x00", self.CAN.ECAN])
# CAN-FD platforms
if self.CP.carFingerprint in CANFD_CAR:
hda2 = self.CP.flags & HyundaiFlags.CANFD_HDA2
hda2_long = hda2 and self.CP.openpilotLongitudinalControl
# steering control
can_sends.extend(hyundaicanfd.create_steering_messages(self.packer, self.CP, self.CAN, CC.enabled, apply_steer_req, apply_steer))
# prevent LFA from activating on HDA2 by sending "no lane lines detected" to ADAS ECU
if self.frame % 5 == 0 and hda2:
can_sends.append(hyundaicanfd.create_suppress_lfa(self.packer, self.CAN, CS.hda2_lfa_block_msg,
self.CP.flags & HyundaiFlags.CANFD_HDA2_ALT_STEERING))
# LFA and HDA icons
if self.frame % 5 == 0 and (not hda2 or hda2_long):
can_sends.append(hyundaicanfd.create_lfahda_cluster(self.packer, self.CAN, CC.enabled))
# blinkers
if hda2 and self.CP.flags & HyundaiFlags.ENABLE_BLINKERS:
can_sends.extend(hyundaicanfd.create_spas_messages(self.packer, self.CAN, self.frame, CC.leftBlinker, CC.rightBlinker))
if self.CP.openpilotLongitudinalControl:
if hda2:
can_sends.extend(hyundaicanfd.create_adrv_messages(self.packer, self.CAN, self.frame))
if self.frame % 2 == 0:
can_sends.append(hyundaicanfd.create_acc_control(self.packer, self.CAN, CC.enabled, self.accel_last, accel, stopping, CC.cruiseControl.override,
set_speed_in_units, CS.personality_profile))
self.accel_last = accel
else:
# button presses
can_sends.extend(self.create_button_messages(CC, CS, use_clu11=False))
else:
can_sends.append(hyundaican.create_lkas11(self.packer, self.frame, self.car_fingerprint, apply_steer, apply_steer_req,
torque_fault, CS.lkas11, sys_warning, sys_state, CC.enabled,
hud_control.leftLaneVisible, hud_control.rightLaneVisible,
left_lane_warning, right_lane_warning))
if not self.CP.openpilotLongitudinalControl:
can_sends.extend(self.create_button_messages(CC, CS, use_clu11=True))
if self.frame % 2 == 0 and self.CP.openpilotLongitudinalControl:
# TODO: unclear if this is needed
jerk = 3.0 if actuators.longControlState == LongCtrlState.pid else 1.0
use_fca = self.CP.flags & HyundaiFlags.USE_FCA.value
can_sends.extend(hyundaican.create_acc_commands(self.packer, CC.enabled, accel, jerk, int(self.frame / 2),
hud_control.leadVisible, set_speed_in_units, stopping,
CC.cruiseControl.override, use_fca, CS.out.cruiseState.available, CS.personality_profile))
# 20 Hz LFA MFA message
if self.frame % 5 == 0 and self.CP.flags & HyundaiFlags.SEND_LFA.value:
can_sends.append(hyundaican.create_lfahda_mfc(self.packer, CC.enabled))
# 5 Hz ACC options
if self.frame % 20 == 0 and self.CP.openpilotLongitudinalControl:
can_sends.extend(hyundaican.create_acc_opt(self.packer))
# 2 Hz front radar options
if self.frame % 50 == 0 and self.CP.openpilotLongitudinalControl:
can_sends.append(hyundaican.create_frt_radar_opt(self.packer))
new_actuators = actuators.copy()
new_actuators.steer = apply_steer / self.params.STEER_MAX
new_actuators.steerOutputCan = apply_steer
new_actuators.accel = accel
self.frame += 1
return new_actuators, can_sends
def create_button_messages(self, CC: car.CarControl, CS: car.CarState, use_clu11: bool):
can_sends = []
if use_clu11:
if CC.cruiseControl.cancel:
can_sends.append(hyundaican.create_clu11(self.packer, self.frame, CS.clu11, Buttons.CANCEL, self.CP.carFingerprint))
elif CC.cruiseControl.resume:
# send resume at a max freq of 10Hz
if (self.frame - self.last_button_frame) * DT_CTRL > 0.1:
# send 25 messages at a time to increases the likelihood of resume being accepted
can_sends.extend([hyundaican.create_clu11(self.packer, self.frame, CS.clu11, Buttons.RES_ACCEL, self.CP.carFingerprint)] * 25)
if (self.frame - self.last_button_frame) * DT_CTRL >= 0.15:
self.last_button_frame = self.frame
else:
if (self.frame - self.last_button_frame) * DT_CTRL > 0.25:
# cruise cancel
if CC.cruiseControl.cancel:
if self.CP.flags & HyundaiFlags.CANFD_ALT_BUTTONS:
can_sends.append(hyundaicanfd.create_acc_cancel(self.packer, self.CP, self.CAN, CS.cruise_info))
self.last_button_frame = self.frame
else:
for _ in range(20):
can_sends.append(hyundaicanfd.create_buttons(self.packer, self.CP, self.CAN, CS.buttons_counter+1, Buttons.CANCEL))
self.last_button_frame = self.frame
# cruise standstill resume
elif CC.cruiseControl.resume:
if self.CP.flags & HyundaiFlags.CANFD_ALT_BUTTONS:
# TODO: resume for alt button cars
pass
else:
for _ in range(20):
can_sends.append(hyundaicanfd.create_buttons(self.packer, self.CP, self.CAN, CS.buttons_counter+1, Buttons.RES_ACCEL))
self.last_button_frame = self.frame
return can_sends

View File

@@ -6,11 +6,15 @@ from opendbc.can.packer import CANPacker
from openpilot.selfdrive.car import apply_driver_steer_torque_limits, common_fault_avoidance from openpilot.selfdrive.car import apply_driver_steer_torque_limits, common_fault_avoidance
from openpilot.selfdrive.car.hyundai import hyundaicanfd, hyundaican from openpilot.selfdrive.car.hyundai import hyundaicanfd, hyundaican
from openpilot.selfdrive.car.hyundai.hyundaicanfd import CanBus from openpilot.selfdrive.car.hyundai.hyundaicanfd import CanBus
from openpilot.selfdrive.car.hyundai.values import HyundaiFlags, Buttons, CarControllerParams, CANFD_CAR, CAR from openpilot.selfdrive.car.hyundai.values import HyundaiFlags, Buttons, CarControllerParams, CANFD_CAR, CAR, LEGACY_SAFETY_MODE_CAR
from openpilot.selfdrive.controls.lib.drive_helpers import V_CRUISE_MAX
from openpilot.common.params import Params
VisualAlert = car.CarControl.HUDControl.VisualAlert VisualAlert = car.CarControl.HUDControl.VisualAlert
LongCtrlState = car.CarControl.Actuators.LongControlState LongCtrlState = car.CarControl.Actuators.LongControlState
params_memory = Params("/dev/shm/params")
# EPS faults if you apply torque while the steering angle is above 90 degrees for more than 1 second # EPS faults if you apply torque while the steering angle is above 90 degrees for more than 1 second
# All slightly below EPS thresholds to avoid fault # All slightly below EPS thresholds to avoid fault
MAX_ANGLE = 85 MAX_ANGLE = 85
@@ -55,11 +59,17 @@ class CarController:
self.apply_steer_last = 0 self.apply_steer_last = 0
self.car_fingerprint = CP.carFingerprint self.car_fingerprint = CP.carFingerprint
self.last_button_frame = 0 self.last_button_frame = 0
self.last_resume_frame = 0
self.last_debug_frame = 0
def update(self, CC, CS, now_nanos, sport_plus): def update(self, CC, CS, now_nanos, sport_plus):
actuators = CC.actuators actuators = CC.actuators
hud_control = CC.hudControl hud_control = CC.hudControl
# hud_v_cruise = hud_control.setSpeed
# if hud_v_cruise > 70:
# hud_v_cruise = 0
# steering torque # steering torque
new_steer = int(round(actuators.steer * self.params.STEER_MAX)) new_steer = int(round(actuators.steer * self.params.STEER_MAX))
apply_steer = apply_driver_steer_torque_limits(new_steer, self.apply_steer_last, CS.out.steeringTorque, self.params) apply_steer = apply_driver_steer_torque_limits(new_steer, self.apply_steer_last, CS.out.steeringTorque, self.params)
@@ -113,11 +123,12 @@ class CarController:
# steering control # steering control
can_sends.extend(hyundaicanfd.create_steering_messages(self.packer, self.CP, self.CAN, CC.enabled, apply_steer_req, apply_steer)) can_sends.extend(hyundaicanfd.create_steering_messages(self.packer, self.CP, self.CAN, CC.enabled, apply_steer_req, apply_steer))
# prevent LFA from activating on HDA2 by sending "no lane lines detected" to ADAS ECU # MODIFIED BBOT
if self.frame % 5 == 0 and hda2: if self.frame % 5 == 0 and hda2:
can_sends.append(hyundaicanfd.create_suppress_lfa(self.packer, self.CAN, CS.hda2_lfa_block_msg, can_sends.append(hyundaicanfd.create_suppress_lfa(self.packer, self.CAN, CS.hda2_lfa_block_msg,
self.CP.flags & HyundaiFlags.CANFD_HDA2_ALT_STEERING)) self.CP.flags & HyundaiFlags.CANFD_HDA2_ALT_STEERING))
# MODIFIED BBOT
# LFA and HDA icons # LFA and HDA icons
if self.frame % 5 == 0 and (not hda2 or hda2_long): if self.frame % 5 == 0 and (not hda2 or hda2_long):
can_sends.append(hyundaicanfd.create_lfahda_cluster(self.packer, self.CAN, CC.enabled)) can_sends.append(hyundaicanfd.create_lfahda_cluster(self.packer, self.CAN, CC.enabled))
@@ -126,6 +137,8 @@ class CarController:
if hda2 and self.CP.flags & HyundaiFlags.ENABLE_BLINKERS: if hda2 and self.CP.flags & HyundaiFlags.ENABLE_BLINKERS:
can_sends.extend(hyundaicanfd.create_spas_messages(self.packer, self.CAN, self.frame, CC.leftBlinker, CC.rightBlinker)) can_sends.extend(hyundaicanfd.create_spas_messages(self.packer, self.CAN, self.frame, CC.leftBlinker, CC.rightBlinker))
# can_sends.append(hyundaicanfd.create_misc_messages(self.packer, self.CAN, self.frame))
if self.CP.openpilotLongitudinalControl: if self.CP.openpilotLongitudinalControl:
if hda2: if hda2:
can_sends.extend(hyundaicanfd.create_adrv_messages(self.packer, self.CAN, self.frame)) can_sends.extend(hyundaicanfd.create_adrv_messages(self.packer, self.CAN, self.frame))
@@ -135,7 +148,7 @@ class CarController:
self.accel_last = accel self.accel_last = accel
else: else:
# button presses # button presses
can_sends.extend(self.create_button_messages(CC, CS, use_clu11=False)) can_sends.extend(self.create_button_messages(CC, CS, use_clu11=False, set_speed_in_units = None))
else: else:
can_sends.append(hyundaican.create_lkas11(self.packer, self.frame, self.car_fingerprint, apply_steer, apply_steer_req, can_sends.append(hyundaican.create_lkas11(self.packer, self.frame, self.car_fingerprint, apply_steer, apply_steer_req,
torque_fault, CS.lkas11, sys_warning, sys_state, CC.enabled, torque_fault, CS.lkas11, sys_warning, sys_state, CC.enabled,
@@ -165,6 +178,31 @@ class CarController:
if self.frame % 50 == 0 and self.CP.openpilotLongitudinalControl: if self.frame % 50 == 0 and self.CP.openpilotLongitudinalControl:
can_sends.append(hyundaican.create_frt_radar_opt(self.packer)) can_sends.append(hyundaican.create_frt_radar_opt(self.packer))
# CSLC
# if not self.CP.openpilotLongitudinalControl and CS.cruiseState.available and not CS.out.gasPressed and CS.cruise_buttons == Buttons.NONE:
# if False and not self.CP.openpilotLongitudinalControl and CC.enabled and CC.experimental_mode and CS.cruiseState.available and not CS.out.gasPressed and CS.cruise_buttons == Buttons.NONE:
# # cslcSetSpeed = get_set_speed(self, hud_v_cruise)
# cslcSetSpeed = set_speed_in_units
# self.cruise_button = get_cslc_button(self, cslcSetSpeed, CS)
# if self.cruise_button != Buttons.NONE:
# # if self.CP.carFingerprint in LEGACY_SAFETY_MODE_CAR:
# # send_freq = 1
# # # send resume at a max freq of 10Hz
# # if (self.frame - self.last_button_frame) * DT_CTRL > 0.1 * send_freq:
# # # send 25 messages at a time to increases the likelihood of cruise buttons being accepted
# # can_sends.extend([hyundaican.create_clu11(self.packer, self.frame, CS.clu11, self.cruise_button, self.CP.carFingerprint)] * 25)
# # if (self.frame - self.last_button_frame) * DT_CTRL >= 0.15 * send_freq:
# # self.last_button_frame = self.frame
# if self.frame % 2 == 0:
# if self.CP.carFingerprint in CANFD_CAR:
# can_sends.append(hyundaicanfd.create_buttons(self.packer, self.CP, self.CAN, ((self.frame // 2) + 1) % 0x10, self.cruise_button))
# else:
# can_sends.extend([hyundaican.create_clu11(self.packer, (self.frame // 2) + 1, CS.clu11, self.cruise_button, self.CP.carFingerprint)] * 25)
# Test - Works???
# if CS.cruise_buttons == Buttons.NONE and CS.cruiseState.enabled:
# can_sends.append(hyundaicanfd.create_buttons(self.packer, self.CP, self.CAN, ((self.frame // 2) + 1) % 0x10, Buttons.SET_DECEL))
new_actuators = actuators.copy() new_actuators = actuators.copy()
new_actuators.steer = apply_steer / self.params.STEER_MAX new_actuators.steer = apply_steer / self.params.STEER_MAX
new_actuators.steerOutputCan = apply_steer new_actuators.steerOutputCan = apply_steer
@@ -173,20 +211,44 @@ class CarController:
self.frame += 1 self.frame += 1
return new_actuators, can_sends return new_actuators, can_sends
def create_button_messages(self, CC: car.CarControl, CS: car.CarState, use_clu11: bool): def create_button_messages(self, CC: car.CarControl, CS: car.CarState, use_clu11: bool, set_speed_in_units = None):
can_sends = [] can_sends = []
# Test me.
# can_sends.append(hyundaicanfd.create_buttons(self.packer, self.CP, self.CAN, 1, Buttons.RES_ACCEL))
# if self.CP.openpilotLongitudinalControl:
# CC.cruiseControl.resume = True
# self.CP.openpilotLongitudinalControl = False
# else:
# CC.cruiseControl.cancel = True
# self.CP.openpilotLongitudinalControl = True
if use_clu11: if use_clu11:
if CC.cruiseControl.cancel: if CC.cruiseControl.cancel:
can_sends.append(hyundaican.create_clu11(self.packer, self.frame, CS.clu11, Buttons.CANCEL, self.CP.carFingerprint)) can_sends.append(hyundaican.create_clu11(self.packer, self.frame, CS.clu11, Buttons.CANCEL, self.CP.carFingerprint))
elif CC.cruiseControl.resume: elif CC.cruiseControl.resume:
# send resume at a max freq of 10Hz # send resume at a max freq of 10Hz
if (self.frame - self.last_button_frame) * DT_CTRL > 0.1: if (self.frame - self.last_button_frame) * DT_CTRL > 0.1:
# send 25 messages at a time to increases the likelihood of resume being accepted # send 25 messages at a time to increases the likeli M,hood of resume being accepted
can_sends.extend([hyundaican.create_clu11(self.packer, self.frame, CS.clu11, Buttons.RES_ACCEL, self.CP.carFingerprint)] * 25) can_sends.extend([hyundaican.create_clu11(self.packer, self.frame, CS.clu11, Buttons.RES_ACCEL, self.CP.carFingerprint)] * 25)
if (self.frame - self.last_button_frame) * DT_CTRL >= 0.15: if (self.frame - self.last_button_frame) * DT_CTRL >= 0.15:
self.last_button_frame = self.frame self.last_button_frame = self.frame
else: else:
if (self.frame - self.last_button_frame) * DT_CTRL > 0.25: if (self.frame - self.last_button_frame) * DT_CTRL > 0.25:
# if (self.frame - self.last_button_frame) * DT_CTRL > 3:
# if self.last_resume_frame = self.frame
if CS.oscar_lane_center_btn_pressed:
CS.oscar_lane_center_btn_pressed = False
# CC.cruiseControl.resume = True
CC.cruiseControl.cancel = True
# Test this...
# Also try create_acc_commands
# This attempts to set the speed to
# stopping = CC.actuators.longControlState == LongCtrlState.stopping
# can_sends.append(hyundaicanfd.create_acc_control(self.packer, self.CAN, CC.enabled, self.accel_last, CC.actuators.accel, stopping, CC.cruiseControl.override,
# 40, CS.personality_profile))
# cruise cancel # cruise cancel
if CC.cruiseControl.cancel: if CC.cruiseControl.cancel:
if self.CP.flags & HyundaiFlags.CANFD_ALT_BUTTONS: if self.CP.flags & HyundaiFlags.CANFD_ALT_BUTTONS:
@@ -199,12 +261,67 @@ class CarController:
# cruise standstill resume # cruise standstill resume
elif CC.cruiseControl.resume: elif CC.cruiseControl.resume:
if (self.frame - self.last_button_frame) * DT_CTRL > 4:
if self.CP.flags & HyundaiFlags.CANFD_ALT_BUTTONS: if self.CP.flags & HyundaiFlags.CANFD_ALT_BUTTONS:
# TODO: resume for alt button cars # for _ in range(20):
pass nothing = 0
# Nothing for now --?
# oscar - test me
# can_sends.append(hyundaicanfd.create_buttons(self.packer, self.CP, self.CAN, CS.buttons_counter+1, Buttons.CANCEL))
# can_sends.append(hyundaicanfd.create_buttons(self.packer, self.CP, self.CAN, CS.buttons_counter+1, Buttons.RES_ACCEL))
else: else:
for _ in range(20): for _ in range(20):
can_sends.append(hyundaicanfd.create_buttons(self.packer, self.CP, self.CAN, CS.buttons_counter+1, Buttons.RES_ACCEL)) can_sends.append(hyundaicanfd.create_buttons(self.packer, self.CP, self.CAN, CS.buttons_counter+1, Buttons.RES_ACCEL))
self.last_button_frame = self.frame self.last_button_frame = self.frame
self.last_resume_frame = self.frame
elif set_speed_in_units is not None and not self.CP.openpilotLongitudinalControl and CS.cruiseState.enabled and not CS.out.gasPressed and CS.cruise_buttons == Buttons.NONE:
# if False and not self.CP.openpilotLongitudinalControl and CC.enabled and CC.experimental_mode and CS.cruiseState.available and not CS.out.gasPressed and CS.cruise_buttons == Buttons.NONE:
# # cslcSetSpeed = get_set_speed(self, hud_v_cruise)
cslcSetSpeed = set_speed_in_units
self.cruise_button = get_cslc_button(self, cslcSetSpeed, CS)
if self.cruise_button != Buttons.NONE:
# if self.CP.carFingerprint in LEGACY_SAFETY_MODE_CAR:
# send_freq = 1
# # send resume at a max freq of 10Hz
# if (self.frame - self.last_button_frame) * DT_CTRL > 0.1 * send_freq:
# # send 25 messages at a time to increases the likelihood of cruise buttons being accepted
# can_sends.extend([hyundaican.create_clu11(self.packer, self.frame, CS.clu11, self.cruise_button, self.CP.carFingerprint)] * 25)
# if (self.frame - self.last_button_frame) * DT_CTRL >= 0.15 * send_freq:
# self.last_button_frame = self.frame
if self.frame % 2 == 0:
for _ in range(20):
if self.CP.carFingerprint in CANFD_CAR:
can_sends.append(hyundaicanfd.create_buttons(self.packer, self.CP, self.CAN, ((self.frame // 2) + 1) % 0x10, self.cruise_button))
else:
can_sends.extend([hyundaican.create_clu11(self.packer, (self.frame // 2) + 1, CS.clu11, self.cruise_button, self.CP.carFingerprint)] * 25)
self.last_button_frame = self.frame
# can_sends.extend([hyundaican.create_clu11(self.packer, self.frame, CS.clu11, Buttons.SET_DECEL, self.CP.carFingerprint)] * 25)
return can_sends return can_sends
def get_set_speed(self, hud_v_cruise):
v_cruise_kph = min(hud_v_cruise * CV.MS_TO_KPH, V_CRUISE_MAX)
v_cruise = int(round(v_cruise_kph * CV.KPH_TO_MPH))
v_cruise_slc: int = 0
# v_cruise_slc = params_memory.get_int("CSLCSpeed")
if v_cruise_slc > 0:
v_cruise = v_cruise_slc
return v_cruise
def get_cslc_button(self, cslcSetSpeed, CS, CC):
cruiseBtn = Buttons.NONE
speedSetPoint = int(round(CS.out.cruiseState.speed * CV.MS_TO_MPH))
if cslcSetSpeed < speedSetPoint and speedSetPoint > 25 and CC.enabled and CC.experimental_mode:
cruiseBtn = Buttons.SET_DECEL
elif cslcSetSpeed > speedSetPoint and speedSetPoint < 85 and CC.enabled:
cruiseBtn = Buttons.RES_ACCEL
else:
cruiseBtn = Buttons.SET_DECEL
# cruiseBtn = Buttons.NONE
return cruiseBtn

View File

@@ -10,6 +10,7 @@ from openpilot.selfdrive.car.hyundai.hyundaicanfd import CanBus
from openpilot.selfdrive.car.hyundai.values import HyundaiFlags, CAR, DBC, CAN_GEARS, CAMERA_SCC_CAR, \ from openpilot.selfdrive.car.hyundai.values import HyundaiFlags, CAR, DBC, CAN_GEARS, CAMERA_SCC_CAR, \
CANFD_CAR, EV_CAR, HYBRID_CAR, Buttons, CarControllerParams CANFD_CAR, EV_CAR, HYBRID_CAR, Buttons, CarControllerParams
from openpilot.selfdrive.car.interfaces import CarStateBase from openpilot.selfdrive.car.interfaces import CarStateBase
from openpilot.selfdrive.frogpilot.functions.speed_limit_controller import SpeedLimitController
PREV_BUTTON_SAMPLES = 8 PREV_BUTTON_SAMPLES = 8
CLUSTER_SAMPLE_RATE = 20 # frames CLUSTER_SAMPLE_RATE = 20 # frames
@@ -167,36 +168,51 @@ class CarState(CarStateBase):
if self.prev_main_buttons == 0 and self.main_buttons[-1] != 0: if self.prev_main_buttons == 0 and self.main_buttons[-1] != 0:
self.main_enabled = not self.main_enabled self.main_enabled = not self.main_enabled
# BBot functions for lfa and gap buttons - test speed up / down
self.oscar_lane_center_btn_pressed= False
self.oscar_slc_decel = False
self.oscar_slc_accel = False
self.param_memory.put("oscar_debug", "Hello World")
# if self.cruise_buttons[-1] == Buttons.GAP_DIST and self.prev_cruise_buttons == 0:
# self.oscar_lane_center_btn_pressed= True
# lkas_pressed = cp.vl["BCM_PO_11"]["LFA_Pressed"]
# if lkas_pressed and not self.lkas_previously_pressed:
# self.custom_speed_up = True
# self.lkas_previously_pressed = lkas_pressed
# Driving personalities function # Driving personalities function
if self.personalities_via_wheel and ret.cruiseState.available: # if self.personalities_via_wheel and ret.cruiseState.available:
# Sync with the onroad UI button # # Sync with the onroad UI button
if self.param_memory.get_bool("PersonalityChangedViaUI"): # if self.param_memory.get_bool("PersonalityChangedViaUI"):
self.personality_profile = self.param.get_int("LongitudinalPersonality") # self.personality_profile = self.param.get_int("LongitudinalPersonality")
self.param_memory.put_bool("PersonalityChangedViaUI", False) # self.param_memory.put_bool("PersonalityChangedViaUI", False)
# Change personality upon steering wheel button press # # Change personality upon steering wheel button press
if self.cruise_buttons[-1] == Buttons.GAP_DIST and self.prev_cruise_buttons == 0: # if self.cruise_buttons[-1] == Buttons.GAP_DIST and self.prev_cruise_buttons == 0:
self.param_memory.put_bool("PersonalityChangedViaWheel", True) # self.param_memory.put_bool("PersonalityChangedViaWheel", True)
self.personality_profile = (self.previous_personality_profile + 2) % 3 # self.personality_profile = (self.previous_personality_profile + 2) % 3
if self.personality_profile != self.previous_personality_profile and self.personality_profile >= 0: # if self.personality_profile != self.previous_personality_profile and self.personality_profile >= 0:
self.param.put_int("LongitudinalPersonality", self.personality_profile) # self.param.put_int("LongitudinalPersonality", self.personality_profile)
self.previous_personality_profile = self.personality_profile # self.previous_personality_profile = self.personality_profile
# Toggle Experimental Mode from steering wheel function # # Toggle Experimental Mode from steering wheel function
if self.experimental_mode_via_lkas and ret.cruiseState.available: # if self.experimental_mode_via_lkas and ret.cruiseState.available:
lkas_pressed = cp.vl["BCM_PO_11"]["LFA_Pressed"] # lkas_pressed = cp.vl["BCM_PO_11"]["LFA_Pressed"]
if lkas_pressed and not self.lkas_previously_pressed: # if lkas_pressed and not self.lkas_previously_pressed:
if self.conditional_experimental_mode: # if self.conditional_experimental_mode:
# Set "CEStatus" to work with "Conditional Experimental Mode" # # Set "CEStatus" to work with "Conditional Experimental Mode"
conditional_status = self.param_memory.get_int("CEStatus") # conditional_status = self.param_memory.get_int("CEStatus")
override_value = 0 if conditional_status in (1, 2, 3, 4) else 1 if conditional_status >= 5 else 2 # override_value = 0 if conditional_status in (1, 2, 3, 4) else 1 if conditional_status >= 5 else 2
self.param_memory.put_int("CEStatus", override_value) # self.param_memory.put_int("CEStatus", override_value)
else: # else:
experimental_mode = self.param.get_bool("ExperimentalMode") # experimental_mode = self.param.get_bool("ExperimentalMode")
# Invert the value of "ExperimentalMode" # # Invert the value of "ExperimentalMode"
put_bool_nonblocking("ExperimentalMode", not experimental_mode) # put_bool_nonblocking("ExperimentalMode", not experimental_mode)
self.lkas_previously_pressed = lkas_pressed # self.lkas_previously_pressed = lkas_pressed
return ret return ret
@@ -283,39 +299,71 @@ class CarState(CarStateBase):
self.hda2_lfa_block_msg = copy.copy(cp_cam.vl["CAM_0x362"] if self.CP.flags & HyundaiFlags.CANFD_HDA2_ALT_STEERING self.hda2_lfa_block_msg = copy.copy(cp_cam.vl["CAM_0x362"] if self.CP.flags & HyundaiFlags.CANFD_HDA2_ALT_STEERING
else cp_cam.vl["CAM_0x2a4"]) else cp_cam.vl["CAM_0x2a4"])
# Driving personalities function SpeedLimitController.load_state()
if self.personalities_via_wheel and ret.cruiseState.available: SpeedLimitController.car_speed_limit = self.calculate_speed_limit_canfd(self.CP, cp, cp_cam) * speed_factor
# Sync with the onroad UI button SpeedLimitController.write_car_state()
if self.param_memory.get_bool("PersonalityChangedViaUI"):
self.personality_profile = self.param.get_int("LongitudinalPersonality") # self.custom_speed_up = False
self.param_memory.put_bool("PersonalityChangedViaUI", False) self.oscar_lane_center_btn_pressed = False
if ret.cruiseState.available:
# Change personality upon steering wheel button press
if self.cruise_buttons[-1] == Buttons.GAP_DIST and self.prev_cruise_buttons == 0: if self.cruise_buttons[-1] == Buttons.GAP_DIST and self.prev_cruise_buttons == 0:
self.param_memory.put_bool("PersonalityChangedViaWheel", True) self.oscar_lane_center_btn_pressed = True
self.personality_profile = (self.previous_personality_profile + 2) % 3
if self.personality_profile != self.previous_personality_profile and self.personality_profile >= 0: lkas_pressed = False
self.param.put_int("LongitudinalPersonality", self.personality_profile) try:
self.previous_personality_profile = self.personality_profile
# Toggle Experimental Mode from steering wheel function
if self.experimental_mode_via_lkas and ret.cruiseState.available:
lkas_pressed = cp.vl[self.cruise_btns_msg_canfd]["LKAS_BTN"] lkas_pressed = cp.vl[self.cruise_btns_msg_canfd]["LKAS_BTN"]
if lkas_pressed and not self.lkas_previously_pressed: except:
if self.conditional_experimental_mode: nothing = 0
# Set "CEStatus" to work with "Conditional Experimental Mode"
conditional_status = self.param_memory.get_int("CEStatus") # intentionally cause a failure
override_value = 0 if conditional_status in (1, 2, 3, 4) else 1 if conditional_status >= 5 else 2 if lkas_pressed:
self.param_memory.put_int("CEStatus", override_value) floog=norpdywoop
else: # if self.cruise_buttons[-1] == Buttons.GAP_DIST and self.prev_cruise_buttons == 0:
experimental_mode = self.param.get_bool("ExperimentalMode") # self.oscar_lane_center_btn_pressed= True
# Invert the value of "ExperimentalMode"
put_bool_nonblocking("ExperimentalMode", not experimental_mode) # Driving personalities function
self.lkas_previously_pressed = lkas_pressed # if self.personalities_via_wheel and ret.cruiseState.available:
# # Sync with the onroad UI button
# if self.param_memory.get_bool("PersonalityChangedViaUI"):
# self.personality_profile = self.param.get_int("LongitudinalPersonality")
# self.param_memory.put_bool("PersonalityChangedViaUI", False)
# # Change personality upon steering wheel button press
# if self.cruise_buttons[-1] == Buttons.GAP_DIST and self.prev_cruise_buttons == 0:
# self.param_memory.put_bool("PersonalityChangedViaWheel", True)
# self.personality_profile = (self.previous_personality_profile + 2) % 3
# if self.personality_profile != self.previous_personality_profile and self.personality_profile >= 0:
# self.param.put_int("LongitudinalPersonality", self.personality_profile)
# self.previous_personality_profile = self.personality_profile
# # Toggle Experimental Mode from steering wheel function
# if self.experimental_mode_via_lkas and ret.cruiseState.available:
# lkas_pressed = cp.vl[self.cruise_btns_msg_canfd]["LKAS_BTN"]
# if lkas_pressed and not self.lkas_previously_pressed:
# if self.conditional_experimental_mode:
# # Set "CEStatus" to work with "Conditional Experimental Mode"
# conditional_status = self.param_memory.get_int("CEStatus")
# override_value = 0 if conditional_status in (1, 2, 3, 4) else 1 if conditional_status >= 5 else 2
# self.param_memory.put_int("CEStatus", override_value)
# else:
# experimental_mode = self.param.get_bool("ExperimentalMode")
# # Invert the value of "ExperimentalMode"
# put_bool_nonblocking("ExperimentalMode", not experimental_mode)
# self.lkas_previously_pressed = lkas_pressed
return ret return ret
# BBOT does not work
def calculate_speed_limit_canfd(self, CP, cp, cp_cam):
try:
self._speed_limit_clu = cp.vl["CLUSTER_SPEED_LIMIT"]["SPEED_LIMIT_1"]
return self._speed_limit_clu if self._speed_limit_clu not in (0, 255) else 0
except:
return 0
def get_can_parser(self, CP): def get_can_parser(self, CP):
if CP.carFingerprint in CANFD_CAR: if CP.carFingerprint in CANFD_CAR:
return self.get_can_parser_canfd(CP) return self.get_can_parser_canfd(CP)
@@ -415,6 +463,9 @@ class CarState(CarStateBase):
("BLINDSPOTS_REAR_CORNERS", 20), ("BLINDSPOTS_REAR_CORNERS", 20),
] ]
# if CP.nav_msg:
# messages.append(("CLUSTER_SPEED_LIMIT", 10))
if not (CP.flags & HyundaiFlags.CANFD_CAMERA_SCC.value) and not CP.openpilotLongitudinalControl: if not (CP.flags & HyundaiFlags.CANFD_CAMERA_SCC.value) and not CP.openpilotLongitudinalControl:
messages += [ messages += [
("SCC_CONTROL", 50), ("SCC_CONTROL", 50),
@@ -433,4 +484,6 @@ class CarState(CarStateBase):
("SCC_CONTROL", 50), ("SCC_CONTROL", 50),
] ]
return CANParser(DBC[CP.carFingerprint]["pt"], messages, CanBus(CP).CAM) return CANParser(DBC[CP.carFingerprint]["pt"], messages, CanBus(CP).CAM)

View File

@@ -41,7 +41,7 @@ def create_steering_messages(packer, CP, CAN, enabled, lat_active, apply_steer):
values = { values = {
"LKA_MODE": 2, "LKA_MODE": 2,
"LKA_ICON": 2 if enabled else 1, "LKA_ICON": 2 if enabled else 1 if lat_active else 0,
"TORQUE_REQUEST": apply_steer, "TORQUE_REQUEST": apply_steer,
"LKA_ASSIST": 0, "LKA_ASSIST": 0,
"STEER_REQ": 1 if lat_active else 0, "STEER_REQ": 1 if lat_active else 0,
@@ -116,7 +116,9 @@ def create_acc_cancel(packer, CP, CAN, cruise_info_copy):
def create_lfahda_cluster(packer, CAN, enabled): def create_lfahda_cluster(packer, CAN, enabled):
values = { values = {
"HDA_ICON": 1 if enabled else 0, "HDA_ICON": 1 if enabled else 0,
"LFA_ICON": 2 if enabled else 0, # 0 off, 1 gray, 2 green, 3 blinking (wheel icon)
"LFA_ICON": 0 if enabled else 0, # was green before i think in 2? 3 should be flashing?
# "LFA_ICON": 2 if enabled else 0,
} }
return packer.make_can_msg("LFAHDA_CLUSTER", CAN.ECAN, values) return packer.make_can_msg("LFAHDA_CLUSTER", CAN.ECAN, values)
@@ -151,7 +153,6 @@ def create_acc_control(packer, CAN, enabled, accel_last, accel, stopping, gas_ov
return packer.make_can_msg("SCC_CONTROL", CAN.ECAN, values) return packer.make_can_msg("SCC_CONTROL", CAN.ECAN, values)
def create_spas_messages(packer, CAN, frame, left_blink, right_blink): def create_spas_messages(packer, CAN, frame, left_blink, right_blink):
ret = [] ret = []

View File

@@ -9,6 +9,9 @@ from openpilot.selfdrive.car.hyundai.radar_interface import RADAR_START_ADDR
from openpilot.selfdrive.car import create_button_events, get_safety_config from openpilot.selfdrive.car import create_button_events, get_safety_config
from openpilot.selfdrive.car.interfaces import CarInterfaceBase from openpilot.selfdrive.car.interfaces import CarInterfaceBase
from openpilot.selfdrive.car.disable_ecu import disable_ecu from openpilot.selfdrive.car.disable_ecu import disable_ecu
from openpilot.common.params import Params
params_memory = Params("/dev/shm/params")
Ecu = car.CarParams.Ecu Ecu = car.CarParams.Ecu
SafetyModel = car.CarParams.SafetyModel SafetyModel = car.CarParams.SafetyModel
@@ -35,6 +38,7 @@ class CarInterface(CarInterfaceBase):
def _get_params(ret, candidate, fingerprint, car_fw, experimental_long, docs): def _get_params(ret, candidate, fingerprint, car_fw, experimental_long, docs):
ret.carName = "hyundai" ret.carName = "hyundai"
ret.radarUnavailable = RADAR_START_ADDR not in fingerprint[1] or DBC[ret.carFingerprint]["radar"] is None ret.radarUnavailable = RADAR_START_ADDR not in fingerprint[1] or DBC[ret.carFingerprint]["radar"] is None
params_memory.put_bool("CSLCAvailable", True)
# These cars have been put into dashcam only due to both a lack of users and test coverage. # These cars have been put into dashcam only due to both a lack of users and test coverage.
# These cars likely still work fine. Once a user confirms each car works and a test route is # These cars likely still work fine. Once a user confirms each car works and a test route is
@@ -50,6 +54,7 @@ class CarInterface(CarInterfaceBase):
if hda2: if hda2:
if 0x110 in fingerprint[CAN.CAM]: if 0x110 in fingerprint[CAN.CAM]:
ret.flags |= HyundaiFlags.CANFD_HDA2_ALT_STEERING.value ret.flags |= HyundaiFlags.CANFD_HDA2_ALT_STEERING.value
params_memory.put_bool("CSLCAvailable", False)
else: else:
# non-HDA2 # non-HDA2
if 0x1cf not in fingerprint[CAN.ECAN]: if 0x1cf not in fingerprint[CAN.ECAN]:
@@ -291,10 +296,12 @@ class CarInterface(CarInterfaceBase):
ret.longitudinalActuatorDelayUpperBound = 0.5 ret.longitudinalActuatorDelayUpperBound = 0.5
# *** feature detection *** # *** feature detection ***
if candidate in CANFD_CAR: # if candidate in CANFD_CAR:
ret.enableBsm = 0x1e5 in fingerprint[CAN.ECAN] # ret.enableBsm = 0x1e5 in fingerprint[CAN.ECAN]
else: # ret.nav_msg = 0x544 in fingerprint[0]
ret.enableBsm = 0x58b in fingerprint[0] # else:
# ret.enableBsm = 0x58b in fingerprint[0]
# ret.nav_msg = False
# *** panda safety config *** # *** panda safety config ***
ret.safetyConfigs = set_safety_config_hyundai(candidate, CAN, can_fd=(candidate in CANFD_CAR)) ret.safetyConfigs = set_safety_config_hyundai(candidate, CAN, can_fd=(candidate in CANFD_CAR))
@@ -313,6 +320,7 @@ class CarInterface(CarInterfaceBase):
ret.safetyConfigs[-1].safetyParam |= Panda.FLAG_HYUNDAI_CAMERA_SCC ret.safetyConfigs[-1].safetyParam |= Panda.FLAG_HYUNDAI_CAMERA_SCC
if ret.openpilotLongitudinalControl: if ret.openpilotLongitudinalControl:
ret.safetyConfigs[-1].safetyParam |= Panda.FLAG_HYUNDAI_LONG ret.safetyConfigs[-1].safetyParam |= Panda.FLAG_HYUNDAI_LONG
params_memory.put_bool("CSLCAvailable", False)
if candidate in HYBRID_CAR: if candidate in HYBRID_CAR:
ret.safetyConfigs[-1].safetyParam |= Panda.FLAG_HYUNDAI_HYBRID_GAS ret.safetyConfigs[-1].safetyParam |= Panda.FLAG_HYUNDAI_HYBRID_GAS
elif candidate in EV_CAR: elif candidate in EV_CAR:

View File

@@ -605,6 +605,7 @@ class Controls:
self.state = State.enabled self.state = State.enabled
self.current_alert_types.append(ET.ENABLE) self.current_alert_types.append(ET.ENABLE)
self.v_cruise_helper.initialize_v_cruise(CS, self.experimental_mode, self.conditional_experimental_mode) self.v_cruise_helper.initialize_v_cruise(CS, self.experimental_mode, self.conditional_experimental_mode)
# self.v_cruise_helper.initialize_v_cruise(CS, self.frogpilot_variables, self.experimental_mode, self.conditional_experimental_mode)
# Check if openpilot is engaged and actuators are enabled # Check if openpilot is engaged and actuators are enabled
self.enabled = self.state in ENABLED_STATES self.enabled = self.state in ENABLED_STATES
@@ -659,7 +660,7 @@ class Controls:
self.lateral_allowed |= CS.cruiseState.enabled or (CS.cruiseState.available and self.always_on_lateral_main) self.lateral_allowed |= CS.cruiseState.enabled or (CS.cruiseState.available and self.always_on_lateral_main)
self.FPCC.alwaysOnLateral = self.lateral_allowed and driving_gear and signal_check self.FPCC.alwaysOnLateral = self.lateral_allowed and driving_gear and signal_check
if self.FPCC.alwaysOnLateral:/ if self.FPCC.alwaysOnLateral:
self.current_alert_types.append(ET.WARNING) self.current_alert_types.append(ET.WARNING)
# Check which actuators can be enabled # Check which actuators can be enabled
@@ -1002,6 +1003,8 @@ class Controls:
self.average_desired_curvature = self.params.get_bool("AverageCurvature") self.average_desired_curvature = self.params.get_bool("AverageCurvature")
self.conditional_experimental_mode = self.params.get_bool("ConditionalExperimental") self.conditional_experimental_mode = self.params.get_bool("ConditionalExperimental")
# self.frogpilot_variables.CSLC = self.params.get_bool("CSLCEnabled")
# self.frogpilot_variables.CSLCA = self.params.get_bool("CSLCAvailable")
custom_theme = self.params.get_bool("CustomTheme") custom_theme = self.params.get_bool("CustomTheme")
custom_sounds = self.params.get_int("CustomSounds") if custom_theme else 0 custom_sounds = self.params.get_int("CustomSounds") if custom_theme else 0

View File

@@ -92,6 +92,7 @@ class DesireHelper:
self.lane_change_state = LaneChangeState.off self.lane_change_state = LaneChangeState.off
self.lane_change_direction = LaneChangeDirection.none self.lane_change_direction = LaneChangeDirection.none
elif one_blinker and below_lane_change_speed and frogpilot_planner.turn_desires: elif one_blinker and below_lane_change_speed and frogpilot_planner.turn_desires:
# BBOT
self.turn_direction = TurnDirection.turnLeft if carstate.leftBlinker else TurnDirection.turnRight self.turn_direction = TurnDirection.turnLeft if carstate.leftBlinker else TurnDirection.turnRight
# Set the "turn_completed" flag to prevent lane changes after completing a turn # Set the "turn_completed" flag to prevent lane changes after completing a turn
self.turn_completed = True self.turn_completed = True

View File

@@ -139,6 +139,11 @@ class VCruiseHelper:
if self.CP.pcmCruise: if self.CP.pcmCruise:
return return
# if frogpilot_variables.CSLC:
# self.v_cruise_kph = CS.cruiseState.speed * CV.MS_TO_KPH
# self.v_cruise_cluster_kph = self.v_cruise_kph
# return
initial = V_CRUISE_INITIAL_EXPERIMENTAL_MODE if experimental_mode and not conditional_experimental_mode else V_CRUISE_INITIAL initial = V_CRUISE_INITIAL_EXPERIMENTAL_MODE if experimental_mode and not conditional_experimental_mode else V_CRUISE_INITIAL
# 250kph or above probably means we never had a set speed # 250kph or above probably means we never had a set speed

View File

@@ -231,7 +231,7 @@ def startup_master_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubM
if "REPLAY" in os.environ: if "REPLAY" in os.environ:
branch = "replay" branch = "replay"
return StartupAlert("Hippity hoppity this is my property", "so I do what I want 🐸", alert_status=AlertStatus.frogpilot) return StartupAlert("Oscarpilot ready", "Be excellent to eachother", alert_status=AlertStatus.frogpilot)
def below_engage_speed_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int) -> Alert: def below_engage_speed_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int) -> Alert:
return NoEntryAlert(f"Drive above {get_display_speed(CP.minEnableSpeed, metric)} to engage") return NoEntryAlert(f"Drive above {get_display_speed(CP.minEnableSpeed, metric)} to engage")
@@ -373,7 +373,8 @@ EVENTS: Dict[int, Dict[str, Union[Alert, AlertCallbackType]]] = {
}, },
EventName.startupMaster: { EventName.startupMaster: {
ET.PERMANENT: startup_master_alert, # ET.PERMANENT: startup_master_alert,
ET.PERMANENT: StartupAlert("OscarPilot Ready"),
}, },
# Car is recognized, but marked as dashcam only # Car is recognized, but marked as dashcam only

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@@ -135,7 +135,7 @@ class ConditionalExperimentalMode:
self.lead_detection(radarState) self.lead_detection(radarState)
self.road_curvature(modelData, v_ego) self.road_curvature(modelData, v_ego)
self.slow_lead(mpc, radarState, v_ego) self.slow_lead(mpc, radarState, v_ego)
self.stop_sign_and_light(modelData, v_ego) # self.stop_sign_and_light(modelData, v_ego)
self.v_ego_slowing_down(v_ego) self.v_ego_slowing_down(v_ego)
self.v_lead_slowing_down(mpc, radarState) self.v_lead_slowing_down(mpc, radarState)

View File

@@ -56,6 +56,7 @@ def calculate_lane_width(lane, current_lane, road_edge):
class FrogPilotPlanner: class FrogPilotPlanner:
def __init__(self, params, params_memory): def __init__(self, params, params_memory):
self.params_memory = params_memory
self.cem = ConditionalExperimentalMode() self.cem = ConditionalExperimentalMode()
self.mtsc = MapTurnSpeedController() self.mtsc = MapTurnSpeedController()
@@ -105,6 +106,8 @@ class FrogPilotPlanner:
self.x_desired_trajectory_full = np.interp(ModelConstants.T_IDXS, T_IDXS_MPC, mpc.x_solution) self.x_desired_trajectory_full = np.interp(ModelConstants.T_IDXS, T_IDXS_MPC, mpc.x_solution)
self.x_desired_trajectory = self.x_desired_trajectory_full[:CONTROL_N] self.x_desired_trajectory = self.x_desired_trajectory_full[:CONTROL_N]
# self.params_memory.put_int("CSLCSpeed", int(round(self.v_cruise * CV.MS_TO_MPH)))
def update_v_cruise(self, carState, controlsState, modelData, enabled, v_cruise, v_ego): def update_v_cruise(self, carState, controlsState, modelData, enabled, v_cruise, v_ego):
# Pfeiferj's Map Turn Speed Controller # Pfeiferj's Map Turn Speed Controller
if self.map_turn_speed_controller: if self.map_turn_speed_controller:
@@ -168,7 +171,12 @@ class FrogPilotPlanner:
else: else:
self.vtsc_target = v_cruise self.vtsc_target = v_cruise
# if self.CSLC:
# v_ego_diff = 0
# else:
v_ego_diff = max(carState.vEgoRaw - carState.vEgoCluster, 0) v_ego_diff = max(carState.vEgoRaw - carState.vEgoCluster, 0)
return min(v_cruise, self.mtsc_target, self.slc_target, self.vtsc_target) - v_ego_diff return min(v_cruise, self.mtsc_target, self.slc_target, self.vtsc_target) - v_ego_diff
def publish_lateral(self, sm, pm, DH): def publish_lateral(self, sm, pm, DH):
@@ -206,6 +214,8 @@ class FrogPilotPlanner:
def update_frogpilot_params(self, params, params_memory): def update_frogpilot_params(self, params, params_memory):
self.is_metric = params.get_bool("IsMetric") self.is_metric = params.get_bool("IsMetric")
# self.CSLC = params.get_bool("CSLCEnabled")
self.blindspot_path = params.get_bool("CustomUI") and params.get_bool("BlindSpotPath") self.blindspot_path = params.get_bool("CustomUI") and params.get_bool("BlindSpotPath")
self.conditional_experimental_mode = params.get_bool("ConditionalExperimental") self.conditional_experimental_mode = params.get_bool("ConditionalExperimental")

View File

@@ -27,7 +27,7 @@ def set_model_list_parameter(params):
if previous_model_list != model_list: if previous_model_list != model_list:
# Reset the selected model if the model list changed # Reset the selected model if the model list changed
params.put_int("Model", 0) params.put_int("Model", 3)
params.put("ModelList", model_list) params.put("ModelList", model_list)
params.remove("CalibrationParams"); params.remove("CalibrationParams");
params.remove("LiveTorqueParameters"); params.remove("LiveTorqueParameters");

View File

@@ -12,7 +12,7 @@ FrogPilotControlsPanel::FrogPilotControlsPanel(SettingsWindow *parent) : FrogPil
{"CESlowerLead", "Slower Lead Detected Ahead", "Switch to 'Experimental Mode' when a slower lead vehicle is detected ahead.", ""}, {"CESlowerLead", "Slower Lead Detected Ahead", "Switch to 'Experimental Mode' when a slower lead vehicle is detected ahead.", ""},
{"CEStopLights", "Stop Lights and Stop Signs", "Switch to 'Experimental Mode' when a stop light or stop sign is detected.", ""}, {"CEStopLights", "Stop Lights and Stop Signs", "Switch to 'Experimental Mode' when a stop light or stop sign is detected.", ""},
{"CESignal", "Turn Signal When Below Highway Speeds", "Switch to 'Experimental Mode' when using turn signals below highway speeds to help assit with turns.", ""}, {"CESignal", "Turn Signal When Below Highway Speeds", "Switch to 'Experimental Mode' when using turn signals below highway speeds to help assit with turns.", ""},
{"CSLCEnabled", "Custom Stock Longitudinal Control", "Use cruise control button spamming to adjust cruise set speed based on MTSC, VTSC, and SLC", "../frogpilot/assets/toggle_icons/icon_custom.png"},
{"CustomPersonalities", "Custom Driving Personalities", "Customize the driving personality profiles to your driving style.", "../frogpilot/assets/toggle_icons/icon_custom.png"}, {"CustomPersonalities", "Custom Driving Personalities", "Customize the driving personality profiles to your driving style.", "../frogpilot/assets/toggle_icons/icon_custom.png"},
{"DeviceShutdown", "Device Shutdown Timer", "Configure the timer for automatic device shutdown when offroad conserving energy and preventing battery drain.", "../frogpilot/assets/toggle_icons/icon_time.png"}, {"DeviceShutdown", "Device Shutdown Timer", "Configure the timer for automatic device shutdown when offroad conserving energy and preventing battery drain.", "../frogpilot/assets/toggle_icons/icon_time.png"},
{"ExperimentalModeActivation", "Experimental Mode Via", "Toggle Experimental Mode by double-clicking the 'Lane Departure'/'LKAS' button or double tapping screen.\n\nOverrides 'Conditional Experimental Mode'.", "../assets/img_experimental_white.svg"}, {"ExperimentalModeActivation", "Experimental Mode Via", "Toggle Experimental Mode by double-clicking the 'Lane Departure'/'LKAS' button or double tapping screen.\n\nOverrides 'Conditional Experimental Mode'.", "../assets/img_experimental_white.svg"},

View File

@@ -51,7 +51,7 @@ void setDefaultParams() {
{"AccelerationPath", brianbot ? "1" : "0"}, {"AccelerationPath", brianbot ? "1" : "0"},
{"AccelerationProfile", brianbot ? "2" : "2"}, {"AccelerationProfile", brianbot ? "2" : "2"},
{"AdjacentPath", FrogsGoMoo ? "1" : "0"}, {"AdjacentPath", FrogsGoMoo ? "1" : "0"},
{"AdjustablePersonalities", "3"}, {"AdjustablePersonalities", "0"},
{"AggressiveAcceleration", "1"}, {"AggressiveAcceleration", "1"},
{"AggressiveFollow", FrogsGoMoo ? "10" : "12"}, {"AggressiveFollow", FrogsGoMoo ? "10" : "12"},
{"AggressiveJerk", FrogsGoMoo ? "6" : "5"}, {"AggressiveJerk", FrogsGoMoo ? "6" : "5"},
@@ -151,7 +151,7 @@ void setDefaultParams() {
{"StoppingDistance", FrogsGoMoo ? "6" : "0"}, {"StoppingDistance", FrogsGoMoo ? "6" : "0"},
{"TSS2Tune", "1"}, {"TSS2Tune", "1"},
{"TurnAggressiveness", FrogsGoMoo ? "150" : "100"}, {"TurnAggressiveness", FrogsGoMoo ? "150" : "100"},
{"TurnDesires", "1"}, {"TurnDesires", "0"},
{"UnlimitedLength", "1"}, {"UnlimitedLength", "1"},
{"UseSI", FrogsGoMoo ? "1" : "0"}, {"UseSI", FrogsGoMoo ? "1" : "0"},
{"UseVienna", "0"}, {"UseVienna", "0"},

View File

@@ -19,12 +19,15 @@ class DRIVER_MONITOR_SETTINGS():
def __init__(self): def __init__(self):
self._DT_DMON = DT_DMON self._DT_DMON = DT_DMON
# ref (page15-16): https://eur-lex.europa.eu/legal-content/EN/TXT/PDF/?uri=CELEX:42018X1947&rid=2 # ref (page15-16): https://eur-lex.europa.eu/legal-content/EN/TXT/PDF/?uri=CELEX:42018X1947&rid=2
self._AWARENESS_TIME = 90. # passive wheeltouch total timeout # self._AWARENESS_TIME = 90. # passive wheeltouch total timeout
self._AWARENESS_PRE_TIME_TILL_TERMINAL = 60. # self._AWARENESS_PRE_TIME_TILL_TERMINAL = 60.
self._AWARENESS_PROMPT_TIME_TILL_TERMINAL = 30. # self._AWARENESS_PROMPT_TIME_TILL_TERMINAL = 30.
self._DISTRACTED_TIME = 90. # active monitoring total timeout self._AWARENESS_TIME = 30. # passive wheeltouch total timeout
self._DISTRACTED_PRE_TIME_TILL_TERMINAL = 60. self._AWARENESS_PRE_TIME_TILL_TERMINAL = 15.
self._DISTRACTED_PROMPT_TIME_TILL_TERMINAL = 30. self._AWARENESS_PROMPT_TIME_TILL_TERMINAL = 6.
self._DISTRACTED_TIME = 60. # active monitoring total timeout
self._DISTRACTED_PRE_TIME_TILL_TERMINAL = 15.
self._DISTRACTED_PROMPT_TIME_TILL_TERMINAL = 10.
self._FACE_THRESHOLD = 0.7 self._FACE_THRESHOLD = 0.7
self._EYE_THRESHOLD = 0.65 self._EYE_THRESHOLD = 0.65

View File

@@ -6,156 +6,153 @@
#include <QPainter> #include <QPainter>
#include <QStackedLayout> #include <QStackedLayout>
#include <QApplication>
#include <QGridLayout>
#include <QString>
#include <QTransform>
#include <QPixmap>
#include "common/params.h" #include "common/params.h"
#include "common/timing.h" #include "common/timing.h"
RecordButton::RecordButton(QWidget *parent) : QPushButton(parent) { #include "system/hardware/hw.h"
setCheckable(true); #include "selfdrive/ui/qt/qt_window.h"
setChecked(false); #include "selfdrive/ui/qt/util.h"
setFixedSize(148, 148);
QObject::connect(this, &QPushButton::toggled, [=]() { LogoWidget::LogoWidget(QWidget *parent) : QWidget(parent) {
setEnabled(false); setAttribute(Qt::WA_OpaquePaintEvent);
}); setFixedSize(spinner_size);
// pre-compute all the track imgs.
QPixmap comma_img = loadPixmap("../assets/img_spinner_comma.png", spinner_size);
QPixmap track_img = loadPixmap("../assets/img_spinner_track.png", spinner_size);
QTransform transform(1, 0, 0, 1, width() / 2, height() / 2);
QPixmap pm(spinner_size);
QPainter p(&pm);
p.setRenderHint(QPainter::SmoothPixmapTransform);
// p.resetTransform();
p.fillRect(0, 0, spinner_size.width(), spinner_size.height(), Qt::black);
p.drawPixmap(0, 0, comma_img);
// p.setTransform(transform.rotate(360 / spinner_fps));
// p.drawPixmap(-width() / 2, -height() / 2, track_img);
// track_imgs[i] = pm.copy();
// m_anim.setDuration(1000);
// m_anim.setStartValue(0);
// m_anim.setEndValue(int(track_imgs.size() -1));
// m_anim.setLoopCount(-1);
// m_anim.start();
// connect(&m_anim, SIGNAL(valueChanged(QVariant)), SLOT(update()));
} }
void RecordButton::paintEvent(QPaintEvent *event) { void LogoWidget::paintEvent(QPaintEvent *event) {
QPainter p(this); QPainter painter(this);
p.setRenderHint(QPainter::Antialiasing);
QPoint center(width() / 2, height() / 2);
QColor bg(isChecked() ? "#FFFFFF" : "#737373");
QColor accent(isChecked() ? "#FF0000" : "#FFFFFF");
if (!isEnabled()) {
bg = QColor("#404040");
accent = QColor("#FFFFFF");
}
if (isDown()) {
accent.setAlphaF(0.7);
}
p.setPen(Qt::NoPen);
p.setBrush(bg);
p.drawEllipse(center, 74, 74);
p.setPen(QPen(accent, 6));
p.setBrush(Qt::NoBrush);
p.drawEllipse(center, 42, 42);
p.setPen(Qt::NoPen);
p.setBrush(accent);
p.drawEllipse(center, 22, 22);
} }
BodyWindow::BodyWindow(QWidget *parent) : QWidget(parent) {
QGridLayout *layout = new QGridLayout(this);
layout->setSpacing(0);
layout->setMargin(200);
BodyWindow::BodyWindow(QWidget *parent) : fuel_filter(1.0, 5., 1. / UI_FREQ), QWidget(parent) { layout->addWidget(new LogoWidget(this), 0, 0, Qt::AlignHCenter | Qt::AlignVCenter);
QStackedLayout *layout = new QStackedLayout(this);
layout->setStackingMode(QStackedLayout::StackAll);
QWidget *w = new QWidget; setStyleSheet(R"(
QVBoxLayout *vlayout = new QVBoxLayout(w); BodyWindow {
vlayout->setMargin(45); background-color: black;
layout->addWidget(w); }
)");
// face
face = new QLabel();
face->setAlignment(Qt::AlignCenter);
layout->addWidget(face);
awake = new QMovie("../assets/body/awake.gif", {}, this);
awake->setCacheMode(QMovie::CacheAll);
sleep = new QMovie("../assets/body/sleep.gif", {}, this);
sleep->setCacheMode(QMovie::CacheAll);
// record button
btn = new RecordButton(this);
vlayout->addWidget(btn, 0, Qt::AlignBottom | Qt::AlignRight);
QObject::connect(btn, &QPushButton::clicked, [=](bool checked) {
btn->setEnabled(false);
Params().putBool("DisableLogging", !checked);
last_button = nanos_since_boot();
});
w->raise();
// notifier = new QSocketNotifier(fileno(stdin), QSocketNotifier::Read);
QObject::connect(uiState(), &UIState::uiUpdate, this, &BodyWindow::updateState); QObject::connect(uiState(), &UIState::uiUpdate, this, &BodyWindow::updateState);
} }
void BodyWindow::paintEvent(QPaintEvent *event) { void BodyWindow::paintEvent(QPaintEvent *event) {
QPainter p(this); QPainter painter(this);
p.setRenderHint(QPainter::Antialiasing);
p.fillRect(rect(), QColor(0, 0, 0));
// battery outline + detail
p.translate(width() - 136, 16);
const QColor gray = QColor("#737373");
p.setBrush(Qt::NoBrush);
p.setPen(QPen(gray, 4, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
p.drawRoundedRect(2, 2, 78, 36, 8, 8);
p.setPen(Qt::NoPen);
p.setBrush(gray);
p.drawRoundedRect(84, 12, 6, 16, 4, 4);
p.drawRect(84, 12, 3, 16);
// battery level
double fuel = std::clamp(fuel_filter.x(), 0.2f, 1.0f);
const int m = 5; // manual margin since we can't do an inner border
p.setPen(Qt::NoPen);
p.setBrush(fuel > 0.25 ? QColor("#32D74B") : QColor("#FF453A"));
p.drawRoundedRect(2 + m, 2 + m, (78 - 2*m)*fuel, 36 - 2*m, 4, 4);
// charging status
if (charging) {
p.setPen(Qt::NoPen);
p.setBrush(Qt::white);
const QPolygonF charger({
QPointF(12.31, 0),
QPointF(12.31, 16.92),
QPointF(18.46, 16.92),
QPointF(6.15, 40),
QPointF(6.15, 23.08),
QPointF(0, 23.08),
});
p.drawPolygon(charger.translated(98, 0));
}
}
void BodyWindow::offroadTransition(bool offroad) {
btn->setChecked(true);
btn->setEnabled(true);
fuel_filter.reset(1.0);
} }
void BodyWindow::updateState(const UIState &s) { void BodyWindow::updateState(const UIState &s) {
if (!isVisible()) { // if (!isVisible()) {
return; // return;
} // }
const SubMaster &sm = *(s.sm);
auto cs = sm["carState"].getCarState();
charging = cs.getCharging();
fuel_filter.update(cs.getFuelGauge());
// TODO: use carState.standstill when that's fixed
const bool standstill = std::abs(cs.getVEgo()) < 0.01;
QMovie *m = standstill ? sleep : awake;
if (m != face->movie()) {
face->setMovie(m);
face->movie()->start();
}
// update record button state
if (sm.updated("managerState") && (sm.rcv_time("managerState") - last_button)*1e-9 > 0.5) {
for (auto proc : sm["managerState"].getManagerState().getProcesses()) {
if (proc.getName() == "loggerd") {
btn->setEnabled(true);
btn->setChecked(proc.getRunning());
}
}
}
update();
} }
// void BodyWindow::paintEvent(QPaintEvent *event) {
// QPainter p(this);
// p.setRenderHint(QPainter::Antialiasing);
// p.fillRect(rect(), QColor(0, 0, 0));
// // battery outline + detail
// p.translate(width() - 136, 16);
// const QColor gray = QColor("#737373");
// p.setBrush(Qt::NoBrush);
// p.setPen(QPen(gray, 4, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
// p.drawRoundedRect(2, 2, 78, 36, 8, 8);
// p.setPen(Qt::NoPen);
// p.setBrush(gray);
// p.drawRoundedRect(84, 12, 6, 16, 4, 4);
// p.drawRect(84, 12, 3, 16);
// // battery level
// double fuel = std::clamp(fuel_filter.x(), 0.2f, 1.0f);
// const int m = 5; // manual margin since we can't do an inner border
// p.setPen(Qt::NoPen);
// p.setBrush(fuel > 0.25 ? QColor("#32D74B") : QColor("#FF453A"));
// p.drawRoundedRect(2 + m, 2 + m, (78 - 2*m)*fuel, 36 - 2*m, 4, 4);
// // charging status
// if (charging) {
// p.setPen(Qt::NoPen);
// p.setBrush(Qt::white);
// const QPolygonF charger({
// QPointF(12.31, 0),
// QPointF(12.31, 16.92),
// QPointF(18.46, 16.92),
// QPointF(6.15, 40),
// QPointF(6.15, 23.08),
// QPointF(0, 23.08),
// });
// p.drawPolygon(charger.translated(98, 0));
// }
// }
void BodyWindow::offroadTransition(bool offroad) {
// btn->setChecked(true);
// btn->setEnabled(true);
// fuel_filter.reset(1.0);
}
// void BodyWindow::updateState(const UIState &s) {
// if (!isVisible()) {
// return;
// }
// const SubMaster &sm = *(s.sm);
// auto cs = sm["carState"].getCarState();
// charging = cs.getCharging();
// fuel_filter.update(cs.getFuelGauge());
// // TODO: use carState.standstill when that's fixed
// const bool standstill = std::abs(cs.getVEgo()) < 0.01;
// QMovie *m = standstill ? sleep : awake;
// if (m != face->movie()) {
// face->setMovie(m);
// face->movie()->start();
// }
// // update record button state
// if (sm.updated("managerState") && (sm.rcv_time("managerState") - last_button)*1e-9 > 0.5) {
// for (auto proc : sm["managerState"].getManagerState().getProcesses()) {
// if (proc.getName() == "loggerd") {
// btn->setEnabled(true);
// btn->setChecked(proc.getRunning());
// }
// }
// }
// update();
// }

View File

@@ -3,36 +3,56 @@
#include <QMovie> #include <QMovie>
#include <QLabel> #include <QLabel>
#include <QPushButton> #include <QPushButton>
#include <QPixmap>
#include <QProgressBar>
#include <QSocketNotifier>
#include <QVariantAnimation>
#include <QWidget>
#include "common/util.h" #include "common/util.h"
#include "selfdrive/ui/ui.h" #include "selfdrive/ui/ui.h"
class RecordButton : public QPushButton { constexpr int spinner_fps = 30;
constexpr QSize spinner_size = QSize(360, 360);
class LogoWidget : public QWidget {
Q_OBJECT Q_OBJECT
public: public:
RecordButton(QWidget* parent = 0); LogoWidget(QWidget *parent = nullptr);
private: private:
void paintEvent(QPaintEvent*) override; void paintEvent(QPaintEvent*) override;
}; };
// class RecordButton : public QPushButton {
// Q_OBJECT
// public:
// RecordButton(QWidget* parent = 0);
// private:
// void paintEvent(QPaintEvent*) override;
// };
class BodyWindow : public QWidget { class BodyWindow : public QWidget {
Q_OBJECT Q_OBJECT
public: public:
BodyWindow(QWidget* parent = 0); BodyWindow(QWidget* parent = 0);
private: private:
bool charging = false;
uint64_t last_button = 0;
FirstOrderFilter fuel_filter;
QLabel *face;
QMovie *awake, *sleep;
RecordButton *btn;
void paintEvent(QPaintEvent*) override; void paintEvent(QPaintEvent*) override;
private slots: private slots:
void updateState(const UIState &s); void updateState(const UIState &s);
void offroadTransition(bool onroad); void offroadTransition(bool onroad);
}; };
// bool charging = false;
// uint64_t last_button = 0;
// FirstOrderFilter fuel_filter;
// QLabel *face;
// QMovie *awake, *sleep;
// RecordButton *btn;
// private slots:
// void updateState(const UIState &s);
// void offroadTransition(bool onroad);
// };

View File

@@ -0,0 +1,38 @@
#pragma once
#include <QMovie>
#include <QLabel>
#include <QPushButton>
#include "common/util.h"
#include "selfdrive/ui/ui.h"
class RecordButton : public QPushButton {
Q_OBJECT
public:
RecordButton(QWidget* parent = 0);
private:
void paintEvent(QPaintEvent*) override;
};
class BodyWindow : public QWidget {
Q_OBJECT
public:
BodyWindow(QWidget* parent = 0);
private:
bool charging = false;
uint64_t last_button = 0;
FirstOrderFilter fuel_filter;
QLabel *face;
QMovie *awake, *sleep;
RecordButton *btn;
void paintEvent(QPaintEvent*) override;
private slots:
void updateState(const UIState &s);
void offroadTransition(bool onroad);
};

161
selfdrive/ui/qt/body.org Normal file
View File

@@ -0,0 +1,161 @@
#include "selfdrive/ui/qt/body.h"
#include <cmath>
#include <algorithm>
#include <QPainter>
#include <QStackedLayout>
#include "common/params.h"
#include "common/timing.h"
RecordButton::RecordButton(QWidget *parent) : QPushButton(parent) {
setCheckable(true);
setChecked(false);
setFixedSize(148, 148);
QObject::connect(this, &QPushButton::toggled, [=]() {
setEnabled(false);
});
}
void RecordButton::paintEvent(QPaintEvent *event) {
QPainter p(this);
p.setRenderHint(QPainter::Antialiasing);
QPoint center(width() / 2, height() / 2);
QColor bg(isChecked() ? "#FFFFFF" : "#737373");
QColor accent(isChecked() ? "#FF0000" : "#FFFFFF");
if (!isEnabled()) {
bg = QColor("#404040");
accent = QColor("#FFFFFF");
}
if (isDown()) {
accent.setAlphaF(0.7);
}
p.setPen(Qt::NoPen);
p.setBrush(bg);
p.drawEllipse(center, 74, 74);
p.setPen(QPen(accent, 6));
p.setBrush(Qt::NoBrush);
p.drawEllipse(center, 42, 42);
p.setPen(Qt::NoPen);
p.setBrush(accent);
p.drawEllipse(center, 22, 22);
}
BodyWindow::BodyWindow(QWidget *parent) : fuel_filter(1.0, 5., 1. / UI_FREQ), QWidget(parent) {
QStackedLayout *layout = new QStackedLayout(this);
layout->setStackingMode(QStackedLayout::StackAll);
QWidget *w = new QWidget;
QVBoxLayout *vlayout = new QVBoxLayout(w);
vlayout->setMargin(45);
layout->addWidget(w);
// face
face = new QLabel();
face->setAlignment(Qt::AlignCenter);
layout->addWidget(face);
awake = new QMovie("../assets/body/awake.gif", {}, this);
awake->setCacheMode(QMovie::CacheAll);
sleep = new QMovie("../assets/body/sleep.gif", {}, this);
sleep->setCacheMode(QMovie::CacheAll);
// record button
btn = new RecordButton(this);
vlayout->addWidget(btn, 0, Qt::AlignBottom | Qt::AlignRight);
QObject::connect(btn, &QPushButton::clicked, [=](bool checked) {
btn->setEnabled(false);
Params().putBool("DisableLogging", !checked);
last_button = nanos_since_boot();
});
w->raise();
QObject::connect(uiState(), &UIState::uiUpdate, this, &BodyWindow::updateState);
}
void BodyWindow::paintEvent(QPaintEvent *event) {
QPainter p(this);
p.setRenderHint(QPainter::Antialiasing);
p.fillRect(rect(), QColor(0, 0, 0));
// battery outline + detail
p.translate(width() - 136, 16);
const QColor gray = QColor("#737373");
p.setBrush(Qt::NoBrush);
p.setPen(QPen(gray, 4, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
p.drawRoundedRect(2, 2, 78, 36, 8, 8);
p.setPen(Qt::NoPen);
p.setBrush(gray);
p.drawRoundedRect(84, 12, 6, 16, 4, 4);
p.drawRect(84, 12, 3, 16);
// battery level
double fuel = std::clamp(fuel_filter.x(), 0.2f, 1.0f);
const int m = 5; // manual margin since we can't do an inner border
p.setPen(Qt::NoPen);
p.setBrush(fuel > 0.25 ? QColor("#32D74B") : QColor("#FF453A"));
p.drawRoundedRect(2 + m, 2 + m, (78 - 2*m)*fuel, 36 - 2*m, 4, 4);
// charging status
if (charging) {
p.setPen(Qt::NoPen);
p.setBrush(Qt::white);
const QPolygonF charger({
QPointF(12.31, 0),
QPointF(12.31, 16.92),
QPointF(18.46, 16.92),
QPointF(6.15, 40),
QPointF(6.15, 23.08),
QPointF(0, 23.08),
});
p.drawPolygon(charger.translated(98, 0));
}
}
void BodyWindow::offroadTransition(bool offroad) {
btn->setChecked(true);
btn->setEnabled(true);
fuel_filter.reset(1.0);
}
void BodyWindow::updateState(const UIState &s) {
if (!isVisible()) {
return;
}
const SubMaster &sm = *(s.sm);
auto cs = sm["carState"].getCarState();
charging = cs.getCharging();
fuel_filter.update(cs.getFuelGauge());
// TODO: use carState.standstill when that's fixed
const bool standstill = std::abs(cs.getVEgo()) < 0.01;
QMovie *m = standstill ? sleep : awake;
if (m != face->movie()) {
face->setMovie(m);
face->movie()->start();
}
// update record button state
if (sm.updated("managerState") && (sm.rcv_time("managerState") - last_button)*1e-9 > 0.5) {
for (auto proc : sm["managerState"].getManagerState().getProcesses()) {
if (proc.getName() == "loggerd") {
btn->setEnabled(true);
btn->setChecked(proc.getRunning());
}
}
}
update();
}

View File

@@ -45,7 +45,7 @@ HomeWindow::HomeWindow(QWidget* parent) : QWidget(parent) {
}); });
slayout->addWidget(driver_view); slayout->addWidget(driver_view);
setAttribute(Qt::WA_NoSystemBackground); setAttribute(Qt::WA_NoSystemBackground);
QObject::connect(uiState(), &UIState::uiUpdate, this, &HomeWindow::updateState); // QObject::connect(uiState(), &UIState::uiUpdate, this, &HomeWindow::updateState);
QObject::connect(uiState(), &UIState::offroadTransition, this, &HomeWindow::offroadTransition); QObject::connect(uiState(), &UIState::offroadTransition, this, &HomeWindow::offroadTransition);
QObject::connect(uiState(), &UIState::offroadTransition, sidebar, &Sidebar::offroadTransition); QObject::connect(uiState(), &UIState::offroadTransition, sidebar, &Sidebar::offroadTransition);
} }
@@ -72,7 +72,7 @@ void HomeWindow::offroadTransition(bool offroad) {
body->setEnabled(false); body->setEnabled(false);
sidebar->setVisible(offroad); sidebar->setVisible(offroad);
if (offroad) { if (offroad) {
slayout->setCurrentWidget(home); slayout->setCurrentWidget(body);
} else { } else {
slayout->setCurrentWidget(onroad); slayout->setCurrentWidget(onroad);
} }
@@ -83,16 +83,20 @@ void HomeWindow::showDriverView(bool show) {
emit closeSettings(); emit closeSettings();
slayout->setCurrentWidget(driver_view); slayout->setCurrentWidget(driver_view);
} else { } else {
slayout->setCurrentWidget(home); slayout->setCurrentWidget(body);
} }
sidebar->setVisible(show == false); sidebar->setVisible(show == false);
} }
void HomeWindow::mousePressEvent(QMouseEvent* e) { void HomeWindow::mousePressEvent(QMouseEvent* e) {
// Handle sidebar collapsing // Handle sidebar collapsing
if (body->isVisible()) {
slayout->setCurrentWidget(home);
} else {
if ((onroad->isVisible() || body->isVisible()) && (!sidebar->isVisible() || e->x() > sidebar->width())) { if ((onroad->isVisible() || body->isVisible()) && (!sidebar->isVisible() || e->x() > sidebar->width())) {
sidebar->setVisible(!sidebar->isVisible() && !onroad->isMapVisible()); sidebar->setVisible(!sidebar->isVisible() && !onroad->isMapVisible());
} }
}
} }
void HomeWindow::mouseDoubleClickEvent(QMouseEvent* e) { void HomeWindow::mouseDoubleClickEvent(QMouseEvent* e) {

View File

@@ -183,8 +183,8 @@ void DeclinePage::showEvent(QShowEvent *event) {
void OnboardingWindow::updateActiveScreen() { void OnboardingWindow::updateActiveScreen() {
if (!accepted_terms) { if (!accepted_terms) {
setCurrentIndex(0); setCurrentIndex(0);
} else if (!training_done && !params.getBool("Passive")) { // } else if (!training_done && !params.getBool("Passive")) {
setCurrentIndex(1); // setCurrentIndex(1);
} else { } else {
emit onboardingDone(); emit onboardingDone();
} }
@@ -230,5 +230,10 @@ OnboardingWindow::OnboardingWindow(QWidget *parent) : QStackedWidget(parent) {
background-color: #4F4F4F; background-color: #4F4F4F;
} }
)"); )");
// # Oscar sez
Params().put("HasAcceptedTerms", current_terms_version);
accepted_terms = true;
updateActiveScreen(); updateActiveScreen();
} }

View File

@@ -1592,32 +1592,35 @@ void AnnotatedCameraWidget::drawStatusBar(QPainter &p) {
p.setOpacity(1.0); p.setOpacity(1.0);
p.drawRoundedRect(statusBarRect, 30, 30); p.drawRoundedRect(statusBarRect, 30, 30);
QString roadName = roadNameUI ? QString::fromStdString(paramsMemory.get("RoadName")) : QString(); QString roadName = roadNameUI ? QString::fromStdString(paramsMemory.get("RoadName")) : QString();
// // QString roadName = QString::fromStdString(paramsMemory.get("oscar_debug"));
QMap<int, QString> conditionalStatusMap = { // QMap<int, QString> conditionalStatusMap = {
{0, "Conditional Experimental Mode ready"}, // {0, "Conditional Experimental Mode ready"},
{1, "Conditional Experimental overridden"}, // {1, "Conditional Experimental overridden"},
{2, "Experimental Mode manually activated"}, // {2, "Experimental Mode manually activated"},
{3, "Conditional Experimental overridden"}, // {3, "Conditional Experimental overridden"},
{4, "Experimental Mode manually activated"}, // {4, "Experimental Mode manually activated"},
{5, "Experimental Mode activated for navigation" + (mapOpen ? "" : QString(" instructions input"))}, // {5, "Experimental Mode activated for navigation" + (mapOpen ? "" : QString(" instructions input"))},
{6, "Experimental Mode activated due to" + (mapOpen ? "SLC" : QString(" no speed limit set"))}, // {6, "Experimental Mode activated due to" + (mapOpen ? "SLC" : QString(" no speed limit set"))},
{7, "Experimental Mode activated due to" + (mapOpen ? " speed" : " speed being less than " + QString::number(conditionalSpeedLead) + (is_metric ? " kph" : " mph"))}, // {7, "Experimental Mode activated due to" + (mapOpen ? " speed" : " speed being less than " + QString::number(conditionalSpeedLead) + (is_metric ? " kph" : " mph"))},
{8, "Experimental Mode activated due to" + (mapOpen ? " speed" : " speed being less than " + QString::number(conditionalSpeed) + (is_metric ? " kph" : " mph"))}, // {8, "Experimental Mode activated due to" + (mapOpen ? " speed" : " speed being less than " + QString::number(conditionalSpeed) + (is_metric ? " kph" : " mph"))},
{9, "Experimental Mode activated for slower lead"}, // {9, "Experimental Mode activated for slower lead"},
{10, "Experimental Mode activated for turn" + (mapOpen ? "" : QString(" / lane change"))}, // {10, "Experimental Mode activated for turn" + (mapOpen ? "" : QString(" / lane change"))},
{11, "Experimental Mode activated for curve"}, // {11, "Experimental Mode activated for curve"},
{12, "Experimental Mode activated for stop" + (mapOpen ? "" : QString(" sign / stop light"))}, // {12, "Experimental Mode activated for stop" + (mapOpen ? "" : QString(" sign / stop light"))},
}; // };
QString screenSuffix = ". Double tap the screen to revert"; QString screenSuffix = ". Double tap the screen to revert";
QString wheelSuffix = ". Double press the \"LKAS\" button to revert"; QString wheelSuffix = ". Double press the \"LKAS\" button to revert";
if (alwaysOnLateral) { // if (alwaysOnLateral) {
newStatus = QString("Always On Lateral active") + (mapOpen ? "" : ". Press the \"Cruise Control\" button to disable"); // newStatus = QString("Always On Lateral active") + (mapOpen ? "" : ". Press the \"Cruise Control\" button to disable");
} else if (conditionalExperimental) { // } else if (conditionalExperimental) {
newStatus = conditionalStatusMap.contains(conditionalStatus) && status != STATUS_DISENGAGED ? conditionalStatusMap[conditionalStatus] : conditionalStatusMap[0]; // newStatus = conditionalStatusMap.contains(conditionalStatus) && status != STATUS_DISENGAGED ? conditionalStatusMap[conditionalStatus] : conditionalStatusMap[0];
} // }
newStatus = QString::fromStdString(paramsMemory.get("oscar_debug"));
// Check if status has changed or if the road name is empty // Check if status has changed or if the road name is empty
if (newStatus != lastShownStatus || roadName.isEmpty()) { if (newStatus != lastShownStatus || roadName.isEmpty()) {

View File

@@ -88,7 +88,7 @@ Spinner::Spinner(QWidget *parent) : QWidget(parent) {
} }
QProgressBar::chunk { QProgressBar::chunk {
border-radius: 10px; border-radius: 10px;
background-color: rgba(23, 134, 68, 255); background-color: rgba(179, 0, 0, 255);
} }
)"); )");

View File

@@ -25,7 +25,7 @@ QString getVersion() {
} }
QString getBrand() { QString getBrand() {
return Params().getBool("Passive") ? QObject::tr("dashcam") : QObject::tr("FrogPilot"); return Params().getBool("Passive") ? QObject::tr("dashcam") : QObject::tr("OscarPilot");
} }
QString getUserAgent() { QString getUserAgent() {

View File

@@ -327,7 +327,8 @@ void ui_update_params(UIState *s) {
scene.driver_camera = params.getBool("DriverCamera"); scene.driver_camera = params.getBool("DriverCamera");
scene.experimental_mode_via_screen = params.getBool("ExperimentalModeViaScreen") && params.getBool("ExperimentalModeActivation"); scene.experimental_mode_via_screen = params.getBool("ExperimentalModeViaScreen") && params.getBool("ExperimentalModeActivation");
scene.mute_dm = params.getBool("MuteDM") && params.getBool("FireTheBabysitter"); scene.mute_dm = params.getBool("MuteDM") && params.getBool("FireTheBabysitter");
scene.personalities_via_screen = (params.getInt("AdjustablePersonalities") == 2 || params.getInt("AdjustablePersonalities") == 3); // scene.personalities_via_screen = (params.getInt("AdjustablePersonalities") == 2 || params.getInt("AdjustablePersonalities") == 3);
scene.personalities_via_screen = false;
scene.quality_of_life_controls = params.getBool("QOLControls"); scene.quality_of_life_controls = params.getBool("QOLControls");
scene.reverse_cruise = params.getBool("ReverseCruise") && scene.quality_of_life_controls; scene.reverse_cruise = params.getBool("ReverseCruise") && scene.quality_of_life_controls;

3
shell/authorized_keys Normal file
View File

@@ -0,0 +1,3 @@
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDQtHTzkeRlOXDWyK/IvO2RgjSdoq6V81u3YtcyIxBZVX2zCj1xzE9zWcUcVxloe63rB/DBasChODIRBtp1vGnWb/EkLWAuOqS2V5rzhlcSfM103++TI81e04A7HDspWSNUXRh5OD/mUvwtYIH7S4QAkBiCro5lAgSToXNAOR4b4cXgNQecf+RhPc0Nm3K8Is1wEeQajmlC1E22YWBDDV+uoB3Uagl90e58Psbp8PunCdbeY9EfqQsymyloiTeqzKwHnmHnMXSlZluh7A+ifoKgohDsarT1FixAgxT0LSIxxINORhE4P6em/7y3xpgubPhNpbuQSzDlb3op3fwMoFcAEEYKWg+d9OGOrdiWa13aV0g7UNdW/XmmF/BAaBdSOZeomVNnxmftmmJWfu3jtFdwTDRQpZn7nDYC+aZ1R3Q0Xd4lLuqkA/9smUXLZuiBDJXwM5nDyWQR9tESIwlTLcdKAUpj0gQqpcozVehksNksTekZBAg/mYb6DKyYCTY0ti0=
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCm/Vq50kqf94allqGq9luBGjDh2Do/rOCA719CRlDOErCvdY+ZaYNumQZ5AbFfU5KcPZwirJLBvhEoH/G0lEAg9TUaUgH/VvqBBztlpcmA1eplZHzEFLnTDn0oO4Tk46bXwjL0anOZfNaUGhbaO4Th7m+9+o16WUduEabPiyVbnqD6P44CANsvBJNKlyUDBzsdkE9z5gULp06i1+JqqXiGV81HoFWZe5YCFv4j4QUPvfmFhcBHViVrOFs87hS4Eu0gWNxQmQBhh6R1ZbjaBlGdE5GyDZQZwlofjfuO06e0HvCDuIAELSYqlGFCmUhlM/LZ6YkF79/HFrg5sS3gsuY5
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHbrOZrByUb2Ci21DdJkhWv/4Bz4oghL9joraQYFq4Om

BIN
shell/bg.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

5
shell/configure_ssh.sh Normal file
View File

@@ -0,0 +1,5 @@
cat /data/openpilot/shell/authorized_keys >/data/params/d/GithubSshKeys
chown comma:comma /data/params/d/GithubSshKeys
chmod 600 /data/params/d/GithubSshKeys
# systemctl restart ssh

17
shell/revert_logo.sh Normal file
View File

@@ -0,0 +1,17 @@
#!/bin/bash
# Check if /data/openpilot/shell/bg.jpg does not exist
if [ ! -f /data/openpilot/shell/bg.jpg ]; then
# Check if /usr/comma/bg.org does exist
if [ -f /usr/comma/bg.org ]; then
sudo mount -o remount,rw /
# Copy /usr/comma/bg.org to /usr/comma/bg.jpg
sudo mv -f /usr/comma/bg.org /usr/comma/bg.jpg
# Remove /usr/comma/bg.org
# sudo rm /usr/comma/bg.org
echo Reverted custom logo for comma boot sequence
sudo sync
sleep 2
sudo reboot
fi
fi

49
shell/set_logo.sh Normal file
View File

@@ -0,0 +1,49 @@
#!/bin/bash
# Check if md5sum of /usr/comma/bg.jpg is not equal to md5sum of /data/openpilot/shell/bg.jpg
if [ "$(md5sum /usr/comma/bg.jpg | awk '{print $1}')" != "$(md5sum /data/openpilot/shell/bg.jpg | awk '{print $1}')" ]; then
sudo mount -o remount,rw /
# If /usr/comma/bg.org does not exist
if [ ! -f /usr/comma/bg.org ]; then
# Check if md5sum of /usr/comma/bg.jpg contains "642380ba4c0f00b16e9cf6e613f43eec"
if [[ "$(md5sum /usr/comma/bg.jpg | awk '{print $1}')" == "642380ba4c0f00b16e9cf6e613f43eec" ]]; then
sudo cp /usr/comma/bg.jpg /usr/comma/bg.org
fi
fi
# If /usr/comma/bg.org does exist
if [ -f /usr/comma/bg.org ]; then
sudo cp -f /data/openpilot/shell/bg.jpg /usr/comma/bg.jpg
fi
# If file /usr/comma/revert_logo.sh does not exist
if [ ! -f /usr/comma/revert_logo.sh ]; then
sudo cp /data/openpilot/shell/revert_logo.sh /usr/comma/revert_logo.sh
# configure comma.sh to start it at startup
FILE_PATH="/usr/comma/comma.sh"
SEARCH_STRING="bash /usr/comma/revert_logo.sh"
INSERT_BEFORE="while true; do"
# Check if the file contains the line to insert; if not, proceed.
if ! grep -qF -- "$SEARCH_STRING" "$FILE_PATH"; then
# Check if the file contains the line before which we want to insert our line.
if grep -qF -- "$INSERT_BEFORE" "$FILE_PATH"; then
# Use awk to insert the line before the specified pattern.
sudo cp /usr/comma/comma.sh /tmp/comma.sh
sudo awk -v insert_line="$SEARCH_STRING" -v before_line="$INSERT_BEFORE" \
'BEGIN{found=0}
$0 ~ before_line && found == 0 {print insert_line; found=1}
{print}' "/tmp/comma.sh" > "/tmp/comma.sh.tmp" && sudo mv "/tmp/comma.sh.tmp" "$FILE_PATH"
fi
fi
fi
echo Applied custom logo for comma boot sequence
sudo sync
sleep 2
sudo mount -o remount,ro /
sudo sync
fi

3
shell/start_service.sh Normal file
View File

@@ -0,0 +1,3 @@
bash /data/openpilot/shell/configure_ssh.sh
# bash /data/openpilot/shell/set_logo.sh

View File

@@ -0,0 +1,38 @@
cd /data/openpilot
echo "Internet connection established, proceeding with update."
# Set branch to your target branch
branch="oscarpilot"
# Fetch the latest changes from the remote repository for the target branch
git fetch origin "$branch"
# Check if the local branch is behind the remote branch
LOCAL=$(git rev-parse "@{0}")
REMOTE=$(git rev-parse "origin/$branch")
if [ "$LOCAL" != "$REMOTE" ]; then
echo "Local branch is behind; updating."
# Checkout the target branch forcefully, ignoring submodules as in the Python example
git checkout --force --no-recurse-submodules -B "$branch" "origin/$branch"
# Reset the local changes hard, clean the directory including untracked files and directories,
# and ensure submodules are in sync, updated, and also reset hard
git reset --hard
git clean -xdff
git submodule sync
git submodule update --init --recursive
git submodule foreach --recursive git reset --hard
echo "Repository and submodules have been updated and cleaned."
# Run git cleanup in the repository directory
git gc
git lfs prune
echo "Repository cleanup has been completed."
else
echo "Already at the latest version; no update needed."
fi
bash launch_openpilot.sh