Compare commits
75 Commits
FrogPilot
...
154eee2f08
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
154eee2f08 | ||
|
|
b3d781ef26 | ||
|
|
9eee0333ec | ||
|
|
dc1ee37053 | ||
|
|
05c45829f8 | ||
|
|
808fc67534 | ||
|
|
ee9802a513 | ||
|
|
dc9dfa03e9 | ||
|
|
17bc9cf1f3 | ||
|
|
b8aecdb78c | ||
|
|
e2ebe7048c | ||
|
|
794b1d8bdd | ||
|
|
fccc1221f6 | ||
|
|
4bbc34c365 | ||
|
|
589c5dfc82 | ||
|
|
ff80bfe06a | ||
|
|
f1c84854ed | ||
|
|
d6404224fa | ||
|
|
9fd53b7ec1 | ||
|
|
a82120e55e | ||
|
|
99006f0f6c | ||
|
|
0f5573f493 | ||
|
|
73315b7009 | ||
|
|
821d9c5807 | ||
|
|
ebad1a29b2 | ||
|
|
00bef387df | ||
|
|
13db24e327 | ||
|
|
7f7d487723 | ||
|
|
50dd50f0a7 | ||
|
|
3fc6fa0b52 | ||
|
|
412553e741 | ||
|
|
0f7641ea39 | ||
|
|
b98b001ceb | ||
|
|
af0fc9daec | ||
|
|
e10db32b69 | ||
|
|
e034f72f3d | ||
|
|
2803846987 | ||
|
|
9634f1b2e6 | ||
|
|
8f817dffd6 | ||
|
|
a380603637 | ||
|
|
9e67df39d3 | ||
|
|
2236323030 | ||
|
|
829b75411b | ||
|
|
da6553c24d | ||
|
|
4948aecc6e | ||
|
|
be628a964e | ||
|
|
52c28f6710 | ||
|
|
8d971f0671 | ||
|
|
88785baa11 | ||
|
|
b5fd185742 | ||
|
|
ad5e06b0ad | ||
|
|
96aa4c3e93 | ||
|
|
5307871310 | ||
|
|
90b8e9f072 | ||
|
|
7853d218a3 | ||
|
|
f931d2982e | ||
|
|
38a3903009 | ||
|
|
2964ede91a | ||
|
|
7949e90b75 | ||
|
|
a7e39e1ccf | ||
|
|
26af5117de | ||
|
|
a8a7c6a20c | ||
|
|
7fb4b58320 | ||
|
|
377c6e3021 | ||
|
|
9213866846 | ||
|
|
67178ebc4b | ||
|
|
746d9fc631 | ||
|
|
e55aa65d18 | ||
|
|
a4f130ba44 | ||
|
|
a81f6285c1 | ||
|
|
072ed7e50f | ||
|
|
425594dd0c | ||
|
|
b7cb5c8893 | ||
|
|
705a30835a | ||
|
|
76f2507503 |
1
.gitattributes
vendored
Normal file
@@ -0,0 +1 @@
|
||||
*.onnx filter=lfs diff=lfs merge=lfs -text
|
||||
29
README.md
@@ -1,14 +1,33 @@
|
||||
This is oscarpilot. It is a mod of frogpilot.
|
||||
|
||||
- increased driver monitor timeouts to 30 sec warn / 60 second fatal
|
||||
- changed some default settings, notably farmville model default
|
||||
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
|
||||
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 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
|
||||
is at your own risk. To the greatest extent possible, by using this software, you agree to free Brian Hanson, frogpilot, and openpilot
|
||||
of any liability by your unauthorized choice to use this software, and you use at your own risk.
|
||||
- increased driver monitor timeouts to 10 sec warn / 60 second terminate.
|
||||
- Justification:
|
||||
- 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.
|
||||
|
||||

