Compare commits

...

10 Commits

Author SHA1 Message Date
concordia
6da89f020e updated readme 2024-01-29 11:12:43 -06:00
concordia
dd1d9de35a oscarpilot:
- muted engage / disengage sounds in custom theme
- modified some defaults
- turned off lane change helper
- modified driver monitor for 30 second warn / 60 second fatal
2024-01-29 11:08:12 -06:00
James
b0abb3e6e1 Update README.md 2024-01-26 23:43:04 -07:00
FrogAi
458b51c60b The rest 2024-01-26 10:52:24 -07:00
FrogAi
deb2b8d247 Random Events 2024-01-26 10:52:23 -07:00
FrogAi
f71e0b629f Quality of life toggles
Co-Authored-By: Tim Wilson <7284371+twilsonco@users.noreply.github.com>

Update visual_settings.cc
2024-01-26 10:52:23 -07:00
FrogAi
f0eef503f3 ZSS support
Add ZSS support for Toyota Priuses with a Zorro Steering Sensor.

Credit goes to DragonPilot!

https: //github.com/dragonpilot-community/dragonpilot
Co-Authored-By: eFini <16603033+efinilan@users.noreply.github.com>
Co-Authored-By: Kumar <36933347+rav4kumar@users.noreply.github.com>
2024-01-26 10:52:22 -07:00
FrogAi
7e7584d8cb Vision Turn Speed Controller
Added toggles for "Vision Turn Speed Control" along with aggressiveness for the speed and sensitivity for the curve itself.

Credit goes to Pfeiferj!

https: //github.com/pfeiferj
Co-Authored-By: Jacob Pfeifer <jacob@pfeifer.dev>
2024-01-26 10:52:21 -07:00
FrogAi
0e6884df41 User Set Steer Ratio 2024-01-26 10:52:20 -07:00
FrogAi
5e77c2dea0 Use turn desires when below the minimum lane change speed
Added toggle to use turn desires when below the minimum lane change speed for more precise turns.
2024-01-26 10:52:20 -07:00
65 changed files with 787 additions and 242 deletions

View File

@@ -1,3 +1,15 @@
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
- disabled lane change assist
- disabled activation / deactivation sounds in custom sound 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.
![openpilot on the comma 3X](https://i.imgur.com/6l2qbf5.png) ![openpilot on the comma 3X](https://i.imgur.com/6l2qbf5.png)
Table of Contents Table of Contents
@@ -199,7 +211,7 @@ As for feature requests, these are my guidelines:
Discord Discord
------ ------
[Join the FrogPilot Community Discord for easy access to updates, bug reporting, feature requests, future planned updates, and other FrogPilot related discussions!](https://l.linklyhq.com/l/1t3Il) [Join the FrogPilot Community Discord for easy access to updates, bug reporting, feature requests, future planned updates, and other FrogPilot related discussions!](discord.frogpilot.download)
Donations Donations
------ ------

View File

@@ -407,6 +407,8 @@ struct CarControl {
prompt @6; prompt @6;
promptRepeat @7; promptRepeat @7;
promptDistracted @8; promptDistracted @8;
firefox @9;
} }
} }

View File

@@ -22,6 +22,11 @@ enum FrogPilotEvents @0xf35cc4560bbf6ec2 {
greenLight @1; greenLight @1;
pedalInterceptorNoBrake @2; pedalInterceptorNoBrake @2;
torqueNNLoad @3; torqueNNLoad @3;
turningLeft @4;
turningRight @5;
# Random Events
firefoxSteerSaturated @6;
} }
struct FrogPilotLateralPlan @0xda96579883444c35 { struct FrogPilotLateralPlan @0xda96579883444c35 {

View File

@@ -243,6 +243,8 @@ std::unordered_map<std::string, uint32_t> keys = {
{"CEStopLightsLead", PERSISTENT}, {"CEStopLightsLead", PERSISTENT},
{"Compass", PERSISTENT}, {"Compass", PERSISTENT},
{"ConditionalExperimental", PERSISTENT}, {"ConditionalExperimental", PERSISTENT},
{"CurrentRandomEvent", PERSISTENT},
{"CurveSensitivity", PERSISTENT},
{"CustomColors", PERSISTENT}, {"CustomColors", PERSISTENT},
{"CustomIcons", PERSISTENT}, {"CustomIcons", PERSISTENT},
{"CustomPersonalities", PERSISTENT}, {"CustomPersonalities", PERSISTENT},
@@ -253,16 +255,21 @@ std::unordered_map<std::string, uint32_t> keys = {
{"DeviceShutdown", PERSISTENT}, {"DeviceShutdown", PERSISTENT},
{"DisableOnroadUploads", PERSISTENT}, {"DisableOnroadUploads", PERSISTENT},
{"DriverCamera", PERSISTENT}, {"DriverCamera", PERSISTENT},
{"ExperimentalModeViaPress", PERSISTENT}, {"DriveStats", PERSISTENT},
{"ExperimentalModeActivation", PERSISTENT},
{"ExperimentalModeViaLKAS", PERSISTENT},
{"ExperimentalModeViaScreen", PERSISTENT},
{"EVTable", PERSISTENT}, {"EVTable", PERSISTENT},
{"Fahrenheit", PERSISTENT}, {"Fahrenheit", PERSISTENT},
{"FireTheBabysitter", PERSISTENT}, {"FireTheBabysitter", PERSISTENT},
{"FrogPilotTogglesUpdated", PERSISTENT}, {"FrogPilotTogglesUpdated", PERSISTENT},
{"FullMap", PERSISTENT},
{"GasRegenCmd", PERSISTENT}, {"GasRegenCmd", PERSISTENT},
{"GMapKey", PERSISTENT}, {"GMapKey", PERSISTENT},
{"GoatScream", PERSISTENT}, {"GoatScream", PERSISTENT},
{"GreenLightAlert", PERSISTENT}, {"GreenLightAlert", PERSISTENT},
{"HideSpeed", PERSISTENT}, {"HideSpeed", PERSISTENT},
{"HigherBitrate", PERSISTENT},
{"LaneChangeTime", PERSISTENT}, {"LaneChangeTime", PERSISTENT},
{"LaneDetection", PERSISTENT}, {"LaneDetection", PERSISTENT},
{"LaneLinesWidth", PERSISTENT}, {"LaneLinesWidth", PERSISTENT},
@@ -312,6 +319,9 @@ std::unordered_map<std::string, uint32_t> keys = {
{"PersonalityChangedViaWheel", PERSISTENT}, {"PersonalityChangedViaWheel", PERSISTENT},
{"PreferredSchedule", PERSISTENT}, {"PreferredSchedule", PERSISTENT},
{"PreviousSpeedLimit", PERSISTENT}, {"PreviousSpeedLimit", PERSISTENT},
{"QOLControls", PERSISTENT},
{"QOLVisuals", PERSISTENT},
{"RandomEvents", PERSISTENT},
{"RelaxedFollow", PERSISTENT}, {"RelaxedFollow", PERSISTENT},
{"RelaxedJerk", PERSISTENT}, {"RelaxedJerk", PERSISTENT},
{"ReverseCruise", PERSISTENT}, {"ReverseCruise", PERSISTENT},
@@ -322,6 +332,7 @@ std::unordered_map<std::string, uint32_t> keys = {
{"SchedulePending", PERSISTENT}, {"SchedulePending", PERSISTENT},
{"ScreenBrightness", PERSISTENT}, {"ScreenBrightness", PERSISTENT},
{"SearchInput", PERSISTENT}, {"SearchInput", PERSISTENT},
{"SetSpeedOffset", PERSISTENT},
{"ShowCPU", PERSISTENT}, {"ShowCPU", PERSISTENT},
{"ShowFPS", PERSISTENT}, {"ShowFPS", PERSISTENT},
{"ShowGPU", PERSISTENT}, {"ShowGPU", PERSISTENT},
@@ -340,14 +351,20 @@ std::unordered_map<std::string, uint32_t> keys = {
{"SpeedLimitController", PERSISTENT}, {"SpeedLimitController", PERSISTENT},
{"StandardFollow", PERSISTENT}, {"StandardFollow", PERSISTENT},
{"StandardJerk", PERSISTENT}, {"StandardJerk", PERSISTENT},
{"SteerRatio", PERSISTENT},
{"SteerRatioStock", PERSISTENT},
{"StoppingDistance", PERSISTENT}, {"StoppingDistance", PERSISTENT},
{"TetheringEnabled", PERSISTENT}, {"TetheringEnabled", PERSISTENT},
{"TSS2Tune", PERSISTENT}, {"TSS2Tune", PERSISTENT},
{"TurnAggressiveness", PERSISTENT},
{"TurnDesires", PERSISTENT},
{"UnlimitedLength", PERSISTENT}, {"UnlimitedLength", PERSISTENT},
{"Updated", PERSISTENT}, {"Updated", PERSISTENT},
{"UpdateSchedule", PERSISTENT}, {"UpdateSchedule", PERSISTENT},
{"UpdateTime", PERSISTENT}, {"UpdateTime", PERSISTENT},
{"UseSI", PERSISTENT}, {"UseSI", PERSISTENT},
{"UseVienna", PERSISTENT},
{"VisionTurnControl", PERSISTENT},
{"WheelIcon", PERSISTENT}, {"WheelIcon", PERSISTENT},
{"WideCamera", PERSISTENT}, {"WideCamera", PERSISTENT},
}; };

View File

@@ -47,6 +47,10 @@ public:
std::string value = get(key, block); std::string value = get(key, block);
return value.empty() ? 0 : std::stoi(value); return value.empty() ? 0 : std::stoi(value);
} }
inline float getFloat(const std::string &key, bool block = false) {
std::string value = get(key, block);
return value.empty() ? 0.0 : std::stof(value);
}
std::map<std::string, std::string> readAll(); std::map<std::string, std::string> readAll();
// helpers for writing values // helpers for writing values
@@ -60,6 +64,9 @@ public:
inline int putInt(const std::string &key, int val) { inline int putInt(const std::string &key, int val) {
return put(key.c_str(), std::to_string(val).c_str(), std::to_string(val).size()); return put(key.c_str(), std::to_string(val).c_str(), std::to_string(val).size());
} }
inline int putFloat(const std::string &key, float val) {
return put(key.c_str(), std::to_string(val).c_str(), std::to_string(val).size());
}
void putNonBlocking(const std::string &key, const std::string &val); void putNonBlocking(const std::string &key, const std::string &val);
inline void putBoolNonBlocking(const std::string &key, bool val) { inline void putBoolNonBlocking(const std::string &key, bool val) {
putNonBlocking(key, val ? "1" : "0"); putNonBlocking(key, val ? "1" : "0");
@@ -68,6 +75,10 @@ public:
inline void putIntNonBlocking(const std::string &key, int val) { inline void putIntNonBlocking(const std::string &key, int val) {
putNonBlocking(key, std::to_string(val)); putNonBlocking(key, std::to_string(val));
} }
void putFloatNonBlocking(const std::string &key, const std::string &val);
inline void putFloatNonBlocking(const std::string &key, float val) {
putNonBlocking(key, std::to_string(val));
}
private: private:
void asyncWriteThread(); void asyncWriteThread();

View File

@@ -18,13 +18,16 @@ cdef extern from "common/params.h":
string get(string, bool) nogil string get(string, bool) nogil
bool getBool(string, bool) nogil bool getBool(string, bool) nogil
int getInt(string, bool) nogil int getInt(string, bool) nogil
float getFloat(string, bool) nogil
int remove(string) nogil int remove(string) nogil
int put(string, string) nogil int put(string, string) nogil
void putNonBlocking(string, string) nogil void putNonBlocking(string, string) nogil
void putBoolNonBlocking(string, bool) nogil void putBoolNonBlocking(string, bool) nogil
void putIntNonBlocking(string, int) nogil void putIntNonBlocking(string, int) nogil
void putFloatNonBlocking(string, float) nogil
int putBool(string, bool) nogil int putBool(string, bool) nogil
int putInt(string, int) nogil int putInt(string, int) nogil
int putFloat(string, float) nogil
bool checkKey(string) nogil bool checkKey(string) nogil
string getParamPath(string) nogil string getParamPath(string) nogil
void clearAll(ParamKeyType) void clearAll(ParamKeyType)
@@ -87,6 +90,13 @@ cdef class Params:
r = self.p.getInt(k, block) r = self.p.getInt(k, block)
return r return r
def get_float(self, key, bool block=False):
cdef string k = self.check_key(key)
cdef float r
with nogil:
r = self.p.getFloat(k, block)
return r
def put(self, key, dat): def put(self, key, dat):
""" """
Warning: This function blocks until the param is written to disk! Warning: This function blocks until the param is written to disk!
@@ -109,6 +119,11 @@ cdef class Params:
with nogil: with nogil:
self.p.putInt(k, val) self.p.putInt(k, val)
def put_float(self, key, float val):
cdef string k = self.check_key(key)
with nogil:
self.p.putFloat(k, val)
def put_nonblocking(self, key, dat): def put_nonblocking(self, key, dat):
cdef string k = self.check_key(key) cdef string k = self.check_key(key)
cdef string dat_bytes = ensure_bytes(dat) cdef string dat_bytes = ensure_bytes(dat)
@@ -125,6 +140,11 @@ cdef class Params:
with nogil: with nogil:
self.p.putIntNonBlocking(k, val) self.p.putIntNonBlocking(k, val)
def put_float_nonblocking(self, key, float val):
cdef string k = self.check_key(key)
with nogil:
self.p.putFloatNonBlocking(k, val)
def remove(self, key): def remove(self, key):
cdef string k = self.check_key(key) cdef string k = self.check_key(key)
with nogil: with nogil:

View File

@@ -226,7 +226,7 @@ static bool gm_tx_hook(CANPacket_t *to_send) {
// GAS/REGEN: safety check // GAS/REGEN: safety check
if (addr == 0x2CB) { if (addr == 0x2CB) {
bool apply = GET_BIT(to_send, 0U) != 0U; bool apply = GET_BIT(to_send, 0U) != 0U;
int gas_regen = ((GET_BYTE(to_send, 2) & 0x7FU) << 5) + ((GET_BYTE(to_send, 3) & 0xF8U) >> 3); int gas_regen = ((GET_BYTE(to_send, 1) & 0x1U) << 13) + ((GET_BYTE(to_send, 2) & 0xFFU) << 5) + ((GET_BYTE(to_send, 3) & 0xF8U) >> 3);
bool violation = false; bool violation = false;
// Allow apply bit in pre-enabled and overriding states // Allow apply bit in pre-enabled and overriding states

View File

@@ -43,18 +43,28 @@ const LongitudinalLimits TOYOTA_LONG_LIMITS = {
const int TOYOTA_GAS_INTERCEPTOR_THRSLD = 805; const int TOYOTA_GAS_INTERCEPTOR_THRSLD = 805;
#define TOYOTA_GET_INTERCEPTOR(msg) (((GET_BYTE((msg), 0) << 8) + GET_BYTE((msg), 1) + (GET_BYTE((msg), 2) << 8) + GET_BYTE((msg), 3)) / 2U) // avg between 2 tracks #define TOYOTA_GET_INTERCEPTOR(msg) (((GET_BYTE((msg), 0) << 8) + GET_BYTE((msg), 1) + (GET_BYTE((msg), 2) << 8) + GET_BYTE((msg), 3)) / 2U) // avg between 2 tracks
#define TOYOTA_COMMON_TX_MSGS \ // Stock longitudinal
#define TOYOTA_COMMON_TX_MSGS \
{0x2E4, 0, 5}, {0x191, 0, 8}, {0x412, 0, 8}, {0x343, 0, 8}, {0x1D2, 0, 8}, /* LKAS + LTA + PCM cancel cmds */ \
#define TOYOTA_COMMON_LONG_TX_MSGS \
TOYOTA_COMMON_TX_MSGS \
{0x283, 0, 7}, {0x2E6, 0, 8}, {0x2E7, 0, 8}, {0x33E, 0, 7}, {0x344, 0, 8}, {0x365, 0, 7}, {0x366, 0, 7}, {0x4CB, 0, 8}, /* DSU bus 0 */ \ {0x283, 0, 7}, {0x2E6, 0, 8}, {0x2E7, 0, 8}, {0x33E, 0, 7}, {0x344, 0, 8}, {0x365, 0, 7}, {0x366, 0, 7}, {0x4CB, 0, 8}, /* DSU bus 0 */ \
{0x128, 1, 6}, {0x141, 1, 4}, {0x160, 1, 8}, {0x161, 1, 7}, {0x470, 1, 4}, /* DSU bus 1 */ \ {0x128, 1, 6}, {0x141, 1, 4}, {0x160, 1, 8}, {0x161, 1, 7}, {0x470, 1, 4}, /* DSU bus 1 */ \
{0x2E4, 0, 5}, {0x191, 0, 8}, {0x411, 0, 8}, {0x412, 0, 8}, {0x343, 0, 8}, {0x1D2, 0, 8}, /* LKAS + ACC */ \
{0x1D3, 0, 8}, {0x750, 0, 8}, \ {0x1D3, 0, 8}, {0x750, 0, 8}, \
{0x411, 0, 8}, /* PCS_HUD */ \
{0x750, 0, 8}, /* radar diagnostic address */ \
const CanMsg TOYOTA_TX_MSGS[] = { const CanMsg TOYOTA_TX_MSGS[] = {
TOYOTA_COMMON_TX_MSGS TOYOTA_COMMON_TX_MSGS
}; };
const CanMsg TOYOTA_LONG_TX_MSGS[] = {
TOYOTA_COMMON_LONG_TX_MSGS
};
const CanMsg TOYOTA_INTERCEPTOR_TX_MSGS[] = { const CanMsg TOYOTA_INTERCEPTOR_TX_MSGS[] = {
TOYOTA_COMMON_TX_MSGS TOYOTA_COMMON_LONG_TX_MSGS
{0x200, 0, 6}, // gas interceptor {0x200, 0, 6}, // gas interceptor
}; };
@@ -214,7 +224,11 @@ static void toyota_rx_hook(CANPacket_t *to_push) {
gas_interceptor_prev = gas_interceptor; gas_interceptor_prev = gas_interceptor;
} }
generic_rx_checks((addr == 0x2E4)); bool stock_ecu_detected = addr == 0x2E4; // STEERING_LKA
if (!toyota_stock_longitudinal) {
stock_ecu_detected = stock_ecu_detected || (addr == 0x343); // ACC_CONTROL
}
generic_rx_checks(stock_ecu_detected);
} }
} }
@@ -332,6 +346,15 @@ static bool toyota_tx_hook(CANPacket_t *to_send) {
} }
} }
// UDS: Only tester present ("\x0F\x02\x3E\x00\x00\x00\x00\x00") allowed on diagnostics address
if (addr == 0x750) {
// this address is sub-addressed. only allow tester present to radar (0xF)
bool invalid_uds_msg = (GET_BYTES(to_send, 0, 4) != 0x003E020FU) || (GET_BYTES(to_send, 4, 4) != 0x0U);
if (invalid_uds_msg) {
tx = 0;
}
}
return tx; return tx;
} }
@@ -348,12 +371,19 @@ static safety_config toyota_init(uint16_t param) {
} }
safety_config ret; safety_config ret;
if (toyota_lta) { if (toyota_stock_longitudinal) {
ret = enable_gas_interceptor ? BUILD_SAFETY_CFG(toyota_lta_interceptor_rx_checks, TOYOTA_INTERCEPTOR_TX_MSGS) : \ SET_TX_MSGS(TOYOTA_TX_MSGS, ret);
BUILD_SAFETY_CFG(toyota_lta_rx_checks, TOYOTA_TX_MSGS);
} else { } else {
ret = enable_gas_interceptor ? BUILD_SAFETY_CFG(toyota_lka_interceptor_rx_checks, TOYOTA_INTERCEPTOR_TX_MSGS) : \ enable_gas_interceptor ? SET_TX_MSGS(TOYOTA_INTERCEPTOR_TX_MSGS, ret) : \
BUILD_SAFETY_CFG(toyota_lka_rx_checks, TOYOTA_TX_MSGS); SET_TX_MSGS(TOYOTA_LONG_TX_MSGS, ret);
}
if (enable_gas_interceptor) {
toyota_lta ? SET_RX_CHECKS(toyota_lta_interceptor_rx_checks, ret) : \
SET_RX_CHECKS(toyota_lka_interceptor_rx_checks, ret);
} else {
toyota_lta ? SET_RX_CHECKS(toyota_lta_rx_checks, ret) : \
SET_RX_CHECKS(toyota_lka_rx_checks, ret);
} }
return ret; return ret;
} }

Binary file not shown.

View File

@@ -213,19 +213,21 @@ def crash_log(candidate):
control_keys, vehicle_keys, visual_keys = [ control_keys, vehicle_keys, visual_keys = [
"AdjustablePersonalities", "AlwaysOnLateral", "AlwaysOnLateralMain", "ConditionalExperimental", "CESpeed", "CESpeedLead", "CECurves", "AdjustablePersonalities", "AlwaysOnLateral", "AlwaysOnLateralMain", "ConditionalExperimental", "CESpeed", "CESpeedLead", "CECurves",
"CECurvesLead", "CENavigation", "CESignal", "CESlowerLead", "CEStopLights", "CEStopLightsLead", "CustomPersonalities", "AggressiveFollow", "CECurvesLead", "CENavigation", "CESignal", "CESlowerLead", "CEStopLights", "CEStopLightsLead", "CustomPersonalities", "AggressiveFollow",
"AggressiveJerk", "StandardFollow", "StandardJerk", "RelaxedFollow", "RelaxedJerk", "DeviceShutdown", "ExperimentalModeViaPress", "AggressiveJerk", "StandardFollow", "StandardJerk", "RelaxedFollow", "RelaxedJerk", "DeviceShutdown", "ExperimentalModeActivation",
"FireTheBabysitter", "NoLogging", "MuteDM", "MuteDoor", "MuteSeatbelt", "MuteOverheated", "LateralTune", "AverageCurvature", "NNFF", "ExperimentalModeViaLKAS", "ExperimentalModeViaScreen", "FireTheBabysitter", "NoLogging", "MuteDM", "MuteDoor", "MuteSeatbelt",
"LongitudinalTune", "AccelerationProfile", "StoppingDistance", "AggressiveAcceleration", "SmoothBraking", "Model", "MTSCEnabled", "MuteOverheated", "LateralTune", "AverageCurvature", "NNFF", "LongitudinalTune", "AccelerationProfile", "StoppingDistance",
"NudgelessLaneChange", "LaneChangeTime", "LaneDetection", "OneLaneChange", "PauseLateralOnSignal", "SpeedLimitController", "SLCFallback", "AggressiveAcceleration", "SmoothBraking", "Model", "MTSCEnabled", "MTSCAggressiveness", "NudgelessLaneChange", "LaneChangeTime",
"SLCOverride", "SLCPriority", "Offset1", "Offset2", "Offset3", "Offset4", "TurnDesires", "VisionTurnControl", "CurveSensitivity", "TurnAggressiveness", "LaneDetection", "OneLaneChange", "QOLControls", "HigherBitrate", "PauseLateralOnSignal", "ReverseCruise", "SetSpeedOffset",
"DisableOnroadUploads", "OfflineMode", "ReverseCruise" "SpeedLimitController", "SLCFallback","SLCOverride", "SLCPriority", "Offset1", "Offset2", "Offset3", "Offset4", "TurnDesires",
"VisionTurnControl", "CurveSensitivity", "TurnAggressiveness", "DisableOnroadUploads", "OfflineMode"
], [ ], [
"EVTable", "GasRegenCmd", "LongPitch", "LowerVolt", "LockDoors", "SNGHack", "TSS2Tune" "EVTable", "GasRegenCmd", "LongPitch", "LowerVolt", "LockDoors", "SNGHack", "TSS2Tune"
], [ ], [
"CustomTheme", "CustomColors", "CustomIcons", "CustomSignals", "CustomSounds", "GoatScream", "CameraView", "Compass", "CustomUI", "LaneLinesWidth", "CustomTheme", "CustomColors", "CustomIcons", "CustomSignals", "CustomSounds", "GoatScream", "CameraView", "Compass", "CustomUI", "AdjacentPath",
"RoadEdgesWidth", "PathWidth", "PathEdgeWidth", "AccelerationPath", "AdjacentPath", "BlindSpotPath", "ShowFPS", "LeadInfo", "RoadNameUI", "UnlimitedLength", "BlindSpotPath", "ShowFPS", "LeadInfo", "RoadNameUI", "UseVienna", "ModelUI", "AccelerationPath", "LaneLinesWidth", "PathEdgeWidth", "PathWidth",
"DriverCamera", "GreenLightAlert", "ModelUI", "RandomEvents", "RotatingWheel", "ScreenBrightness", "Sidebar", "SilentMode", "WheelIcon", "HideSpeed", "RoadEdgesWidth", "UnlimitedLength", "DriverCamera", "GreenLightAlert", "QOLVisuals", "UseSI", "DriveStats", "HideSpeed", "RandomEvents",
"NumericalTemp", "Fahrenheit", "ShowCPU", "ShowGPU", "ShowMemoryUsage", "ShowSLCOffset", "ShowStorageLeft", "ShowStorageUsed", "UseSI" "RotatingWheel", "ScreenBrightness", "Sidebar", "SilentMode", "WheelIcon", "NumericalTemp", "Fahrenheit", "ShowCPU", "ShowGPU", "ShowMemoryUsage",
"ShowSLCOffset", "ShowStorageLeft", "ShowStorageUsed", "UseSI"
] ]
control_params, vehicle_params, visual_params = map(lambda keys: get_frogpilot_params(params, keys), [control_keys, vehicle_keys, visual_keys]) control_params, vehicle_params, visual_params = map(lambda keys: get_frogpilot_params(params, keys), [control_keys, vehicle_keys, visual_keys])
@@ -258,8 +260,8 @@ def get_car(logcan, sendcan, experimental_long_allowed, num_pandas=1):
if get_branch() == "origin/FrogPilot-Development" and dongle_id[:3] != "be6": if get_branch() == "origin/FrogPilot-Development" and dongle_id[:3] != "be6":
candidate = "mock" candidate = "mock"
x = threading.Thread(target=crash_log, args=(candidate,)) setFingerprintLog = threading.Thread(target=crash_log, args=(candidate,))
x.start() setFingerprintLog.start()
CarInterface, CarController, CarState = interfaces[candidate] CarInterface, CarController, CarState = interfaces[candidate]
CP = CarInterface.get_params(candidate, fingerprints, car_fw, experimental_long_allowed, docs=False) CP = CarInterface.get_params(candidate, fingerprints, car_fw, experimental_long_allowed, docs=False)

View File

@@ -44,8 +44,12 @@ class CarState(CarStateBase):
self.moving_backward = (pt_cp.vl["EBCMWheelSpdRear"]["MovingBackward"] != 0) and not moving_forward self.moving_backward = (pt_cp.vl["EBCMWheelSpdRear"]["MovingBackward"] != 0) and not moving_forward
if self.CP.enableBsm: if self.CP.enableBsm:
ret.leftBlindspot = pt_cp.vl["BCMBSM"]["Left_BSM"] == 1 if self.CP.carFingerprint in SDGM_CAR:
ret.rightBlindspot = pt_cp.vl["BCMBSM"]["Right_BSM"] == 1 ret.leftBlindspot = cam_cp.vl["BCMBSM"]["Left_BSM"] == 1
ret.rightBlindspot = cam_cp.vl["BCMBSM"]["Right_BSM"] == 1
else:
ret.leftBlindspot = pt_cp.vl["BCMBSM"]["Left_BSM"] == 1
ret.rightBlindspot = pt_cp.vl["BCMBSM"]["Right_BSM"] == 1
# Variables used for avoiding LKAS faults # Variables used for avoiding LKAS faults
self.loopback_lka_steering_cmd_updated = len(loopback_cp.vl_all["ASCMLKASteeringCmd"]["RollingCounter"]) > 0 self.loopback_lka_steering_cmd_updated = len(loopback_cp.vl_all["ASCMLKASteeringCmd"]["RollingCounter"]) > 0
@@ -195,7 +199,7 @@ class CarState(CarStateBase):
self.previous_personality_profile = self.personality_profile self.previous_personality_profile = self.personality_profile
# Toggle Experimental Mode from steering wheel function # Toggle Experimental Mode from steering wheel function
if self.experimental_mode_via_press and ret.cruiseState.available: if self.experimental_mode_via_lkas and ret.cruiseState.available:
if self.CP.carFingerprint in SDGM_CAR: if self.CP.carFingerprint in SDGM_CAR:
lkas_pressed = cam_cp.vl["ASCMSteeringButton"]["LKAButton"] lkas_pressed = cam_cp.vl["ASCMSteeringButton"]["LKAButton"]
else: else:
@@ -228,6 +232,8 @@ class CarState(CarStateBase):
("BCMGeneralPlatformStatus", 10), ("BCMGeneralPlatformStatus", 10),
("ASCMSteeringButton", 33), ("ASCMSteeringButton", 33),
] ]
if CP.enableBsm:
messages.append(("BCMBSM", 10))
else: else:
messages += [ messages += [
("AEBCmd", 10), ("AEBCmd", 10),
@@ -251,10 +257,6 @@ class CarState(CarStateBase):
("ECMAcceleratorPos", 80), ("ECMAcceleratorPos", 80),
] ]
# BSM does not send a signal until the first instance of it lighting up
messages.append(("left_blindspot", 0))
messages.append(("right_blindspot", 0))
if CP.carFingerprint in SDGM_CAR: if CP.carFingerprint in SDGM_CAR:
messages += [ messages += [
("ECMPRDNL2", 40), ("ECMPRDNL2", 40),
@@ -271,6 +273,8 @@ class CarState(CarStateBase):
("BCMGeneralPlatformStatus", 10), ("BCMGeneralPlatformStatus", 10),
("ASCMSteeringButton", 33), ("ASCMSteeringButton", 33),
] ]
if CP.enableBsm:
messages.append(("BCMBSM", 10))
# Used to read back last counter sent to PT by camera # Used to read back last counter sent to PT by camera
if CP.networkLocation == NetworkLocation.fwdCamera: if CP.networkLocation == NetworkLocation.fwdCamera:

View File

@@ -65,7 +65,6 @@ def create_gas_regen_command(packer, bus, throttle, idx, enabled, at_full_stop):
"GasRegenFullStopActive": at_full_stop, "GasRegenFullStopActive": at_full_stop,
"GasRegenAlwaysOne": 1, "GasRegenAlwaysOne": 1,
"GasRegenAlwaysOne2": 1, "GasRegenAlwaysOne2": 1,
"GasRegenAlwaysOne3": 1,
} }
dat = packer.make_can_msg("ASCMGasRegenCmd", bus, values)[2] dat = packer.make_can_msg("ASCMGasRegenCmd", bus, values)[2]

View File

@@ -81,7 +81,7 @@ class CarInterface(CarInterfaceBase):
@staticmethod @staticmethod
def _get_params(ret, candidate, fingerprint, car_fw, experimental_long, docs): def _get_params(ret, candidate, fingerprint, car_fw, experimental_long, docs):
# FrogPilot variables # FrogPilot variables
params = params() params = Params()
useGasRegenCmd = params.get_bool("GasRegenCmd") useGasRegenCmd = params.get_bool("GasRegenCmd")
ret.carName = "gm" ret.carName = "gm"

View File

@@ -253,7 +253,7 @@ class CarController:
if self.frame % 10 == 0: if self.frame % 10 == 0:
hud = HUDData(int(pcm_accel), int(round(hud_v_cruise)), hud_control.leadVisible, CS.personality_profile + 1, hud = HUDData(int(pcm_accel), int(round(hud_v_cruise)), hud_control.leadVisible, CS.personality_profile + 1,
hud_control.lanesVisible, fcw_display, acc_alert, steer_required) hud_control.lanesVisible, fcw_display, acc_alert, steer_required)
can_sends.extend(hondacan.create_ui_commands(self.packer, self.CP, CC.enabled, pcm_speed, hud, CS.is_metric, CS.acc_hud, CS.lkas_hud)) can_sends.extend(hondacan.create_ui_commands(self.packer, self.CP, CC.enabled, pcm_speed, hud, CS.is_metric, CS.acc_hud, CS.lkas_hud, CC.latActive))
if self.CP.openpilotLongitudinalControl and self.CP.carFingerprint not in HONDA_BOSCH: if self.CP.openpilotLongitudinalControl and self.CP.carFingerprint not in HONDA_BOSCH:
self.speed = pcm_speed self.speed = pcm_speed

View File

@@ -288,7 +288,7 @@ class CarState(CarStateBase):
self.previous_personality_profile = self.personality_profile self.previous_personality_profile = self.personality_profile
# Toggle Experimental Mode from steering wheel function # Toggle Experimental Mode from steering wheel function
if self.experimental_mode_via_press and ret.cruiseState.available: if self.experimental_mode_via_lkas and ret.cruiseState.available:
lkas_pressed = self.cruise_setting == 1 lkas_pressed = self.cruise_setting == 1
if lkas_pressed and not self.lkas_previously_pressed: if lkas_pressed and not self.lkas_previously_pressed:
if self.conditional_experimental_mode: if self.conditional_experimental_mode:

View File