|
||||
|
||||
|
||||
1
commit_and_push
Normal file
@@ -0,0 +1 @@
|
||||
git add -A; git commit -m "wip"; bash push_private
|
||||
@@ -244,6 +244,10 @@ std::unordered_map<std::string, uint32_t> keys = {
|
||||
{"Compass", PERSISTENT},
|
||||
{"ConditionalExperimental", PERSISTENT},
|
||||
{"CurrentRandomEvent", PERSISTENT},
|
||||
{"CSLCAvailable", PERSISTENT},
|
||||
{"CSLCEnabled", PERSISTENT},
|
||||
{"CSLCSetSpeed", PERSISTENT},
|
||||
{"CSLCTempSpeed", PERSISTENT},
|
||||
{"CurveSensitivity", PERSISTENT},
|
||||
{"CustomColors", PERSISTENT},
|
||||
{"CustomIcons", PERSISTENT},
|
||||
@@ -327,6 +331,7 @@ std::unordered_map<std::string, uint32_t> keys = {
|
||||
{"ReverseCruise", PERSISTENT},
|
||||
{"RoadEdgesWidth", PERSISTENT},
|
||||
{"RoadName", PERSISTENT},
|
||||
{"oscar_debug", PERSISTENT},
|
||||
{"RoadNameUI", PERSISTENT},
|
||||
{"RotatingWheel", PERSISTENT},
|
||||
{"SchedulePending", PERSISTENT},
|
||||
|
||||
2457
hyundai_can_full.dbc
Normal file
@@ -1,5 +1,12 @@
|
||||
#!/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"
|
||||
exec ./launch_chffrplus.sh
|
||||
|
||||
|
||||
40
notes
Normal 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
|
||||
@@ -273,7 +273,8 @@ static bool hyundai_tx_hook(CANPacket_t *to_send) {
|
||||
|
||||
bool allowed_resume = (button == 1) && controls_allowed;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -247,8 +247,9 @@ static bool hyundai_canfd_tx_hook(CANPacket_t *to_send) {
|
||||
int button = GET_BYTE(to_send, 2) & 0x7U;
|
||||
bool is_cancel = (button == HYUNDAI_BTN_CANCEL);
|
||||
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) {
|
||||
tx = false;
|
||||
}
|
||||
|
||||
1
push_github
Normal file
@@ -0,0 +1 @@
|
||||
GIT_SSH_COMMAND='ssh -i ~/.ssh/id_rsa_brianhansonxyzgithub -o IdentitiesOnly=yes' git push github oscarpilot
|
||||
1
push_private
Normal file
@@ -0,0 +1 @@
|
||||
git push origin oscarpilot
|
||||
|
Before Width: | Height: | Size: 108 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 69 KiB After Width: | Height: | Size: 2.8 KiB |
210
selfdrive/car/hyundai/carcontroller.org
Normal 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
|
||||
@@ -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.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
|
||||
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
|
||||
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
|
||||
# All slightly below EPS thresholds to avoid fault
|
||||
MAX_ANGLE = 85
|
||||
@@ -55,11 +59,17 @@ class CarController:
|
||||
self.apply_steer_last = 0
|
||||
self.car_fingerprint = CP.carFingerprint
|
||||
self.last_button_frame = 0
|
||||
self.last_resume_frame = 0
|
||||
self.last_debug_frame = 0
|
||||
|
||||
def update(self, CC, CS, now_nanos, sport_plus):
|
||||
actuators = CC.actuators
|
||||
hud_control = CC.hudControl
|
||||
|
||||
# hud_v_cruise = hud_control.setSpeed
|
||||
# if hud_v_cruise > 70:
|
||||
# hud_v_cruise = 0
|
||||
|
||||
# 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)
|
||||
@@ -113,11 +123,12 @@ class CarController:
|
||||
# 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
|
||||
# MODIFIED BBOT
|
||||
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))
|
||||
|
||||
# MODIFIED BBOT
|
||||
# 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))
|
||||
@@ -126,6 +137,8 @@ class CarController:
|
||||
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.append(hyundaicanfd.create_misc_messages(self.packer, self.CAN, self.frame))
|
||||
|
||||
if self.CP.openpilotLongitudinalControl:
|
||||
if hda2:
|
||||
can_sends.extend(hyundaicanfd.create_adrv_messages(self.packer, self.CAN, self.frame))
|
||||
@@ -135,7 +148,7 @@ class CarController:
|
||||
self.accel_last = accel
|
||||
else:
|
||||
# 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:
|
||||
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,
|
||||
@@ -165,6 +178,31 @@ class CarController:
|
||||
if self.frame % 50 == 0 and self.CP.openpilotLongitudinalControl:
|
||||
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.steer = apply_steer / self.params.STEER_MAX
|
||||
new_actuators.steerOutputCan = apply_steer
|
||||
@@ -173,20 +211,44 @@ class CarController:
|
||||
self.frame += 1
|
||||
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 = []
|
||||
|
||||
# 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 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
|
||||
# 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)
|
||||
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:
|
||||
# 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
|
||||
if CC.cruiseControl.cancel:
|
||||
if self.CP.flags & HyundaiFlags.CANFD_ALT_BUTTONS:
|
||||
@@ -199,12 +261,67 @@ class CarController:
|
||||
|
||||
# cruise standstill resume
|
||||
elif CC.cruiseControl.resume:
|
||||
if (self.frame - self.last_button_frame) * DT_CTRL > 4:
|
||||
if self.CP.flags & HyundaiFlags.CANFD_ALT_BUTTONS:
|
||||
# TODO: resume for alt button cars
|
||||
pass
|
||||
# for _ in range(20):
|
||||
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:
|
||||
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
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
@@ -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, \
|
||||
CANFD_CAR, EV_CAR, HYBRID_CAR, Buttons, CarControllerParams
|
||||
from openpilot.selfdrive.car.interfaces import CarStateBase
|
||||
from openpilot.selfdrive.frogpilot.functions.speed_limit_controller import SpeedLimitController
|
||||
|
||||
PREV_BUTTON_SAMPLES = 8
|
||||
CLUSTER_SAMPLE_RATE = 20 # frames
|
||||
@@ -167,36 +168,51 @@ class CarState(CarStateBase):
|
||||
if self.prev_main_buttons == 0 and self.main_buttons[-1] != 0:
|
||||
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
|
||||
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)
|
||||
# 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
|
||||
# # 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
|
||||
# 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["BCM_PO_11"]["LFA_Pressed"]
|
||||
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
|
||||
# # Toggle Experimental Mode from steering wheel function
|
||||
# if self.experimental_mode_via_lkas and ret.cruiseState.available:
|
||||
# lkas_pressed = cp.vl["BCM_PO_11"]["LFA_Pressed"]
|
||||
# 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
|
||||
|
||||
@@ -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
|
||||
else cp_cam.vl["CAM_0x2a4"])
|
||||
|
||||
# Driving personalities function
|
||||
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)
|
||||
SpeedLimitController.load_state()
|
||||
SpeedLimitController.car_speed_limit = self.calculate_speed_limit_canfd(self.CP, cp, cp_cam) * speed_factor
|
||||
SpeedLimitController.write_car_state()
|
||||
|
||||
# self.custom_speed_up = 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:
|
||||
self.param_memory.put_bool("PersonalityChangedViaWheel", True)
|
||||
self.personality_profile = (self.previous_personality_profile + 2) % 3
|
||||
self.oscar_lane_center_btn_pressed = True
|
||||
|
||||
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 = False
|
||||
try:
|
||||
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
|
||||
except:
|
||||
nothing = 0
|
||||
|
||||
# intentionally cause a failure
|
||||
if lkas_pressed:
|
||||
floog=norpdywoop
|
||||
# if self.cruise_buttons[-1] == Buttons.GAP_DIST and self.prev_cruise_buttons == 0:
|
||||
# self.oscar_lane_center_btn_pressed= True
|
||||
|
||||
# Driving personalities function
|
||||
# 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
|
||||
|
||||
# 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):
|
||||
if CP.carFingerprint in CANFD_CAR:
|
||||
return self.get_can_parser_canfd(CP)
|
||||
@@ -415,6 +463,9 @@ class CarState(CarStateBase):
|
||||
("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:
|
||||
messages += [
|
||||
("SCC_CONTROL", 50),
|
||||
@@ -433,4 +484,6 @@ class CarState(CarStateBase):
|
||||
("SCC_CONTROL", 50),
|
||||
]
|
||||
|
||||
|
||||
|
||||
return CANParser(DBC[CP.carFingerprint]["pt"], messages, CanBus(CP).CAM)
|
||||
|
||||
@@ -41,7 +41,7 @@ def create_steering_messages(packer, CP, CAN, enabled, lat_active, apply_steer):
|
||||
|
||||
values = {
|
||||
"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,
|
||||
"LKA_ASSIST": 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):
|
||||
values = {
|
||||
"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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
def create_spas_messages(packer, CAN, frame, left_blink, right_blink):
|
||||
ret = []
|
||||
|
||||
|
||||
@@ -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.interfaces import CarInterfaceBase
|
||||
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
|
||||
SafetyModel = car.CarParams.SafetyModel
|
||||
@@ -35,6 +38,7 @@ class CarInterface(CarInterfaceBase):
|
||||
def _get_params(ret, candidate, fingerprint, car_fw, experimental_long, docs):
|
||||
ret.carName = "hyundai"
|
||||
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 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 0x110 in fingerprint[CAN.CAM]:
|
||||
ret.flags |= HyundaiFlags.CANFD_HDA2_ALT_STEERING.value
|
||||
params_memory.put_bool("CSLCAvailable", False)
|
||||
else:
|
||||
# non-HDA2
|
||||
if 0x1cf not in fingerprint[CAN.ECAN]:
|
||||
@@ -291,10 +296,12 @@ class CarInterface(CarInterfaceBase):
|
||||
ret.longitudinalActuatorDelayUpperBound = 0.5
|
||||
|
||||
# *** feature detection ***
|
||||
if candidate in CANFD_CAR:
|
||||
ret.enableBsm = 0x1e5 in fingerprint[CAN.ECAN]
|
||||
else:
|
||||
ret.enableBsm = 0x58b in fingerprint[0]
|
||||
# if candidate in CANFD_CAR:
|
||||
# ret.enableBsm = 0x1e5 in fingerprint[CAN.ECAN]
|
||||
# ret.nav_msg = 0x544 in fingerprint[0]
|
||||
# else:
|
||||
# ret.enableBsm = 0x58b in fingerprint[0]
|
||||
# ret.nav_msg = False
|
||||
|
||||
# *** panda safety config ***
|
||||
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
|
||||
if ret.openpilotLongitudinalControl:
|
||||
ret.safetyConfigs[-1].safetyParam |= Panda.FLAG_HYUNDAI_LONG
|
||||
params_memory.put_bool("CSLCAvailable", False)
|
||||
if candidate in HYBRID_CAR:
|
||||
ret.safetyConfigs[-1].safetyParam |= Panda.FLAG_HYUNDAI_HYBRID_GAS
|
||||
elif candidate in EV_CAR:
|
||||
|
||||
@@ -605,6 +605,7 @@ class Controls:
|
||||
self.state = State.enabled
|
||||
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.frogpilot_variables, self.experimental_mode, self.conditional_experimental_mode)
|
||||
|
||||
# Check if openpilot is engaged and actuators are enabled
|
||||
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.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)
|
||||
|
||||
# Check which actuators can be enabled
|
||||
@@ -1002,6 +1003,8 @@ class Controls:
|
||||
|
||||
self.average_desired_curvature = self.params.get_bool("AverageCurvature")
|
||||
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_sounds = self.params.get_int("CustomSounds") if custom_theme else 0
|
||||
|
||||
@@ -92,6 +92,7 @@ class DesireHelper:
|
||||
self.lane_change_state = LaneChangeState.off
|
||||
self.lane_change_direction = LaneChangeDirection.none
|
||||
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
|
||||
# Set the "turn_completed" flag to prevent lane changes after completing a turn
|
||||
self.turn_completed = True
|
||||
|
||||
@@ -139,6 +139,11 @@ class VCruiseHelper:
|
||||
if self.CP.pcmCruise:
|
||||
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
|
||||
|
||||
# 250kph or above probably means we never had a set speed
|
||||
|
||||
@@ -231,7 +231,7 @@ def startup_master_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubM
|
||||
if "REPLAY" in os.environ:
|
||||
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:
|
||||
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: {
|
||||
ET.PERMANENT: startup_master_alert,
|
||||
# ET.PERMANENT: startup_master_alert,
|
||||
ET.PERMANENT: StartupAlert("OscarPilot Ready"),
|
||||
},
|
||||
|
||||
# Car is recognized, but marked as dashcam only
|
||||
|
||||
|
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 1.8 KiB |
@@ -135,7 +135,7 @@ class ConditionalExperimentalMode:
|
||||
self.lead_detection(radarState)
|
||||
self.road_curvature(modelData, 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_lead_slowing_down(mpc, radarState)
|
||||
|
||||
|
||||
@@ -56,6 +56,7 @@ def calculate_lane_width(lane, current_lane, road_edge):
|
||||
|
||||
class FrogPilotPlanner:
|
||||
def __init__(self, params, params_memory):
|
||||
self.params_memory = params_memory
|
||||
self.cem = ConditionalExperimentalMode()
|
||||
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 = 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):
|
||||
# Pfeiferj's Map Turn Speed Controller
|
||||
if self.map_turn_speed_controller:
|
||||
@@ -168,7 +171,12 @@ class FrogPilotPlanner:
|
||||
else:
|
||||
self.vtsc_target = v_cruise
|
||||
|
||||
# if self.CSLC:
|
||||
# v_ego_diff = 0
|
||||
# else:
|
||||
|
||||
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
|
||||
|
||||
def publish_lateral(self, sm, pm, DH):
|
||||
@@ -206,6 +214,8 @@ class FrogPilotPlanner:
|
||||
def update_frogpilot_params(self, params, params_memory):
|
||||
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.conditional_experimental_mode = params.get_bool("ConditionalExperimental")
|
||||
|
||||
@@ -27,7 +27,7 @@ def set_model_list_parameter(params):
|
||||
|
||||
if previous_model_list != model_list:
|
||||
# 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.remove("CalibrationParams");
|
||||
params.remove("LiveTorqueParameters");
|
||||
|
||||
@@ -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.", ""},
|
||||
{"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.", ""},
|
||||
|
||||
{"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"},
|
||||
{"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"},
|
||||
|
||||
@@ -45,13 +45,13 @@ void setDefaultParams() {
|
||||
Params params = Params();
|
||||
bool FrogsGoMoo = params.get("DongleId").substr(0, 3) == "be6";
|
||||
|
||||
bool brianbot = true;
|
||||
bool brianbot = params.get("DongleId").substr(0, 6) == "90bb71";
|
||||
|
||||
std::map<std::string, std::string> defaultValues {
|
||||
{"AccelerationPath", brianbot ? "1" : "0"},
|
||||
{"AccelerationProfile", brianbot ? "2" : "2"},
|
||||
{"AdjacentPath", FrogsGoMoo ? "1" : "0"},
|
||||
{"AdjustablePersonalities", "3"},
|
||||
{"AdjustablePersonalities", "0"},
|
||||
{"AggressiveAcceleration", "1"},
|
||||
{"AggressiveFollow", FrogsGoMoo ? "10" : "12"},
|
||||
{"AggressiveJerk", FrogsGoMoo ? "6" : "5"},
|
||||
@@ -151,7 +151,7 @@ void setDefaultParams() {
|
||||
{"StoppingDistance", FrogsGoMoo ? "6" : "0"},
|
||||
{"TSS2Tune", "1"},
|
||||
{"TurnAggressiveness", FrogsGoMoo ? "150" : "100"},
|
||||
{"TurnDesires", "1"},
|
||||
{"TurnDesires", "0"},
|
||||
{"UnlimitedLength", "1"},
|
||||
{"UseSI", FrogsGoMoo ? "1" : "0"},
|
||||
{"UseVienna", "0"},
|
||||
|
||||
@@ -91,7 +91,7 @@ public:
|
||||
background-color: #4a4a4a;
|
||||
}
|
||||
QPushButton:checked:enabled {
|
||||
background-color: #33Ab4C;
|
||||
background-color: #0048FF;
|
||||
}
|
||||
QPushButton:disabled {
|
||||
color: #33E4E4E4;
|
||||
@@ -202,7 +202,7 @@ public:
|
||||
background-color: #4a4a4a;
|
||||
}
|
||||
QPushButton:checked:enabled {
|
||||
background-color: #33Ab4C;
|
||||
background-color: #0048FF;
|
||||
}
|
||||
QPushButton:disabled {
|
||||
color: #33E4E4E4;
|
||||
@@ -523,7 +523,7 @@ public:
|
||||
background-color: #4a4a4a;
|
||||
}
|
||||
QPushButton:checked:enabled {
|
||||
background-color: #33Ab4C;
|
||||
background-color: #0048FF;
|
||||
}
|
||||
QPushButton:disabled {
|
||||
color: #33E4E4E4;
|
||||
|
||||
@@ -19,12 +19,15 @@ class DRIVER_MONITOR_SETTINGS():
|
||||
def __init__(self):
|
||||
self._DT_DMON = DT_DMON
|
||||
# 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_PRE_TIME_TILL_TERMINAL = 60.
|
||||
self._AWARENESS_PROMPT_TIME_TILL_TERMINAL = 30.
|
||||
self._DISTRACTED_TIME = 90. # active monitoring total timeout
|
||||
self._DISTRACTED_PRE_TIME_TILL_TERMINAL = 60.
|
||||
self._DISTRACTED_PROMPT_TIME_TILL_TERMINAL = 30.
|
||||
# self._AWARENESS_TIME = 90. # passive wheeltouch total timeout
|
||||
# self._AWARENESS_PRE_TIME_TILL_TERMINAL = 60.
|
||||
# self._AWARENESS_PROMPT_TIME_TILL_TERMINAL = 30.
|
||||
self._AWARENESS_TIME = 30. # passive wheeltouch total timeout
|
||||
self._AWARENESS_PRE_TIME_TILL_TERMINAL = 15.
|
||||
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._EYE_THRESHOLD = 0.65
|
||||
|
||||
@@ -6,156 +6,154 @@
|
||||
#include <QPainter>
|
||||
#include <QStackedLayout>
|
||||
|
||||
#include <QApplication>
|
||||
#include <QGridLayout>
|
||||
#include <QString>
|
||||
#include <QTransform>
|
||||
#include <QPixmap>
|
||||
|
||||
#include "common/params.h"
|
||||
#include "common/timing.h"
|
||||
|
||||
RecordButton::RecordButton(QWidget *parent) : QPushButton(parent) {
|
||||
setCheckable(true);
|
||||
setChecked(false);
|
||||
setFixedSize(148, 148);
|
||||
#include "system/hardware/hw.h"
|
||||
#include "selfdrive/ui/qt/qt_window.h"
|
||||
#include "selfdrive/ui/qt/util.h"
|
||||
|
||||
QObject::connect(this, &QPushButton::toggled, [=]() {
|
||||
setEnabled(false);
|
||||
});
|
||||
LogoWidget::LogoWidget(QWidget *parent) : QWidget(parent) {
|
||||
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.fillRect(0, 0, spinner_size.width(), spinner_size.height(), Qt::red);
|
||||
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) {
|
||||
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);
|
||||
void LogoWidget::paintEvent(QPaintEvent *event) {
|
||||
QPainter painter(this);
|
||||
}
|
||||
|
||||
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) {
|
||||
QStackedLayout *layout = new QStackedLayout(this);
|
||||
layout->setStackingMode(QStackedLayout::StackAll);
|
||||
layout->addWidget(new LogoWidget(this), 0, 0, Qt::AlignHCenter | Qt::AlignVCenter);
|
||||
|
||||
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();
|
||||
setStyleSheet(R"(
|
||||
BodyWindow {
|
||||
background-color: blue;
|
||||
}
|
||||
)");
|
||||
|
||||
// notifier = new QSocketNotifier(fileno(stdin), QSocketNotifier::Read);
|
||||
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);
|
||||
QPainter painter(this);
|
||||
}
|
||||
|
||||
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();
|
||||
// if (!isVisible()) {
|
||||
// return;
|
||||
// }
|
||||
}
|
||||
|
||||
// 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();
|
||||
// }
|
||||
|
||||
@@ -3,36 +3,56 @@
|
||||
#include <QMovie>
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
#include <QPixmap>
|
||||
#include <QProgressBar>
|
||||
#include <QSocketNotifier>
|
||||
#include <QVariantAnimation>
|
||||
#include <QWidget>
|
||||
|
||||
|
||||
#include "common/util.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
|
||||
|
||||
public:
|
||||
RecordButton(QWidget* parent = 0);
|
||||
|
||||
LogoWidget(QWidget *parent = nullptr);
|
||||
private:
|
||||
void paintEvent(QPaintEvent*) override;
|
||||
};
|
||||
|
||||
// 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);
|
||||
};
|
||||
|
||||
// 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);
|
||||
// };
|
||||
|
||||
38
selfdrive/ui/qt/body.h.org
Normal 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
@@ -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();
|
||||
}
|
||||
@@ -45,7 +45,7 @@ HomeWindow::HomeWindow(QWidget* parent) : QWidget(parent) {
|
||||
});
|
||||
slayout->addWidget(driver_view);
|
||||
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, sidebar, &Sidebar::offroadTransition);
|
||||
}
|
||||
@@ -72,7 +72,7 @@ void HomeWindow::offroadTransition(bool offroad) {
|
||||
body->setEnabled(false);
|
||||
sidebar->setVisible(offroad);
|
||||
if (offroad) {
|
||||
slayout->setCurrentWidget(home);
|
||||
slayout->setCurrentWidget(body);
|
||||
} else {
|
||||
slayout->setCurrentWidget(onroad);
|
||||
}
|
||||
@@ -83,16 +83,20 @@ void HomeWindow::showDriverView(bool show) {
|
||||
emit closeSettings();
|
||||
slayout->setCurrentWidget(driver_view);
|
||||
} else {
|
||||
slayout->setCurrentWidget(home);
|
||||
slayout->setCurrentWidget(body);
|
||||
}
|
||||
sidebar->setVisible(show == false);
|
||||
}
|
||||
|
||||
void HomeWindow::mousePressEvent(QMouseEvent* e) {
|
||||
// Handle sidebar collapsing
|
||||
if (body->isVisible()) {
|
||||
slayout->setCurrentWidget(home);
|
||||
} else {
|
||||
if ((onroad->isVisible() || body->isVisible()) && (!sidebar->isVisible() || e->x() > sidebar->width())) {
|
||||
sidebar->setVisible(!sidebar->isVisible() && !onroad->isMapVisible());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HomeWindow::mouseDoubleClickEvent(QMouseEvent* e) {
|
||||
|
||||
@@ -183,8 +183,8 @@ void DeclinePage::showEvent(QShowEvent *event) {
|
||||
void OnboardingWindow::updateActiveScreen() {
|
||||
if (!accepted_terms) {
|
||||
setCurrentIndex(0);
|
||||
} else if (!training_done && !params.getBool("Passive")) {
|
||||
setCurrentIndex(1);
|
||||
// } else if (!training_done && !params.getBool("Passive")) {
|
||||
// setCurrentIndex(1);
|
||||
} else {
|
||||
emit onboardingDone();
|
||||
}
|
||||
@@ -230,5 +230,10 @@ OnboardingWindow::OnboardingWindow(QWidget *parent) : QStackedWidget(parent) {
|
||||
background-color: #4F4F4F;
|
||||
}
|
||||
)");
|
||||
|
||||
// # Oscar sez
|
||||
// Params().put("HasAcceptedTerms", current_terms_version);
|
||||
// accepted_terms = true;
|
||||
|
||||
updateActiveScreen();
|
||||
}
|
||||
|
||||
@@ -1592,32 +1592,35 @@ void AnnotatedCameraWidget::drawStatusBar(QPainter &p) {
|
||||
p.setOpacity(1.0);
|
||||
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 = {
|
||||
{0, "Conditional Experimental Mode ready"},
|
||||
{1, "Conditional Experimental overridden"},
|
||||
{2, "Experimental Mode manually activated"},
|
||||
{3, "Conditional Experimental overridden"},
|
||||
{4, "Experimental Mode manually activated"},
|
||||
{5, "Experimental Mode activated for navigation" + (mapOpen ? "" : QString(" instructions input"))},
|
||||
{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"))},
|
||||
{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"},
|
||||
{10, "Experimental Mode activated for turn" + (mapOpen ? "" : QString(" / lane change"))},
|
||||
{11, "Experimental Mode activated for curve"},
|
||||
{12, "Experimental Mode activated for stop" + (mapOpen ? "" : QString(" sign / stop light"))},
|
||||
};
|
||||
// QMap<int, QString> conditionalStatusMap = {
|
||||
// {0, "Conditional Experimental Mode ready"},
|
||||
// {1, "Conditional Experimental overridden"},
|
||||
// {2, "Experimental Mode manually activated"},
|
||||
// {3, "Conditional Experimental overridden"},
|
||||
// {4, "Experimental Mode manually activated"},
|
||||
// {5, "Experimental Mode activated for navigation" + (mapOpen ? "" : QString(" instructions input"))},
|
||||
// {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"))},
|
||||
// {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"},
|
||||
// {10, "Experimental Mode activated for turn" + (mapOpen ? "" : QString(" / lane change"))},
|
||||
// {11, "Experimental Mode activated for curve"},
|
||||
// {12, "Experimental Mode activated for stop" + (mapOpen ? "" : QString(" sign / stop light"))},
|
||||
// };
|
||||
|
||||
QString screenSuffix = ". Double tap the screen to revert";
|
||||
QString wheelSuffix = ". Double press the \"LKAS\" button to revert";
|
||||
|
||||
if (alwaysOnLateral) {
|
||||
newStatus = QString("Always On Lateral active") + (mapOpen ? "" : ". Press the \"Cruise Control\" button to disable");
|
||||
} else if (conditionalExperimental) {
|
||||
newStatus = conditionalStatusMap.contains(conditionalStatus) && status != STATUS_DISENGAGED ? conditionalStatusMap[conditionalStatus] : conditionalStatusMap[0];
|
||||
}
|
||||
// if (alwaysOnLateral) {
|
||||
// newStatus = QString("Always On Lateral active") + (mapOpen ? "" : ". Press the \"Cruise Control\" button to disable");
|
||||
// } else if (conditionalExperimental) {
|
||||
// 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
|
||||
if (newStatus != lastShownStatus || roadName.isEmpty()) {
|
||||
|
||||
@@ -88,7 +88,7 @@ Spinner::Spinner(QWidget *parent) : QWidget(parent) {
|
||||
}
|
||||
QProgressBar::chunk {
|
||||
border-radius: 10px;
|
||||
background-color: rgba(23, 134, 68, 255);
|
||||
background-color: rgba(179, 0, 0, 255);
|
||||
}
|
||||
)");
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ QString getVersion() {
|
||||
}
|
||||
|
||||
QString getBrand() {
|
||||
return Params().getBool("Passive") ? QObject::tr("dashcam") : QObject::tr("FrogPilot");
|
||||
return Params().getBool("Passive") ? QObject::tr("dashcam") : QObject::tr("OscarPilot");
|
||||
}
|
||||
|
||||
QString getUserAgent() {
|
||||
|
||||
@@ -327,7 +327,8 @@ void ui_update_params(UIState *s) {
|
||||
scene.driver_camera = params.getBool("DriverCamera");
|
||||
scene.experimental_mode_via_screen = params.getBool("ExperimentalModeViaScreen") && params.getBool("ExperimentalModeActivation");
|
||||
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.reverse_cruise = params.getBool("ReverseCruise") && scene.quality_of_life_controls;
|
||||
|
||||
3
shell/authorized_keys
Normal 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
|
After Width: | Height: | Size: 44 KiB |
5
shell/configure_ssh.sh
Normal 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
@@ -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
@@ -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
@@ -0,0 +1,3 @@
|
||||
bash /data/openpilot/shell/configure_ssh.sh
|
||||
bash /data/openpilot/shell/set_logo.sh
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
[
|
||||
{
|
||||
"name": "boot",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/boot-fd30f580375279ff4605034ec13711890a2b227205571a087cdc5226a2710275.img.xz",
|
||||
"url": "https://op.labythan.com/agnos/boot-fd30f580375279ff4605034ec13711890a2b227205571a087cdc5226a2710275.img.xz",
|
||||
"hash": "fd30f580375279ff4605034ec13711890a2b227205571a087cdc5226a2710275",
|
||||
"hash_raw": "fd30f580375279ff4605034ec13711890a2b227205571a087cdc5226a2710275",
|
||||
"size": 15636480,
|
||||
@@ -11,7 +11,7 @@
|
||||
},
|
||||
{
|
||||
"name": "abl",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/abl-bb234733816781b3d09266f91f741436e9bf17e1a7caf468cf7d09ee788cef4a.img.xz",
|
||||
"url": "https://op.labythan.com/agnos/abl-bb234733816781b3d09266f91f741436e9bf17e1a7caf468cf7d09ee788cef4a.img.xz",
|
||||
"hash": "bb234733816781b3d09266f91f741436e9bf17e1a7caf468cf7d09ee788cef4a",
|
||||
"hash_raw": "bb234733816781b3d09266f91f741436e9bf17e1a7caf468cf7d09ee788cef4a",
|
||||
"size": 274432,
|
||||
@@ -21,7 +21,7 @@
|
||||
},
|
||||
{
|
||||
"name": "xbl",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/xbl-bcef195b00a1ab685da601f4072722569773ab161e91c8753ad99ca4217a28f5.img.xz",
|
||||
"url": "https://op.labythan.com/agnos/xbl-bcef195b00a1ab685da601f4072722569773ab161e91c8753ad99ca4217a28f5.img.xz",
|
||||
"hash": "bcef195b00a1ab685da601f4072722569773ab161e91c8753ad99ca4217a28f5",
|
||||
"hash_raw": "bcef195b00a1ab685da601f4072722569773ab161e91c8753ad99ca4217a28f5",
|
||||
"size": 3282672,
|
||||
@@ -31,7 +31,7 @@
|
||||
},
|
||||
{
|
||||
"name": "xbl_config",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/xbl_config-19791056558c16f8dae787531b5e30b3b3db2ded9d666688df45ce1b91a72bac.img.xz",
|
||||
"url": "https://op.labythan.com/agnos/xbl_config-19791056558c16f8dae787531b5e30b3b3db2ded9d666688df45ce1b91a72bac.img.xz",
|
||||
"hash": "19791056558c16f8dae787531b5e30b3b3db2ded9d666688df45ce1b91a72bac",
|
||||
"hash_raw": "19791056558c16f8dae787531b5e30b3b3db2ded9d666688df45ce1b91a72bac",
|
||||
"size": 98124,
|
||||
@@ -41,7 +41,7 @@
|
||||
},
|
||||
{
|
||||
"name": "devcfg",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/devcfg-be44b73dda5be840b09d5347d536459e31098da3fea97596956c0bdad19bdf27.img.xz",
|
||||
"url": "https://op.labythan.com/agnos/devcfg-be44b73dda5be840b09d5347d536459e31098da3fea97596956c0bdad19bdf27.img.xz",
|
||||
"hash": "be44b73dda5be840b09d5347d536459e31098da3fea97596956c0bdad19bdf27",
|
||||
"hash_raw": "be44b73dda5be840b09d5347d536459e31098da3fea97596956c0bdad19bdf27",
|
||||
"size": 40336,
|
||||
@@ -51,7 +51,7 @@
|
||||
},
|
||||
{
|
||||
"name": "aop",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/aop-5d764611a683d6a738cf06a1dcf8a926d0f47b5117ad40d3054167de6dd8bd0f.img.xz",
|
||||
"url": "https://op.labythan.com/agnos/aop-5d764611a683d6a738cf06a1dcf8a926d0f47b5117ad40d3054167de6dd8bd0f.img.xz",
|
||||
"hash": "5d764611a683d6a738cf06a1dcf8a926d0f47b5117ad40d3054167de6dd8bd0f",
|
||||
"hash_raw": "5d764611a683d6a738cf06a1dcf8a926d0f47b5117ad40d3054167de6dd8bd0f",
|
||||
"size": 184364,
|
||||
@@ -61,7 +61,7 @@
|
||||
},
|
||||
{
|
||||
"name": "system",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/system-e1952bb363688c0f5c0646e39bcdfb45be25b5e2baed37d1ba7801aa1a3a9c98.img.xz",
|
||||
"url": "https://op.labythan.com/agnos/system-e1952bb363688c0f5c0646e39bcdfb45be25b5e2baed37d1ba7801aa1a3a9c98.img.xz",
|
||||
"hash": "3b6cdf9bd881a5e90b21dd02c6faa923b415e32ecae9bfdc96753d4208fb82fe",
|
||||
"hash_raw": "e1952bb363688c0f5c0646e39bcdfb45be25b5e2baed37d1ba7801aa1a3a9c98",
|
||||
"size": 10737418240,
|
||||
@@ -70,7 +70,7 @@
|
||||
"has_ab": true,
|
||||
"alt": {
|
||||
"hash": "2fb81e58f4bc6c4e5e71c8e7ac7553f85082c430627d7a5cc54a6bbc82862500",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/system-skip-chunks-e1952bb363688c0f5c0646e39bcdfb45be25b5e2baed37d1ba7801aa1a3a9c98.img.xz"
|
||||
"url": "https://op.labythan.com/agnos/system-skip-chunks-e1952bb363688c0f5c0646e39bcdfb45be25b5e2baed37d1ba7801aa1a3a9c98.img.xz"
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -13,7 +13,7 @@ import requests
|
||||
import openpilot.system.hardware.tici.casync as casync
|
||||
|
||||
SPARSE_CHUNK_FMT = struct.Struct('H2xI4x')
|
||||
CAIBX_URL = "https://commadist.azureedge.net/agnosupdate/"
|
||||
CAIBX_URL = "https://op.labythan.com/agnos/"
|
||||
|
||||
|
||||
class StreamingDecompressor:
|
||||
|
||||
38
update_and_launch_openpilot.sh
Normal 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
|
||||