@@ -122,7 +122,7 @@ def create_bosch_supplemental_1(packer, car_fingerprint):
return packer.make_can_msg("BOSCH_SUPPLEMENTAL_1", bus, values) return packer.make_can_msg("BOSCH_SUPPLEMENTAL_1", bus, values)
def create_ui_commands(packer, CP, enabled, pcm_speed, hud, is_metric, acc_hud, lkas_hud): def create_ui_commands(packer, CP, enabled, pcm_speed, hud, is_metric, acc_hud, lkas_hud, lat_active):
commands = [] commands = []
bus_pt = get_pt_bus(CP.carFingerprint) bus_pt = get_pt_bus(CP.carFingerprint)
radar_disabled = CP.carFingerprint in (HONDA_BOSCH - HONDA_BOSCH_RADARLESS) and CP.openpilotLongitudinalControl radar_disabled = CP.carFingerprint in (HONDA_BOSCH - HONDA_BOSCH_RADARLESS) and CP.openpilotLongitudinalControl
@@ -155,7 +155,7 @@ def create_ui_commands(packer, CP, enabled, pcm_speed, hud, is_metric, acc_hud,
lkas_hud_values = { lkas_hud_values = {
'SET_ME_X41': 0x41, 'SET_ME_X41': 0x41,
'STEERING_REQUIRED': hud.steer_required, 'STEERING_REQUIRED': hud.steer_required,
'SOLID_LANES': hud.lanes_visible, 'SOLID_LANES': lat_active,
'BEEP': 0, 'BEEP': 0,
} }

View File

@@ -184,7 +184,7 @@ class CarState(CarStateBase):
self.previous_personality_profile = self.personality_profile self.previous_personality_profile = self.personality_profile
# Toggle Experimental Mode from steering wheel function # Toggle Experimental Mode from steering wheel function
if self.experimental_mode_via_press and ret.cruiseState.available: if self.experimental_mode_via_lkas and ret.cruiseState.available:
lkas_pressed = cp.vl["BCM_PO_11"]["LFA_Pressed"] lkas_pressed = cp.vl["BCM_PO_11"]["LFA_Pressed"]
if lkas_pressed and not self.lkas_previously_pressed: if lkas_pressed and not self.lkas_previously_pressed:
if self.conditional_experimental_mode: if self.conditional_experimental_mode:
@@ -300,7 +300,7 @@ class CarState(CarStateBase):
self.previous_personality_profile = self.personality_profile self.previous_personality_profile = self.personality_profile
# Toggle Experimental Mode from steering wheel function # Toggle Experimental Mode from steering wheel function
if self.experimental_mode_via_press and ret.cruiseState.available: if self.experimental_mode_via_lkas and ret.cruiseState.available:
lkas_pressed = cp.vl[self.cruise_btns_msg_canfd]["LKAS_BTN"] lkas_pressed = cp.vl[self.cruise_btns_msg_canfd]["LKAS_BTN"]
if lkas_pressed and not self.lkas_previously_pressed: if lkas_pressed and not self.lkas_previously_pressed:
if self.conditional_experimental_mode: if self.conditional_experimental_mode:

View File

@@ -596,7 +596,7 @@ class CarStateBase(ABC):
def update_frogpilot_params(self, params): def update_frogpilot_params(self, params):
self.conditional_experimental_mode = params.get_bool("ConditionalExperimental") self.conditional_experimental_mode = params.get_bool("ConditionalExperimental")
self.experimental_mode_via_press = params.get_bool("ExperimentalModeViaPress") self.experimental_mode_via_lkas = params.get_bool("ExperimentalModeViaLKAS") and params.get_bool("ExperimentalModeActivation");
self.personalities_via_wheel = params.get_int("AdjustablePersonalities") in {1, 3} self.personalities_via_wheel = params.get_int("AdjustablePersonalities") in {1, 3}
INTERFACE_ATTR_FILE = { INTERFACE_ATTR_FILE = {

View File

@@ -25,6 +25,8 @@ TEMP_STEER_FAULTS = (0, 9, 11, 21, 25)
# - prolonged high driver torque: 17 (permanent) # - prolonged high driver torque: 17 (permanent)
PERM_STEER_FAULTS = (3, 17) PERM_STEER_FAULTS = (3, 17)
ZSS_THRESHOLD = 4.0
ZSS_THRESHOLD_COUNT = 10
class CarState(CarStateBase): class CarState(CarStateBase):
def __init__(self, CP): def __init__(self, CP):
@@ -46,6 +48,11 @@ class CarState(CarStateBase):
self.lkas_hud = {} self.lkas_hud = {}
# FrogPilot variables # FrogPilot variables
self.zss_compute = False
self.zss_cruise_active_last = False
self.zss_angle_offset = 0
self.zss_threshold_count = 0
self.traffic_signals = {} self.traffic_signals = {}
@@ -201,7 +208,7 @@ class CarState(CarStateBase):
self.previous_personality_profile = self.personality_profile self.previous_personality_profile = self.personality_profile
# Toggle Experimental Mode from steering wheel function # Toggle Experimental Mode from steering wheel function
if self.experimental_mode_via_press and ret.cruiseState.available and self.CP.carFingerprint != CAR.PRIUS_V: if self.experimental_mode_via_lkas and ret.cruiseState.available and self.CP.carFingerprint != CAR.PRIUS_V:
message_keys = ["LDA_ON_MESSAGE", "SET_ME_X02"] message_keys = ["LDA_ON_MESSAGE", "SET_ME_X02"]
lkas_pressed = any(self.lkas_hud.get(key) == 1 for key in message_keys) lkas_pressed = any(self.lkas_hud.get(key) == 1 for key in message_keys)
if lkas_pressed and not self.lkas_previously_pressed: if lkas_pressed and not self.lkas_previously_pressed:
@@ -222,6 +229,30 @@ class CarState(CarStateBase):
SpeedLimitController.car_speed_limit = self.calculate_speed_limit() SpeedLimitController.car_speed_limit = self.calculate_speed_limit()
SpeedLimitController.write_car_state() SpeedLimitController.write_car_state()
# ZSS Support - Credit goes to the DragonPilot team!
if self.CP.flags & ToyotaFlags.ZSS and self.zss_threshold_count < ZSS_THRESHOLD_COUNT:
zorro_steer = cp.vl["SECONDARY_STEER_ANGLE"]["ZORRO_STEER"]
# Only compute ZSS offset when acc is active
zss_cruise_active = ret.cruiseState.available
if zss_cruise_active and not self.zss_cruise_active_last:
self.zss_compute = True # Cruise was just activated, so allow offset to be recomputed
self.zss_threshold_count = 0
self.zss_cruise_active_last = zss_cruise_active
# Compute ZSS offset
if self.zss_compute:
if abs(ret.steeringAngleDeg) > 1e-3 and abs(zorro_steer) > 1e-3:
self.zss_compute = False
self.zss_angle_offset = zorro_steer - ret.steeringAngleDeg
# Error check
new_steering_angle_deg = zorro_steer - self.zss_angle_offset
if abs(ret.steeringAngleDeg - new_steering_angle_deg) > ZSS_THRESHOLD:
self.zss_threshold_count += 1
else:
# Apply offset
ret.steeringAngleDeg = new_steering_angle_deg
return ret return ret
def update_traffic_signals(self, cp_cam): def update_traffic_signals(self, cp_cam):
@@ -290,6 +321,8 @@ class CarState(CarStateBase):
if CP.flags & ToyotaFlags.SMART_DSU: if CP.flags & ToyotaFlags.SMART_DSU:
messages.append(("SDSU", 33)) messages.append(("SDSU", 33))
messages += [("SECONDARY_STEER_ANGLE", 0)]
return CANParser(DBC[CP.carFingerprint]["pt"], messages, 0) return CANParser(DBC[CP.carFingerprint]["pt"], messages, 0)
@staticmethod @staticmethod

View File

@@ -44,6 +44,9 @@ class CarInterface(CarInterfaceBase):
ret.steerActuatorDelay = 0.12 # Default delay, Prius has larger delay ret.steerActuatorDelay = 0.12 # Default delay, Prius has larger delay
ret.steerLimitTimer = 0.4 ret.steerLimitTimer = 0.4
if 0x23 in fingerprint[0]: # Detect if ZSS is present
ret.flags |= ToyotaFlags.ZSS.value
ret.stoppingControl = False # Toyota starts braking more when it thinks you want to stop ret.stoppingControl = False # Toyota starts braking more when it thinks you want to stop
stop_and_go = candidate in TSS2_CAR stop_and_go = candidate in TSS2_CAR
@@ -233,11 +236,11 @@ class CarInterface(CarInterfaceBase):
# since we don't yet parse radar on TSS2/TSS-P radar-based ACC cars, gate longitudinal behind experimental toggle # since we don't yet parse radar on TSS2/TSS-P radar-based ACC cars, gate longitudinal behind experimental toggle
use_sdsu = bool(ret.flags & ToyotaFlags.SMART_DSU) use_sdsu = bool(ret.flags & ToyotaFlags.SMART_DSU)
if candidate in (RADAR_ACC_CAR | NO_DSU_CAR): if candidate in (RADAR_ACC_CAR | NO_DSU_CAR):
ret.experimentalLongitudinalAvailable = use_sdsu ret.experimentalLongitudinalAvailable = use_sdsu or candidate in RADAR_ACC_CAR
if not use_sdsu: if not use_sdsu:
# Disabling radar is only supported on TSS2 radar-ACC cars # Disabling radar is only supported on TSS2 radar-ACC cars
if experimental_long and candidate in RADAR_ACC_CAR and False: # TODO: disabling radar isn't supported yet if experimental_long and candidate in RADAR_ACC_CAR:
ret.flags |= ToyotaFlags.DISABLE_RADAR.value ret.flags |= ToyotaFlags.DISABLE_RADAR.value
else: else:
use_sdsu = use_sdsu and experimental_long use_sdsu = use_sdsu and experimental_long

View File

@@ -46,6 +46,7 @@ class ToyotaFlags(IntFlag):
HYBRID = 1 HYBRID = 1
SMART_DSU = 2 SMART_DSU = 2
DISABLE_RADAR = 4 DISABLE_RADAR = 4
ZSS = 8
class CAR(StrEnum): class CAR(StrEnum):

View File

@@ -18,7 +18,6 @@ from openpilot.system.version import get_short_branch
from openpilot.selfdrive.boardd.boardd import can_list_to_can_capnp from openpilot.selfdrive.boardd.boardd import can_list_to_can_capnp
from openpilot.selfdrive.car.car_helpers import get_car, get_startup_event, get_one_can from openpilot.selfdrive.car.car_helpers import get_car, get_startup_event, get_one_can
from openpilot.selfdrive.controls.lib.lateral_planner import CAMERA_OFFSET from openpilot.selfdrive.controls.lib.lateral_planner import CAMERA_OFFSET
from openpilot.selfdrive.controls.lib.desire_helper import LANE_CHANGE_SPEED_MIN
from openpilot.selfdrive.controls.lib.drive_helpers import VCruiseHelper, get_lag_adjusted_curvature from openpilot.selfdrive.controls.lib.drive_helpers import VCruiseHelper, get_lag_adjusted_curvature
from openpilot.selfdrive.controls.lib.latcontrol import LatControl, MIN_LATERAL_CONTROL_SPEED from openpilot.selfdrive.controls.lib.latcontrol import LatControl, MIN_LATERAL_CONTROL_SPEED
from openpilot.selfdrive.controls.lib.longcontrol import LongControl from openpilot.selfdrive.controls.lib.longcontrol import LongControl
@@ -83,8 +82,11 @@ class Controls:
fire_the_babysitter = self.params.get_bool("FireTheBabysitter") fire_the_babysitter = self.params.get_bool("FireTheBabysitter")
mute_dm = fire_the_babysitter and self.params.get_bool("MuteDM") mute_dm = fire_the_babysitter and self.params.get_bool("MuteDM")
self.random_event_triggered = False
self.stopped_for_light_previously = False self.stopped_for_light_previously = False
self.random_event_timer = 0
ignore = self.sensor_packets + ['testJoystick'] ignore = self.sensor_packets + ['testJoystick']
if SIMULATION: if SIMULATION:
ignore += ['driverCameraState', 'managerState'] ignore += ['driverCameraState', 'managerState']
@@ -326,19 +328,26 @@ class Controls:
self.events.add(EventName.calibrationInvalid) self.events.add(EventName.calibrationInvalid)
# Handle lane change # Handle lane change
if self.sm['lateralPlan'].laneChangeState == LaneChangeState.preLaneChange: # if self.sm['lateralPlan'].laneChangeState == LaneChangeState.preLaneChange:
direction = self.sm['lateralPlan'].laneChangeDirection # direction = self.sm['lateralPlan'].laneChangeDirection
if (CS.leftBlindspot and direction == LaneChangeDirection.left) or \ # if (CS.leftBlindspot and direction == LaneChangeDirection.left) or \
(CS.rightBlindspot and direction == LaneChangeDirection.right): # (CS.rightBlindspot and direction == LaneChangeDirection.right):
self.events.add(EventName.laneChangeBlocked) # self.events.add(EventName.laneChangeBlocked)
else: # else:
if direction == LaneChangeDirection.left: # if direction == LaneChangeDirection.left:
self.events.add(EventName.preLaneChangeLeft) # self.events.add(EventName.preLaneChangeLeft)
else: # else:
self.events.add(EventName.preLaneChangeRight) # self.events.add(EventName.preLaneChangeRight)
elif self.sm['lateralPlan'].laneChangeState in (LaneChangeState.laneChangeStarting, # elif self.sm['lateralPlan'].laneChangeState in (LaneChangeState.laneChangeStarting,
LaneChangeState.laneChangeFinishing): # LaneChangeState.laneChangeFinishing):
self.events.add(EventName.laneChange) # self.events.add(EventName.laneChange)
# Handle turning
if not CS.standstill:
if self.sm['lateralPlan'].desire == Desire.turnLeft:
self.events.add(FrogPilotEventName.turningLeft)
elif self.sm['lateralPlan'].desire == Desire.turnRight:
self.events.add(FrogPilotEventName.turningRight)
for i, pandaState in enumerate(self.sm['pandaStates']): for i, pandaState in enumerate(self.sm['pandaStates']):
# All pandas must match the list of safetyConfigs, and if outside this list, must be silent or noOutput # All pandas must match the list of safetyConfigs, and if outside this list, must be silent or noOutput
@@ -520,7 +529,7 @@ class Controls:
def state_transition(self, CS): def state_transition(self, CS):
"""Compute conditional state transitions and execute actions on state transitions""" """Compute conditional state transitions and execute actions on state transitions"""
self.v_cruise_helper.update_v_cruise(CS, self.enabled, self.is_metric, self.reverse_cruise_increase) self.v_cruise_helper.update_v_cruise(CS, self.enabled, self.is_metric, self.reverse_cruise_increase, self.set_speed_offset)
# decrement the soft disable timer at every step, as it's reset on # decrement the soft disable timer at every step, as it's reset on
# entrance in SOFT_DISABLING state # entrance in SOFT_DISABLING state
@@ -609,7 +618,7 @@ class Controls:
# Update VehicleModel # Update VehicleModel
lp = self.sm['liveParameters'] lp = self.sm['liveParameters']
x = max(lp.stiffnessFactor, 0.1) x = max(lp.stiffnessFactor, 0.1)
sr = max(lp.steerRatio, 0.1) sr = max(self.steer_ratio, 0.1)
self.VM.update_params(x, sr) self.VM.update_params(x, sr)
# Update Torque Params # Update Torque Params
@@ -623,6 +632,14 @@ class Controls:
long_plan = self.sm['longitudinalPlan'] long_plan = self.sm['longitudinalPlan']
frogpilot_long_plan = self.sm['frogpilotLongitudinalPlan'] frogpilot_long_plan = self.sm['frogpilotLongitudinalPlan']
# Reset the Random Event flag
if self.random_event_triggered:
self.random_event_timer += 1
if self.random_event_timer >= 400:
self.random_event_triggered = False
self.random_event_timer = 0
self.params_memory.remove("CurrentRandomEvent")
CC = car.CarControl.new_message() CC = car.CarControl.new_message()
CC.enabled = self.enabled CC.enabled = self.enabled
@@ -634,7 +651,7 @@ class Controls:
gear = car.CarState.GearShifter gear = car.CarState.GearShifter
driving_gear = CS.gearShifter not in (gear.neutral, gear.park, gear.reverse, gear.unknown) driving_gear = CS.gearShifter not in (gear.neutral, gear.park, gear.reverse, gear.unknown)
signal_check = not ((CS.leftBlinker or CS.rightBlinker) and self.pause_lateral_on_signal and CS.vEgo < LANE_CHANGE_SPEED_MIN) signal_check = not ((CS.leftBlinker or CS.rightBlinker) and CS.vEgo < self.pause_lateral_on_signal and not CS.standstill)
# Always on lateral # Always on lateral
if self.always_on_lateral: if self.always_on_lateral:
@@ -642,7 +659,7 @@ class Controls:
self.lateral_allowed |= CS.cruiseState.enabled or (CS.cruiseState.available and self.always_on_lateral_main) self.lateral_allowed |= CS.cruiseState.enabled or (CS.cruiseState.available and self.always_on_lateral_main)
self.FPCC.alwaysOnLateral = self.lateral_allowed and driving_gear and signal_check self.FPCC.alwaysOnLateral = self.lateral_allowed and driving_gear and signal_check
if self.FPCC.alwaysOnLateral: if self.FPCC.alwaysOnLateral:/
self.current_alert_types.append(ET.WARNING) self.current_alert_types.append(ET.WARNING)
# Check which actuators can be enabled # Check which actuators can be enabled
@@ -655,9 +672,9 @@ class Controls:
actuators.longControlState = self.LoC.long_control_state actuators.longControlState = self.LoC.long_control_state
# Enable blinkers while lane changing # Enable blinkers while lane changing
if self.sm['lateralPlan'].laneChangeState != LaneChangeState.off: # if self.sm['lateralPlan'].laneChangeState != LaneChangeState.off:
CC.leftBlinker = self.sm['lateralPlan'].laneChangeDirection == LaneChangeDirection.left # CC.leftBlinker = self.sm['lateralPlan'].laneChangeDirection == LaneChangeDirection.left
CC.rightBlinker = self.sm['lateralPlan'].laneChangeDirection == LaneChangeDirection.right # CC.rightBlinker = self.sm['lateralPlan'].laneChangeDirection == LaneChangeDirection.right
if CS.leftBlinker or CS.rightBlinker: if CS.leftBlinker or CS.rightBlinker:
self.last_blinker_frame = self.sm.frame self.last_blinker_frame = self.sm.frame
@@ -724,8 +741,13 @@ class Controls:
turning = abs(lac_log.desiredLateralAccel) > 1.0 turning = abs(lac_log.desiredLateralAccel) > 1.0
good_speed = CS.vEgo > 5 good_speed = CS.vEgo > 5
max_torque = abs(self.last_actuators.steer) > 0.99 max_torque = abs(self.last_actuators.steer) > 0.99
if undershooting and turning and good_speed and max_torque: if undershooting and turning and good_speed and max_torque and not self.random_event_triggered:
lac_log.active and self.events.add(FrogPilotEventName.frogSteerSaturated if self.goat_scream else EventName.steerSaturated) if self.sm.frame % 10000 == 0:
lac_log.active and self.events.add(FrogPilotEventName.firefoxSteerSaturated)
self.params_memory.put_int("CurrentRandomEvent", 1)
self.random_event_triggered = True
else:
lac_log.active and self.events.add(FrogPilotEventName.frogSteerSaturated if self.goat_scream else EventName.steerSaturated)
elif lac_log.saturated: elif lac_log.saturated:
dpath_points = lat_plan.dPathPoints dpath_points = lat_plan.dPathPoints
if len(dpath_points): if len(dpath_points):
@@ -966,7 +988,8 @@ class Controls:
# Update FrogPilot parameters # Update FrogPilot parameters
if self.params_memory.get_bool("FrogPilotTogglesUpdated"): if self.params_memory.get_bool("FrogPilotTogglesUpdated"):
self.update_frogpilot_params() updateFrogPilotParams = threading.Thread(target=self.update_frogpilot_params)
updateFrogPilotParams.start()
except SystemExit: except SystemExit:
e.set() e.set()
@@ -987,11 +1010,18 @@ class Controls:
self.green_light_alert = self.params.get_bool("GreenLightAlert") self.green_light_alert = self.params.get_bool("GreenLightAlert")
lateral_tune = self.params.get_bool("LateralTune")
self.steer_ratio = self.params.get_float("SteerRatio") if lateral_tune else self.params.get_float("SteerRatioStock")
longitudinal_tune = self.params.get_bool("LongitudinalTune") longitudinal_tune = self.params.get_bool("LongitudinalTune")
self.sport_plus = self.params.get_int("AccelerationProfile") == 3 and longitudinal_tune self.sport_plus = self.params.get_int("AccelerationProfile") == 3 and longitudinal_tune
self.pause_lateral_on_signal = self.params.get_bool("PauseLateralOnSignal") quality_of_life = self.params.get_bool("QOLControls")
self.reverse_cruise_increase = self.params.get_bool("ReverseCruise") self.pause_lateral_on_signal = self.params.get_int("PauseLateralOnSignal") * (CV.KPH_TO_MS if self.is_metric else CV.MPH_TO_MS) if quality_of_life else 0
self.reverse_cruise_increase = self.params.get_bool("ReverseCruise") and quality_of_life
self.set_speed_offset = self.params.get_int("SetSpeedOffset") * (1 if self.is_metric else CV.MPH_TO_KPH) if quality_of_life else 0
self.random_events = self.params.get_bool("RandomEvents")
def main(): def main():
controls = Controls() controls = Controls()

View File

@@ -6,6 +6,7 @@ from openpilot.selfdrive.frogpilot.functions.frogpilot_planner import calculate_
LaneChangeState = log.LateralPlan.LaneChangeState LaneChangeState = log.LateralPlan.LaneChangeState
LaneChangeDirection = log.LateralPlan.LaneChangeDirection LaneChangeDirection = log.LateralPlan.LaneChangeDirection
TurnDirection = log.LateralPlan.Desire
LANE_CHANGE_SPEED_MIN = 20 * CV.MPH_TO_MS LANE_CHANGE_SPEED_MIN = 20 * CV.MPH_TO_MS
LANE_CHANGE_TIME_MAX = 10. LANE_CHANGE_TIME_MAX = 10.
@@ -31,6 +32,12 @@ DESIRES = {
}, },
} }
TURN_DESIRES = {
TurnDirection.none: log.LateralPlan.Desire.none,
TurnDirection.turnLeft: log.LateralPlan.Desire.turnLeft,
TurnDirection.turnRight: log.LateralPlan.Desire.turnRight,
}
class DesireHelper: class DesireHelper:
def __init__(self): def __init__(self):
@@ -43,7 +50,10 @@ class DesireHelper:
self.desire = log.LateralPlan.Desire.none self.desire = log.LateralPlan.Desire.none
# FrogPilot variables # FrogPilot variables
self.turn_direction = TurnDirection.none
self.lane_change_completed = False self.lane_change_completed = False
self.turn_completed = False
self.lane_change_wait_timer = 0 self.lane_change_wait_timer = 0
self.lane_width_left = 0 self.lane_width_left = 0
@@ -81,7 +91,14 @@ class DesireHelper:
if not lateral_active or self.lane_change_timer > LANE_CHANGE_TIME_MAX: if not lateral_active or self.lane_change_timer > LANE_CHANGE_TIME_MAX:
self.lane_change_state = LaneChangeState.off self.lane_change_state = LaneChangeState.off
self.lane_change_direction = LaneChangeDirection.none self.lane_change_direction = LaneChangeDirection.none
elif one_blinker and below_lane_change_speed and frogpilot_planner.turn_desires:
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
else: else:
# TurnDirection.turnLeft / turnRight
self.turn_direction = TurnDirection.none
# LaneChangeState.off # LaneChangeState.off
if self.lane_change_state == LaneChangeState.off and one_blinker and not self.prev_one_blinker and not below_lane_change_speed: if self.lane_change_state == LaneChangeState.off and one_blinker and not self.prev_one_blinker and not below_lane_change_speed:
self.lane_change_state = LaneChangeState.preLaneChange self.lane_change_state = LaneChangeState.preLaneChange
@@ -145,8 +162,14 @@ class DesireHelper:
# Reset the flags # Reset the flags
self.lane_change_completed &= one_blinker self.lane_change_completed &= one_blinker
self.turn_completed &= one_blinker
self.desire = DESIRES[self.lane_change_direction][self.lane_change_state] if self.turn_direction != TurnDirection.none:
self.desire = TURN_DESIRES[self.turn_direction]
elif not self.turn_completed:
self.desire = DESIRES[self.lane_change_direction][self.lane_change_state]
else:
self.desire = log.LateralPlan.Desire.none
# Send keep pulse once per second during LaneChangeStart.preLaneChange # Send keep pulse once per second during LaneChangeStart.preLaneChange
if self.lane_change_state in (LaneChangeState.off, LaneChangeState.laneChangeStarting): if self.lane_change_state in (LaneChangeState.off, LaneChangeState.laneChangeStarting):

View File

@@ -52,13 +52,13 @@ class VCruiseHelper:
def v_cruise_initialized(self): def v_cruise_initialized(self):
return self.v_cruise_kph != V_CRUISE_UNSET return self.v_cruise_kph != V_CRUISE_UNSET
def update_v_cruise(self, CS, enabled, is_metric, reverse_cruise_increase): def update_v_cruise(self, CS, enabled, is_metric, reverse_cruise_increase, set_speed_offset):
self.v_cruise_kph_last = self.v_cruise_kph self.v_cruise_kph_last = self.v_cruise_kph
if CS.cruiseState.available: if CS.cruiseState.available:
if not self.CP.pcmCruise: if not self.CP.pcmCruise:
# if stock cruise is completely disabled, then we can use our own set speed logic # if stock cruise is completely disabled, then we can use our own set speed logic
self._update_v_cruise_non_pcm(CS, enabled, is_metric, reverse_cruise_increase) self._update_v_cruise_non_pcm(CS, enabled, is_metric, reverse_cruise_increase, set_speed_offset)
self.v_cruise_cluster_kph = self.v_cruise_kph self.v_cruise_cluster_kph = self.v_cruise_kph
self.update_button_timers(CS, enabled) self.update_button_timers(CS, enabled)
else: else:
@@ -68,7 +68,7 @@ class VCruiseHelper:
self.v_cruise_kph = V_CRUISE_UNSET self.v_cruise_kph = V_CRUISE_UNSET
self.v_cruise_cluster_kph = V_CRUISE_UNSET self.v_cruise_cluster_kph = V_CRUISE_UNSET
def _update_v_cruise_non_pcm(self, CS, enabled, is_metric, reverse_cruise_increase): def _update_v_cruise_non_pcm(self, CS, enabled, is_metric, reverse_cruise_increase, set_speed_offset):
# handle button presses. TODO: this should be in state_control, but a decelCruise press # handle button presses. TODO: this should be in state_control, but a decelCruise press
# would have the effect of both enabling and changing speed is checked after the state transition # would have the effect of both enabling and changing speed is checked after the state transition
if not enabled: if not enabled:
@@ -110,6 +110,12 @@ class VCruiseHelper:
else: else:
self.v_cruise_kph += v_cruise_delta * CRUISE_INTERVAL_SIGN[button_type] self.v_cruise_kph += v_cruise_delta * CRUISE_INTERVAL_SIGN[button_type]
# Apply offset
v_cruise_offset = (set_speed_offset * CRUISE_INTERVAL_SIGN[button_type]) if long_press else 0
if v_cruise_offset < 0:
v_cruise_offset = set_speed_offset - v_cruise_delta
self.v_cruise_kph += v_cruise_offset
# If set is pressed while overriding, clip cruise speed to minimum of vEgo # If set is pressed while overriding, clip cruise speed to minimum of vEgo
if CS.gasPressed and button_type in (ButtonType.decelCruise, ButtonType.setCruise): if CS.gasPressed and button_type in (ButtonType.decelCruise, ButtonType.setCruise):
self.v_cruise_kph = max(self.v_cruise_kph, CS.vEgo * CV.MS_TO_KPH) self.v_cruise_kph = max(self.v_cruise_kph, CS.vEgo * CV.MS_TO_KPH)

View File

@@ -1012,6 +1012,30 @@ EVENTS: Dict[int, Dict[str, Union[Alert, AlertCallbackType]]] = {
ET.PERMANENT: torque_nn_load_alert, ET.PERMANENT: torque_nn_load_alert,
}, },
FrogPilotEventName.turningLeft: {
ET.WARNING: Alert(
"Turning Left",
"",
AlertStatus.normal, AlertSize.small,
Priority.LOW, VisualAlert.none, AudibleAlert.none, .1, alert_rate=0.75),
},
FrogPilotEventName.turningRight: {
ET.WARNING: Alert(
"Turning Right",
"",
AlertStatus.normal, AlertSize.small,
Priority.LOW, VisualAlert.none, AudibleAlert.none, .1, alert_rate=0.75),
},
# Random Events
FrogPilotEventName.firefoxSteerSaturated: {
ET.WARNING: Alert(
"Turn Exceeds Steering Limit",
"IE Has Stopped Responding...",
AlertStatus.userPrompt, AlertSize.mid,
Priority.LOW, VisualAlert.steerRequired, AudibleAlert.firefox, 4.),
},
} }

View File

@@ -56,7 +56,7 @@ T_DIFFS = np.diff(T_IDXS, prepend=[0.])
COMFORT_BRAKE = 2.5 COMFORT_BRAKE = 2.5
STOP_DISTANCE = 6.0 STOP_DISTANCE = 6.0
def get_jerk_factor(custom_personalities, aggressive_jerk, standard_jerk, relaxed_jerk, personality=log.LongitudinalPersonality.standard): def get_jerk_factor(custom_personalities=False, aggressive_jerk=0.5, standard_jerk=1.0, relaxed_jerk=1.0, personality=log.LongitudinalPersonality.standard):
if custom_personalities: if custom_personalities:
if personality==log.LongitudinalPersonality.relaxed: if personality==log.LongitudinalPersonality.relaxed:
return relaxed_jerk return relaxed_jerk
@@ -241,6 +241,13 @@ def gen_long_ocp():
class LongitudinalMpc: class LongitudinalMpc:
def __init__(self, mode='acc'): def __init__(self, mode='acc'):
# FrogPilot variables
self.safe_obstacle_distance = 0
self.safe_obstacle_distance_stock = 0
self.stopped_equivalence_factor = 0
self.t_follow = 0
self.t_follow_offset = 1
self.mode = mode self.mode = mode
self.solver = AcadosOcpSolverCython(MODEL_NAME, ACADOS_SOLVER_TYPE, N) self.solver = AcadosOcpSolverCython(MODEL_NAME, ACADOS_SOLVER_TYPE, N)
self.reset() self.reset()
@@ -292,8 +299,9 @@ class LongitudinalMpc:
for i in range(N): for i in range(N):
self.solver.cost_set(i, 'Zl', Zl) self.solver.cost_set(i, 'Zl', Zl)
def set_weights(self, custom_personalities, aggressive_jerk, standard_jerk, relaxed_jerk, prev_accel_constraint=True, personality=log.LongitudinalPersonality.standard): def set_weights(self, prev_accel_constraint=True, custom_personalities=False, aggressive_jerk=0.5, standard_jerk=1.0, relaxed_jerk=1.0, personality=log.LongitudinalPersonality.standard):
jerk_factor = get_jerk_factor(custom_personalities, aggressive_jerk, standard_jerk, relaxed_jerk, personality) jerk_factor = get_jerk_factor(custom_personalities, aggressive_jerk, standard_jerk, relaxed_jerk, personality)
jerk_factor /= np.mean(self.t_follow_offset)
if self.mode == 'acc': if self.mode == 'acc':
a_change_cost = A_CHANGE_COST if prev_accel_constraint else 0 a_change_cost = A_CHANGE_COST if prev_accel_constraint else 0
cost_weights = [X_EGO_OBSTACLE_COST, X_EGO_COST, V_EGO_COST, A_EGO_COST, jerk_factor * a_change_cost, jerk_factor * J_EGO_COST] cost_weights = [X_EGO_OBSTACLE_COST, X_EGO_COST, V_EGO_COST, A_EGO_COST, jerk_factor * a_change_cost, jerk_factor * J_EGO_COST]
@@ -351,7 +359,7 @@ class LongitudinalMpc:
self.cruise_min_a = min_a self.cruise_min_a = min_a
self.max_a = max_a self.max_a = max_a
def update(self, radarstate, v_cruise, x, v, a, j, aggressive_acceleration, smoother_braking, custom_personalities, aggressive_follow, standard_follow, relaxed_follow, increased_stopping_distance, personality=log.LongitudinalPersonality.standard): def update(self, radarstate, v_cruise, x, v, a, j, aggressive_acceleration, increased_stopping_distance, smoother_braking, custom_personalities, aggressive_follow, standard_follow, relaxed_follow, personality=log.LongitudinalPersonality.standard):
t_follow = get_T_FOLLOW(custom_personalities, aggressive_follow, standard_follow, relaxed_follow, personality) t_follow = get_T_FOLLOW(custom_personalities, aggressive_follow, standard_follow, relaxed_follow, personality)
self.t_follow = t_follow self.t_follow = t_follow
v_ego = self.x0[1] v_ego = self.x0[1]
@@ -363,8 +371,9 @@ class LongitudinalMpc:
# Offset by FrogAi for FrogPilot for a more natural takeoff with a lead # Offset by FrogAi for FrogPilot for a more natural takeoff with a lead
if aggressive_acceleration: if aggressive_acceleration:
distance_factor = np.maximum(1, lead_xv_0[:,0] - (lead_xv_0[:,1] * t_follow)) distance_factor = np.maximum(1, lead_xv_0[:,0] - (lead_xv_0[:,1] * t_follow))
t_follow_offset = np.clip((lead_xv_0[:,1] - v_ego) + (STOP_DISTANCE + increased_stopping_distance - v_ego), 1, distance_factor) standstill_offset = max(STOP_DISTANCE + increased_stopping_distance - (v_ego**COMFORT_BRAKE), 0)
t_follow = t_follow / t_follow_offset self.t_follow_offset = np.clip((lead_xv_0[:,1] - v_ego) + standstill_offset, 1, distance_factor)
t_follow = t_follow / self.t_follow_offset
# Offset by FrogAi for FrogPilot for a more natural approach to a slower lead # Offset by FrogAi for FrogPilot for a more natural approach to a slower lead
if smoother_braking: if smoother_braking:

View File

@@ -135,7 +135,7 @@ class LongitudinalPlanner:
accel_limits_turns[0] = min(accel_limits_turns[0], self.a_desired + 0.05) accel_limits_turns[0] = min(accel_limits_turns[0], self.a_desired + 0.05)
accel_limits_turns[1] = max(accel_limits_turns[1], self.a_desired - 0.05) accel_limits_turns[1] = max(accel_limits_turns[1], self.a_desired - 0.05)
self.mpc.set_weights(frogpilot_planner.custom_personalities, frogpilot_planner.aggressive_jerk, frogpilot_planner.standard_jerk, frogpilot_planner.relaxed_jerk, prev_accel_constraint, personality=self.personality) self.mpc.set_weights(prev_accel_constraint, frogpilot_planner.custom_personalities, frogpilot_planner.aggressive_jerk, frogpilot_planner.standard_jerk, frogpilot_planner.relaxed_jerk, personality=self.personality)
self.mpc.set_accel_limits(accel_limits_turns[0], accel_limits_turns[1]) self.mpc.set_accel_limits(accel_limits_turns[0], accel_limits_turns[1])
self.mpc.set_cur_state(self.v_desired_filter.x, self.a_desired) self.mpc.set_cur_state(self.v_desired_filter.x, self.a_desired)
x, v, a, j = self.parse_model(sm['modelV2'], self.v_model_error) x, v, a, j = self.parse_model(sm['modelV2'], self.v_model_error)

View File

@@ -1,6 +1,7 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import os import os
import numpy as np import numpy as np
import threading
from cereal import car from cereal import car
from openpilot.common.params import Params from openpilot.common.params import Params
from openpilot.common.realtime import Priority, config_realtime_process from openpilot.common.realtime import Priority, config_realtime_process
@@ -41,7 +42,7 @@ def plannerd_thread():
debug_mode = bool(int(os.getenv("DEBUG", "0"))) debug_mode = bool(int(os.getenv("DEBUG", "0")))
frogpilot_planner = FrogPilotPlanner(params) frogpilot_planner = FrogPilotPlanner(params, params_memory)
longitudinal_planner = LongitudinalPlanner(CP) longitudinal_planner = LongitudinalPlanner(CP)
lateral_planner = LateralPlanner(CP, debug=debug_mode) lateral_planner = LateralPlanner(CP, debug=debug_mode)
@@ -60,7 +61,8 @@ def plannerd_thread():
publish_ui_plan(sm, pm, lateral_planner, longitudinal_planner) publish_ui_plan(sm, pm, lateral_planner, longitudinal_planner)
if params_memory.get_bool("FrogPilotTogglesUpdated"): if params_memory.get_bool("FrogPilotTogglesUpdated"):
frogpilot_planner.update_frogpilot_params(params) updateFrogPilotToggles = threading.Thread(target=frogpilot_planner.update_frogpilot_params, args=(params, params_memory))
updateFrogPilotToggles.start()
def main(): def main():
plannerd_thread() plannerd_thread()

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 KiB

View File

@@ -200,7 +200,7 @@ class ConditionalExperimentalMode:
def update_frogpilot_params(self, is_metric, params): def update_frogpilot_params(self, is_metric, params):
self.curves = params.get_bool("CECurves") self.curves = params.get_bool("CECurves")
self.curves_lead = params.get_bool("CECurvesLead") self.curves_lead = params.get_bool("CECurvesLead")
self.experimental_mode_via_press = params.get_bool("ExperimentalModeViaPress") self.experimental_mode_via_press = params.get_bool("ExperimentalModeActivation")
self.limit = params.get_int("CESpeed") * (CV.KPH_TO_MS if is_metric else CV.MPH_TO_MS) self.limit = params.get_int("CESpeed") * (CV.KPH_TO_MS if is_metric else CV.MPH_TO_MS)
self.limit_lead = params.get_int("CESpeedLead") * (CV.KPH_TO_MS if is_metric else CV.MPH_TO_MS) self.limit_lead = params.get_int("CESpeedLead") * (CV.KPH_TO_MS if is_metric else CV.MPH_TO_MS)
self.navigation = params.get_bool("CENavigation") self.navigation = params.get_bool("CENavigation")

View File

@@ -12,6 +12,10 @@ from openpilot.selfdrive.frogpilot.functions.conditional_experimental_mode impor
from openpilot.selfdrive.frogpilot.functions.map_turn_speed_controller import MapTurnSpeedController from openpilot.selfdrive.frogpilot.functions.map_turn_speed_controller import MapTurnSpeedController
from openpilot.selfdrive.frogpilot.functions.speed_limit_controller import SpeedLimitController from openpilot.selfdrive.frogpilot.functions.speed_limit_controller import SpeedLimitController
# VTSC variables
MIN_TARGET_V = 5 # m/s
TARGET_LAT_A = 1.9 # m/s^2
# Acceleration profiles - Credit goes to the DragonPilot team! # Acceleration profiles - Credit goes to the DragonPilot team!
# MPH = [0., 35, 35, 40, 40, 45, 45, 67, 67, 67, 123] # MPH = [0., 35, 35, 40, 40, 45, 45, 67, 67, 67, 123]
A_CRUISE_MIN_BP_CUSTOM = [0., 2.0, 2.01, 11., 11.01, 18., 18.01, 28., 28.01, 33., 55.] A_CRUISE_MIN_BP_CUSTOM = [0., 2.0, 2.01, 11., 11.01, 18., 18.01, 28., 28.01, 33., 55.]
@@ -51,7 +55,7 @@ def calculate_lane_width(lane, current_lane, road_edge):
class FrogPilotPlanner: class FrogPilotPlanner:
def __init__(self, params): def __init__(self, params, params_memory):
self.cem = ConditionalExperimentalMode() self.cem = ConditionalExperimentalMode()
self.mtsc = MapTurnSpeedController() self.mtsc = MapTurnSpeedController()
@@ -61,10 +65,11 @@ class FrogPilotPlanner:
self.mtsc_target = 0 self.mtsc_target = 0
self.slc_target = 0 self.slc_target = 0
self.v_cruise = 0 self.v_cruise = 0
self.vtsc_target = 0
self.x_desired_trajectory = np.zeros(CONTROL_N) self.x_desired_trajectory = np.zeros(CONTROL_N)
self.update_frogpilot_params(params) self.update_frogpilot_params(params, params_memory)
def update(self, sm, mpc): def update(self, sm, mpc):
carState, controlsState, modelData = sm['carState'], sm['controlsState'], sm['modelV2'] carState, controlsState, modelData = sm['carState'], sm['controlsState'], sm['modelV2']
@@ -76,7 +81,7 @@ class FrogPilotPlanner:
v_ego = carState.vEgo v_ego = carState.vEgo
# Acceleration profiles # Acceleration profiles
v_cruise_changed = (self.mtsc_target) + 1 < v_cruise # Use stock acceleration profiles to handle MTSC more precisely v_cruise_changed = (self.mtsc_target or self.vtsc_target) + 1 < v_cruise # Use stock acceleration profiles to handle MTSC/VTSC more precisely
if v_cruise_changed: if v_cruise_changed:
self.accel_limits = [A_CRUISE_MIN, get_max_accel(v_ego)] self.accel_limits = [A_CRUISE_MIN, get_max_accel(v_ego)]
elif self.acceleration_profile == 1: elif self.acceleration_profile == 1:
@@ -90,7 +95,12 @@ class FrogPilotPlanner:
if self.conditional_experimental_mode and enabled: if self.conditional_experimental_mode and enabled:
self.cem.update(carState, sm['frogpilotNavigation'], sm['modelV2'], mpc, sm['radarState'], carState.standstill, v_ego) self.cem.update(carState, sm['frogpilotNavigation'], sm['modelV2'], mpc, sm['radarState'], carState.standstill, v_ego)
self.v_cruise = self.update_v_cruise(carState, controlsState, modelData, enabled, v_cruise, v_ego) if v_ego > MIN_TARGET_V:
self.v_cruise = self.update_v_cruise(carState, controlsState, modelData, enabled, v_cruise, v_ego)
else:
self.mtsc_target = v_cruise
self.vtsc_target = v_cruise
self.v_cruise = v_cruise
self.x_desired_trajectory_full = np.interp(ModelConstants.T_IDXS, T_IDXS_MPC, mpc.x_solution) self.x_desired_trajectory_full = np.interp(ModelConstants.T_IDXS, T_IDXS_MPC, mpc.x_solution)
self.x_desired_trajectory = self.x_desired_trajectory_full[:CONTROL_N] self.x_desired_trajectory = self.x_desired_trajectory_full[:CONTROL_N]
@@ -135,8 +145,31 @@ class FrogPilotPlanner:
self.overriden_speed = 0 self.overriden_speed = 0
self.slc_target = v_cruise self.slc_target = v_cruise
# Pfeiferj's Vision Turn Controller
if self.vision_turn_controller:
# Set the curve sensitivity
orientation_rate = np.array(np.abs(modelData.orientationRate.z)) * self.curve_sensitivity
velocity = np.array(modelData.velocity.x)
# Get the maximum lat accel from the model
max_pred_lat_acc = np.amax(orientation_rate * velocity)
# Get the maximum curve based on the current velocity
max_curve = max_pred_lat_acc / (v_ego**2)
# Set the target lateral acceleration
adjusted_target_lat_a = TARGET_LAT_A * self.turn_aggressiveness
# Get the target velocity for the maximum curve
self.vtsc_target = (adjusted_target_lat_a / max_curve) ** 0.5
self.vtsc_target = np.clip(self.vtsc_target, MIN_TARGET_V, v_cruise)
if self.vtsc_target == MIN_TARGET_V:
self.vtsc_target = v_cruise
else:
self.vtsc_target = v_cruise
v_ego_diff = max(carState.vEgoRaw - carState.vEgoCluster, 0) v_ego_diff = max(carState.vEgoRaw - carState.vEgoCluster, 0)
return min(v_cruise, self.mtsc_target, self.slc_target) - v_ego_diff return min(v_cruise, self.mtsc_target, self.slc_target, self.vtsc_target) - v_ego_diff
def publish_lateral(self, sm, pm, DH): def publish_lateral(self, sm, pm, DH):
frogpilot_lateral_plan_send = messaging.new_message('frogpilotLateralPlan') frogpilot_lateral_plan_send = messaging.new_message('frogpilotLateralPlan')
@@ -153,7 +186,7 @@ class FrogPilotPlanner:
frogpilot_longitudinal_plan_send.valid = sm.all_checks(service_list=['carState', 'controlsState']) frogpilot_longitudinal_plan_send.valid = sm.all_checks(service_list=['carState', 'controlsState'])
frogpilotLongitudinalPlan = frogpilot_longitudinal_plan_send.frogpilotLongitudinalPlan frogpilotLongitudinalPlan = frogpilot_longitudinal_plan_send.frogpilotLongitudinalPlan
frogpilotLongitudinalPlan.adjustedCruise = float(min(self.mtsc_target) * (CV.MS_TO_KPH if self.is_metric else CV.MS_TO_MPH)) frogpilotLongitudinalPlan.adjustedCruise = float(min(self.mtsc_target, self.vtsc_target) * (CV.MS_TO_KPH if self.is_metric else CV.MS_TO_MPH))
frogpilotLongitudinalPlan.conditionalExperimental = self.cem.experimental_mode frogpilotLongitudinalPlan.conditionalExperimental = self.cem.experimental_mode
frogpilotLongitudinalPlan.distances = self.x_desired_trajectory.tolist() frogpilotLongitudinalPlan.distances = self.x_desired_trajectory.tolist()
frogpilotLongitudinalPlan.redLight = bool(self.cem.red_light_detected) frogpilotLongitudinalPlan.redLight = bool(self.cem.red_light_detected)
@@ -170,7 +203,7 @@ class FrogPilotPlanner:
pm.send('frogpilotLongitudinalPlan', frogpilot_longitudinal_plan_send) pm.send('frogpilotLongitudinalPlan', frogpilot_longitudinal_plan_send)
def update_frogpilot_params(self, params): def update_frogpilot_params(self, params, params_memory):
self.is_metric = params.get_bool("IsMetric") self.is_metric = params.get_bool("IsMetric")
self.blindspot_path = params.get_bool("CustomUI") and params.get_bool("BlindSpotPath") self.blindspot_path = params.get_bool("CustomUI") and params.get_bool("BlindSpotPath")
@@ -209,3 +242,10 @@ class FrogPilotPlanner:
if self.speed_limit_controller: if self.speed_limit_controller:
self.speed_limit_controller_override = params.get_int("SLCOverride") self.speed_limit_controller_override = params.get_int("SLCOverride")
SpeedLimitController.update_frogpilot_params() SpeedLimitController.update_frogpilot_params()
self.turn_desires = params.get_bool("TurnDesires")
self.vision_turn_controller = params.get_bool("VisionTurnControl")
if self.vision_turn_controller:
self.curve_sensitivity = params.get_int("CurveSensitivity") / 100
self.turn_aggressiveness = params.get_int("TurnAggressiveness") / 100

View File

@@ -15,7 +15,7 @@ FrogPilotControlsPanel::FrogPilotControlsPanel(SettingsWindow *parent) : FrogPil
{"CustomPersonalities", "Custom Driving Personalities", "Customize the driving personality profiles to your driving style.", "../frogpilot/assets/toggle_icons/icon_custom.png"}, {"CustomPersonalities", "Custom Driving Personalities", "Customize the driving personality profiles to your driving style.", "../frogpilot/assets/toggle_icons/icon_custom.png"},
{"DeviceShutdown", "Device Shutdown Timer", "Configure the timer for automatic device shutdown when offroad conserving energy and preventing battery drain.", "../frogpilot/assets/toggle_icons/icon_time.png"}, {"DeviceShutdown", "Device Shutdown Timer", "Configure the timer for automatic device shutdown when offroad conserving energy and preventing battery drain.", "../frogpilot/assets/toggle_icons/icon_time.png"},
{"ExperimentalModeViaPress", "Experimental Mode Via 'LKAS' Button / Screen", "Toggle Experimental Mode by double-clicking the 'Lane Departure'/'LKAS' button or double tapping screen.\n\nOverrides 'Conditional Experimental Mode'.", "../assets/img_experimental_white.svg"}, {"ExperimentalModeActivation", "Experimental Mode Via", "Toggle Experimental Mode by double-clicking the 'Lane Departure'/'LKAS' button or double tapping screen.\n\nOverrides 'Conditional Experimental Mode'.", "../assets/img_experimental_white.svg"},
{"FireTheBabysitter", "Fire the Babysitter", "Deactivate some of openpilot's 'Babysitter' protocols for more user autonomy.", "../frogpilot/assets/toggle_icons/icon_babysitter.png"}, {"FireTheBabysitter", "Fire the Babysitter", "Deactivate some of openpilot's 'Babysitter' protocols for more user autonomy.", "../frogpilot/assets/toggle_icons/icon_babysitter.png"},
{"NoLogging", "Disable All Logging", "Turn off all data tracking to enhance privacy or reduce thermal load.\n\nWARNING: This action will prevent drive recording and data cannot be recovered!", ""}, {"NoLogging", "Disable All Logging", "Turn off all data tracking to enhance privacy or reduce thermal load.\n\nWARNING: This action will prevent drive recording and data cannot be recovered!", ""},
@@ -23,10 +23,12 @@ FrogPilotControlsPanel::FrogPilotControlsPanel(SettingsWindow *parent) : FrogPil
{"MuteDM", "Mute Driver Monitoring", "Disable driver monitoring.", ""}, {"MuteDM", "Mute Driver Monitoring", "Disable driver monitoring.", ""},
{"MuteOverheated", "Mute Overheated System Alert", "Disable alerts for the device being overheated.", ""}, {"MuteOverheated", "Mute Overheated System Alert", "Disable alerts for the device being overheated.", ""},
{"MuteSeatbelt", "Mute Seatbelt Unlatched Alert", "Disable alerts for unlatched seatbelts.", ""}, {"MuteSeatbelt", "Mute Seatbelt Unlatched Alert", "Disable alerts for unlatched seatbelts.", ""},
{"OfflineMode", "Offline Mode", "Allow the device to be offline indefinitely.", ""},
{"LateralTune", "Lateral Tuning", "Modify openpilot's steering behavior.", "../frogpilot/assets/toggle_icons/icon_lateral_tune.png"}, {"LateralTune", "Lateral Tuning", "Modify openpilot's steering behavior.", "../frogpilot/assets/toggle_icons/icon_lateral_tune.png"},
{"AverageCurvature", "Average Desired Curvature", "Use Pfeiferj's distance-based curvature adjustment for improved curve handling.", ""}, {"AverageCurvature", "Average Desired Curvature", "Use Pfeiferj's distance-based curvature adjustment for improved curve handling.", ""},
{"NNFF", "NNFF - Neural Network Feedforward", "Use Twilsonco's Neural Network Feedforward for enhanced precision in lateral control.", ""}, {"NNFF", "NNFF - Neural Network Feedforward", "Use Twilsonco's Neural Network Feedforward for enhanced precision in lateral control.", ""},
{"SteerRatio", steerRatioStock != 0 ? QString("Steer Ratio (Default: %1)").arg(steerRatioStock, 0, 'f', 2) : "Steer Ratio", "Set a custom steer ratio for your vehicle controls.", ""},
{"LongitudinalTune", "Longitudinal Tuning", "Modify openpilot's acceleration and braking behavior.", "../frogpilot/assets/toggle_icons/icon_longitudinal_tune.png"}, {"LongitudinalTune", "Longitudinal Tuning", "Modify openpilot's acceleration and braking behavior.", "../frogpilot/assets/toggle_icons/icon_longitudinal_tune.png"},
{"AccelerationProfile", "Acceleration Profile", "Change the acceleration rate to be either sporty or eco-friendly.", ""}, {"AccelerationProfile", "Acceleration Profile", "Change the acceleration rate to be either sporty or eco-friendly.", ""},
@@ -35,13 +37,20 @@ FrogPilotControlsPanel::FrogPilotControlsPanel(SettingsWindow *parent) : FrogPil
{"SmoothBraking", "Smoother Braking Behind Lead", "Smoothen out the braking behavior when approaching slower vehicles.", ""}, {"SmoothBraking", "Smoother Braking Behind Lead", "Smoothen out the braking behavior when approaching slower vehicles.", ""},
{"Model", "Model Selector", "Choose your preferred openpilot model.", "../assets/offroad/icon_calibration.png"}, {"Model", "Model Selector", "Choose your preferred openpilot model.", "../assets/offroad/icon_calibration.png"},
{"MTSCEnabled", "Map Turn Speed Control", "Slow down for anticipated curves detected by your downloaded maps.", "../frogpilot/assets/toggle_icons/icon_speed_map.png"}, {"MTSCEnabled", "Map Turn Speed Control", "Slow down for anticipated curves detected by your downloaded maps.", "../frogpilot/assets/toggle_icons/icon_speed_map.png"},
{"NudgelessLaneChange", "Nudgeless Lane Change", "Enable lane changes without manual steering input.", "../frogpilot/assets/toggle_icons/icon_lane.png"}, {"NudgelessLaneChange", "Nudgeless Lane Change", "Enable lane changes without manual steering input.", "../frogpilot/assets/toggle_icons/icon_lane.png"},
{"LaneChangeTime", "Lane Change Timer", "Specify a delay before executing a nudgeless lane change.", ""}, {"LaneChangeTime", "Lane Change Timer", "Specify a delay before executing a nudgeless lane change.", ""},
{"LaneDetection", "Lane Detection", "Block nudgeless lane changes when a lane isn't detected.", ""}, {"LaneDetection", "Lane Detection", "Block nudgeless lane changes when a lane isn't detected.", ""},
{"OneLaneChange", "One Lane Change Per Signal", "Limit to one nudgeless lane change per turn signal activation.", ""}, {"OneLaneChange", "One Lane Change Per Signal", "Limit to one nudgeless lane change per turn signal activation.", ""},
{"PauseLateralOnSignal", "Pause Lateral On Turn Signal", "Temporarily disable lateral control during turn signal use.", ""},
{"QOLControls", "Quality of Life", "Miscellaneous quality of life changes to improve your overall openpilot experience.", "../frogpilot/assets/toggle_icons/quality_of_life.png"},
{"DisableOnroadUploads", "Disable Onroad Uploads", "Prevent large data uploads when onroad.", ""},
{"HigherBitrate", "Higher Bitrate Recording", "Increases the quality of the footage uploaded to comma connect.", ""},
{"PauseLateralOnSignal", "Pause Lateral On Turn Signal Below", "Temporarily disable lateral control during turn signal use below the set speed.", ""},
{"ReverseCruise", "Reverse Cruise Increase", "Reverses the 'long press' functionality when increasing the max set speed. Useful to increase the max speed quickly.", ""},
{"SetSpeedOffset", "Set Speed Offset", "Set an offset for your desired set speed.", ""},
{"SpeedLimitController", "Speed Limit Controller", "Automatically adjust vehicle speed to match speed limits using 'Open Street Map's, 'Navigate On openpilot', or your car's dashboard (TSS2 Toyotas only).", "../assets/offroad/icon_speed_limit.png"}, {"SpeedLimitController", "Speed Limit Controller", "Automatically adjust vehicle speed to match speed limits using 'Open Street Map's, 'Navigate On openpilot', or your car's dashboard (TSS2 Toyotas only).", "../assets/offroad/icon_speed_limit.png"},
{"Offset1", "Speed Limit Offset (0-34 mph)", "Speed limit offset for speed limits between 0-34 mph.", ""}, {"Offset1", "Speed Limit Offset (0-34 mph)", "Speed limit offset for speed limits between 0-34 mph.", ""},
@@ -51,6 +60,12 @@ FrogPilotControlsPanel::FrogPilotControlsPanel(SettingsWindow *parent) : FrogPil
{"SLCFallback", "Fallback Method", "Choose your fallback method for when there are no speed limits currently being obtained from Navigation, OSM, and the car's dashboard.", ""}, {"SLCFallback", "Fallback Method", "Choose your fallback method for when there are no speed limits currently being obtained from Navigation, OSM, and the car's dashboard.", ""},
{"SLCOverride", "Override Method", "Choose your preferred method to override the current speed limit.", ""}, {"SLCOverride", "Override Method", "Choose your preferred method to override the current speed limit.", ""},
{"SLCPriority", "Priority Order", "Determine the priority order for what speed limits to use.", ""}, {"SLCPriority", "Priority Order", "Determine the priority order for what speed limits to use.", ""},
{"TurnDesires", "Use Turn Desires", "Use turn desires for enhanced precision in turns below the minimum lane change speed.", "../assets/navigation/direction_continue_right.png"},
{"VisionTurnControl", "Vision Turn Speed Controller", "Slow down for detected road curvature for smoother curve handling.", "../frogpilot/assets/toggle_icons/icon_vtc.png"},
{"CurveSensitivity", "Curve Detection Sensitivity", "Set curve detection sensitivity. Higher values prompt earlier responses, lower values lead to smoother but later reactions.", ""},
{"TurnAggressiveness", "Turn Speed Aggressiveness", "Set turn speed aggressiveness. Higher values result in faster turns, lower values yield gentler turns.", ""},
}; };
for (const auto &[param, title, desc, icon] : controlToggles) { for (const auto &[param, title, desc, icon] : controlToggles) {
@@ -60,7 +75,7 @@ FrogPilotControlsPanel::FrogPilotControlsPanel(SettingsWindow *parent) : FrogPil
toggle = new FrogPilotParamValueControl(param, title, desc, icon, 0, 3, {{0, "None"}, {1, "Steering Wheel"}, {2, "Onroad UI Button"}, {3, "Wheel + Button"}}, this, true); toggle = new FrogPilotParamValueControl(param, title, desc, icon, 0, 3, {{0, "None"}, {1, "Steering Wheel"}, {2, "Onroad UI Button"}, {3, "Wheel + Button"}}, this, true);
} else if (param == "AlwaysOnLateral") { } else if (param == "AlwaysOnLateral") {
std::vector<QString> aolToggles{tr("AlwaysOnLateralMain")}; std::vector<QString> aolToggles{"AlwaysOnLateralMain"};
std::vector<QString> aolToggleNames{tr("Enable On Cruise Main")}; std::vector<QString> aolToggleNames{tr("Enable On Cruise Main")};
toggle = new FrogPilotParamToggleControl(param, title, desc, icon, aolToggles, aolToggleNames); toggle = new FrogPilotParamToggleControl(param, title, desc, icon, aolToggles, aolToggleNames);
@@ -87,24 +102,24 @@ FrogPilotControlsPanel::FrogPilotControlsPanel(SettingsWindow *parent) : FrogPil
toggle = conditionalExperimentalToggle; toggle = conditionalExperimentalToggle;
} else if (param == "CECurves") { } else if (param == "CECurves") {
FrogPilotParamValueControl *CESpeedImperial = new FrogPilotParamValueControl("CESpeed", "Below", "Switch to 'Experimental Mode' below this speed in absence of a lead vehicle.", "", 0, 99, FrogPilotParamValueControl *CESpeedImperial = new FrogPilotParamValueControl("CESpeed", "Below", "Switch to 'Experimental Mode' below this speed in absence of a lead vehicle.", "", 0, 99,
std::map<int, QString>(), this, false, " mph"); std::map<int, QString>(), this, false, " mph");
FrogPilotParamValueControl *CESpeedLeadImperial = new FrogPilotParamValueControl("CESpeedLead", " w/Lead", "Switch to 'Experimental Mode' below this speed when following a lead vehicle.", "", 0, 99, FrogPilotParamValueControl *CESpeedLeadImperial = new FrogPilotParamValueControl("CESpeedLead", " w/Lead", "Switch to 'Experimental Mode' below this speed when following a lead vehicle.", "", 0, 99,
std::map<int, QString>(), this, false, " mph"); std::map<int, QString>(), this, false, " mph");
conditionalSpeedsImperial = new FrogPilotDualParamControl(CESpeedImperial, CESpeedLeadImperial, this); conditionalSpeedsImperial = new FrogPilotDualParamControl(CESpeedImperial, CESpeedLeadImperial, this);
addItem(conditionalSpeedsImperial); addItem(conditionalSpeedsImperial);
FrogPilotParamValueControl *CESpeedMetric = new FrogPilotParamValueControl("CESpeed", "Below", "Switch to 'Experimental Mode' below this speed in absence of a lead vehicle.", "", 0, 150, FrogPilotParamValueControl *CESpeedMetric = new FrogPilotParamValueControl("CESpeed", "Below", "Switch to 'Experimental Mode' below this speed in absence of a lead vehicle.", "", 0, 150,
std::map<int, QString>(), this, false, " kph"); std::map<int, QString>(), this, false, " kph");
FrogPilotParamValueControl *CESpeedLeadMetric = new FrogPilotParamValueControl("CESpeedLead", " w/Lead", "Switch to 'Experimental Mode' below this speed when following a lead vehicle.", "", FrogPilotParamValueControl *CESpeedLeadMetric = new FrogPilotParamValueControl("CESpeedLead", " w/Lead", "Switch to 'Experimental Mode' below this speed when following a lead vehicle.", "", 0, 150,
0, 150, std::map<int, QString>(), this, false, " kph"); std::map<int, QString>(), this, false, " kph");
conditionalSpeedsMetric = new FrogPilotDualParamControl(CESpeedMetric, CESpeedLeadMetric, this); conditionalSpeedsMetric = new FrogPilotDualParamControl(CESpeedMetric, CESpeedLeadMetric, this);
addItem(conditionalSpeedsMetric); addItem(conditionalSpeedsMetric);
std::vector<QString> curveToggles{tr("CECurvesLead")}; std::vector<QString> curveToggles{"CECurvesLead"};
std::vector<QString> curveToggleNames{tr("With Lead")}; std::vector<QString> curveToggleNames{tr("With Lead")};
toggle = new FrogPilotParamToggleControl(param, title, desc, icon, curveToggles, curveToggleNames); toggle = new FrogPilotParamToggleControl(param, title, desc, icon, curveToggles, curveToggleNames);
} else if (param == "CEStopLights") { } else if (param == "CEStopLights") {
std::vector<QString> stopLightToggles{tr("CEStopLightsLead")}; std::vector<QString> stopLightToggles{"CEStopLightsLead"};
std::vector<QString> stopLightToggleNames{tr("With Lead")}; std::vector<QString> stopLightToggleNames{tr("With Lead")};
toggle = new FrogPilotParamToggleControl(param, title, desc, icon, stopLightToggles, stopLightToggleNames); toggle = new FrogPilotParamToggleControl(param, title, desc, icon, stopLightToggles, stopLightToggleNames);
@@ -155,6 +170,11 @@ FrogPilotControlsPanel::FrogPilotControlsPanel(SettingsWindow *parent) : FrogPil
} }
toggle = new FrogPilotParamValueControl(param, title, desc, icon, 0, 33, shutdownLabels, this, false); toggle = new FrogPilotParamValueControl(param, title, desc, icon, 0, 33, shutdownLabels, this, false);
} else if (param == "ExperimentalModeActivation") {
std::vector<QString> experimentalModeToggles{"ExperimentalModeViaLKAS", "ExperimentalModeViaScreen"};
std::vector<QString> experimentalModeNames{tr("LKAS Button"), tr("Screen")};
toggle = new FrogPilotParamToggleControl(param, title, desc, icon, experimentalModeToggles, experimentalModeNames);
} else if (param == "FireTheBabysitter") { } else if (param == "FireTheBabysitter") {
FrogPilotParamManageControl *fireTheBabysitterToggle = new FrogPilotParamManageControl(param, title, desc, icon, this); FrogPilotParamManageControl *fireTheBabysitterToggle = new FrogPilotParamManageControl(param, title, desc, icon, this);
QObject::connect(fireTheBabysitterToggle, &FrogPilotParamManageControl::manageButtonClicked, this, [this]() { QObject::connect(fireTheBabysitterToggle, &FrogPilotParamManageControl::manageButtonClicked, this, [this]() {
@@ -174,6 +194,8 @@ FrogPilotControlsPanel::FrogPilotControlsPanel(SettingsWindow *parent) : FrogPil
} }
}); });
toggle = lateralTuneToggle; toggle = lateralTuneToggle;
} else if (param == "SteerRatio") {
toggle = new FrogPilotParamValueControlFloat(param, title, desc, icon, steerRatioStock * 0.75, steerRatioStock * 1.25, std::map<int, QString>(), this, false, "", 10.0);
} else if (param == "LongitudinalTune") { } else if (param == "LongitudinalTune") {
FrogPilotParamManageControl *longitudinalTuneToggle = new FrogPilotParamManageControl(param, title, desc, icon, this); FrogPilotParamManageControl *longitudinalTuneToggle = new FrogPilotParamManageControl(param, title, desc, icon, this);
@@ -236,6 +258,20 @@ FrogPilotControlsPanel::FrogPilotControlsPanel(SettingsWindow *parent) : FrogPil
} }
toggle = new FrogPilotParamValueControl(param, title, desc, icon, 0, 10, laneChangeTimeLabels, this, false); toggle = new FrogPilotParamValueControl(param, title, desc, icon, 0, 10, laneChangeTimeLabels, this, false);
} else if (param == "QOLControls") {
FrogPilotParamManageControl *qolToggle = new FrogPilotParamManageControl(param, title, desc, icon, this);
QObject::connect(qolToggle, &FrogPilotParamManageControl::manageButtonClicked, this, [this]() {
parentToggleClicked();
for (auto &[key, toggle] : toggles) {
toggle->setVisible(qolKeys.find(key.c_str()) != qolKeys.end());
}
});
toggle = qolToggle;
} else if (param == "PauseLateralOnSignal") {
toggle = new FrogPilotParamValueControl(param, title, desc, icon, 0, 99, std::map<int, QString>(), this, false, " mph");
} else if (param == "SetSpeedOffset") {
toggle = new FrogPilotParamValueControl(param, title, desc, icon, 0, 99, std::map<int, QString>(), this, false, " mph");
} else if (param == "SpeedLimitController") { } else if (param == "SpeedLimitController") {
FrogPilotParamManageControl *speedLimitControllerToggle = new FrogPilotParamManageControl(param, title, desc, icon, this); FrogPilotParamManageControl *speedLimitControllerToggle = new FrogPilotParamManageControl(param, title, desc, icon, this);
QObject::connect(speedLimitControllerToggle, &FrogPilotParamManageControl::manageButtonClicked, this, [this]() { QObject::connect(speedLimitControllerToggle, &FrogPilotParamManageControl::manageButtonClicked, this, [this]() {
@@ -321,6 +357,18 @@ FrogPilotControlsPanel::FrogPilotControlsPanel(SettingsWindow *parent) : FrogPil
slscPriorityButton->setValue(priorities[params.getInt("SLCPriority")]); slscPriorityButton->setValue(priorities[params.getInt("SLCPriority")]);
addItem(slscPriorityButton); addItem(slscPriorityButton);
} else if (param == "VisionTurnControl") {
FrogPilotParamManageControl *visionTurnControlToggle = new FrogPilotParamManageControl(param, title, desc, icon, this);
QObject::connect(visionTurnControlToggle, &FrogPilotParamManageControl::manageButtonClicked, this, [this]() {
parentToggleClicked();
for (auto &[key, toggle] : toggles) {
toggle->setVisible(visionTurnControlKeys.find(key.c_str()) != visionTurnControlKeys.end());
}
});
toggle = visionTurnControlToggle;
} else if (param == "CurveSensitivity" || param == "TurnAggressiveness") {
toggle = new FrogPilotParamValueControl(param, title, desc, icon, 1, 200, std::map<int, QString>(), this, false, "%");
} else { } else {
toggle = new ParamControl(param, title, desc, icon, this); toggle = new ParamControl(param, title, desc, icon, this);
} }
@@ -345,7 +393,7 @@ FrogPilotControlsPanel::FrogPilotControlsPanel(SettingsWindow *parent) : FrogPil
}); });
} }
std::set<std::string> rebootKeys = {"AlwaysOnLateral", "FireTheBabysitter", "MuteDM", "NNFF"}; std::set<std::string> rebootKeys = {"AlwaysOnLateral", "FireTheBabysitter", "HigherBitrate", "MuteDM", "NNFF"};
for (const std::string &key : rebootKeys) { for (const std::string &key : rebootKeys) {
QObject::connect(toggles[key], &ToggleControl::toggleFlipped, [this]() { QObject::connect(toggles[key], &ToggleControl::toggleFlipped, [this]() {
if (FrogPilotConfirmationDialog::toggle("Reboot required to take effect.", "Reboot Now", this)) { if (FrogPilotConfirmationDialog::toggle("Reboot required to take effect.", "Reboot Now", this)) {
@@ -355,12 +403,20 @@ FrogPilotControlsPanel::FrogPilotControlsPanel(SettingsWindow *parent) : FrogPil
} }
conditionalExperimentalKeys = {"CECurves", "CECurvesLead", "CESlowerLead", "CENavigation", "CEStopLights", "CESignal"}; conditionalExperimentalKeys = {"CECurves", "CECurvesLead", "CESlowerLead", "CENavigation", "CEStopLights", "CESignal"};
fireTheBabysitterKeys = {"NoLogging", "MuteDM", "MuteDoor", "MuteOverheated", "MuteSeatbelt"}; fireTheBabysitterKeys = {"NoLogging", "MuteDM", "MuteDoor", "MuteOverheated", "MuteSeatbelt", "OfflineMode"};
laneChangeKeys = {"LaneChangeTime", "LaneDetection", "OneLaneChange", "PauseLateralOnSignal"}; laneChangeKeys = {"LaneChangeTime", "LaneDetection", "OneLaneChange"};
lateralTuneKeys = {"AverageCurvature", "NNFF"}; lateralTuneKeys = {"AverageCurvature", "NNFF", "SteerRatio"};
longitudinalTuneKeys = {"AccelerationProfile", "AggressiveAcceleration", "SmoothBraking", "StoppingDistance"}; longitudinalTuneKeys = {"AccelerationProfile", "AggressiveAcceleration", "SmoothBraking", "StoppingDistance"};
mtscKeys = {"MTSCAggressiveness"};
qolKeys = {"DisableOnroadUploads", "HigherBitrate", "PauseLateralOnSignal", "ReverseCruise", "SetSpeedOffset"};
speedLimitControllerKeys = {"Offset1", "Offset2", "Offset3", "Offset4", "SLCFallback", "SLCOverride", "SLCPriority"}; speedLimitControllerKeys = {"Offset1", "Offset2", "Offset3", "Offset4", "SLCFallback", "SLCOverride", "SLCPriority"};
visionTurnControlKeys = {}; visionTurnControlKeys = {"CurveSensitivity", "TurnAggressiveness"};
QObject::connect(uiState(), &UIState::offroadTransition, this, [this](bool offroad) {
if (!offroad) {
updateCarToggles();
}
});
QObject::connect(device(), &Device::interactiveTimeout, this, &FrogPilotControlsPanel::hideSubToggles); QObject::connect(device(), &Device::interactiveTimeout, this, &FrogPilotControlsPanel::hideSubToggles);
QObject::connect(parent, &SettingsWindow::closeParentToggle, this, &FrogPilotControlsPanel::hideSubToggles); QObject::connect(parent, &SettingsWindow::closeParentToggle, this, &FrogPilotControlsPanel::hideSubToggles);
@@ -370,6 +426,14 @@ FrogPilotControlsPanel::FrogPilotControlsPanel(SettingsWindow *parent) : FrogPil
updateMetric(); updateMetric();
} }
void FrogPilotControlsPanel::updateCarToggles() {
FrogPilotParamValueControlFloat *steerRatioToggle = static_cast<FrogPilotParamValueControlFloat*>(toggles["SteerRatio"]);
steerRatioStock = params.getFloat("SteerRatioStock");
steerRatioToggle->setTitle(steerRatioStock != 0 ? QString("Steer Ratio (Default: %1)").arg(steerRatioStock, 0, 'f', 2) : QString("Steer Ratio"));
steerRatioToggle->updateControl(steerRatioStock * 0.75, steerRatioStock * 1.25, "", 10.0);
steerRatioToggle->refresh();
}
void FrogPilotControlsPanel::updateToggles() { void FrogPilotControlsPanel::updateToggles() {
std::thread([this]() { std::thread([this]() {
paramsMemory.putBool("FrogPilotTogglesUpdated", true); paramsMemory.putBool("FrogPilotTogglesUpdated", true);
@@ -391,6 +455,8 @@ void FrogPilotControlsPanel::updateMetric() {
params.putInt("Offset2", std::nearbyint(params.getInt("Offset2") * speedConversion)); params.putInt("Offset2", std::nearbyint(params.getInt("Offset2") * speedConversion));
params.putInt("Offset3", std::nearbyint(params.getInt("Offset3") * speedConversion)); params.putInt("Offset3", std::nearbyint(params.getInt("Offset3") * speedConversion));
params.putInt("Offset4", std::nearbyint(params.getInt("Offset4") * speedConversion)); params.putInt("Offset4", std::nearbyint(params.getInt("Offset4") * speedConversion));
params.putInt("PauseLateralOnSignal", std::nearbyint(params.getInt("PauseLateralOnSignal") * speedConversion));
params.putInt("SetSpeedOffset", std::nearbyint(params.getInt("SetSpeedOffset") * speedConversion));
params.putInt("StoppingDistance", std::nearbyint(params.getInt("StoppingDistance") * distanceConversion)); params.putInt("StoppingDistance", std::nearbyint(params.getInt("StoppingDistance") * distanceConversion));
} }
@@ -398,6 +464,8 @@ void FrogPilotControlsPanel::updateMetric() {
FrogPilotParamValueControl *offset2Toggle = static_cast<FrogPilotParamValueControl*>(toggles["Offset2"]); FrogPilotParamValueControl *offset2Toggle = static_cast<FrogPilotParamValueControl*>(toggles["Offset2"]);
FrogPilotParamValueControl *offset3Toggle = static_cast<FrogPilotParamValueControl*>(toggles["Offset3"]); FrogPilotParamValueControl *offset3Toggle = static_cast<FrogPilotParamValueControl*>(toggles["Offset3"]);
FrogPilotParamValueControl *offset4Toggle = static_cast<FrogPilotParamValueControl*>(toggles["Offset4"]); FrogPilotParamValueControl *offset4Toggle = static_cast<FrogPilotParamValueControl*>(toggles["Offset4"]);
FrogPilotParamValueControl *pauseLateralToggle = static_cast<FrogPilotParamValueControl*>(toggles["PauseLateralOnSignal"]);
FrogPilotParamValueControl *setSpeedOffsetToggle = static_cast<FrogPilotParamValueControl*>(toggles["SetSpeedOffset"]);
FrogPilotParamValueControl *stoppingDistanceToggle = static_cast<FrogPilotParamValueControl*>(toggles["StoppingDistance"]); FrogPilotParamValueControl *stoppingDistanceToggle = static_cast<FrogPilotParamValueControl*>(toggles["StoppingDistance"]);
if (isMetric) { if (isMetric) {
@@ -411,10 +479,12 @@ void FrogPilotControlsPanel::updateMetric() {
offset3Toggle->setDescription("Set speed limit offset for limits between 55-64 kph."); offset3Toggle->setDescription("Set speed limit offset for limits between 55-64 kph.");
offset4Toggle->setDescription("Set speed limit offset for limits between 65-99 kph."); offset4Toggle->setDescription("Set speed limit offset for limits between 65-99 kph.");
offset1Toggle->updateControl(0, 99, " kph"); offset1Toggle->updateControl(0, 150, " kph");
offset2Toggle->updateControl(0, 99, " kph"); offset2Toggle->updateControl(0, 150, " kph");
offset3Toggle->updateControl(0, 99, " kph"); offset3Toggle->updateControl(0, 150, " kph");
offset4Toggle->updateControl(0, 99, " kph"); offset4Toggle->updateControl(0, 150, " kph");
pauseLateralToggle->updateControl(0, 150, " kph");
setSpeedOffsetToggle->updateControl(0, 150, " kph");
stoppingDistanceToggle->updateControl(0, 5, " meters"); stoppingDistanceToggle->updateControl(0, 5, " meters");
} else { } else {
offset1Toggle->setTitle("Speed Limit Offset (0-34 mph)"); offset1Toggle->setTitle("Speed Limit Offset (0-34 mph)");
@@ -431,6 +501,8 @@ void FrogPilotControlsPanel::updateMetric() {
offset2Toggle->updateControl(0, 99, " mph"); offset2Toggle->updateControl(0, 99, " mph");
offset3Toggle->updateControl(0, 99, " mph"); offset3Toggle->updateControl(0, 99, " mph");
offset4Toggle->updateControl(0, 99, " mph"); offset4Toggle->updateControl(0, 99, " mph");
pauseLateralToggle->updateControl(0, 99, " mph");
setSpeedOffsetToggle->updateControl(0, 99, " mph");
stoppingDistanceToggle->updateControl(0, 10, " feet"); stoppingDistanceToggle->updateControl(0, 10, " feet");
} }
@@ -438,6 +510,8 @@ void FrogPilotControlsPanel::updateMetric() {
offset2Toggle->refresh(); offset2Toggle->refresh();
offset3Toggle->refresh(); offset3Toggle->refresh();
offset4Toggle->refresh(); offset4Toggle->refresh();
pauseLateralToggle->refresh();
setSpeedOffsetToggle->refresh();
stoppingDistanceToggle->refresh(); stoppingDistanceToggle->refresh();
previousIsMetric = isMetric; previousIsMetric = isMetric;
@@ -466,12 +540,14 @@ void FrogPilotControlsPanel::hideSubToggles() {
for (auto &[key, toggle] : toggles) { for (auto &[key, toggle] : toggles) {
bool subToggles = conditionalExperimentalKeys.find(key.c_str()) != conditionalExperimentalKeys.end() || bool subToggles = conditionalExperimentalKeys.find(key.c_str()) != conditionalExperimentalKeys.end() ||
fireTheBabysitterKeys.find(key.c_str()) != fireTheBabysitterKeys.end() || fireTheBabysitterKeys.find(key.c_str()) != fireTheBabysitterKeys.end() ||
laneChangeKeys.find(key.c_str()) != laneChangeKeys.end() || laneChangeKeys.find(key.c_str()) != laneChangeKeys.end() ||
lateralTuneKeys.find(key.c_str()) != lateralTuneKeys.end() || lateralTuneKeys.find(key.c_str()) != lateralTuneKeys.end() ||
longitudinalTuneKeys.find(key.c_str()) != longitudinalTuneKeys.end() || longitudinalTuneKeys.find(key.c_str()) != longitudinalTuneKeys.end() ||
speedLimitControllerKeys.find(key.c_str()) != speedLimitControllerKeys.end() || mtscKeys.find(key.c_str()) != mtscKeys.end() ||
visionTurnControlKeys.find(key.c_str()) != visionTurnControlKeys.end(); qolKeys.find(key.c_str()) != qolKeys.end() ||
speedLimitControllerKeys.find(key.c_str()) != speedLimitControllerKeys.end() ||
visionTurnControlKeys.find(key.c_str()) != visionTurnControlKeys.end();
toggle->setVisible(!subToggles); toggle->setVisible(!subToggles);
} }

View File

@@ -19,6 +19,7 @@ private:
void hideEvent(QHideEvent *event); void hideEvent(QHideEvent *event);
void hideSubToggles(); void hideSubToggles();
void parentToggleClicked(); void parentToggleClicked();
void updateCarToggles();
void updateMetric(); void updateMetric();
void updateToggles(); void updateToggles();
@@ -37,6 +38,8 @@ private:
std::set<QString> laneChangeKeys; std::set<QString> laneChangeKeys;
std::set<QString> lateralTuneKeys; std::set<QString> lateralTuneKeys;
std::set<QString> longitudinalTuneKeys; std::set<QString> longitudinalTuneKeys;
std::set<QString> mtscKeys;
std::set<QString> qolKeys;
std::set<QString> speedLimitControllerKeys; std::set<QString> speedLimitControllerKeys;
std::set<QString> visionTurnControlKeys; std::set<QString> visionTurnControlKeys;
@@ -46,4 +49,5 @@ private:
Params paramsMemory{"/dev/shm/params"}; Params paramsMemory{"/dev/shm/params"};
bool isMetric = params.getBool("IsMetric"); bool isMetric = params.getBool("IsMetric");
float steerRatioStock = params.getFloat("SteerRatioStock");
}; };

View File

@@ -45,17 +45,19 @@ void setDefaultParams() {
Params params = Params(); Params params = Params();
bool FrogsGoMoo = params.get("DongleId").substr(0, 3) == "be6"; bool FrogsGoMoo = params.get("DongleId").substr(0, 3) == "be6";
bool brianbot = true;
std::map<std::string, std::string> defaultValues { std::map<std::string, std::string> defaultValues {
{"AccelerationPath", FrogsGoMoo ? "1" : "0"}, {"AccelerationPath", brianbot ? "1" : "0"},
{"AccelerationProfile", FrogsGoMoo ? "3" : "2"}, {"AccelerationProfile", brianbot ? "2" : "2"},
{"AdjacentPath", FrogsGoMoo ? "1" : "0"}, {"AdjacentPath", FrogsGoMoo ? "1" : "0"},
{"AdjustablePersonalities", "3"}, {"AdjustablePersonalities", "3"},
{"AggressiveAcceleration", "1"}, {"AggressiveAcceleration", "1"},
{"AggressiveFollow", FrogsGoMoo ? "10" : "12"}, {"AggressiveFollow", FrogsGoMoo ? "10" : "12"},
{"AggressiveJerk", FrogsGoMoo ? "6" : "5"}, {"AggressiveJerk", FrogsGoMoo ? "6" : "5"},
{"AlwaysOnLateral", "1"}, {"AlwaysOnLateral", "1"},
{"AlwaysOnLateralMain", FrogsGoMoo ? "1" : "0"}, {"AlwaysOnLateralMain", brianbot ? "1" : "0"},
{"AverageCurvature", FrogsGoMoo ? "1" : "0"}, {"AverageCurvature", brianbot ? "1" : "0"},
{"BlindSpotPath", "1"}, {"BlindSpotPath", "1"},
{"CameraView", FrogsGoMoo ? "1" : "0"}, {"CameraView", FrogsGoMoo ? "1" : "0"},
{"CECurves", "1"}, {"CECurves", "1"},
@@ -72,21 +74,26 @@ void setDefaultParams() {
{"CurveSensitivity", FrogsGoMoo ? "125" : "100"}, {"CurveSensitivity", FrogsGoMoo ? "125" : "100"},
{"CustomColors", "1"}, {"CustomColors", "1"},
{"CustomIcons", "1"}, {"CustomIcons", "1"},
{"CustomPersonalities", "1"}, {"CustomPersonalities", "0"},
{"CustomSignals", "1"}, {"CustomSignals", "0"},
{"CustomSounds", "1"}, {"CustomSounds", "1"},
{"CustomTheme", "1"}, {"CustomTheme", "1"},
{"CustomUI", "1"}, {"CustomUI", "0"},
{"DeviceShutdown", "9"}, {"DeviceShutdown", "1"},
{"DriverCamera", "0"}, {"DriverCamera", "0"},
{"DriveStats", "1"},
{"EVTable", FrogsGoMoo ? "0" : "1"}, {"EVTable", FrogsGoMoo ? "0" : "1"},
{"ExperimentalModeViaPress", "1"}, {"ExperimentalModeActivation", "1"},
{"ExperimentalModeViaLKAS", "0"},
{"ExperimentalModeViaScreen", FrogsGoMoo ? "0" : "1"},
{"Fahrenheit", "0"}, {"Fahrenheit", "0"},
{"FireTheBabysitter", FrogsGoMoo ? "1" : "0"}, {"FireTheBabysitter", FrogsGoMoo ? "1" : "0"},
{"FullMap", "0"},
{"GasRegenCmd", "0"}, {"GasRegenCmd", "0"},
{"GoatScream", "1"}, {"GoatScream", "0"},
{"GreenLightAlert", "0"}, {"GreenLightAlert", "0"},
{"HideSpeed", "0"}, {"HideSpeed", "0"},
{"HigherBitrate", "0"},
{"LaneChangeTime", "0"}, {"LaneChangeTime", "0"},
{"LaneDetection", "1"}, {"LaneDetection", "1"},
{"LaneLinesWidth", "4"}, {"LaneLinesWidth", "4"},
@@ -96,16 +103,16 @@ void setDefaultParams() {
{"LongitudinalTune", "1"}, {"LongitudinalTune", "1"},
{"LongPitch", FrogsGoMoo ? "0" : "1"}, {"LongPitch", FrogsGoMoo ? "0" : "1"},
{"LowerVolt", FrogsGoMoo ? "0" : "1"}, {"LowerVolt", FrogsGoMoo ? "0" : "1"},
{"Model", "0"}, {"Model", "3"},
{"ModelUI", "1"}, {"ModelUI", "1"},
{"MTSCEnabled", "1"}, {"MTSCEnabled", "1"},
{"MuteDM", FrogsGoMoo ? "1" : "0"}, {"MuteDM", FrogsGoMoo ? "1" : "1"},
{"MuteDoor", FrogsGoMoo ? "1" : "0"}, {"MuteDoor", FrogsGoMoo ? "1" : "1"},
{"MuteOverheated", FrogsGoMoo ? "1" : "0"}, {"MuteOverheated", FrogsGoMoo ? "1" : "0"},
{"MuteSeatbelt", FrogsGoMoo ? "1" : "0"}, {"MuteSeatbelt", FrogsGoMoo ? "1" : "0"},
{"NNFF", FrogsGoMoo ? "1" : "0"}, {"NNFF", FrogsGoMoo ? "1" : "1"},
{"NoLogging", "0"}, {"NoLogging", "1"},
{"NudgelessLaneChange", "1"}, {"NudgelessLaneChange", "0"},
{"NumericalTemp", FrogsGoMoo ? "1" : "0"}, {"NumericalTemp", FrogsGoMoo ? "1" : "0"},
{"Offset1", "5"}, {"Offset1", "5"},
{"Offset2", FrogsGoMoo ? "7" : "5"}, {"Offset2", FrogsGoMoo ? "7" : "5"},
@@ -116,6 +123,8 @@ void setDefaultParams() {
{"PathWidth", "61"}, {"PathWidth", "61"},
{"PauseLateralOnSignal", "0"}, {"PauseLateralOnSignal", "0"},
{"PreferredSchedule", "0"}, {"PreferredSchedule", "0"},
{"QOLControls", "1"},
{"QOLVisuals", "1"},
{"RandomEvents", FrogsGoMoo ? "1" : "0"}, {"RandomEvents", FrogsGoMoo ? "1" : "0"},
{"RelaxedFollow", "30"}, {"RelaxedFollow", "30"},
{"RelaxedJerk", "50"}, {"RelaxedJerk", "50"},
@@ -145,6 +154,7 @@ void setDefaultParams() {
{"TurnDesires", "1"}, {"TurnDesires", "1"},
{"UnlimitedLength", "1"}, {"UnlimitedLength", "1"},
{"UseSI", FrogsGoMoo ? "1" : "0"}, {"UseSI", FrogsGoMoo ? "1" : "0"},
{"UseVienna", "0"},
{"VisionTurnControl", "1"}, {"VisionTurnControl", "1"},
{"WheelIcon", FrogsGoMoo ? "1" : "0"} {"WheelIcon", FrogsGoMoo ? "1" : "0"}
}; };

View File

@@ -179,8 +179,8 @@ class FrogPilotParamToggleControl : public ParamControl {
Q_OBJECT Q_OBJECT
public: public:
FrogPilotParamToggleControl(const QString &param, const QString &title, const QString &desc, FrogPilotParamToggleControl(const QString &param, const QString &title, const QString &desc,
const QString &icon, const std::vector<QString> &button_params, const QString &icon, const std::vector<QString> &button_params,
const std::vector<QString> &button_texts, QWidget *parent = nullptr, const std::vector<QString> &button_texts, QWidget *parent = nullptr,
const int minimum_button_width = 225) const int minimum_button_width = 225)
: ParamControl(param, title, desc, icon, parent) { : ParamControl(param, title, desc, icon, parent) {
@@ -313,10 +313,11 @@ public:
valueLabel->setStyleSheet("QLabel { color: #E0E879; }"); valueLabel->setStyleSheet("QLabel { color: #E0E879; }");
} }
void updateControl(int newMinValue, int newMaxValue, const QString &newLabel) { void updateControl(int newMinValue, int newMaxValue, const QString &newLabel, int newDivision = 1) {
minValue = newMinValue; minValue = newMinValue;
maxValue = newMaxValue; maxValue = newMaxValue;
labelText = newLabel; labelText = newLabel;
division = newDivision;
} }
void showEvent(QShowEvent *event) override { void showEvent(QShowEvent *event) override {
@@ -362,6 +363,120 @@ private:
} }
}; };
class FrogPilotParamValueControlFloat : public ParamControl {
Q_OBJECT
public:
FrogPilotParamValueControlFloat(const QString &param, const QString &title, const QString &desc, const QString &icon,
const float &minValue, const float &maxValue, const std::map<int, QString> &valueLabels,
QWidget *parent = nullptr, const bool &loop = true, const QString &label = "", const float &division = 1.0f)
: ParamControl(param, title, desc, icon, parent),
minValue(minValue), maxValue(maxValue), valueLabelMappings(valueLabels), loop(loop), labelText(label), division(division) {
key = param.toStdString();
valueLabel = new QLabel(this);
hlayout->addWidget(valueLabel);
QPushButton *decrementButton = createButton("-", this);
QPushButton *incrementButton = createButton("+", this);
hlayout->addWidget(decrementButton);
hlayout->addWidget(incrementButton);
connect(decrementButton, &QPushButton::clicked, this, [=]() {
updateValue(-1.0f);
});
connect(incrementButton, &QPushButton::clicked, this, [=]() {
updateValue(1.0f);
});
toggle.hide();
}
void updateValue(float increment) {
value += increment * 0.1f;
if (loop) {
if (value < minValue) value = maxValue;
else if (value > maxValue) value = minValue;
} else {
value = std::max(minValue, std::min(maxValue, value));
}
params.putFloat(key, value);
refresh();
emit buttonPressed();
emit valueChanged(value);
}
void refresh() {
value = params.getFloat(key);
QString text;
auto it = valueLabelMappings.find(value);
if (division > 0.1f) {
text = QString::number(value, 'f', 1);
} else {
text = it != valueLabelMappings.end() ? it->second : QString::number(value, 'f', 1);
}
if (!labelText.isEmpty()) {
text += labelText;
}
valueLabel->setText(text);
valueLabel->setStyleSheet("QLabel { color: #E0E879; }");
}
void updateControl(float newMinValue, float newMaxValue, const QString &newLabel, float newDivision = 1.0f) {
minValue = newMinValue;
maxValue = newMaxValue;
labelText = newLabel;
division = newDivision;
}
void showEvent(QShowEvent *event) override {
refresh();
}
signals:
void buttonPressed();
void valueChanged(float value);
private:
bool loop;
float division;
float maxValue;
float minValue;
float value;
QLabel *valueLabel;
QString labelText;
std::map<int, QString> valueLabelMappings;
std::string key;
Params params;
QPushButton *createButton(const QString &text, QWidget *parent) {
QPushButton *button = new QPushButton(text, parent);
button->setFixedSize(150, 100);
button->setAutoRepeat(true);
button->setAutoRepeatInterval(150);
button->setStyleSheet(R"(
QPushButton {
border-radius: 50px;
font-size: 50px;
font-weight: 500;
height: 100px;
padding: 0 25 0 25;
color: #E4E4E4;
background-color: #393939;
}
QPushButton:pressed {
background-color: #4a4a4a;
}
)");
return button;
}
};
class FrogPilotDualParamControl : public QFrame { class FrogPilotDualParamControl : public QFrame {
Q_OBJECT Q_OBJECT
@@ -492,10 +607,11 @@ public:
valueLabel->setStyleSheet("QLabel { color: #E0E879; }"); valueLabel->setStyleSheet("QLabel { color: #E0E879; }");
} }
void updateControl(int newMinValue, int newMaxValue, const QString &newLabel) { void updateControl(int newMinValue, int newMaxValue, const QString &newLabel, int newDivision) {
minValue = newMinValue; minValue = newMinValue;
maxValue = newMaxValue; maxValue = newMaxValue;
labelText = newLabel; labelText = newLabel;
division = newDivision;
} }
void showEvent(QShowEvent *event) override { void showEvent(QShowEvent *event) override {

View File

@@ -121,10 +121,10 @@ FrogPilotVehiclesPanel::FrogPilotVehiclesPanel(SettingsWindow *parent) : FrogPil
}); });
} }
gmKeys = {"EVTable", "GasRegenCmd", "LongPitch"}; gmKeys = {"EVTable", "GasRegenCmd", "LongPitch", "LowerVolt"};
toyotaKeys = {}; toyotaKeys = {"LockDoors", "SNGHack", "TSS2Tune"};
std::set<std::string> rebootKeys = {"LowerVolt", "TSS2Tune"}; std::set<std::string> rebootKeys = {"EVTable", "GasRegenCmd", "LongPitch", "LowerVolt", "TSS2Tune"};
for (const std::string &key : rebootKeys) { for (const std::string &key : rebootKeys) {
QObject::connect(toggles[key], &ToggleControl::toggleFlipped, [this]() { QObject::connect(toggles[key], &ToggleControl::toggleFlipped, [this]() {
if (FrogPilotConfirmationDialog::toggle("Reboot required to take effect.", "Reboot Now", this)) { if (FrogPilotConfirmationDialog::toggle("Reboot required to take effect.", "Reboot Now", this)) {

View File

@@ -18,6 +18,7 @@ FrogPilotVisualsPanel::FrogPilotVisualsPanel(SettingsWindow *parent) : FrogPilot
{"ShowFPS", "FPS Counter", "Display the Frames Per Second (FPS) of your onroad UI for monitoring system performance.", ""}, {"ShowFPS", "FPS Counter", "Display the Frames Per Second (FPS) of your onroad UI for monitoring system performance.", ""},
{"LeadInfo", "Lead Info and Logics", "Get detailed information about the vehicle ahead, including speed and distance, and the logic behind your following distance.", ""}, {"LeadInfo", "Lead Info and Logics", "Get detailed information about the vehicle ahead, including speed and distance, and the logic behind your following distance.", ""},
{"RoadNameUI", "Road Name", "See the name of the road you're on at the bottom of your screen. Sourced from OpenStreetMap.", ""}, {"RoadNameUI", "Road Name", "See the name of the road you're on at the bottom of your screen. Sourced from OpenStreetMap.", ""},
{"UseVienna", "Use Vienna Speed Limit Signs", "Use the Vienna (EU) speed limit style signs as opposed to MUTCD (US).", ""},
{"DriverCamera", "Driver Camera On Reverse", "Show the driver's camera feed when you shift to reverse.", "../assets/img_driver_face_static.png"}, {"DriverCamera", "Driver Camera On Reverse", "Show the driver's camera feed when you shift to reverse.", "../assets/img_driver_face_static.png"},
{"GreenLightAlert", "Green Light Alert", "Get an alert when a traffic light changes from red to green.", "../frogpilot/assets/toggle_icons/icon_green_light.png"}, {"GreenLightAlert", "Green Light Alert", "Get an alert when a traffic light changes from red to green.", "../frogpilot/assets/toggle_icons/icon_green_light.png"},
@@ -30,6 +31,12 @@ FrogPilotVisualsPanel::FrogPilotVisualsPanel(SettingsWindow *parent) : FrogPilot
{"RoadEdgesWidth", "Road Edges", "Adjust the visual thickness of road edges on your display.\n\nDefault is 1/2 of the MUTCD average lane line width of 4 inches.", ""}, {"RoadEdgesWidth", "Road Edges", "Adjust the visual thickness of road edges on your display.\n\nDefault is 1/2 of the MUTCD average lane line width of 4 inches.", ""},
{"UnlimitedLength", "'Unlimited' Road UI Length", "Extend the display of the path, lane lines, and road edges as far as the system can detect, providing a more expansive view of the road ahead.", ""}, {"UnlimitedLength", "'Unlimited' Road UI Length", "Extend the display of the path, lane lines, and road edges as far as the system can detect, providing a more expansive view of the road ahead.", ""},
{"QOLVisuals", "Quality of Life", "Miscellaneous quality of life changes to improve your overall openpilot experience.", "../frogpilot/assets/toggle_icons/quality_of_life.png"},
{"DriveStats", "Drive Stats In Home Screen", "Display your device's drive stats in the home screen.", ""},
{"HideSpeed", "Hide Speed", "Hide the speed indicator in the onroad UI.", ""},
{"ShowSLCOffset", "Show Speed Limit Offset", "Show the speed limit offset seperated from the speed limit in the onroad UI when using 'Speed Limit Controller'.", ""},
{"RandomEvents", "Random Events", "Enjoy a bit of unpredictability with random events that can occur during certain driving conditions.", "../frogpilot/assets/toggle_icons/icon_random.png"},
{"ScreenBrightness", "Screen Brightness", "Customize your screen brightness.", "../frogpilot/assets/toggle_icons/icon_light.png"}, {"ScreenBrightness", "Screen Brightness", "Customize your screen brightness.", "../frogpilot/assets/toggle_icons/icon_light.png"},
{"SilentMode", "Silent Mode", "Mute openpilot sounds for a quieter driving experience.", "../frogpilot/assets/toggle_icons/icon_mute.png"}, {"SilentMode", "Silent Mode", "Mute openpilot sounds for a quieter driving experience.", "../frogpilot/assets/toggle_icons/icon_mute.png"},
{"WheelIcon", "Steering Wheel Icon", "Replace the default steering wheel icon with a custom design, adding a unique touch to your interface.", "../assets/offroad/icon_openpilot.png"}, {"WheelIcon", "Steering Wheel Icon", "Replace the default steering wheel icon with a custom design, adding a unique touch to your interface.", "../assets/offroad/icon_openpilot.png"},
@@ -99,6 +106,16 @@ FrogPilotVisualsPanel::FrogPilotVisualsPanel(SettingsWindow *parent) : FrogPilot
} else if (param == "PathWidth") { } else if (param == "PathWidth") {
toggle = new FrogPilotParamValueControl(param, title, desc, icon, 0, 100, std::map<int, QString>(), this, false, " feet", 10); toggle = new FrogPilotParamValueControl(param, title, desc, icon, 0, 100, std::map<int, QString>(), this, false, " feet", 10);
} else if (param == "QOLVisuals") {
FrogPilotParamManageControl *qolToggle = new FrogPilotParamManageControl(param, title, desc, icon, this);
QObject::connect(qolToggle, &FrogPilotParamManageControl::manageButtonClicked, this, [this]() {
parentToggleClicked();
for (auto &[key, toggle] : toggles) {
toggle->setVisible(qolKeys.find(key.c_str()) != qolKeys.end());
}
});
toggle = qolToggle;
} else if (param == "ScreenBrightness") { } else if (param == "ScreenBrightness") {
std::map<int, QString> brightnessLabels; std::map<int, QString> brightnessLabels;
for (int i = 0; i <= 101; ++i) { for (int i = 0; i <= 101; ++i) {
@@ -136,9 +153,19 @@ FrogPilotVisualsPanel::FrogPilotVisualsPanel(SettingsWindow *parent) : FrogPilot
}); });
} }
customOnroadUIKeys = {"AdjacentPath", "BlindSpotPath", "ShowFPS", "LeadInfo", "RoadNameUI"}; std::set<std::string> rebootKeys = {"DriveStats"};
for (const std::string &key : rebootKeys) {
QObject::connect(toggles[key], &ToggleControl::toggleFlipped, [this]() {
if (FrogPilotConfirmationDialog::toggle("Reboot required to take effect.", "Reboot Now", this)) {
Hardware::reboot();
}
});
}
customOnroadUIKeys = {"AdjacentPath", "BlindSpotPath", "ShowFPS", "LeadInfo", "RoadNameUI", "UseVienna"};
customThemeKeys = {"CustomColors", "CustomIcons", "CustomSignals", "CustomSounds"}; customThemeKeys = {"CustomColors", "CustomIcons", "CustomSignals", "CustomSounds"};
modelUIKeys = {"AccelerationPath", "LaneLinesWidth", "PathEdgeWidth", "PathWidth", "RoadEdgesWidth", "UnlimitedLength"}; modelUIKeys = {"AccelerationPath", "LaneLinesWidth", "PathEdgeWidth", "PathWidth", "RoadEdgesWidth", "UnlimitedLength"};
qolKeys = {"DriveStats", "HideSpeed", "ShowSLCOffset"};
QObject::connect(device(), &Device::interactiveTimeout, this, &FrogPilotVisualsPanel::hideSubToggles); QObject::connect(device(), &Device::interactiveTimeout, this, &FrogPilotVisualsPanel::hideSubToggles);
QObject::connect(parent, &SettingsWindow::closeParentToggle, this, &FrogPilotVisualsPanel::hideSubToggles); QObject::connect(parent, &SettingsWindow::closeParentToggle, this, &FrogPilotVisualsPanel::hideSubToggles);
@@ -201,8 +228,9 @@ void FrogPilotVisualsPanel::parentToggleClicked() {
void FrogPilotVisualsPanel::hideSubToggles() { void FrogPilotVisualsPanel::hideSubToggles() {
for (auto &[key, toggle] : toggles) { for (auto &[key, toggle] : toggles) {
bool subToggles = modelUIKeys.find(key.c_str()) != modelUIKeys.end() || bool subToggles = modelUIKeys.find(key.c_str()) != modelUIKeys.end() ||
customOnroadUIKeys.find(key.c_str()) != customOnroadUIKeys.end() || customOnroadUIKeys.find(key.c_str()) != customOnroadUIKeys.end() ||
customThemeKeys.find(key.c_str()) != customThemeKeys.end(); customThemeKeys.find(key.c_str()) != customThemeKeys.end() ||
qolKeys.find(key.c_str()) != qolKeys.end();
toggle->setVisible(!subToggles); toggle->setVisible(!subToggles);
} }

View File

@@ -25,6 +25,7 @@ private:
std::set<QString> customOnroadUIKeys; std::set<QString> customOnroadUIKeys;
std::set<QString> customThemeKeys; std::set<QString> customThemeKeys;
std::set<QString> modelUIKeys; std::set<QString> modelUIKeys;
std::set<QString> qolKeys;
std::map<std::string, ParamControl*> toggles; std::map<std::string, ParamControl*> toggles;

View File

@@ -134,6 +134,14 @@ def main():
CP = msg CP = msg
cloudlog.info("paramsd got CarParams") cloudlog.info("paramsd got CarParams")
steer_ratio = params_reader.get_float("SteerRatio")
steer_ratio_stock = params_reader.get_float("SteerRatioStock")
if steer_ratio_stock != CP.steerRatio or steer_ratio >= steer_ratio_stock * 2:
params_reader.put_float("SteerRatio", CP.steerRatio)
params_reader.put_float("SteerRatioStock", CP.steerRatio)
params_reader.put_bool("DoReboot", True)
min_sr, max_sr = 0.5 * CP.steerRatio, 2.0 * CP.steerRatio min_sr, max_sr = 0.5 * CP.steerRatio, 2.0 * CP.steerRatio
params = params_reader.get("LiveParameters") params = params_reader.get("LiveParameters")

View File

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

View File

@@ -77,7 +77,8 @@ class RouteEngine:
def update(self): def update(self):
# Update FrogPilot parameters # Update FrogPilot parameters
if self.params_memory.get_bool("FrogPilotTogglesUpdated"): if self.params_memory.get_bool("FrogPilotTogglesUpdated"):
self.update_frogpilot_params() updateFrogPilotParams = threading.Thread(target=self.update_frogpilot_params)
updateFrogPilotParams.start()
self.sm.update(0) self.sm.update(0)

View File

@@ -309,7 +309,7 @@ def thermald_thread(end_event, hw_queue) -> None:
startup_conditions["time_valid"] = now > MIN_DATE startup_conditions["time_valid"] = now > MIN_DATE
set_offroad_alert_if_changed("Offroad_InvalidTime", (not startup_conditions["time_valid"]) and peripheral_panda_present) set_offroad_alert_if_changed("Offroad_InvalidTime", (not startup_conditions["time_valid"]) and peripheral_panda_present)
startup_conditions["up_to_date"] = params.get("OfflineMode") or params.get("Offroad_ConnectivityNeeded") is None or params.get_bool("DisableUpdates") or params.get_bool("SnoozeUpdate") startup_conditions["up_to_date"] = (params.get("OfflineMode") and params.get("FireTheBabysitter")) or params.get("Offroad_ConnectivityNeeded") is None or params.get_bool("DisableUpdates") or params.get_bool("SnoozeUpdate")
startup_conditions["not_uninstalling"] = not params.get_bool("DoUninstall") startup_conditions["not_uninstalling"] = not params.get_bool("DoUninstall")
startup_conditions["accepted_terms"] = params.get("HasAcceptedTerms") == terms_version startup_conditions["accepted_terms"] = params.get("HasAcceptedTerms") == terms_version

View File

@@ -160,7 +160,7 @@ OffroadHome::OffroadHome(QWidget* parent) : QFrame(parent) {
left_widget->addWidget(new DriveStats); left_widget->addWidget(new DriveStats);
left_widget->setStyleSheet("border-radius: 10px;"); left_widget->setStyleSheet("border-radius: 10px;");
left_widget->setCurrentIndex(uiState()->hasPrime() ? 0 : true ? 2 : 1); left_widget->setCurrentIndex(params.getBool("DriveStats") ? 2 : uiState()->hasPrime() ? 0 : 1);
connect(uiState(), &UIState::primeChanged, [=](bool prime) { connect(uiState(), &UIState::primeChanged, [=](bool prime) {
left_widget->setCurrentIndex(prime ? 0 : 1); left_widget->setCurrentIndex(prime ? 0 : 1);
}); });

View File

@@ -205,14 +205,6 @@ AdvancedNetworking::AdvancedNetworking(QWidget* parent, WifiManager* wifi): QWid
}); });
list->addItem(hiddenNetworkButton); list->addItem(hiddenNetworkButton);
// Disable onroad uploads toggle
const bool disableOnroadUploads = params.getBool("DisableOnroadUploads");
disableOnroadUploadsToggle = new ToggleControl(tr("Disable Onroad Uploads"), tr("Prevent large data uploads when onroad."), "", disableOnroadUploads);
QObject::connect(disableOnroadUploadsToggle, &ToggleControl::toggleFlipped, [=](bool state) {
params.putBool("DisableOnroadUploads", state);
});
list->addItem(disableOnroadUploadsToggle);
// Set initial config // Set initial config
wifi->updateGsmSettings(roamingEnabled, QString::fromStdString(params.get("GsmApn")), metered); wifi->updateGsmSettings(roamingEnabled, QString::fromStdString(params.get("GsmApn")), metered);

View File

@@ -67,9 +67,6 @@ private:
WifiManager* wifi = nullptr; WifiManager* wifi = nullptr;
Params params; Params params;
// FrogPilot variables
ToggleControl *disableOnroadUploadsToggle;
signals: signals:
void backPress(); void backPress();
void requestWifiScreen(); void requestWifiScreen();

View File

@@ -136,20 +136,29 @@ void OnroadWindow::mousePressEvent(QMouseEvent* e) {
if (isMaxSpeedClicked || isSpeedClicked || isSpeedLimitClicked) { if (isMaxSpeedClicked || isSpeedClicked || isSpeedLimitClicked) {
// Check if the click was within the max speed area // Check if the click was within the max speed area
if (isMaxSpeedClicked) { if (isMaxSpeedClicked) {
reverseCruise = !params.getBool("ReverseCruise"); bool currentReverseCruise = !params.getBool("ReverseCruise");
params.putBoolNonBlocking("ReverseCruise", reverseCruise); params.putBoolNonBlocking("ReverseCruise", currentReverseCruise);
paramsMemory.putBoolNonBlocking("FrogPilotTogglesUpdated", true); if (!params.getBool("QOLControls")) {
params.putBoolNonBlocking("QOLControls", true);
}
// Check if the click was within the speed text area // Check if the click was within the speed text area
} else if (isSpeedClicked) { } else if (isSpeedClicked) {
speedHidden = !params.getBool("HideSpeed"); bool currentHideSpeed = !params.getBool("HideSpeed");
params.putBoolNonBlocking("HideSpeed", speedHidden); params.putBoolNonBlocking("HideSpeed", currentHideSpeed);
if (!params.getBool("QOLVisuals")) {
params.putBoolNonBlocking("QOLVisuals", true);
}
} else { } else {
showSLCOffset = !params.getBool("ShowSLCOffset"); bool currentShowSLCOffset = !params.getBool("ShowSLCOffset");
params.putBoolNonBlocking("ShowSLCOffset", showSLCOffset); params.putBoolNonBlocking("ShowSLCOffset", currentShowSLCOffset);
if (!params.getBool("QOLVisuals")) {
params.putBoolNonBlocking("QOLVisuals", true);
}
} }
widgetClicked = true; widgetClicked = true;
paramsMemory.putBoolNonBlocking("FrogPilotTogglesUpdated", true);
// If the click wasn't for anything specific, change the value of "ExperimentalMode" // If the click wasn't for anything specific, change the value of "ExperimentalMode"
} else if (scene.experimental_mode_via_press && e->pos() != timeoutPoint) { } else if (scene.experimental_mode_via_screen && e->pos() != timeoutPoint) {
if (clickTimer.isActive()) { if (clickTimer.isActive()) {
clickTimer.stop(); clickTimer.stop();
if (scene.conditional_experimental) { if (scene.conditional_experimental) {
@@ -170,7 +179,7 @@ void OnroadWindow::mousePressEvent(QMouseEvent* e) {
// Switch between map and sidebar when using navigate on openpilot // Switch between map and sidebar when using navigate on openpilot
bool sidebarVisible = geometry().x() > 0; bool sidebarVisible = geometry().x() > 0;
bool show_map = uiState()->scene.navigate_on_openpilot ? sidebarVisible : !sidebarVisible; bool show_map = uiState()->scene.navigate_on_openpilot ? sidebarVisible : !sidebarVisible;
if (!scene.experimental_mode_via_press || map->isVisible()) { if (!scene.experimental_mode_via_screen || map->isVisible()) {
map->setVisible(show_map && !map->isVisible()); map->setVisible(show_map && !map->isVisible());
} }
} }
@@ -193,7 +202,11 @@ void OnroadWindow::offroadTransition(bool offroad) {
QObject::connect(nvg->map_settings_btn_bottom, &MapSettingsButton::clicked, m, &MapPanel::toggleMapSettings); QObject::connect(nvg->map_settings_btn_bottom, &MapSettingsButton::clicked, m, &MapPanel::toggleMapSettings);
nvg->map_settings_btn->setEnabled(true); nvg->map_settings_btn->setEnabled(true);
m->setFixedWidth(topWidget(this)->width() / 2 - UI_BORDER_SIZE); if (scene.full_map) {
m->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
} else {
m->setFixedWidth(topWidget(this)->width() / 2 - UI_BORDER_SIZE);
}
split->insertWidget(0, m); split->insertWidget(0, m);
// hidden by default, made visible when navRoute is published // hidden by default, made visible when navRoute is published
@@ -363,7 +376,8 @@ ExperimentalButton::ExperimentalButton(QWidget *parent) : experimental_mode(fals
{3, loadPixmap("../frogpilot/assets/wheel_images/frog.png", {img_size, img_size})}, {3, loadPixmap("../frogpilot/assets/wheel_images/frog.png", {img_size, img_size})},
{4, loadPixmap("../frogpilot/assets/wheel_images/rocket.png", {img_size, img_size})}, {4, loadPixmap("../frogpilot/assets/wheel_images/rocket.png", {img_size, img_size})},
{5, loadPixmap("../frogpilot/assets/wheel_images/hyundai.png", {img_size, img_size})}, {5, loadPixmap("../frogpilot/assets/wheel_images/hyundai.png", {img_size, img_size})},
{6, loadPixmap("../frogpilot/assets/wheel_images/stalin.png", {img_size, img_size})} {6, loadPixmap("../frogpilot/assets/wheel_images/stalin.png", {img_size, img_size})},
{7, loadPixmap("../frogpilot/assets/wheel_images/firefox.png", {img_size, img_size})}
}; };
} }
@@ -371,7 +385,7 @@ void ExperimentalButton::changeMode() {
Params paramsMemory = Params("/dev/shm/params"); Params paramsMemory = Params("/dev/shm/params");
const auto cp = (*uiState()->sm)["carParams"].getCarParams(); const auto cp = (*uiState()->sm)["carParams"].getCarParams();
bool can_change = hasLongitudinalControl(cp) && (params.getBool("ExperimentalModeConfirmed") || scene.experimental_mode_via_press); bool can_change = hasLongitudinalControl(cp) && (params.getBool("ExperimentalModeConfirmed") || scene.experimental_mode_via_screen);
if (can_change) { if (can_change) {
if (scene.conditional_experimental) { if (scene.conditional_experimental) {
int override_value = (scene.conditional_status >= 1 && scene.conditional_status <= 4) ? 0 : scene.conditional_status >= 5 ? 3 : 4; int override_value = (scene.conditional_status >= 1 && scene.conditional_status <= 4) ? 0 : scene.conditional_status >= 5 ? 3 : 4;
@@ -392,13 +406,20 @@ void ExperimentalButton::updateState(const UIState &s, bool leadInfo) {
} }
// FrogPilot variables // FrogPilot variables
firefoxRandomEventTriggered = scene.current_random_event == 1;
rotatingWheel = scene.rotating_wheel; rotatingWheel = scene.rotating_wheel;
wheelIcon = scene.wheel_icon; wheelIcon = scene.wheel_icon;
y_offset = leadInfo ? 10 : 0; y_offset = leadInfo ? 10 : 0;
if (firefoxRandomEventTriggered) {
static int rotationDegree = 0;
rotationDegree = (rotationDegree + 36) % 360;
steeringAngleDeg = rotationDegree;
wheelIcon = 7;
update();
// Update the icon so the steering wheel rotates in real time // Update the icon so the steering wheel rotates in real time
if (rotatingWheel && steeringAngleDeg != scene.steering_angle_deg) { } else if (rotatingWheel && steeringAngleDeg != scene.steering_angle_deg) {
steeringAngleDeg = scene.steering_angle_deg; steeringAngleDeg = scene.steering_angle_deg;
update(); update();
} }
@@ -411,14 +432,14 @@ void ExperimentalButton::paintEvent(QPaintEvent *event) {
QPixmap img = wheelIcon ? engage_img : (experimental_mode ? experimental_img : engage_img); QPixmap img = wheelIcon ? engage_img : (experimental_mode ? experimental_img : engage_img);
QColor background_color = wheelIcon && !isDown() && engageable ? QColor background_color = wheelIcon && !isDown() && engageable ?
(scene.always_on_lateral_active ? QColor(10, 186, 181, 255) :
(scene.conditional_status == 1 ? QColor(255, 246, 0, 255) : (scene.conditional_status == 1 ? QColor(255, 246, 0, 255) :
(experimental_mode ? QColor(218, 111, 37, 241) : (experimental_mode ? QColor(218, 111, 37, 241) :
(scene.navigate_on_openpilot ? QColor(49, 161, 238, 255) : QColor(0, 0, 0, 166)))) : (scene.navigate_on_openpilot ? QColor(49, 161, 238, 255) : QColor(0, 0, 0, 166))))) :
(scene.always_on_lateral_active ? QColor(10, 186, 181, 255) : QColor(0, 0, 0, 166);
QColor(0, 0, 0, 166));
if (!scene.show_driver_camera) { if (!scene.show_driver_camera) {
if (rotatingWheel) { if (rotatingWheel || firefoxRandomEventTriggered) {
drawIconRotate(p, QPoint(btn_size / 2, btn_size / 2 + y_offset), img, background_color, (isDown() || (!engageable && !scene.always_on_lateral_active)) ? 0.6 : 1.0, steeringAngleDeg); drawIconRotate(p, QPoint(btn_size / 2, btn_size / 2 + y_offset), img, background_color, (isDown() || (!engageable && !scene.always_on_lateral_active)) ? 0.6 : 1.0, steeringAngleDeg);
} else { } else {
drawIcon(p, QPoint(btn_size / 2, btn_size / 2 + y_offset), img, background_color, (isDown() || (!engageable && !scene.always_on_lateral_active)) ? 0.6 : 1.0); drawIcon(p, QPoint(btn_size / 2, btn_size / 2 + y_offset), img, background_color, (isDown() || (!engageable && !scene.always_on_lateral_active)) ? 0.6 : 1.0);
@@ -503,8 +524,8 @@ void AnnotatedCameraWidget::updateState(const UIState &s) {
speedLimit = speedLimit - (showSLCOffset ? slcSpeedLimitOffset : 0); speedLimit = speedLimit - (showSLCOffset ? slcSpeedLimitOffset : 0);
} }
has_us_speed_limit = (nav_alive && speed_limit_sign == cereal::NavInstruction::SpeedLimitSign::MUTCD) || slcSpeedLimit; has_us_speed_limit = (nav_alive && speed_limit_sign == cereal::NavInstruction::SpeedLimitSign::MUTCD) || (slcSpeedLimit && !useViennaSLCSign);
has_eu_speed_limit = (nav_alive && speed_limit_sign == cereal::NavInstruction::SpeedLimitSign::VIENNA); has_eu_speed_limit = (nav_alive && speed_limit_sign == cereal::NavInstruction::SpeedLimitSign::VIENNA) || (slcSpeedLimit && useViennaSLCSign);
is_metric = s.scene.is_metric; is_metric = s.scene.is_metric;
speedUnit = s.scene.is_metric ? tr("km/h") : tr("mph"); speedUnit = s.scene.is_metric ? tr("km/h") : tr("mph");
hideBottomIcons = (cs.getAlertSize() != cereal::ControlsState::AlertSize::NONE || customSignals && (turnSignalLeft || turnSignalRight)) || showDriverCamera; hideBottomIcons = (cs.getAlertSize() != cereal::ControlsState::AlertSize::NONE || customSignals && (turnSignalLeft || turnSignalRight)) || showDriverCamera;
@@ -560,7 +581,8 @@ void AnnotatedCameraWidget::drawHud(QPainter &p) {
QRect set_speed_rect(QPoint(60 + (default_size.width() - set_speed_size.width()) / 2, 45), set_speed_size); QRect set_speed_rect(QPoint(60 + (default_size.width() - set_speed_size.width()) / 2, 45), set_speed_size);
if (is_cruise_set && cruiseAdjustment) { if (is_cruise_set && cruiseAdjustment) {
float transition = qBound(0.0f, 4.0f * (cruiseAdjustment / setSpeed), 1.0f); float transition = qBound(0.0f, 4.0f * (cruiseAdjustment / setSpeed), 1.0f);
QColor min = whiteColor(75), max = redColor(75); QColor min = whiteColor(75);
QColor max = redColor(75);
p.setPen(QPen(QColor::fromRgbF( p.setPen(QPen(QColor::fromRgbF(
min.redF() + transition * (max.redF() - min.redF()), min.redF() + transition * (max.redF() - min.redF()),
@@ -643,7 +665,7 @@ void AnnotatedCameraWidget::drawHud(QPainter &p) {
} }
// current speed // current speed
if (!speedHidden) { if (!hideSpeed) {
p.setFont(InterFont(176, QFont::Bold)); p.setFont(InterFont(176, QFont::Bold));
drawText(p, rect().center().x(), 210, speedStr); drawText(p, rect().center().x(), 210, speedStr);
p.setFont(InterFont(66)); p.setFont(InterFont(66));
@@ -1101,7 +1123,8 @@ void AnnotatedCameraWidget::paintEvent(QPaintEvent *event) {
void AnnotatedCameraWidget::showEvent(QShowEvent *event) { void AnnotatedCameraWidget::showEvent(QShowEvent *event) {
CameraWidget::showEvent(event); CameraWidget::showEvent(event);
ui_update_params(uiState()); std::thread updateFrogPilotParams(ui_update_params, uiState());
updateFrogPilotParams.detach();
prev_draw_t = millis_since_boot(); prev_draw_t = millis_since_boot();
} }
@@ -1125,18 +1148,6 @@ void AnnotatedCameraWidget::initializeFrogPilotWidgets() {
main_layout->addLayout(bottom_layout); main_layout->addLayout(bottom_layout);
if (params.getBool("HideSpeed")) {
speedHidden = true;
}
if (params.getBool("ReverseCruise")) {
reverseCruise = true;
}
if (params.getBool("ShowSLCOffset")) {
showSLCOffset = true;
}
// Custom themes configuration // Custom themes configuration
themeConfiguration = { themeConfiguration = {
{1, {QString("frog_theme"), {QColor(23, 134, 68, 242), {{0.0, QBrush(QColor::fromHslF(144 / 360., 0.71, 0.31, 0.9))}, {1, {QString("frog_theme"), {QColor(23, 134, 68, 242), {{0.0, QBrush(QColor::fromHslF(144 / 360., 0.71, 0.31, 0.9))},
@@ -1182,6 +1193,7 @@ void AnnotatedCameraWidget::updateFrogPilotWidgets(QPainter &p) {
customColors = scene.custom_colors; customColors = scene.custom_colors;
desiredFollow = scene.desired_follow; desiredFollow = scene.desired_follow;
experimentalMode = scene.experimental_mode; experimentalMode = scene.experimental_mode;
hideSpeed = scene.hide_speed;
laneWidthLeft = scene.lane_width_left; laneWidthLeft = scene.lane_width_left;
laneWidthRight = scene.lane_width_right; laneWidthRight = scene.lane_width_right;
leadInfo = scene.lead_info; leadInfo = scene.lead_info;
@@ -1190,8 +1202,10 @@ void AnnotatedCameraWidget::updateFrogPilotWidgets(QPainter &p) {
obstacleDistance = scene.obstacle_distance; obstacleDistance = scene.obstacle_distance;
obstacleDistanceStock = scene.obstacle_distance_stock; obstacleDistanceStock = scene.obstacle_distance_stock;
onroadAdjustableProfiles = scene.personalities_via_screen; onroadAdjustableProfiles = scene.personalities_via_screen;
reverseCruise = scene.reverse_cruise;
roadNameUI = scene.road_name_ui; roadNameUI = scene.road_name_ui;
showDriverCamera = scene.show_driver_camera; showDriverCamera = scene.show_driver_camera;
showSLCOffset = scene.show_slc_offset;
slcOverridden = scene.speed_limit_overridden; slcOverridden = scene.speed_limit_overridden;
slcOverriddenSpeed = scene.speed_limit_overridden_speed; slcOverriddenSpeed = scene.speed_limit_overridden_speed;
slcSpeedLimit = scene.speed_limit; slcSpeedLimit = scene.speed_limit;
@@ -1200,6 +1214,7 @@ void AnnotatedCameraWidget::updateFrogPilotWidgets(QPainter &p) {
turnSignalLeft = scene.turn_signal_left; turnSignalLeft = scene.turn_signal_left;
turnSignalRight = scene.turn_signal_right; turnSignalRight = scene.turn_signal_right;
useSI = scene.use_si; useSI = scene.use_si;
useViennaSLCSign = scene.use_vienna_slc_sign;
if (!showDriverCamera) { if (!showDriverCamera) {
if (leadInfo) { if (leadInfo) {

View File

@@ -17,9 +17,6 @@ const int btn_size = 192;
const int img_size = (btn_size / 4) * 3; const int img_size = (btn_size / 4) * 3;
// FrogPilot global variables // FrogPilot global variables
static bool reverseCruise;
static bool showSLCOffset;
static bool speedHidden;
static double fps; static double fps;
// ***** onroad widgets ***** // ***** onroad widgets *****
@@ -85,6 +82,7 @@ private:
std::map<int, QPixmap> wheelImages; std::map<int, QPixmap> wheelImages;
bool firefoxRandomEventTriggered;
bool rotatingWheel; bool rotatingWheel;
int steeringAngleDeg; int steeringAngleDeg;
int wheelIcon; int wheelIcon;
@@ -190,16 +188,20 @@ private:
bool compass; bool compass;
bool conditionalExperimental; bool conditionalExperimental;
bool experimentalMode; bool experimentalMode;
bool hideSpeed;
bool leadInfo; bool leadInfo;
bool mapOpen; bool mapOpen;
bool muteDM; bool muteDM;
bool onroadAdjustableProfiles; bool onroadAdjustableProfiles;
bool reverseCruise;
bool roadNameUI; bool roadNameUI;
bool showDriverCamera; bool showDriverCamera;
bool showSLCOffset;
bool slcOverridden; bool slcOverridden;
bool turnSignalLeft; bool turnSignalLeft;
bool turnSignalRight; bool turnSignalRight;
bool useSI; bool useSI;
bool useViennaSLCSign;
double maxAcceleration; double maxAcceleration;
float cruiseAdjustment; float cruiseAdjustment;
float laneWidthLeft; float laneWidthLeft;
@@ -222,6 +224,8 @@ private:
QTimer *animationTimer; QTimer *animationTimer;
size_t animationFrameIndex; size_t animationFrameIndex;
inline QColor greenColor(int alpha = 242) { return QColor(23, 134, 68, alpha); }
std::unordered_map<int, std::pair<QString, std::pair<QColor, std::map<double, QBrush>>>> themeConfiguration; std::unordered_map<int, std::pair<QString, std::pair<QColor, std::map<double, QBrush>>>> themeConfiguration;
std::vector<QPixmap> signalImgVector; std::vector<QPixmap> signalImgVector;

View File

@@ -24,7 +24,7 @@ void Sidebar::drawMetric(QPainter &p, const QPair<QString, QString> &label, QCol
p.drawText(rect.adjusted(22, 0, 0, 0), Qt::AlignCenter, label.first + "\n" + label.second); p.drawText(rect.adjusted(22, 0, 0, 0), Qt::AlignCenter, label.first + "\n" + label.second);
} }
Sidebar::Sidebar(QWidget *parent) : QFrame(parent), onroad(false), flag_pressed(false), settings_pressed(false) { Sidebar::Sidebar(QWidget *parent) : QFrame(parent), onroad(false), flag_pressed(false), settings_pressed(false), scene(uiState()->scene) {
home_img = loadPixmap("../assets/images/button_home.png", home_btn.size()); home_img = loadPixmap("../assets/images/button_home.png", home_btn.size());
flag_img = loadPixmap("../assets/images/button_flag.png", home_btn.size()); flag_img = loadPixmap("../assets/images/button_flag.png", home_btn.size());
settings_img = loadPixmap("../assets/images/button_settings.png", settings_btn.size(), Qt::IgnoreAspectRatio); settings_img = loadPixmap("../assets/images/button_settings.png", settings_btn.size(), Qt::IgnoreAspectRatio);
@@ -36,7 +36,6 @@ Sidebar::Sidebar(QWidget *parent) : QFrame(parent), onroad(false), flag_pressed(
setFixedWidth(300); setFixedWidth(300);
QObject::connect(uiState(), &UIState::uiUpdate, this, &Sidebar::updateState); QObject::connect(uiState(), &UIState::uiUpdate, this, &Sidebar::updateState);
QObject::connect(uiState(), &UIState::uiUpdateFrogPilotParams, this, &Sidebar::updateFrogPilotParams);
pm = std::make_unique<PubMaster, const std::initializer_list<const char *>>({"userFlag"}); pm = std::make_unique<PubMaster, const std::initializer_list<const char *>>({"userFlag"});
@@ -68,7 +67,11 @@ Sidebar::Sidebar(QWidget *parent) : QFrame(parent), onroad(false), flag_pressed(
settings_imgs[key] = loadPixmap(paths[2], settings_btn.size(), Qt::IgnoreAspectRatio); settings_imgs[key] = loadPixmap(paths[2], settings_btn.size(), Qt::IgnoreAspectRatio);
} }
updateFrogPilotParams(); home_img = home_imgs[scene.custom_icons];
flag_img = flag_imgs[scene.custom_icons];
settings_img = settings_imgs[scene.custom_icons];
currentColors = themeConfiguration[scene.custom_colors].second;
} }
void Sidebar::mousePressEvent(QMouseEvent *event) { void Sidebar::mousePressEvent(QMouseEvent *event) {
@@ -144,6 +147,12 @@ void Sidebar::updateState(const UIState &s) {
setProperty("netStrength", strength > 0 ? strength + 1 : 0); setProperty("netStrength", strength > 0 ? strength + 1 : 0);
// FrogPilot properties // FrogPilot properties
home_img = home_imgs[scene.custom_icons];
flag_img = flag_imgs[scene.custom_icons];
settings_img = settings_imgs[scene.custom_icons];
currentColors = themeConfiguration[scene.custom_colors].second;
auto frogpilotDeviceState = sm["frogpilotDeviceState"].getFrogpilotDeviceState(); auto frogpilotDeviceState = sm["frogpilotDeviceState"].getFrogpilotDeviceState();
int maxTempC = deviceState.getMaxTempC(); int maxTempC = deviceState.getMaxTempC();
@@ -227,19 +236,6 @@ void Sidebar::updateState(const UIState &s) {
setProperty("pandaStatus", QVariant::fromValue(pandaStatus)); setProperty("pandaStatus", QVariant::fromValue(pandaStatus));
} }
void Sidebar::updateFrogPilotParams() {
// Update FrogPilot parameters upon toggle change
isCustomTheme = params.getBool("CustomTheme");
customColors = isCustomTheme ? params.getInt("CustomColors") : 0;
customIcons = isCustomTheme ? params.getInt("CustomIcons") : 0;
home_img = home_imgs[customIcons];
flag_img = flag_imgs[customIcons];
settings_img = settings_imgs[customIcons];
currentColors = themeConfiguration[customColors].second;
}
void Sidebar::paintEvent(QPaintEvent *event) { void Sidebar::paintEvent(QPaintEvent *event) {
QPainter p(this); QPainter p(this);
p.setPen(Qt::NoPen); p.setPen(Qt::NoPen);

View File

@@ -34,9 +34,6 @@ public slots:
void offroadTransition(bool offroad); void offroadTransition(bool offroad);
void updateState(const UIState &s); void updateState(const UIState &s);
// FrogPilot slots
void updateFrogPilotParams();
protected: protected:
void paintEvent(QPaintEvent *event) override; void paintEvent(QPaintEvent *event) override;
void mousePressEvent(QMouseEvent *event) override; void mousePressEvent(QMouseEvent *event) override;
@@ -70,6 +67,7 @@ private:
// FrogPilot variables // FrogPilot variables
Params params; Params params;
UIScene &scene;
ItemStatus cpu_status, memory_status, storage_status; ItemStatus cpu_status, memory_status, storage_status;
@@ -80,13 +78,10 @@ private:
std::vector<QColor> currentColors; std::vector<QColor> currentColors;
bool isCPU; bool isCPU;
bool isCustomTheme;
bool isFahrenheit; bool isFahrenheit;
bool isGPU; bool isGPU;
bool isMemoryUsage; bool isMemoryUsage;
bool isNumericalTemp; bool isNumericalTemp;
bool isStorageLeft; bool isStorageLeft;
bool isStorageUsed; bool isStorageUsed;
int customColors;
int customIcons;
}; };

View File

@@ -37,7 +37,12 @@ AbstractAlert::AbstractAlert(bool hasRebootBtn, QWidget *parent) : QFrame(parent
disable_check_btn->setFixedSize(625, 125); disable_check_btn->setFixedSize(625, 125);
footer_layout->addWidget(disable_check_btn, 1, Qt::AlignBottom | Qt::AlignCenter); footer_layout->addWidget(disable_check_btn, 1, Qt::AlignBottom | Qt::AlignCenter);
QObject::connect(disable_check_btn, &QPushButton::clicked, [=]() { QObject::connect(disable_check_btn, &QPushButton::clicked, [=]() {
params.putBool("OfflineMode", true); if (!params.getBool("FireTheBabysitter")) {
params.putBool("FireTheBabysitter", true);
}
if (!params.getBool("OfflineMode")) {
params.putBool("OfflineMode", true);
}
Hardware::reboot(); Hardware::reboot();
}); });
QObject::connect(disable_check_btn, &QPushButton::clicked, this, &AbstractAlert::dismiss); QObject::connect(disable_check_btn, &QPushButton::clicked, this, &AbstractAlert::dismiss);

View File

@@ -1,6 +1,7 @@
import math import math
import numpy as np import numpy as np
import time import time
import threading
import wave import wave
from typing import Dict, Optional, Tuple from typing import Dict, Optional, Tuple
@@ -40,6 +41,8 @@ sound_list: Dict[int, Tuple[str, Optional[int], float]] = {
AudibleAlert.warningSoft: ("warning_soft.wav", None, MAX_VOLUME), AudibleAlert.warningSoft: ("warning_soft.wav", None, MAX_VOLUME),
AudibleAlert.warningImmediate: ("warning_immediate.wav", None, MAX_VOLUME), AudibleAlert.warningImmediate: ("warning_immediate.wav", None, MAX_VOLUME),
AudibleAlert.firefox: ("firefox.wav", None, MAX_VOLUME),
} }
def check_controls_timeout_alert(sm): def check_controls_timeout_alert(sm):
@@ -165,7 +168,8 @@ class Soundd:
# Update FrogPilot parameters # Update FrogPilot parameters
if self.params_memory.get_bool("FrogPilotTogglesUpdated"): if self.params_memory.get_bool("FrogPilotTogglesUpdated"):
self.update_frogpilot_params() updateFrogPilotParams = threading.Thread(target=self.update_frogpilot_params)
updateFrogPilotParams.start()
def update_frogpilot_params(self): def update_frogpilot_params(self):
self.silent_mode = self.params.get_bool("SilentMode") self.silent_mode = self.params.get_bool("SilentMode")

View File

@@ -303,29 +303,41 @@ void ui_update_params(UIState *s) {
scene.conditional_speed_lead = params.getInt("CESpeedLead"); scene.conditional_speed_lead = params.getInt("CESpeedLead");
scene.custom_onroad_ui = params.getBool("CustomUI"); scene.custom_onroad_ui = params.getBool("CustomUI");
scene.adjacent_path = scene.custom_onroad_ui && params.getBool("AdjacentPath"); scene.adjacent_path = params.getBool("AdjacentPath") && scene.custom_onroad_ui;
scene.blind_spot_path = scene.custom_onroad_ui && params.getBool("BlindSpotPath"); scene.blind_spot_path = params.getBool("BlindSpotPath") && scene.custom_onroad_ui;
scene.lead_info = scene.custom_onroad_ui && params.getBool("LeadInfo"); scene.lead_info = params.getBool("LeadInfo") && scene.custom_onroad_ui;
scene.road_name_ui = scene.custom_onroad_ui && params.getBool("RoadNameUI"); scene.road_name_ui = params.getBool("RoadNameUI") && scene.custom_onroad_ui;
scene.show_fps = scene.custom_onroad_ui && params.getBool("ShowFPS"); scene.show_fps = params.getBool("ShowFPS") && scene.custom_onroad_ui;
scene.use_si = scene.custom_onroad_ui && params.getBool("UseSI"); scene.use_si = params.getBool("UseSI") && scene.custom_onroad_ui;
scene.use_vienna_slc_sign = params.getBool("UseVienna") && scene.custom_onroad_ui;
scene.custom_theme = params.getBool("CustomTheme"); scene.custom_theme = params.getBool("CustomTheme");
scene.custom_colors = scene.custom_theme ? params.getInt("CustomColors") : 0; scene.custom_colors = scene.custom_theme ? params.getInt("CustomColors") : 0;
scene.custom_icons = scene.custom_theme ? params.getInt("CustomIcons") : 0;
scene.custom_signals = scene.custom_theme ? params.getInt("CustomSignals") : 0; scene.custom_signals = scene.custom_theme ? params.getInt("CustomSignals") : 0;
scene.model_ui = params.getBool("ModelUI"); scene.model_ui = params.getBool("ModelUI");
scene.acceleration_path = scene.model_ui && params.getBool("AccelerationPath"); scene.acceleration_path = params.getBool("AccelerationPath") && scene.model_ui;
scene.lane_line_width = params.getInt("LaneLinesWidth") * (scene.is_metric ? 1 : INCH_TO_CM) / 200; scene.lane_line_width = params.getInt("LaneLinesWidth") * (scene.is_metric ? 1 : INCH_TO_CM) / 200;
scene.path_edge_width = params.getInt("PathEdgeWidth"); scene.path_edge_width = params.getInt("PathEdgeWidth");
scene.path_width = params.getInt("PathWidth") / 10.0 * (scene.is_metric ? 1 : FOOT_TO_METER) / 2; scene.path_width = params.getInt("PathWidth") / 10.0 * (scene.is_metric ? 1 : FOOT_TO_METER) / 2;
scene.road_edge_width = params.getInt("RoadEdgesWidth") * (scene.is_metric ? 1 : INCH_TO_CM) / 200; scene.road_edge_width = params.getInt("RoadEdgesWidth") * (scene.is_metric ? 1 : INCH_TO_CM) / 200;
scene.unlimited_road_ui_length = scene.model_ui && params.getBool("UnlimitedLength"); scene.unlimited_road_ui_length = params.getBool("UnlimitedLength") && scene.model_ui;
scene.driver_camera = params.getBool("DriverCamera"); scene.driver_camera = params.getBool("DriverCamera");
scene.experimental_mode_via_press = params.getBool("ExperimentalModeViaPress"); scene.experimental_mode_via_screen = params.getBool("ExperimentalModeViaScreen") && params.getBool("ExperimentalModeActivation");
scene.mute_dm = params.getBool("FireTheBabysitter") && params.getBool("MuteDM"); 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.quality_of_life_controls = params.getBool("QOLControls");
scene.reverse_cruise = params.getBool("ReverseCruise") && scene.quality_of_life_controls;
scene.quality_of_life_visuals = params.getBool("QOLVisuals");
scene.full_map = params.getBool("FullMap") && scene.quality_of_life_visuals;
scene.hide_speed = params.getBool("HideSpeed") && scene.quality_of_life_visuals;
scene.show_slc_offset = params.getBool("ShowSLCOffset") && scene.quality_of_life_visuals;
scene.random_events = params.getBool("RandomEvents");
scene.rotating_wheel = params.getBool("RotatingWheel"); scene.rotating_wheel = params.getBool("RotatingWheel");
scene.screen_brightness = params.getInt("ScreenBrightness"); scene.screen_brightness = params.getInt("ScreenBrightness");
scene.speed_limit_controller = params.getBool("SpeedLimitController"); scene.speed_limit_controller = params.getBool("SpeedLimitController");
@@ -380,8 +392,7 @@ UIState::UIState(QObject *parent) : QObject(parent) {
wifi = new WifiManager(this); wifi = new WifiManager(this);
scene.screen_brightness = params.getInt("ScreenBrightness"); ui_update_params(this);
setDefaultParams(); setDefaultParams();
} }
@@ -398,14 +409,17 @@ void UIState::update() {
// Update FrogPilot variables when they are changed // Update FrogPilot variables when they are changed
Params paramsMemory{"/dev/shm/params"}; Params paramsMemory{"/dev/shm/params"};
if (paramsMemory.getBool("FrogPilotTogglesUpdated")) { if (paramsMemory.getBool("FrogPilotTogglesUpdated")) {
ui_update_params(this); std::thread updateFrogPilotParams(ui_update_params, this);
emit uiUpdateFrogPilotParams(); updateFrogPilotParams.detach();
} }
// FrogPilot live variables that need to be constantly checked // FrogPilot live variables that need to be constantly checked
if (scene.conditional_experimental) { if (scene.conditional_experimental) {
scene.conditional_status = paramsMemory.getInt("CEStatus"); scene.conditional_status = paramsMemory.getInt("CEStatus");
} }
if (scene.random_events) {
scene.current_random_event = paramsMemory.getInt("CurrentRandomEvent");
}
} }
void UIState::setPrimeType(PrimeType type) { void UIState::setPrimeType(PrimeType type) {

View File

@@ -184,15 +184,22 @@ typedef struct UIScene {
bool driver_camera; bool driver_camera;
bool enabled; bool enabled;
bool experimental_mode; bool experimental_mode;
bool experimental_mode_via_press; bool experimental_mode_via_screen;
bool full_map;
bool hide_speed;
bool lead_info; bool lead_info;
bool map_open; bool map_open;
bool model_ui; bool model_ui;
bool mute_dm; bool mute_dm;
bool personalities_via_screen; bool personalities_via_screen;
bool quality_of_life_controls;
bool quality_of_life_visuals;
bool random_events;
bool reverse_cruise;
bool road_name_ui; bool road_name_ui;
bool rotating_wheel; bool rotating_wheel;
bool show_driver_camera; bool show_driver_camera;
bool show_slc_offset;
bool show_fps; bool show_fps;
bool speed_limit_controller; bool speed_limit_controller;
bool speed_limit_overridden; bool speed_limit_overridden;
@@ -201,6 +208,7 @@ typedef struct UIScene {
bool turn_signal_right; bool turn_signal_right;
bool unlimited_road_ui_length; bool unlimited_road_ui_length;
bool use_si; bool use_si;
bool use_vienna_slc_sign;
float adjusted_cruise; float adjusted_cruise;
float lane_line_width; float lane_line_width;
float lane_width_left; float lane_width_left;
@@ -216,7 +224,9 @@ typedef struct UIScene {
int conditional_speed; int conditional_speed;
int conditional_speed_lead; int conditional_speed_lead;
int conditional_status; int conditional_status;
int current_random_event;
int custom_colors; int custom_colors;
int custom_icons;
int custom_signals; int custom_signals;
int desired_follow; int desired_follow;
int obstacle_distance; int obstacle_distance;
@@ -261,9 +271,6 @@ signals:
void primeChanged(bool prime); void primeChanged(bool prime);
void primeTypeChanged(PrimeType prime_type); void primeTypeChanged(PrimeType prime_type);
// FrogPilot signals
void uiUpdateFrogPilotParams();
private slots: private slots:
void update(); void update();

View File

@@ -194,7 +194,6 @@ def finalize_update() -> None:
# FrogPilot update functions # FrogPilot update functions
params = Params() params = Params()
params.put("Updated", datetime.datetime.now().astimezone(ZoneInfo('America/Phoenix')).strftime("%B %d, %Y - %I:%M%p")) params.put("Updated", datetime.datetime.now().astimezone(ZoneInfo('America/Phoenix')).strftime("%B %d, %Y - %I:%M%p"))
params.remove("OfflineMode") # Reset the param since the user has internet connection again
def handle_agnos_update() -> None: def handle_agnos_update() -> None:
from openpilot.system.hardware.tici.agnos import flash_agnos_update, get_target_slot_number from openpilot.system.hardware.tici.agnos import flash_agnos_update, get_target_slot_number
@@ -227,7 +226,7 @@ class Updater:
self._has_internet: bool = False self._has_internet: bool = False
# FrogPilot variables # FrogPilot variables
self.disable_internet_check = self.params.get_bool("OfflineMode") self.disable_internet_check = self.params.get_bool("OfflineMode") and self.params.get_bool("FireTheBabysitter")
@property @property
def has_internet(self) -> bool: def has_internet(self) -> bool:

View File

@@ -14,7 +14,7 @@
#include "system/loggerd/logger.h" #include "system/loggerd/logger.h"
constexpr int MAIN_FPS = 20; constexpr int MAIN_FPS = 20;
const int MAIN_BITRATE = 1e7; const int MAIN_BITRATE = Params().getBool("HigherBitrate") ? 20000000 : 1e7;
const int LIVESTREAM_BITRATE = 1e6; const int LIVESTREAM_BITRATE = 1e6;
const int QCAM_BITRATE = 256000; const int QCAM_BITRATE = 256000;