From 6c946fc97a0cfd4c7441419667198643e2017d64 Mon Sep 17 00:00:00 2001 From: FrogAi <91348155+FrogAi@users.noreply.github.com> Date: Fri, 1 Mar 2024 09:26:59 -0700 Subject: [PATCH] FrogPilot Setup --- cereal/car.capnp | 2 + cereal/custom.capnp | 8 +- cereal/log.capnp | 9 +- cereal/services.py | 6 + common/conversions.py | 2 + common/params.cc | 12 + common/params.h | 22 + common/params_pyx.pyx | 40 + common/util.h | 3 + release/files_common | 3 + selfdrive/assets/img_spinner_comma.png | Bin 15713 -> 111089 bytes selfdrive/assets/img_spinner_track.png | Bin 41523 -> 71046 bytes selfdrive/car/body/carcontroller.py | 2 +- selfdrive/car/body/carstate.py | 2 +- selfdrive/car/body/interface.py | 10 +- selfdrive/car/car_helpers.py | 10 +- selfdrive/car/chrysler/carcontroller.py | 2 +- selfdrive/car/chrysler/carstate.py | 2 +- selfdrive/car/chrysler/interface.py | 12 +- selfdrive/car/ford/carcontroller.py | 2 +- selfdrive/car/ford/carstate.py | 2 +- selfdrive/car/ford/interface.py | 12 +- selfdrive/car/gm/carcontroller.py | 4 +- selfdrive/car/gm/carstate.py | 4 +- selfdrive/car/gm/interface.py | 12 +- selfdrive/car/gm/values.py | 1 + selfdrive/car/honda/carcontroller.py | 2 +- selfdrive/car/honda/carstate.py | 2 +- selfdrive/car/honda/interface.py | 12 +- selfdrive/car/hyundai/carcontroller.py | 2 +- selfdrive/car/hyundai/carstate.py | 8 +- selfdrive/car/hyundai/interface.py | 12 +- selfdrive/car/interfaces.py | 19 +- selfdrive/car/mazda/carcontroller.py | 2 +- selfdrive/car/mazda/carstate.py | 2 +- selfdrive/car/mazda/interface.py | 12 +- selfdrive/car/mock/interface.py | 6 +- selfdrive/car/nissan/carcontroller.py | 2 +- selfdrive/car/nissan/carstate.py | 2 +- selfdrive/car/nissan/interface.py | 12 +- selfdrive/car/subaru/carcontroller.py | 2 +- selfdrive/car/subaru/carstate.py | 2 +- selfdrive/car/subaru/interface.py | 12 +- selfdrive/car/subaru/values.py | 1 + selfdrive/car/tesla/carcontroller.py | 2 +- selfdrive/car/tesla/carstate.py | 2 +- selfdrive/car/tesla/interface.py | 12 +- selfdrive/car/tests/test_car_interfaces.py | 20 +- selfdrive/car/toyota/carcontroller.py | 12 +- selfdrive/car/toyota/carstate.py | 4 +- selfdrive/car/toyota/interface.py | 12 +- selfdrive/car/toyota/toyotacan.py | 2 +- selfdrive/car/volkswagen/carcontroller.py | 2 +- selfdrive/car/volkswagen/carstate.py | 6 +- selfdrive/car/volkswagen/interface.py | 12 +- selfdrive/controls/controlsd.py | 58 +- selfdrive/controls/lib/desire_helper.py | 15 +- selfdrive/controls/lib/drive_helpers.py | 5 +- selfdrive/controls/lib/events.py | 5 +- .../lib/longitudinal_mpc_lib/long_mpc.py | 4 +- .../controls/lib/longitudinal_planner.py | 10 +- selfdrive/controls/plannerd.py | 15 +- .../assets/toggle_icons/icon_lateral_tune.png | Bin 0 -> 30135 bytes .../toggle_icons/icon_longitudinal_tune.png | Bin 0 -> 37131 bytes .../assets/toggle_icons/quality_of_life.png | Bin 0 -> 42955 bytes .../functions/frogpilot_functions.py | 17 + .../frogpilot/functions/frogpilot_planner.py | 49 ++ selfdrive/frogpilot/ui/control_settings.cc | 163 ++++ selfdrive/frogpilot/ui/control_settings.h | 52 ++ .../frogpilot/ui/frogpilot_ui_functions.cc | 42 + .../frogpilot/ui/frogpilot_ui_functions.h | 745 ++++++++++++++++++ selfdrive/frogpilot/ui/vehicle_settings.cc | 88 +++ selfdrive/frogpilot/ui/vehicle_settings.h | 32 + selfdrive/frogpilot/ui/visual_settings.cc | 156 ++++ selfdrive/frogpilot/ui/visual_settings.h | 45 ++ selfdrive/manager/manager.py | 242 +++++- selfdrive/manager/process.py | 6 +- selfdrive/manager/process_config.py | 22 +- selfdrive/modeld/modeld.py | 4 +- selfdrive/navd/navd.py | 16 +- selfdrive/thermald/power_monitoring.py | 2 + selfdrive/thermald/thermald.py | 6 +- selfdrive/ui/SConscript | 5 +- selfdrive/ui/qt/home.h | 5 + selfdrive/ui/qt/maps/map.h | 3 + selfdrive/ui/qt/maps/map_helpers.h | 1 + selfdrive/ui/qt/maps/map_settings.h | 2 + selfdrive/ui/qt/offroad/settings.cc | 66 +- selfdrive/ui/qt/offroad/settings.h | 17 + selfdrive/ui/qt/offroad/software_settings.cc | 1 + selfdrive/ui/qt/onroad.cc | 116 ++- selfdrive/ui/qt/onroad.h | 29 +- selfdrive/ui/qt/sidebar.cc | 7 +- selfdrive/ui/qt/sidebar.h | 6 + selfdrive/ui/qt/spinner.cc | 2 +- selfdrive/ui/qt/util.cc | 2 +- selfdrive/ui/qt/widgets/controls.h | 4 + selfdrive/ui/qt/widgets/scrollview.cc | 4 + selfdrive/ui/qt/widgets/scrollview.h | 3 + selfdrive/ui/qt/widgets/wifi.h | 4 + selfdrive/ui/qt/window.h | 3 + selfdrive/ui/soundd.py | 12 + selfdrive/ui/ui.cc | 43 +- selfdrive/ui/ui.h | 13 + selfdrive/updated.py | 2 + system/camerad/cameras/camera_qcom2.cc | 3 + 106 files changed, 2349 insertions(+), 185 deletions(-) create mode 100644 selfdrive/frogpilot/assets/toggle_icons/icon_lateral_tune.png create mode 100644 selfdrive/frogpilot/assets/toggle_icons/icon_longitudinal_tune.png create mode 100644 selfdrive/frogpilot/assets/toggle_icons/quality_of_life.png create mode 100644 selfdrive/frogpilot/functions/frogpilot_functions.py create mode 100644 selfdrive/frogpilot/functions/frogpilot_planner.py create mode 100644 selfdrive/frogpilot/ui/control_settings.cc create mode 100644 selfdrive/frogpilot/ui/control_settings.h create mode 100644 selfdrive/frogpilot/ui/frogpilot_ui_functions.cc create mode 100644 selfdrive/frogpilot/ui/frogpilot_ui_functions.h create mode 100644 selfdrive/frogpilot/ui/vehicle_settings.cc create mode 100644 selfdrive/frogpilot/ui/vehicle_settings.h create mode 100644 selfdrive/frogpilot/ui/visual_settings.cc create mode 100644 selfdrive/frogpilot/ui/visual_settings.h diff --git a/cereal/car.capnp b/cereal/car.capnp index 3d7d737..ea7d096 100644 --- a/cereal/car.capnp +++ b/cereal/car.capnp @@ -117,6 +117,8 @@ struct CarEvent @0x9b1657f34caf3ad3 { paramsdTemporaryError @50; paramsdPermanentError @119; + # FrogPilot events + radarCanErrorDEPRECATED @15; communityFeatureDisallowedDEPRECATED @62; radarCommIssueDEPRECATED @67; diff --git a/cereal/custom.capnp b/cereal/custom.capnp index 369222a..fcca5e3 100644 --- a/cereal/custom.capnp +++ b/cereal/custom.capnp @@ -8,16 +8,16 @@ $Cxx.namespace("cereal"); # cereal, so use these if you want custom events in your fork. # you can rename the struct, but don't change the identifier -struct CustomReserved0 @0x81c2f05a394cf4af { +struct FrogPilotCarControl @0x81c2f05a394cf4af { } -struct CustomReserved1 @0xaedffd8f31e7b55d { +struct FrogPilotDeviceState @0xaedffd8f31e7b55d { } -struct CustomReserved2 @0xf35cc4560bbf6ec2 { +struct FrogPilotNavigation @0xf35cc4560bbf6ec2 { } -struct CustomReserved3 @0xda96579883444c35 { +struct FrogPilotPlan @0xda96579883444c35 { } struct CustomReserved4 @0x80ae746ee2596b11 { diff --git a/cereal/log.capnp b/cereal/log.capnp index 9f0ca64..7ff2293 100644 --- a/cereal/log.capnp +++ b/cereal/log.capnp @@ -731,6 +731,7 @@ struct ControlsState @0x97ff69c53601abf1 { normal @0; # low priority alert for user's convenience userPrompt @1; # mid priority alert that might require user intervention critical @2; # high priority alert that needs immediate user intervention + frogpilot @3; # green startup alert } enum AlertSize { @@ -2322,10 +2323,10 @@ struct Event { customReservedRawData2 @126 :Data; # *********** Custom: reserved for forks *********** - customReserved0 @107 :Custom.CustomReserved0; - customReserved1 @108 :Custom.CustomReserved1; - customReserved2 @109 :Custom.CustomReserved2; - customReserved3 @110 :Custom.CustomReserved3; + frogpilotCarControl @107 :Custom.FrogPilotCarControl; + frogpilotDeviceState @108 :Custom.FrogPilotDeviceState; + frogpilotNavigation @109 :Custom.FrogPilotNavigation; + frogpilotPlan @110 :Custom.FrogPilotPlan; customReserved4 @111 :Custom.CustomReserved4; customReserved5 @112 :Custom.CustomReserved5; customReserved6 @113 :Custom.CustomReserved6; diff --git a/cereal/services.py b/cereal/services.py index e79f2e0..0892885 100755 --- a/cereal/services.py +++ b/cereal/services.py @@ -81,6 +81,12 @@ services: dict[str, tuple] = { "userFlag": (True, 0., 1), "microphone": (True, 10., 10), + # FrogPilot + "frogpilotCarControl": (True, 100., 10), + "frogpilotDeviceState": (True, 2., 1), + "frogpilotNavigation": (True, 1., 10), + "frogpilotPlan": (True, 20., 5), + # debug "uiDebug": (True, 0., 1), "testJoystick": (True, 0.), diff --git a/common/conversions.py b/common/conversions.py index b02b33c..ea23a5f 100644 --- a/common/conversions.py +++ b/common/conversions.py @@ -8,6 +8,8 @@ class Conversions: KPH_TO_MS = 1. / MS_TO_KPH MS_TO_MPH = MS_TO_KPH * KPH_TO_MPH MPH_TO_MS = MPH_TO_KPH * KPH_TO_MS + METER_TO_FOOT = 3.28084 + FOOT_TO_METER = 1 / METER_TO_FOOT MS_TO_KNOTS = 1.9438 KNOTS_TO_MS = 1. / MS_TO_KNOTS diff --git a/common/params.cc b/common/params.cc index aef2cbd..7b90e6b 100644 --- a/common/params.cc +++ b/common/params.cc @@ -207,6 +207,18 @@ std::unordered_map keys = { {"UpdaterLastFetchTime", PERSISTENT}, {"Version", PERSISTENT}, {"VisionRadarToggle", PERSISTENT}, + + // FrogPilot parameters + {"CustomAlerts", PERSISTENT}, + {"CustomUI", PERSISTENT}, + {"FrogPilotTogglesUpdated", PERSISTENT}, + {"FrogsGoMoo", PERSISTENT}, + {"LateralTune", PERSISTENT}, + {"LongitudinalTune", PERSISTENT}, + {"QOLControls", PERSISTENT}, + {"QOLVisuals", PERSISTENT}, + {"SilentMode", PERSISTENT}, + {"StockTune", PERSISTENT}, }; } // namespace diff --git a/common/params.h b/common/params.h index d726a61..9c8af82 100644 --- a/common/params.h +++ b/common/params.h @@ -43,6 +43,14 @@ public: inline bool getBool(const std::string &key, bool block = false) { return get(key, block) == "1"; } + inline int getInt(const std::string &key, bool block = false) { + std::string value = get(key, block); + 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 readAll(); // helpers for writing values @@ -53,10 +61,24 @@ public: inline int putBool(const std::string &key, bool val) { return put(key.c_str(), val ? "1" : "0", 1); } + 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()); + } + 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); inline void putBoolNonBlocking(const std::string &key, bool val) { putNonBlocking(key, val ? "1" : "0"); } + void putIntNonBlocking(const std::string &key, const std::string &val); + inline void putIntNonBlocking(const std::string &key, int 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: void asyncWriteThread(); diff --git a/common/params_pyx.pyx b/common/params_pyx.pyx index 535514e..ddce510 100644 --- a/common/params_pyx.pyx +++ b/common/params_pyx.pyx @@ -17,11 +17,17 @@ cdef extern from "common/params.h": c_Params(string) except + nogil string get(string, bool) nogil bool getBool(string, bool) nogil + int getInt(string, bool) nogil + float getFloat(string, bool) nogil int remove(string) nogil int put(string, string) nogil void putNonBlocking(string, string) nogil void putBoolNonBlocking(string, bool) nogil + void putIntNonBlocking(string, int) nogil + void putFloatNonBlocking(string, float) nogil int putBool(string, bool) nogil + int putInt(string, int) nogil + int putFloat(string, float) nogil bool checkKey(string) nogil string getParamPath(string) nogil void clearAll(ParamKeyType) @@ -77,6 +83,20 @@ cdef class Params: r = self.p.getBool(k, block) return r + def get_int(self, key, bool block=False): + cdef string k = self.check_key(key) + cdef int r + with nogil: + r = self.p.getInt(k, block) + 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): """ Warning: This function blocks until the param is written to disk! @@ -94,6 +114,16 @@ cdef class Params: with nogil: self.p.putBool(k, val) + def put_int(self, key, int val): + cdef string k = self.check_key(key) + with nogil: + 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): cdef string k = self.check_key(key) cdef string dat_bytes = ensure_bytes(dat) @@ -105,6 +135,16 @@ cdef class Params: with nogil: self.p.putBoolNonBlocking(k, val) + def put_int_nonblocking(self, key, int val): + cdef string k = self.check_key(key) + with nogil: + 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): cdef string k = self.check_key(key) with nogil: diff --git a/common/util.h b/common/util.h index 0cbad5b..6f29a36 100644 --- a/common/util.h +++ b/common/util.h @@ -37,6 +37,9 @@ const double MS_TO_KPH = 3.6; const double MS_TO_MPH = MS_TO_KPH * KM_TO_MILE; const double METER_TO_MILE = KM_TO_MILE / 1000.0; const double METER_TO_FOOT = 3.28084; +const double FOOT_TO_METER = 1 / METER_TO_FOOT; +const double CM_TO_INCH = METER_TO_FOOT / 100.0 * 12.0; +const double INCH_TO_CM = 1.0 / CM_TO_INCH; namespace util { diff --git a/release/files_common b/release/files_common index 1158d2c..dc05f7f 100644 --- a/release/files_common +++ b/release/files_common @@ -557,3 +557,6 @@ tinygrad_repo/tinygrad/runtime/ops_disk.py tinygrad_repo/tinygrad/runtime/ops_gpu.py tinygrad_repo/tinygrad/shape/* tinygrad_repo/tinygrad/*.py + +selfdrive/frogpilot/functions/frogpilot_functions.py +selfdrive/frogpilot/functions/frogpilot_planner.py diff --git a/selfdrive/assets/img_spinner_comma.png b/selfdrive/assets/img_spinner_comma.png index 16109557f85911820bcafc30b6af681e3d5a1bfb..9f5e558772cbc5dfca7722d794dc7c0fa31cea61 100644 GIT binary patch literal 111089 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 literal 15713 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%0Dwp=5)X&Jz&&A{; z;U^ISXJY!1Ij`aS05#5(^2#dqZS$Z3NC%AM=SXI4%#|%x4bF+z}QT?TAbtXk2p^;i7_kTim# zkp~IyUSdtF;qKiN^VHW7#t))7-EpiyUr}xSmsJ5H}3B7a*alR?aIt=X; z>xje^^AG~b1_MYgL~~i+Yk5m}O?=xOEBV>MQFP*!bf;KH+Mi}?+6+jE=7<(}M2aT1 zODNgGIFc3wWCtewZ=54eK*;?#GXm(|_Xu4)$yJ`5Fy@pk`CXj5htKay7Y79tXkK-Y zXd5sCW^ky;G9fN|({eAw~{1$XK*qh^IbKuNN(;v6k z3b48cL$Muk4$yHGw65{Ap!>YAx#EQ$37<<2l-#Q+;O;<$Di*Ei+k_AyzWQ-TId{mh z3)up1{s53J(y3vAe9RiG?Wia?sEXqmxT-wNkL{|6s7uYwy zl5Bq_kj>qMLwl?)VjmQ-qL=3XW&tE?b7oL#ZL+T8WW+yGtaQ*}o9fnJcHXvO9Z#Sa z{U9wo@*jp(goQ5OWZ$%eXpAYAdjRM`mMrOHZ*u)+Z6$J6p@U)#jk>#*z6qaBohbmc zbvCRik}^9S03?PaAK^$J+se2>aqX2cKr9{S-RCejtnV|V`wO4yPecBDk-AX%kH4kT zf14eSQPK41HW}M0ceNXV z`<_&b$8Pd`&nB?-{02XnLY`8NW&k**xgkY?05=HzUbtlGJb`QMSU7Ix5OsZvNLoCr zOXC^jRkmuq+Vhy_xin)-qt;JT{&qEKK->&!mU1JjQmN1=jLauvv39##%B(XOe;P%H z1qYYaf6C<&0njujos_tBi}FQ26VmL1A`a?heZlQ3%+%2q*h}0ha@#UmGDSgmZ){m+ z3~THtZvI5+t5jOb2OLAzv>ogw&9cniL^qeT$q$7gVvsA(hF-PsubkhoXZitEw4kvp zgcIZnw6zHL4xTr;;_Iew_P-Cyc`_K+<{tV&cQHLUT;}$Ai~RQGwWMpLtVgI_y}Pnp z)45deaJuXd26!`#POS{gW=wv&baIhpxuQkrZhgVAema3M#?RHDT|_kOZ_u;VPWbb| zgmO$y0|&~60ML>so>JXEIZqCD#AqLMqS?%|LVqS8Ri5$$4CsAo6OH4nWf7R}P^lCW zS^D%^Xs-XFQ~_wNM0Bfw*~IOX9zR`Nyg9l`h4m6mAYOygAz7(5cUr2SbPnR)HW(}H za3U1gIKa-ktJxUw-E2N)H%_gZ-`$?89J~3-H68ARs;{x-Pw{Q~dJ8kS z7UJg}yG1I5CWXPUmu?U3Rry&`xWNh;ilFLHna(lq_p;bM>gq=L# z70AS~op=JNxC?pso=9@3aljGAObCTv(j8O zx4UNYx6)EwN)u*JcyM5F^5Ue~CD?hj{=;@_N^QfyUfv~nyd*`?nS&)_)qsp%wNJ7Cr1eD;Ltkkiyt4fX_Gp&*sYw>X-OSIfSFFzQe(j#K8#` zmf4zU{D*p-Gc&^?ulLKv>C`X*RGZ7KaQLwd zPu7M9&fJC)ug5ZGd)0C+2p65}$m7D>wYgZRvN4P+PET#1;uUchqN4@fo!o8rF71TP z3zOBk{s05g^!a;Kw5@(O)=?&ce7t&?pOGaaa+#ZeRnAJKvS zqN|>1?Br{7mM zgD^N?3hBBAiQg`2h}H*rT^~mtm7Q)b+h+I6Ci+h@qI%#uVX&0`)pafvs%+zxV;f%G zWHyDVSf?!}XBlkY>4Gbj3wqz@MN06_GmW(|48?5jNerr z$kdhJ9+JE$@qor!Z~pvt;v0IRyMXW5cQ+7cL9Ww|`I3OK;|X3t@%B0&GROPuEh<87 zeb3TiCUpgPIw3iZAK`SE;f|f{8@AfyxRXHi*r3g1gV{tuG3^RaCib3KBW*!&_*P}N z_hK|+T@+C|MMwXsmEHGSYDlEXDQ`W?GjjLM7)3tULRMb_M{k82Ge0nD1g!n!qhp}q ztC?9lwsX-=yN!6Vf(y3f(0!Fh-OqQdKVQ%S^dM7c`J5fw(cYK7Q{STBWx~kz&1`&z zezx6(qqMx~{JtJQ=M8zn)FcG1+wT}Px&q zYU9k&dwvaJaHhRv|0A}2(Z7Fxo+)yu>60^K+akv~G*_z8P+IH?cTY+1fHI9-&y{c> z$K&p+w0(m$XLf3yjTjN_BoUuviEtP5)`W2_6}eu)e+IsM8j9LH2;IYwnn(QD%FQ{v z)8f5Fn?em1vihIc)&9YXB$Yj)Ph1gGY4JM#!}Foo{3(C^KeE{epO>jC^b~kcL9#a( zmhl6YyW6MVYZn!T?%|Q{dUKiudh$#a$H4o@xMju#!kmY@42a@gm8D6gu){~36!Bkt zljUy-r3}8Btav#Lvf?Oyn=4@x*GtgZXP&Nx+ae9f>e+_&=T9LQmGo!th^q%1D+2m@ z{6~r2o`YK4)t%+pcWn{`zr2K40@8{x{H>7bufth2p&MjsdO(jwPI&;Ga{0=ZGYbrA zY?e=d-ehi_PCU`HRme8Un+|Q(D$NZ8@=o}~kOXuEl6b##U8|+^)-TwyXEIw=y!he0 zmO#GqEyNr7r0nQl zq*r*aLXZ8Q+GK$+%nEdwEB^`$;AvwdE%_l64%Zi$Dd1C1tKi#NHwr~RQhJB~P&^{b6*PpYc zg*=|txbJ0_E>tec5^p`(Q6FcPGyI)|qQ7pDdQrMn{WzGZbTcSIcl8dHH~DAcuvid8 zwB9n8?TS4P+oBMNhq-s_@e7PA2ZbeAaj08pm3{PJ$c21SYe=-_>HkPliGWopy|!Ev z;C8^r(e((X@@^~-eTnOfyYpz`zz-Q*@T}4x94Vsx$70Q;x+`8n>v9@w)<)Kro6ZKN z&Rui)iSA<9KPcJyc$y&V#8tHDf9PHWpdltEK|khW_q3A=_2r!~mqj$d)EvciPKG`z z&9g~_u{$Og{+MrnkPOW)NsZ4>P!h)10EVajs=1gSbWBmV{IzC+tNzlf@ad$B;u8~4 zYDcF8B~oBgRUftBU(R_VJTp^esuP=IJ$_Xx7`@g{N!%WY_mgV z0vPI9h4N2J>oXDmJGZ3cSf6}SaVh*RLxA7YeR$|^4t??pU!$_(XxM)5qekIBUXbt_ zkdM_Lp(O=I|A{5HSkg^A`$c;<-n1!OZ>PoXGkCX4T79+!1|L3qc*e#3gt)Ts>RRfN zDa4(T$nK#7^HMJ-uJO3HLXc`Ac)3=Gq#)I-?;`WYgZcOtRu=w`KU?6r#5QJGs&r)} zkH@(M&~5V)eYZy$_>8zL%yT$VmV%N9cV$_Z10;Asn5Q+&e_-6OU zwvFQD_jKZMXC?%O&k+ioSx5jY1BkxZ6?DfQh}71cA@d$gOfu?U=DBWx$|vZ^TmQTA zecS6FWgK+5Q65(qi7#o=HlLC>fsGCIL#F-oe89J|biH${uYF2SorJ1F=!l~X^A={A8WVfF$F1km#yR?9lMq^y9TIA|N=xLFEvGvp3)XPDG95D9Cb!%s z&+iB+AB5XV34~8HeG2X9Gu#$bUgGkfr7|o0I0@Jm*=X`optv1l9z?1 z?1r;IF3bO^YC0ML2;U?GdD?G)0wd;q*vZ$6aWWR6a3-apw@oU0Oz<(&2`f%NZl@Y{ ze?4eYpR7(UeKw0OZ79)SvD^B9me>O~S}3XDf%MV`F${Yy@^udJ>F;cgwfWOff?#g= z905Kf|BHrjY)sz(r%%`smHk^Yo2v zwTzKcdA!|t6gf@8Hj=}XnW-LPcs+n^BKA+}Dr-syUdf7XsT%-l!a}QvC`3+s9^CsB z=UYc_5p=GQ8dYsnZTP(7+|)vMH<85BpkQ@-AYL6M*J+HMxJic-E;fzcNyt2Z)f0w3_rfDje6r!CD;zh3KyKt5X^G4KwJef5j7jTK@SgC+2YB9^97PCO( z?yE0?q%MwxANsmm5>gKlsRGWvRy_R3=Jj!+{~Te?h|4kfaR0ql@B`tD+CKuJ<01pR zzVmO(Zit+hmKuyzieQUvmX>mC>5jQwO2Cu`B&qa>RiUu&l~xDk`-X%hDjDSgtDo+0 z0vemL?6aaKZHab1lf9D6wYnKDO&`Ght3MnlH%^4ZzWvG05#z0ksjx4GSlRbJ-E0TQ zZUlVbaZZ-c=LkT={!02edy&bW7oVi!;`Dk)2S^LZ#sxzWDQ23Y@5{KG z2cnq(JM@_^VA0F^TOIBcK8a2H0!E64-Om8cafuVY6UB#l9kb7y&vRbqvHKd!+l{W# zYrXD;r)9v?4Mvfzm{@Ij{ub?z8M|`{)Lnh~HwF{D5=2!pF*=NZ=TL<1bQ-SfL+Sdu zxZUVXcsAvMh`qfUpiTkH+rniN(R4ZAnz`ckZn_WSBEO?O9UA_@TR6DTL04LeEhG1p zlf5y04WAsD^hbLM*M~}3?8|$fFB=JHzi(v%lD`{_01+<{RGmO1*P3%`s}q_Ca5FaqQXag%926whNqIY!<6=$-P=0_QaM(&+D7%JN(}X z96?S`M|L)XDme{?aS=(yku$Y^w!b7_|4oGlZV#{`UKkKo-O&~X95=~={BY>CpD<*o zwx>H&ktuyu(BXENvA6&5yKf@FhmYEsFINYU^Cm>JTJUHz(rd*J(I_;SqPpice8+a+<~Grmu@ECg@vCas9LwKpM5|H7rGG>th& z&6l{8rFd19P0FMK$@)&1XoYOjyGnt3pwh8k9mw(oQl`}M3#0y~p9uD+cWQpPtgEo8 zXO&;1z z%OB2$W`8RkpNCV1*QT(z- z3K%7u@S51;R+c!0T^?Irx3?I3D$-P9n`CWfuh@BBxeuAjS2?E{z&PH5XYsr#LjDZA0#>)Bp$ktcxU*hv*a$WF zqn4!Z7S%HXI)uD?vi1FUc@WkL#S}7y<}gJCENwTQ`T^;2rh=kDFCA@=e3*uAonx<_ z=}dE2n)#nH5MYg8Kpzwn3+&?fawso->S~UtX6&rmgJZKfv_FI2)u z{x46{iey+bx3;ojqhgc~DddA6ih3@TkAHt$8?BPAKwLf3gh@01Q?>$2KZQn&-)$N{ zKC3qrQm|=%{Z)|fDbY&e_WYX{WvT)2@v9~Q1}nh%I~;j`n+?Gjo|5<%btP;}UrKjU z5~_;Gs*`0ju}y|Y2W9`!Rq?k#u1x+9S~iqQYb(7c@~TprELunwB?=wF9xw*I0qBKG zL=k>J22|hd1$gE0hhXE4Vzj;6;Hx{A>uI5=1*D*$cIj6gKkh@lCHG^C&~y}F|D@}{ zP#OyEiSJEt#H2L%aX;cCK z18-R84O#Eg5-g|Z)*9IoCz`i^q@e{#Mcnb)`2XqfBPvGJa~pRmk88KE215bVL1M*< zpz~!II-O`SHH$RAv{F#!jH-u`)kIpWxbuuYr_x_ib*8o5Gu>?3}-76`7wL#uh0i%h&v$K+aHP z{0F-~s42Sz;#iKFk#oNo^%+Y~mJQ<7r5a z<>Iu?b4;x)+M@Q&T}A!={AlU9QM`!2cgR09G2k>@93XYvIUsNGXMdm&GBcE7tUCL> zkA>yF*Tm>7AET)P_wp~o!!;_(XQ8yc$Sg0)Vcs(0d*%8=&(zN}ZIz9E7Bs|*C=2oM zR0-J=-oc5OzYm5<$)-~2M0-*Pa^qQ9x0{<%OSv+W1?#DKB)}LeNcI;IZH>^UZAx(K z4W=n}lwax2Y+g)`5?9mu?UtnKvKTr>uAC9H_GTq1zWJAWfF~8EOrREYZ{jQN<@Y8T z@ppQ4A5uF4M#opPGKuQy6DLSe`i{-WWF|1zzm%mcJWbBgJk5|Ym7aH?-nOz&uHkmp zplWzNNo@9o-T(OTP;#>bmZOdE4=mw8S#ab(y2N%xY4eoXMc9|85UPt*8kI=DlnV!Z zVXiLKyPtu2hg$%Uh{YB`hW5`6Hi2YvARs+2!I=7Us%;!Jx$h9WcEqn?!4beB}ygA zm7zaocF5@igrCo29P4(J0V-2{Cwv-Z2kwhlkqI~!@Bs-@OMb34yk0$$zM^{u@v7VN z0HjQx$h9*~C3(V88CKP#;#l+l7Ec6P<_0M1U17{!*v*l_m1xJ?%*@IuImESm4XMYU zK*cj(0KzU^bEN=t7fb4wnYJjUwtk4wHQBjXva?~IM4S6-M~o`bmId2mze$6%>5&-@ zsWRxlJCBegL=m$1V0rCL@m5=+3r#wCz=Z))yySKXGzCgQw3x#1*@vxQt(Zc`1s=}< zCBN!S&AhYlfY&zz^fori)YGXwNlb!HdAclPa)4AyWB(_W#PIIwh}vW9{<>*He3Dl4 z=lKFB_QJQ3D%ot4UkD5EfT+$Q)nLfY9`uS+hg_)5kQRMY=yUiby7WY==&&i!x~V~9 zZuzNI`~vO&suMajW00`Lhl?4$KjT|3*oH}3FT@(n5Roe+Qof$67=IgqUurX?XT`B` z#a_n{ThoJ1aeTp7WzDd0-97)jl)c_a%pWlnM^54Y%9BSg=?=%|s$U=?L{)h#e#+!1Y)zsa0#b~(LbF0iZbOXe>& z_vYU`L6#;A>_!K993O+&?U1n*J*oM%x`=*jsY;v^LE90g!mN$0AfrPkc*oE|kyLZ3 zb5O}--^{?5Ik!H6-|S4$*1X4Tl91JSJnX0%SNfk-h~c={h-h-|JO*zHD^-LSt?nKTG9Q?0`?GM0kRAU3hXH=vXbfiOW|^LynAtnmA@}qkPHb1G_<|HiODNT*MwJFq1~|zN5B=nGem9j)ECLuTMie^ z&bLj+UO@_E8n$>aaq96>QP#rkMnRQr2*ST@ihln-9W8BzdH+w$c%%q;zYn)Nd#DvzuDlS(l{Bp zx*62#e2tOPcr>Wv6p%_o{g!W`!(4m!7^i?+m{to)PxznJOM*9*Xjt>RMSwB~G48Z; z$_q@DPkANZ^$D{v;P+wb!b5 z`Lex;GC3aQRs2IO_T-ZKG+N5?ef~=afe!Mf1@LOLS0nQFa zD4e8_^pasS>d$l}oxe+NAtd3U#5xV@v=Y^Pp8XQM@Q;CfYvmsAB9!w%_8 z+HMrlnh7-TG4;&%5Lk3y%(E5?> zzJWg5;!(G6E@*n6u=z=~W0w{|3pT=`d^RH0%Nbl-+vt)*>?Q@_Ua&Y@CK2Bt2_$Si z5<59;ecseFr}MvJqm@3M4t6|xbOall+TuYB@3YDl*skk{x|26NFBuda`Sm(b43s{U znOx{|77X)7vR0v2`PivSniKbh=b?M`ld_*~rkqZ4{*5>xzSdIEF7=IUlCVVRf4m0J zLS)=nxtsP;h-)&vPP!yrftVT#hgWmi28hpy zCUC9<@EIuk-BuQz87Ce-Lf%ZY6a4cN2Y+#v>_c$dvyt&8-f=$8?f1~ha7@0zkgtu< zpJSfKW5CLle^(Yxxjz4_xPrf-*V*A19Jl*(`Noud&N{V!=EiwZUf zk^5aEnf7WYg9l=U=nX>Qa2lp&_6JD*~6H&-WqV!SZ%d4jL! zDW}IQxuYagK7ICxKHk&+PHyV~#K8trhI@XiTb1(T2%d*74`gS@OS~liM?5tv#_tX9 zKJ%i^lcefTOfgzojXrVi*!OtEYhd-Zkj=Vz$rC%&$vN2JmMmNIZ)kxhrKxcJ1N6uH z_W{d(Y|-ds*b_e$+^hgyg^L0KTelxzkZ#Kvw&kpVvAo|k483hm#?o(tc7{9d+V3+n z<;l#nAXyYQBZheYzlu-*5I8u>dv0-VxF*T71@nOFFF)MYU{{urHegQu}!5;E@y4`PT zt1EDHC6%jHFl)Oyb^FbQ9WZrQ5|Sm>KJWKXuLP?#V{^EY7U$l1!qEofLW;AwUC}V6 zCv4*rlnAPi0k*40*#GZudH}Hjx(UwY%|USgCC2CY7PwgyrN!qBi{LnZP%#a zTBqwRP+hU~&Qt?bJz~y!%6(@MPN#5vR@6nTzlB1BizkHLGMaSldr`{&IVzCdN?M^> z$|Zi~II_7ZjDKCevzkQdI`(b#w^~sl(TvzG6+{=9c$)=NNBef=`c6=2gP4@KG|g@f zudCZHfZ-{pI=&bNue`JnikksxWyk;NEO!j-wwE`dz={3m@bjmr&QqA=(G zr#9dsIy#^@$jOe-r1j7L$JSd%MY(_N!!*(Y5`qE((j`bqs~{cH-QC?Kf(Q~yH;BN{ zB@8*FAT8a^fHVv_M0bG~Od?{BU7d#`=(j%$Brpzpf-w9-taWT14Do-uJo`#(~_Ls1CcC~8qvOaFN)F|4ErdlAZ8p9THS+uMV}XdMgLxc`vr2XA@unI(@Be79m-X^nOOf=m ze2iwlv_VOdX-}adEXe9AxR+2#kNv+M5V$-5Y+`QTt?}&WG$&Rm>9XICIYqFb^>x^4 zLz2@Q=4;C47&J93r68e4b@T&K!N%HH^KW)my#3&tK}z!zJzZDz1ut_Rkh~40wgkf; zhV`bznf$?g{_~4hq;X_%2H>fUlpM7OHzTNQjpD!kIEswPmcIP9tfrx|ut*%L{Tim#@PK;YY)Hdct>k2BYpo$K7& zh-ZeqZ})O?2Y^TNOwy>O~n!-N;ATnNE&6p(Fe&3r-? z6{x6(?#(gTdl&WB&Isb}2ac6;G@RU~ItfbhO8e>J9}K=vPtfTMNR3Q2!?5slH z`#qi#!_c;${{B($&-owu+FN2~Af4sPlT@%#+hEuK{>kjO3mkc|`z)$H8x1!>VVPCT zCtL-6P5obI7B23NrT6EG#$luR6;)FE)ZS%@S=Yp`#aRj8r`@1}DWFj;S+62tqmYiJ zUHQb{RYu2W%Xj596ic8t+!LoV8s1*5K$j8d5@<-1 zlVk?6T)1cW+GGdjry{fr=`?X>+m zsi-~sewoe7ju1?P)*KOi;rk(aCMoaG#+b~t=eh|xVvqVX1Urg0smlMXpQMIFpsQrM z-YkAf`Gn@hVJQE)nD`0SS}iPNd?;8q?7Z+qOKbO=-?^>l7czCBn7U|AWZswNF1lyE z-i1@I&YSp}!xQ$Z=3dIdem?}Y$9s@V(^rzes}q&)Mabl@v(f(KNl*-Wz)zA^E?I+YD*-x>66jaKEKp3+Fl3>#VObuBKWi22ZBHoFr!vd=@v;^z}I!n@GXi9 z^ho^+zV~-1*pY9w-w;}*N)2f_N|ZP!`t{aaDn)?`v&?p5m}P^oartR>MEp0N0RpzB zLcMX=a$sgv(^;(|UxTaCwk5Gt=rG8^*BjZKoJCVKg6e*yrks z*R^h6R*TYK*@Yzq^(L4&^B16rUSl-5sCA#!WlAheHNP*In`k!CJ@(MC?gg+-(d>ON z7qvV5b=_Ojga3Vv-WL+fQ!I+wAvE&XuVBl&lLml=GU~A@jQVQZF8y{H>uje}C1Pu~ zM&1VU^^cXUIaNU`Rs`*iJqe!k2AQ)8n)rr6F;0tNY+%Qk&dfj2jb%gS1W<0!kLIg4 zR&c$PqDqnHP5v_hS65vf(@yu8(8K92P-4!kp4CufCMF%)=Ar~a&-Xo=Y zo*1q61@o)!8H{X|)OFc6v+_M#U!My0kN;5vis-*;DSeSgw5XB8S0)G zB@8GOI^ynmUJ6EaUmuZFRPf&O8W>e_KDy8({7&*LH#}A9f$m4zj|tlbf<-yx2+`pU z+FN?XtjHE9VdBF+67yL>by`|fL%FAY>w5Yoq~qHY6)3&)FyX!mswptrIi4ZoTE`~6 zZtg}VcE;(P)(^YB>SDDQXKIOWnZo}~z+=S0I~t+~U#xWw&)E{s)La7`B>M>jz7<4b z7NxwY>2lCQt`YbFe%T?^i?XoFsag=*1fXiDd)zr2)XS4UzaJDy$Ron0{nzDAWLmY; zQ1$2g@l!W}vUWTj6nX;8s6ZC@;}nfg(A6|k;SaU6^M$f%c_|fr&z%Dr1Ne*sYz=Pa zR0Do68!nl=w8`M;FP%6lN0{wqdjMAs0Gyq=0+Z2R$w{>a3>(h&e8rm?RCV5CFoDvY zxNI27OJ!&^6Q#rvm>LYyq8KO>X34Ljw%s;(D4TQtUorkdLSwrb5lXJw)fQdz;X?n)w~CDu_1 zJg1Z!At=A~3-4(*>4{4{0QHG>GPoB-S%+?mn`G}39aEMzXmmU`Dvj?eY2R1l?l`ye zzs=pB=z~;oZa+E9ZOf2_WjFD*DYa#CF-_4$D|aj}HJdTvaK%9p%kM(Lo2sm3*H-Wl zdrC{5izH2J`LXg$1AifO(&*o>RyG6>n~g6vLajY~I}e0VKd8CCOFa7~1ea2GP5#zK z`AS^7$&9lFJ(?4BlE!YO-`e%}ywlXdgvc4oTz*nu%kPNz+P#DvTx{T^@1Goqr$_@% za6EcN?;o>`+!FD+_8WUOMcbp&CunL_F<>Ite3h_r*gn-{XQ*N3P&Q9A(NOP--5Th{tE@Q2u@+xO!0fCCQ>#?bd!$Dpp5!)=-y)0C*$th)nuMcRb z!o8MP+DJHp-#_BfKe-lx@an%($n(v&^l4cC>3hS~<2HWgrE%$X5a8Ex0>3%CSg4#d zw{T^8yzASB3Cd;N0ha@vIlhhNNV}mNZ>E>0m}g!vlOfkvm23)6J~i=A^?}f$`DdE} zz!(Ds7@?!l(*%oXWkVA7TUnW1J3{~@n(O&2uAaB)S-wK*| zb;uiag<0|9y#+DHRQhui_f;z_u@R#)^<)?@rg&3c)}d&=i0r2);MM2zd!mfHXCv3s@9iwg?@(6W@SB`vLsD$ zz(U2(_;DjNbMg*P87kpZ`X*0b1bktJ=Lj*y+1McHcem%qQJSuT&NNK!ss6e~AQp$M z##DdHH}6YVe#AzdIiSu&Z6J34;83Ppn1E9&7P*(*G_m-q6Po6c`4LAcb9v)zL5_fN z7jn&Uo2fdZ84%iw@w$s^H^g@~C1el4%hLm?@Q;qBc+f^l{rr+7FLyemY~dfKu~kTG zHQ6sYI=4n~xW!Ac1xwKkQ-g1d$NYXj{tab>e}Tf!(kbk>i^-yu$D1E|-M4x9f0_me zW}^pVKlM~!8WiKjZTsC~3GF^esYucslwEwh#uuifX)^fJ zanx3WzFnliFIFeKurXxu4KD!S_{VyF<%@&OKVLeIRCRZo^cBm8RLjlod>x<7eZ@x5 z1nPfWy1+$Urt5^v0y@|yUzp{92pw%I%biI&fo)mYbu(|8RW4T-d?})Cbo_13Bz_~B zWg(W9-^+eiqZVCUv9y8eoFF{oR%g|;);Wle1UjhT<~`;DSVZu-r+3TEbD5l*;pJ_p1V;axo{I6lU26 zK4Xxo1+jea>uPVQwWdUUB}cG|=4n)BTRfaozjroGO9YRFLMm7u4X?-j+C|X&D3LUd zY)KuJWA^~?+~Rn3UBW)txHUJQ_p_ka=sPTBTh^=j3YjnVx}3e*QR1({@C?YJT)={&Hi)ABR>PeOs{0G+LJH` z??W{+s)|)iCttpAvqv3^`JZ6|?rx#kN)nGWE7IB4XBvS0h))-_s11h?-Os!BBC9Z9 z7Vi-cZ*=XAbWkMZ6nEh`Tc_wz72$XGE(0DtHH0Y_L8AiG9>&9dy zhp%=7JucfZJDs8`Cj1AKLYW_!{0EZb5 zoOI#1Dz_NDDj)Zed_Aigv1S%1Fm`z4{D-8$M=!)nDVEF@H*|NU$;m4Z25dMBczyPJ zYD6?1eZ5gsyJ&PCKkFTvdH4a**<;1upl_i+^(pq7Ze?!$8htuh;@olBZm{r-)qhC5 z;D{ecd^cobo!G9_>&mSKjSlSpL;w z+)WMe-KKZGTN118cAZ^SS9Q6Ax5GC0hopPPZg;hxPep&RMee@GWqKBJ(aXZcgKdgO z)A-_8Wd%}0;$q;&U0-;IOSL_}j<;;>L7|lGQ?7tTJfEkz&cG_ZS5hhH%PP-ME z@A~zI%4B+@om*(u%2dN4BMI3?{in64-c)pQ@Z(D8E@fZ(2KJk8_T~iL0~(92S^O-v zW#a`NneXm=ybg`(#1*csS4(hn1XalPP^%>?a(QwTWOmc_1|5W**LuK;6Juq$^0Y%~ zZy}AC&$D_Ufn90VMhzlNSyqL)T?8M|0|{4{x8JF#pfL>3>1Quk}GSB$>Q+ z=O`6T*HQ%w?S6h_HUa2Nk<@DSwHf1#s|(ui+;x4u*Db;u+ibtLuLUIO+s~AGy$4MD z`u0h~tA8EFNb%mM(wD*D#rwCEKhlxTB?$)G4|c(oR}HEUIU4piPx;GH)VyOix~L2@ z2hH%NF8sm9-hk=9A%2{i7I@2yr?#g=5}iCq{7VGE#9d_p+aXc&s^azYt?fBVABgVD3L1T(sB!d6~rdDM*ZL~ zY|{~FmSTS^Rwn}U#VsYPMFPR z;Fw^Gdo{1dm~7x^oD_-^2bGA-@(13gv#9;#ookd=1s(NAX;4C-r-(iFO3g47$D||D za?@#EKgWF9@7!_Mn=t$0rQ*lsueA^-s>%I|^s8K|GBFHUYh7z2m)pUtqqP8jhs#WW z!EM6d7XJirps*5TQWn!Y>!B2MDOAwNiB6AF@uAwlKRpPW{_V@+KNyLmUglC$^GGD& zBeZOu(A&=j^a1?b=d4i0Nw#BDs{$o~-EkH9w+13bHf6(5oj;xz_rOg{=h%wft{h`W z->pS;*KrUNbQ8NuTjy6q+-I=gQS%u}-4WDse}z}qTDIeDE=0|{JcBXY7a<_7fByrw z>w7}b<@E4iYMQ*<(rep@lR7;LqPyz~kXx{EdEsJMOx$Z|xeOr}<$iFmU^flhX;dU` zK3kiS6P>JA8udrJBSO)8-_W0id65xXN*oqTknR;>JQ7H%Uv~>)AsDu&3z);tc0Aua zr5I``iqUOg6nMmDSmZbNqyhNoj5l|A3kg!dAE{x*6#Q1)nb!sDoF@0cGpJxrUYIVI z{N$+!a2H!ndA`9%Q`;4GX1@cai^3lms7+&MSPsY%L6t35vKL04XZhFPxB}6(ij_sw z7k+CmptEuM9DH8x%2}9ZE?DT*+pr7rd7JQov*wE8Kqp0dokHl;vxA^fHof77dG52J ze=laf9rbE^+@OCdZ3{=zzr|TH80ADARHF$C`mFCa>Qj;$RexULL9>KeJ$z>7KRAs< zq6UASn8cgXdi|tu8a=G^XT2zeU2D?!af`$gFQ&&&7WT-c3%-{J=cE@JTmTk)%VM0PhK-?Bq*Lh)|wiA zmTf0)h8q`Fvl*>&Ci8E2l{Om08XF3IaU+XQQRe(CabcQ#wE}vmnF#-3cPyfk<;pF7 zqJA!J=e6oqSz=u5=sjuF3g?j6m`$;QTF*_0sxPGN(f#uOpYMsI9BI>({?uH?#of<{ zQfI;y!}s-u>6xax0;OI>e=FWZg(0Pu@g!{~c#nC`;pLU{{&OhyYqO#Ey{84^1$@Wu z#s3x(tyiQV07dxFNK$QuHd`2n7%0nLVN6t*lU_K?K=p8y%i9hr`C@C0y_JAuz1gT# zR{H!kuMK!OBA#Wx<`B&dkyaDg&nBFcu!~0JzKG2DU^y1#0@C^Y*VhAuNapPMde9`G zHj6R?Iq;@?oY**sV93JHGE*O?3hiApW?VkE5142A*Jdh!HEXeQH|}98^qC?0yRViO z#&t7&Z*iT6{rR^Y712SN)KwFd%f9wYb7Yh^bRuWW_5~_dHX6z=6V7ISO_m~v3rE(- zj>IOmx+Ezbr^a)b`1`@BP3yGenGh$6n&Zzi+>#88L90CBjxH}o&ayJ76!;?E-m(hY zZ*PX)YICl@`e2(BAr7E3199MmH}M<0Ncg^X(N9lb@(Po(^T8An5U)CwdUelf^T)2| zDl&%|TA~jUy{SoL;hvc=%#HjXbXAj2Cqb|UJ-CC-BLx0j#cA|IbsobMsTZ)>*nPAh z(6wOhMfQe8sq29hBy}-?v%C`t#p@j)Q6}1Lvj z)3X2(di{&I4~N=MI=UE6soL|A71vFpc|pSLOx0y%e##rG{49$P{sN9POS|xKUb~vB zf3N@rJH4v8>IFNVqZxI=NswZS$bZcQAo^bXT93)oz}8G)R9tg-wFoZkGHMfG=+*+i zS$`e0h3B0X>?ni@`_|WA#cKj8Jdvq@ZlJHEaupafo6* z62ZAo*&eiNk+bNmKNtY)p|Rz^&=X`aNa1x@wi^s~u6TxQ%=DBC=e6`v7o~-=A3sj@Fv(;qzKut!}6 z>xYd_o>dJuFC`MlPJ0~fi$s-5N$fyy?LSE%GAV6jj5DU0(;IROpiC>RS9c~hWgjk( zox-9w7etBA27H3BUqVnHi6!)CNk_<&hnt+QbOlY;sih}!IDS_sSMhSOuOlfe&avpX zO1l8wL_pAw2N~dU4?RKlf@{^!nx1PXu$)>>$fXY11Z`<|ziR$*6^6AmS~2#!{+ueX zHj#&=*-uR0U$(q240P-XKl?hj@9yMKx#)Gm@UORU#h?S;Qj8%`zve1>u=Lf^)a0Ek z_4wCIh0C;Yq;YE4&AmZcOdb_28?*xn_antU%3{NY;dwt)ua+Jz-#VV}{|S=DFX%>UVAOTXo}BRX|(c`m}MBV<5?8AsSAo2SJcI5J-xs(}-w+IoEzXOUK#K{T3QJrFDweXUAH# z_`MvUcujJXXK_B_#<;5s@r)U=Ei)J>g@?H6r%jK8EOKNqHxxAu5rgYaB?@0*7a4Wq z$5%(zxW6B~1uvo|eH>jiHSJOs5BZOYHIh6j6UpopgWpA}B~Ds9#_`+-Kb zM%|9x5t^!2Do&$AeUk0$-n5Ezyxj2$oU3{v+^Lqwt@h!)Ne@xwC?Ql9Y1yQ1)yE-a2w5r?AR3DS!j7q=%HmEOmrUynv$WfR zR(-w9NI)7lgqrfEJ%WrMGZH6u>6<=*nTWpKT+P^QtDk1~iPA`e8M8368Iv_sB7vbwewW(&^`zr2BOr#k2)zgr+TmnF&nrS`2V4 z^8vvh2CrZ!-+DmpnbQ}9n z%Uy22yz$ofjta;!4{CFI@Q-bWSQko?Pe03*3*Edw8$LUE`mZfk+(-YS&J^PAx{U?@ z_NJ<%D22W7-DyW2YllWTR3NH*I79vK{6Qr(3*NIyRXNsN=d#iFl`8;9D6 zW6F%%#Ux@aOcX0F1ysZ1WG=F}8^|9XY??0D+O)Pwo@!eK=?JzONBZ9&d5xxg3w5Nj z@xGQc-}{+)9dFOtf|781Hm*F{RzEs?m)=jTu}GPcg`X06$x1o`c}}^;nfJ?}TVF5O zp98trTh7jV=mA3#8`eZ1TVi!PcUHgVLLYdN>2;KT?sx(7!S>sK4H_9so-LNDWL9{>!S7h1}B;gYTzu^YKSW(|7a@E@z^%|b$8uz6Di9b}=--ViC{J4GC zKMB6;vpFz51o*UyA?pbpf*iZ=je!pzi?xdFupBzGb(0Eu;&hA~B$B$nRxw5{attcy z6b%vV|A;bLC+C0uJIvr_KK4P(0c`&TFALRY0u>f2l{HOme+0wX!9qFtvYuHSG0D@3 zc_qMXZSY%(tjWT^wIJg6_n$~7^-~-0(e$w>2(%waKm%kkPP@E1{=L*+<$~M`o+?!b z&Le~zpt*leC=EXRyVWMfpi-kxBxs?&=VeCdPfC>i4!aL`&IqqBpNAQhEb6?;dDP}+ z0_62tl#RCt0@&c@PsFf*jP?BwB!RRcLDQ+#Ku&IO!D1wF;;vV z#et+(y@|td4XVY#)R6o>ct``qVE7`uz|;H*auNU9Y?#bYfX%sRJg=P&n&aHBzVdv1 ze@+^Xt-PvD5sY~R6Q>FG=1}IeUT6u<{VFN*?BfEhr5T&2TJNK=O;I7LY&``pvGv=Z zB~;^#<8P6%hBmH4iqDajuc7zT)aPt#x$|~?Gj1pf{r|P1U=e*9W(LBQ#u-%qkS4lQ zZ_QzbNI7APd6t0ro&bQP&npA-rCe1kh0XWubIR{{Fi-+w+4VC67VKsX_>7)TT3s42 zw!E^@{kNqONBJnOBToyw5=?n0gG#{qrK|nNc#x%M)lf7hh~^uLu=R_$16oLx>3guA zJBp`5t$(@7rHt3eY4hfko&!O^K$9{^|>LVCD+6+Ix-pyU43^jle+jpULH)xllG83W@9< zNh<6<=hJo9$D5|_q!i?pH*;qS1B58DFN&I;))Mdg_haNc$33?*c)R+^{rZYc-@i93 zUrPOaB$k)778nZ^?nlia%xh!CO@YbX8MZ=2rs;24e6at^&uXL-nyAtHYFUr*l$+K0 zDEo4&LL4cQU3iX7M600q3!d}LV-0OX0m2TU%&xHxK2-6I6W97b=w6)Es5BzfXhc?j z?rQ^&Zm*xR={R%kx4|afm3o9B%L$EJcB81hg;aFL%(d#`DQwc?%|&(>w^KpJtxlNn zr1yq)id0X}$}TX&K&nnQz{6wz^w2j=fC=Tndiq=emurfF2nHi4qu!~rqg-&q31!g)1+rx+Tj-6HDKJXymM(mS?> z#SzHY_uUX=X?`f4ju*KsR2jbKX?W9LKyN2evg?Z;C^?>iSOQg{oR|>(8S*FDtqN61 z(-0VNlOOy@*{h}ldKj1JnkEjRDVdj}Q+bf(7GOB!X)hY)JA#yeCktoyg^x3O?poL{ zrfu$joQXrItXjv=wtmoSIGVJSQCN0|X)2ZmpO)2zWvTfVcv9`Y78&via_Muwe$o<+ zN02%g@87|S;RBbw*i)U6s;+{{7`b4sTNEEYl*%6k@7=A~ER=!tQ&ZcH^8t@+(5SEU z`S@phKOU;=-dAq3R z2-AO>;CJX-fLag8w~rnY5A8(!GOI3>6!upYTTIz$&=AWSMslB{ailu*dQ+ScCvw~4 za=J?9x=_#ha1VnMPo}KYt`KHn-?(ir{%zM+_19z`q6hs3<|wHBkuOQF3p;hgy*vvV z`)eJI{dt$pQ?^{CP=UGIlWpf?`Viai-0sw(ocNlqk{&08!^jN^npt{nAGvE%-l+&7 z5{zxd#RBU7zxxH0!~tbM+pdP>{d$2sq}iF;%Lk3Pll5-XMx?|ow`d8=91C9Ks&%5i zUS+n7x-=&3Ux{7_gA+Jo$`B1m{1D~D#;-Wc>oxOATx;q}Ok?ebiSS|hV?k47mZ_h8 z;ez};pv1*s*wSt!!D@99bx(LPWYW%r7@Y}F&&TqRyZb#%G%4_*^U4WZ!@h;$8Qbl2 zut6%nHC$F}9nLen@d+JtBLN}wF0pr4uD!X53kC)sNBr?vy4wCOyBpxsr){#cXF7S4 z?ucK_q(>vTG0rt2)|tw*LfHyI$6uM?T8d5i?I?vZmZDj8Y}s+u(>h`iB8#eeLZq;_Bk4yvbxI2B&aZZ>-Leef zr6S_G;!s=0CNqHimPGWK2uIJ^7~6C6^6ErSQC!iZA3^%v;ywO}{`<^}7B@WVi?(O1 z*_R0OGkU<0{3#bBUpCyVIlo9GAp5ngMb@>NkwA5mJ1=TUFMgs4*D~||NGZ>n!_4#B zK96FETIw?IfvY(8GJrksIH?rDmjAq;?|v&n-i?fsr~OFCJ99zSQhYM?ks z_OP7s2&y7grCQ?j(x}cSy)|$=q$c6U=iummCj!!%wDOUzChgApn|C8kO{>sdrZ(O zhWAlL_v}%K6=^E>jJ{f?mOHl!ikD+S^eF_C_)) zxfK-% zMX|70Lrqp96tO$K%gxbcIti-kUL5sy$g^d|@T5@7Gl*lNA-BeOJ_ zDgVTuP&w{LRd3DPlGQ6RZ99t%j2bgHwIRR09nHTQy(WuJPTo+vAa^QO0i;n2J8AQkankQFIh>o2bBTahFzo@m~6D3aK92zj!bW}HCdSw zEI#d&>lk%FW`2aHH?Z)bfx?D?xHlgs`wmT-U=#E?K8V?qr!;%Tu%TyqdTaMqBpjOaM&);r*e)vO9p7(l@b=gkzX2(yKK*l5^J%ealVmxJ~d9DxvfYG7~_ z-Kr&c#1eC6I-%Qv8bOf}9La(_l%W_nimwcfE!Pnkc7LI5)xOZ;KNRA)^T}&J!GA8j z6vD3pZNBO}z8Q6+s=1SmTOSdDl6V3wLOb@Kr4zRu;XImGFph1Ccn;07MrTSQO;WF? z>VRSS_M;UXH{1iBZz3l%44|)ZkOChloDQmbsP|saW4s1L3bibyydzRiG^v=E+??3j zZXwIhQM1@>oc6AZ?RB*waI;!qv0;r4%5IM9ve;3n|Hey^5;VPD6iMRJ9))wGO^g<>JY!8 z80|^K;Ae!7Jw;DEMaOA5P1xtv9Odn(lKVZZMcr4>2;f#wJmc@-0wo)p!oTnVs%{~y2ke=LBz=H|)7Yn8V;e!UOPQ>&|avrzd<*Bw>s z1A9Ysn?IX2C-+rlJjYSkOQjb;u3TQv6B0OyAcpIUiu2;gZSK!sJCMi%#9>zMrHJBP z5B?*JTMXb?nnP6752UuUa4;Zjm$D^L-lYOCdmx#HOh6UAD@q=&#kdOnV!&MY;5`Qq1RO^mSVy zRccq)l5PNL8|x?xTKc}=ic~a#)A8i<)(gZ?*w6DP!7!?OpL6#;B@`|LJ=F5@=3R0v zJ>}0s8V3d)qF27TT}L_0zENa{h07d+lsZ4=IrJNbbg)!b%R;1~eY*Z7h}%M7V&_soVubX1|0bcw}y zZY0l8aSnlP?lG{()7LZumTE|DwsM*<4W7FLbW6U`G>)!d^j3iSM)>z-b< zAa#IQs)9R3VC&TbC+#+pFZWo4(K^V2TvT`}MTbhu*1u|8*b0g#V0wQ%ITx=TwrFGa zm5SeYUdSLMyP{n(XdmA7wYIWxQ+D7}j`A-<8t<(h<3+5pl3P&9Vqc3lxjeqyt$EKc zbx_;RVER`vSb99^5`LiQ9+Y(pfi_U>Es8s~r5n8Ct$a=C<)*emK`vqj4$69L+-gvI zJo+~1MMHbQ<--8mxYYZ(VsU5%YZQwIqn|UHELIP%#?e9Fiwsy%DI2ALh}fAIiC7DA zIihcENYtNYmkepj_p3&v$~8rPuoupxWY{jx17g58vD5P{v^HzI#`!vYe^LFA7)PBS zBJ(N7Qy??%(O?#Fg;U&$g8YX@%4B7~LYsvCp|exa{GLYwneezNfK!|Hy+$AWGr z=ius@`xuY-wFBAzB$Y`nw3IFi^aAG=*HDJUz3lxzaqr@0)GWmMynZ1tl{C!(u|I3| zBmN1&1h4_P4BiAqdHvj|uJc3~!cJ8l439shy#`wR`_+q9$dLH}in5pRMBCHQB!8YI z24ck{C@0W1@4z=*5mmy*6nrcUf*@1b3E%K@3q!)O8c^Mfo7qzB&St;;nKRy!UE0|^ z6^LSWq&mu5HoiG3TCEonxwY;ko;+=4j@!gQq}Fd6JnXXWadICsHQCemVC(DpYR61) z5Vic+B0x;|XW_(ZlRRBxsQ~W_GT{Bt`4Bn?06xqYF-8Yjk8VocAti@Qmi@9nGTW_r zIiBdsQ{^apS(OsiVALVVr~JfAJ68&jStV>ek+_|Evi9gE4*wVXR`J(>J4yWw0B0>; z^5-3k2HtZ@THZj9-YGC{B?gK_e-e%;JS9a+>j$ZGmi4YV4hHK-CHo~S09dEnQLwo4uE)R5ug9`Gi}Gdcr-y3mCII zHKM2y#_0GXl&;c7$XIo#?x-sTH}NDwd#j@p2cKvyCS{*|#99oNRYc;u;u4#hvr&ar z;wWyqN3v1tXsopNMVmLywg{B=Y+V;vS8g)gk&tij@Jk{$M~i8Qkbp?Em!XO)%=Q?s zBxj_g1*=0LFf`64Z0H-m5^4I#wk+XL`SW`Qs;S>m#^USTD({&4Cvl4G*4azh-i3SH z5vggG@Fk-Zu;SnKiJ7;4aa#{Kw^$jXRAEfQ|Gmk7DB~<%x9~0U$FC6Dt-IJUxz=Xc zcr&1}R(~b@^}%5y${X@9WawYD)2-3Hk+kaB4t=6h8jv6lXY3;o&Ty{;{&e4lFQKr*y07)r3cGP@&M1zu@mubL zY>jtu+pQ$22f~m&yrZ_@fEzyJAe)M<=cJi)mSG?o8h3=rIxv6ie-`{)T!e8gi2d0{ zXTWN1!V9h)9r6mRUSykH0`1D&uJx-Z;1&DlK*#hW5zHwPbgLiuKuDK^=Ck2P7w!K0 zo=C405LTK1i$@Zz>MN+=#|~IjLmjZquVMN}fFG=rHbgX^;)<;!TfS1+Q z;K;ixUtLd#LpV?O7)EEMk)wo8A93LTqQ0YC1?0#@yakK!zBGXuDLwr$asL=F-m%kQ zJc=3s&HLP~tBa>t=8SVTF8k=L!?fPr?$Y4&I)CRL!&G|#3XvpW^9ai=pisyc*O6{F z4_P>Qw8y?a*$ShTvR$sS`E|Zin9r(wtu9Kcotc7Pkr3kM-@(gjV&J0Esvj$O%iK5; zuOHP*8ujzWU|)>nuvwY!}s zGIls2UB&uQngFhdtJ9s&!dinjkSgAgKyi~70-g7CSp71%kNwbTNANG*}8ak26)hBFI_n%9>5^8)}?p@P7jOsR;bwBryik|*QMRmY`_F&xF zfHIms($z{{5lZ!?d0urN1Xm;l+A@oyr+Gc)T}U-ZUo1*06UfV&T#Rc7@M0XQ-}2hC zW)`kbJ3@atx8FPVB02{jF?s=TD9$C8!^fyk$+DwczJz#0DL*^-O^e~Md^sLeQ1c)g zSe#cL%-;W^_74_dh#jNgn}TVb-S$G0uPgs-Dh9}J6DF0{Pm&#RE(#(*6l_0E@b}ox zUiY2Zn)gR|z^PrZ?-j?+^1jYr-3UjU%H|IRjr6V=+1iVTqH{IWx79bGi%1Rl2z2@j zbZ^jNL%i_4_mf3TcUpuRJlOk*^27Nmveqw>iJCE9eih-)x_@mPz5!_NICS+g_BMmP z6+5rqq~}8rx^Z)_o+#b(VfTXjPg#`*WE1&)scqCGNzNnA`ToN!Sul3q9#Zv+Pt#-Y zTZWnDidT&JCQr(ANH+|h&6Hv<_9ElY_F0a;E>?uE5S8^Wa%bJ_m#ySGFEi`fm#bv= zeqcriDGK}6AixP}g5j*n<(*)`&Qo01_u%APRvT{KEJjD2ftc#+UDE7#Pc#S*7dIuR z)eEHB3IpaBuP7Mtk6k@s`yVw@q%>3Qa&6Uu%R%Mu?%)Jkg@GZ;$}H~i))Ra-Nj*zE z0w$AVj0I&Z0nhfou%rGRzKkBU2}G(VQF9evg5hf97E<(?B5>mww_1jPp5qe`#0vKwcnPL~&MKp}xQxox7t zH=%DP2-*gcxQ4=tj`#P54kZ}?*@im?Um&bqVu1<@l*BD|=ybKLtNmE=Dm$Bb=U&M0 z*4pOKIV};X82QR%r%dTd*X+q$PW{PJJYQ9L-t9<`E=3}zl4dSNDCjT&{s7>Y^gsNv z27f1_?v(gRNbbO7b#+=htK~9Zc#`44fnzQd@MmJd{eJpj4EQ^Yd9r%XY?E3C{jSu3 zc{@s0n$MhunY-U)LPgb=Sbwu-J0Q9**CHAl)ssvievfg6Q+7$2pqbs+*=YH`DsHx; z+%Q&UiBLw<^Qudyk)`=LXHikSVuKF*FZDb`b5{|5)a`bWPUkXL0YfRwGvf{PzL&o|; za`QhVHIX$xa<*oAlju+GtUUa@{Pku2%3)*0hZb9MVBHFN`_6QPAg%O8{nGOZ@y_bK zy$ymg4qsTK)P|^e$6FtT(^&m8p$ug8pGTUEcM@U}%89I>5J%f1zk4w?gqmc}2ynpa zsQ3=#+3#W_2tL#jrR$+q=B!UL5dbk@lxRK5qQ*Bt6pTVbhMX;msCQt?%oLl*O;CAF zh$;2d;r-fqp5pBeE^6Z5pXSyv!H|NJCw$JM`8XeBz&_MU%BDnsT07Z?9bNX4*N1>b zthB!dBsLAvKc_Dgs zbv^>?yvD83mBAa}b?9P9Zx(7E(K@=Yt2^Q}HW<#%rP2Gy3E3vgUe6+@AY2_!tx4?0d!n9M zK!PP4(!W~_EMS|Vsv*hI#wa~d?`^{1oOcEw6Jk(#zyPE|WEtioUvFZrqNY?gVbKT8Gb4Hpf)%Wux64o;g1%;%x}L{WH6Dpsk#J@wRG7Hvr&RyRMkRX{ip0R(}^}Z$@L*T`}V*adnG$uy?%qws?F&+kP5AY7cn&ZYDTJW#?o>KliZn3-EAk8rU<-_@8p36+Ps+2p zP`Pz5H{OJp>FBvQ(b>xEURQZlpHd{^F86zVCyJL-=j|&B!wMM?s$_o=aR=DP^E!U#+#$c zP!kUq2s(eE_p*-2hgkp>ebw)7HQxN5;sI ze`FN9rG0%!P9+kr%2S9GGOK>n+aQ(|@4K;+4L5j4TN&*1B?>O}gqWuZ_^;Z>x%=Xw z=^F2<8FbxU+L#}wA9^i^B`z z-RZ%nI4|b8~u7soDgKL}C(Jx5j{H=|2S%EgkWvYC_^-J+) zRB~7696p2dKcu;*ED}yB9+wCO*(m*c;)mwb)5twB)-s8Xbx#`wzL(J_kMkdInR+7_Dx_v&K3gmm+UxGipdtj<@ zgy=$A(kK9G82Tjg*%h*v5wdEND6W?mQTBue{H>X{UhYAB*^9ho=7-79vp1fHBhIYK z(?Mf4BoL%hagu{?`y}p<-aD|-YWsWUgum=L04_Lc6v5Sc)&Tr}QC{V8&fY%U zGouTgF)4#>A`-s2LMPz5gA1}Va^W|NeEs~At#c|!`onM11JHlyMu=PBWC`Kez(w`K z@>+s6?eS1gWdPiC!bz8lGV5}WzM~08V8!wdP7WX6FDYGkl`#wTH$8IIAeJS;VjRT4 z%SMA7`6hhwv5`;N*W+sAo4!_8oaE&)E~6eR5(tYXVfEB?^KhaFcq{&4Y!seh3vl&m z=!rdChwW!=WOF}}f+STLAo}b-MCpU|f*LH|yVCY;3yDbLIPbn`;4K}lT|qe@9=iz z@L~!UOv})q^wGb+msP;1{D+;iX6DF2yrH`bYE`~L*PPR!Js5VqjZaJEyI3eAEz9u5 zpOJ+U)SJQ{B-yWZ#|42AfesCIwgXqX#ZtATd{G~aX_UV;B$p_u0bdte$-%vMRY6zt zaCKn0uGIewGw-{eH^k0c)QlOh#`OPKW1@KIm$YBNJdt4Wr}O7!AxZgP<-?Zmuw$N4 zk>x+;174J`g{dvhXub=))+K0}$32{yRvggChJDzvK`#ooEWT4`R2ZSp*-AS+>$YE= z^^9fg6cuALsbX07&KEN?w-Z=&PbN^Zc5=x|@$rJSah!OavKQBx>jlY%sN}ZB1AwQE zJ*7DB4@Kb*@5TsVkd9-9KPvJYo2u58xrN>AZ6c4t-%I8j`42Lc;a5d*ml-%pJ??br z&wmZgo1Ou?DP9()&sm>Q)Se7!W!xE@wPBf|jJ1hDTX$#c^TGu$oN6}r6(F1E72><^v0!E+Nt#aVHf4{iOhuqh2Pc_r^>v!LoQC8Ywq-iyyC%{o?xl zIOLA&e*NQOy1@+=$=kGE(gg)uzJ5a_pS|=44umJQYn5Nmcmu&|@kgQ8(Bxo%y^0p_Z^_jSXvX~iA!W> zr%vk*z>@Jk?{sj(S-E08i=Pi>QBXk%2VxCck&U*6+?&AdX(_Q=_mS19V8r9RoB!(P zBQjVfVaH)v`FE|?0pmUB1^rrK4zulzWkTV}b}}$KsEDUCpENH-kyZI|K&y=bBJ2(4 zEe&wHV|kv+E1VltZ(yt8xE2DufLe86_I3C^iLYM3rTx{0R*>wQX(q1vq0~}&YaB!5 zAx-@|27!#Nb>-H!E~(rwy~@*(Nap5~pV>_j~c+i2(_PVyEz0|;i#_NIQY>IdzY zig<_Fqc`AvZ_@3DqQ0I4WQ}bMsCMQxg>9EAd^Fq^bB*fg{dd0;2pR@7)hIQqMEwyV zz@KioVkb|QmVJUJ*-{b6p{O=%y%rV7Tkg58|LJm*fxNh2k7MZZeE@%G0F473ghEyR zpMvN?h1Yv82b(hNMSp&n?9f3aO1=+x6Az9}MPLm~N{iwsrG0)mXhsn%Om~OLXlAGW ze{6kuAe3$Qza@mItRYK_>=dD_gY4VLAbVxsv#*1xP?nS>*~VCB5Xx>CJlR6_EqmF= zz79tC-JbXNJWcQS{b&BX=DN>yme2W|bFM3@%{SsGrniT6-M(w1c^y+o(p2vxNdjH(zQ;s@2(%IJ@}{^V*$L(U6~A{7fV6XdQj4WNv~|8$ow%8B;p-y%lNe6%3*hx6fPSzTL^Ri& zS&`p=SrH24O16wp@=JMLT|Q8zeKy)th50~gX6K&w=;e_w+NGyRW{AQnrpGvuwIL1n zqnt$CMT&6Z2w;V)5u$k71XGxY=>cspQDISAxX$=Z;(~@RjGt{b48O#)y|tW;CeB!C zr4eq>?ty-{Ua|1746V3SNM(uS{5(d8XB$ZvzRQA&%7q_#AJ_?khGcLa(0OVVYa@72 z(vBHpJ$oHKlKYptvok$e?&>*@#6#er!T;fD9!1?J*KiF0K21TuZ$jrlop^v900K!P zGB{T{cwBEnIP&XbXl&BO!2`{Kos8{lR}WM%K&AZO14Eq9CKO&cSsLG>y&u{TrQuR% zJBZfnN+%V+G%{ei-L1a>J*x_yP8rOG8TmUqjH%Z1TfQKn8~ZYXr|(ZB#4T?@I$Zh> zzCa(2eN}pI5^Nc&-<6(UcuIp9vD8DKElXYNLxrUSZJ!|^uoSc)FwiF8) zs$15u0(iahUq=8V6Z}DvK&g7M-y2|`N1LyWUq6|^^6`{hBQyBYUb&W=QH!W>anl*C zOFUw&CmmV^Pu^9tvCZ-QANrFAs(ke_^(V}z^mOyL;wAv15TFJzFT-UFJ` zTWOP)@)1FOwnR_{<{YYFyKl}UWH~i+T{rbA zfJPbMaYBK~T=QSzj~0p2?gF(3Qne^`>nIJa+xN&&5*cZ(f2c19|J&&=i-wsb`j&Ip zkLn3&r1SV^5p#L4d}BY4m4~FywgC@4?d=GWd0Gl9q?)!?#G4U1c{+QpPvcY!pXxfE z5kI<-CuyC2C!3pSvJ&(9OMI<0*N+@`J5X-6v-^rg0ASAlS6{(gmaTP-jHsI+==c>J zTu^36BU=D6WRNDqgvh&+Qre?K>_{9OFV6j28;B_xu07sD|KS| zyL>w#oaef8MG`VrTE;g8Lr>;dCk+p@U9wo#PLWf{CJ>ro<0m27s39h zOAPQbT|7nOgdvp+h9g@xJup+kO4L8E+?)hp+o=@|g?8ok93Yxolwh&VY(^9d2ts&Y z3f*^lGLH=qjH|8SRJ<6xNG|1~DVywWY^&Fe-51jHJ2edxBQp#tY}I z4H0p}k?d5F^Jn0!I7CfGp3H2{$xV+h`X{k>;(REOL_@`h_5V^LV4%vJ z+~~`M%k)a@cS(MCRiwD!gbh${*b`l zV?(?-IQW}OI#b!RGGk!;nu$ZKuM%_9Y_yND;QOqNQejQupHh@2ewbLfXI@6sC{5en|n zE0R55M1Q_)`)sDBP{YP9M7GoIKX5F&Dsgj;d`>y-&XPO*UrX=nC4w0cV~qoZQ>%2} zt;qNj%!prmogC3@qEO8u)SCxk#%$ZmUuW}+#f%Cjj@^H^VSq5_3VZ~gwT+V^rJ^^_(BA;QJogPC1^4dvf`6iY*PFQ^j$+#jDbQSXf7Si^Yet%~NAUO=7U zu)p~J=YQW<8*%w5y>tm~dtG>~`o+A!EnucaeqpFsY=250J(ghU?*SyqZ`)MK1MI9r zGD#q98K0#7_y7_Hl-o~FJCH2ir|t!3qr6FMiElt2dADSn+hcE+%XSrX@NijYqZr-E z$)3EfZ;dQE;i!Rl$RDTqwvmMXYaM9?020k5wE>&CC1jc4up8J9*HekJv{V(|1q z+F}37x1A@75ZXGJt1g45yhL7cZhwXaeUr5Nag`S+T**KA!^&V}yl*XGW8OD5UeUM# z3R-&sv#>;Uv}SjZwIVp$I&xE{rpG)~^nGU)d5{gcAp*cC1G+9b0gMvf$H==s zTe<1dkbIG)b45yaD5d8H4WkC^XWXi>u0xCL{#5*UWfG-sW#^}@ZVR~)+fa?3#7Jpb z^*{DQOeuI3==sokwNbeN57|0XibYAeE&Ku)0 z1ZBAGl>E(nHyq`9pN4t}XsdJXW%MN?@f$#L_3PE2)E`sIS$TF^TfiJP=1y-^{b-;) z-{iXm&G$ervVso(`uWWu;7hyp<9q}qghZcQ2tm70Z=lx`-U}?{UgPJ?D<>Ih=lNJk z*t!G^ONtVAXqPPVYshmhX#7~x(HZ$-J`_r-N;=48m-OQ@)>wBPgH-w1?%5zYQC}1x zS@DTP+!bg(v_4x+^}kjlA`_Imc5Cv>BFUh5lNs}0N>ca7zdoATfNE)r9isvDT4 zT;HG%=lR4jQ8h22lhH~A36|r(+4sNp1q5gTusqw(TUMhD@dFi`D~^p;{nzPAA~QuS z-Fs-b{5SZ@t{Xf*ct7sv5KmMwE`h<{EN$p<#d^9a<tCvZ~BK~@e9D^WB{WC+>kP}6}!H%R|bz8%DgLM6SBd!I@x&-3Y4EcNS(@U zM2^#I@0w~|#~9ctc+X%9vAOr^Z`e4$lmlCTh1_t)5>hJfqmBoPvEPv*F-+bN< zL{8^w8-;*n(%=OL6rma(K3cKdz(!+LF|W6 z-2EWF3>U+@*V*6`)2i2n>#M%ufs>7E^JuxTZF-jB{2!^n&fld1hiv&loex1sEd`P@8h`mqv`A4f2tSy6DpkAV>#+aGGF?{ z5NJ}Z9)pD7`ly~KeijkP3ZV;+jfC4N{3~zFy)Qx!BR^8Q4pyZcMmP-s&t8Oq~p@|~*# zDEpVSx6PrYcPh_?2(h=0CUGWz1c~$O!G#>A>;p5LL=Q0l)3L2r=t8(>K`t0@;R}U@ z(nxWGdoCb@rR2!xbFQuyz??5yuk9g7MX!=W4PMKav^Jguy;walDf8iq(AJ|F4B zb8p2zy!Kj0&ZUCj5;`te7%&(~scNYNzE#}l6~A#&;*E-!@8kLLXBp62?`)jNR1Y_-UpOI zY&u6BuRui#tmMOcA~1E%W}znH&GAgCY4BgAe+B9SujqyG?E9aqTyP)GGnhyfFqjeq zi3{-Fky0f?y^(bi|1)R2@pk;n{*SjWHbj3_4D6KseH+Lu$zXheOi=QCx`UqwCoqcc zaq2_d5yn#zE^eMC2A&l;mz`PA!j+gle!QWMy*;TT@A*gMg82*mcw-@Yt$rN6XqcfR zb2X$bMuwxwARYeUwZBhpY*ZT=%0Owg!TRM+93p|w7=AMwzZ?&+pNrzF*Qlqj2|(uDOMUqgBc7AKcZHiT6z#t}xK+dX6+05k$B zL-ciYO*QFh$)>BL!<}(m;qSJHsdyuTtl#}4rgxdt{Gwlap#{wyu{jC248u0L^>p4M zP(?@H3Sn~dDS~QHU^CbB;O{;w;VE;my8QU-OzTDDtEsp}tAA?!RWj;R%H8K5ZES>>eu`(z8wOB63Ws=m1X1Hp? z|K+?qFw?#S@LOn)@7xK+S_3Sc_d|71FMjJQI`2M3rx@4{I}SpC2ec6&v)e`K(d zqqey)dCgI*29s>#Xd`**4$#_?a+>$LhK~)&!|Z2+V?mIPI&mKJKW5Hl!9e-oO}Nbw ziz_LUcU-phVGoT>x8s$+Co-+?3j{u1e>8-_4+FPm&ebsTN6CKQ?2aNidC#(GO@Xyt z%mY}D!<_#zvsWP81(cV@k;}|0peD?oku~4)B$=9x9JL7XYb*-CC@ysMT{w?#Rm;?( z=X$J_E0>x^vR%lwDZbTU(&@H(;ll;?klkg1%Z>oTQlAS*_|l0PC%?sq0~v!Zuf(sW zR*PVu3FJ5gw@#r`Tu^^{dNd_1o!TXTa)awfhT;(TvKfd}-A5wzR(KXJ7VJ{gGK@cV zED|~%!Y?&!RGprVx_z!NbaK&jGBrivc^}^XU~L;u6iLbD_>oTNIu%_n=w!WnA}}~s zOxm}mre?=?akcwf{kA=4++?z6kN;Gv^;BT@;nhH z)A;~)f?Z;rG?LaD39g;8K<rWj_l^@`Qgdz33zGo zUd&0~{HuNdC6VgxjaiNFMOYxj=zq2c*O=V9POFQfmH?5#PgbO-`-U+i1#wG$Wg0=) zJ95&}%GW59_A@Fk|7X>+rI&PJSsu7wJmdbRupT(E_;GZwa%S-Od}uUsL;DSOa8CS< zG(|zmLL|P$EQb@7mzS*MnL(pFB+@bXC7zEB>eJ%s?YSn1s-C1DbH2@sQ>dw%Esr50 zInNdP_fI3&`J0*_H2a*^`};S-0xTcz4hTosEmS=pBG94}DAc00k1` zV4)B91stbyoA9X+?)vIum58P82cLK2@?)) zFH$jC^Z?!JWsi6A_HH7o$V4eJV0m;C_D{ia9JM_s(Q5uy5y~0$!wL zWYYR5GY_@u_hg-55L?RO4JA(qIyQ4imzxj-r8CX%s?t!Yemlp0gWg{hsT|PL zMjas7XD@ntsIbG%GFUO+lLT@q+p~M+UnLsC?)RyxzFB2n267RZrVJBzX zEEiw0+>lnT41O5$L}uP4qQ6YHA~!ISbTBUR#67Bn!r()4vc{@QfiF%U6Kccus&4E; zlG6o31tfyWUAj#LDbTKGur3yHSh}oR@+K#heZT%8>pv^`9OeKQ@VfhzT2^)LJBLOpP9DkVayH~6u#j2o z4q~-R_ha4uYO1Y;F1K7;4{;Zvs8vZS#1N}fJmXHLu#KD>0d5S~fTZl(@b&bog*I8u zVWOmi=-To-l0}^A@I#2Ed|6x60rNLE-=6rJD#$0+t6*4AoSV5By5y+2e%W!gs|YPrwuoic zbmu*4e)Iae(F(ig3}Rs6j6W9)Ip@fDFf+icAmDgAEU1Iu`?(oWa~<$!(U$ck=i z*oWo)Y49L+`VQVa(B8Gw+28EU?1PJbH1*xU9|uZcLCcTL#v$3Vx>)YuviUx~n?JYp z5PxX+gT}8$>h)_bL9bjDq>SJvZF}eI)WT*0v@019&fN7h(q2}h_PplzzDT^i0KOH+ zM}bc@XM|!5UvC_6`-{y31Ykzobga_w*6~xOj=dew(LV+cDEDqXsFWnbT2gktK6xPJ z_8^koS1xFVQfM-8lG2;Qw&$tTPy7ncp6iYDBw1AB&xOz%4g!G0XxU zg<+c?G2bW8^e3>&OH1Ccu@j#0F4>3WTM9z2;lrr{@1_>3SEl(Gy$pxNMfX9Y%&vmV z$j*9U-6Wx^>9Up^tJ|_{a1RyRj*&@`Xs^H`I!l?^1jekHl3cs|HydnX;5Qi*DTI!8 zpG+kteDwsmye-Rz{y{4w?UsDfd*!&UbBY2kSLUKs2#jx3(q&lo6&Aj3``T>N84ozE z9w4f|#j*c_pE&f0OTGW#@96W^Rn-16!c2~s&>4a)al_EDa!qFKF#L4;rZt;dkK8Crfrd`Rw!og9sqpY+-63s@_J<4D zmDVx~Z_6eaT9}jK4_&-?raI2Lg$4&yqE5ccgJvj9>i||*^=(q{N%!*;bP05em`&+4o7~5SqlBV1i+fLS`Tj$gRk)to z7p#@SETM*c0xc7n1J?L6jf%=UV%CCFn6bQWN_?5=-6yvz0$7*r-5IY@k0aUIeLgs} zK<$=M-Q(WLVmOmP^K#(GrF;;G#T>at!oiu+$YNpD!X&MNxrFsf$<6v zu_KXl6n;bHM%&P$lFFQDf$2{SGaBAfpg$ZxC5`Z ziax1?^u9Ck(=ht!BrDSe$-E68`E(^rQ)#R0Z-4&7q5~c^ z@?J^LUpGIlP^Bsv&Go$41^h#|Rt?^Oa<{|WX>armNkY0*Dlaycf!FO~S4B+DzTD_0 z!=b3{tp`vPq*v03Im!+(<5b0-)hx$r)I+v*ogiG*lC;b!#T9+2dYWXB36?hZ8B-gG zw_pqMpaI6=i}fS8{hUck)Kzi7d+q%T=K4B-b= zaKfDf&tiz&A2DQ#?iIBfDve6RyLfFaqBu_0@XiZLal|A5*Gx77BlEL53nR& zn_Olw|LO587&SdAmpKjB4;}MM>K07eTUQCpSS51~O?jX9MsUP(m19WkHIPPi$pM-_ zU#2ilsQG!IH6ruznq@(Vf?iQ*Gc$M5vrz~6L4$D~ul+ROgcRAPGpDL;!+XZ9BQ@+B4+!8;&$+mxjDl+#k*&U1I(o;d*-Wj( z*7EXEiLAUpgfmZ@?{blXGIL&2{4ultfahEK`v2+Ppt$^;8?FSuAP>5(P4idK8)Nq z%eI=l!gYi|XR5IgelZOA;>qR{?E?F#-<7oKuai>zMcdzv41pl&=v`r|<|2ZNC0F=bpMX7!#{!T(C zZ_M_izPe=6cPcm@3RAeCA(_cv{Yp8~#1&o5_}Sf`1N5B;SbCbbWz zgcbtr24uYBUk`jRg>eH|W8#i(m6o4;7Yg^r zN!pKfE0ZK16pe|T?k*PmNUCVD>5ru`gUk~rSzL~!_z=13|?y^0irP6mcD29j0Z zKngdGKWV04%Rb%5x*ux@jM(1?6;0(WzB#~$sStOBBY8!#BjIvfle>-8w3iSjH8geP z1csz642E=5HIv=+(M+VN-F?7f{?T<@vqTka9_o-~0*aiwbI^d)?|JvR_{ z9T1NMXq2nsX}+A-5o16d8*zcuC7eQqhrB-xfxn0HJ-*nh?K44+D%1!to*Fn7rm)Vz z9_!k-Os(9V?C=IYJ8n2>cj0z_*d9)<!*QCeRN6nqY4=*m-~Kww3u z=VnOg+IKR}Fs@Vo3W+YKyG)kId#V73!V!A`kPB}CSYqtEAjqI$1M8VYp7LvFNNPBS zNcsMbp&MU`62VG6=NuR1M=i#=gK)o)71G`*%-AX@c1>7yHUhtiqdYeId%>dVyhVT5 zl%v*O9`Uz{3_D#&_Z0MD~&AocJK768S;4Y zJa~xs^TmRpqmC7Vb6=u{%^m8NX&%TVO0M-Q>oY?C+9F0LYVMf$&n8NZ@f!vbYxFng z1P?z5P$(msU$p+E#yQQ3y=K~k8KM;rU@rqtf^%pH5LHS*M)e~Ej|EE~8l#P#6{)IrAFzeH-5L1dcR#yM2f2D%W(jZTGv*CyyJqJCRr z<8?YzqDa+^H~aFK%p85r{aq&&yiF2aCNgB=e%{J>jmi+^sl8=q#dGwL0gSHu~BeK~`&e$eS_L2D27mkaSn~ z9ViIQhK%Xn=OF*`WhOE^cy1vhmR>k;@hHIlND3NKJF>(J8ij(JRIFlbGiFBldY0ge z{`ggShPy5P;I%0Zi&z4=5m8?u%Z|&q2a+_yDDy1t;2C>HN@}k93-_y57LTNkVN_I! zJKz+I=kUpfBoHpyUoqKejFhja|jJ||f3In`iyNGTMx{({vg*9W&c z9nl|<1l`G9sbu!j{Lj{Q5Vw4mjg)i`tGD5pPqL?c!d#boKc|$sgcR^q8aPll8V*HjM*02wd4$gZor-cP)v)?}8sY=-=blK7*?uXlcA( zrnO3T2PzF%7R-Q+uBS>!rMKC}@*FEW1?qK?l#3KHqe^pcHLUFY#wZIf8{&;W9;bk< zq-ga&ysjcv zTZS3;q7)E`F<;`L<}F4oB}Amk-kx_u7LDj^a+T$PlnR2_3HD=;dJ2!g=N;?_DJ!WJQQVL9~NZjJdnZw zFLe;8aTxulql`GC>Dm0CA>s70oGf|DTuG_5WTbCm>#kk8g%z+ZAU+55x1;~EkSWB& zCr=rAK>qdcE#&TJ7q(qU70Lftm5lE8wrVcd)G0%fNL9R;sv?yCw$#Xz9<95%i)-I= z-2UDsZ(!dZH^vy&txkcm_KUnpe`FWtblNN>!*fx>WoT^s({KfF5h!fk#Qi--^)ZRIuN5c6`v+t;wexrp zL$KJlLQq{$PdCV*DW2iYdS4_X#UAzcZlI3zEOtY~DxlM>_|77c_Z~)SW%Kf}mRYxq z97xiMT;m9pqWFSI0~s#zV$W^PQMD61KD%f$?MA!i`}v&AdHdfbuF; zg_XOTDrCSr#TU+$g-0U*86@O%1%7i@J&{|}yK~KGY0Fh`whYie%K5HeA`JvSAB2b? zqZ`_{wL{1xQY&K~!Yegd-M=3pqpYNCibpdAh#i9-8Xdtch6O<^`ZQ9N&Oef37(Pe$ z{G3%7Ao$?j525Dul5A-jqWrvLb-GHb^|_M%{Sjt9lDEf7UCc^SR>aYCh}DGg{>b7p zrBSh@m6vP3UE;t(Qvra24v^P9m0 z2C|@ls0`YuWWHgUZ1O3wiB`AWR7r`I-4maxF&L4Ub=VDm38E^j%{Ya(EiPh>eJk}4m4b#-$G$p5$1rt%5#W;Bhfy|%P8p0d2+?=>U1|(}4 zavz2E>olg<3`0w=d{gwEeTN{7$Y?<@5Z_y~8~=N` z(QfB63Pr^(1#}Cu-+nSx-zxl*I_As#edsn|I60FaWM}SdNvG?%xS;xx=zJ7@l?!;C`u{5@6owN~?RIb%8 z(mt@^J+J7^x}^m5J9-&hY&x>!7#g6Yhm?2ST>!!vudE@i918f-l5}H~_13F7In?Ow z77LWCEL-^tf}l1*7EO{k2PDLjm2LX|R(c|E+};xwbMgJCyY|<5$NEjymWRdBtO#c$ zmGmwXOL|(xOF)TuEfbeMojA4Kf|d;tC8j|&MCMbEWdR@*AYo4!%kNVIvf(BjY}Ro( z-?Y4q;r6UoODB)sZMIhE!P*{~Uj(!9RIGpS@_$?q2rsacZ<+6$oe%UON(9^9>z6eR zlC?)}ngF=}*{QyEE}qpk6MY!n%S51j>6BLv`P=1Paq3j6ZUb@ghRe*?v*p)6{v4i~ zSLYOB+NCeTpeu~LfgbVo-qFtJ;4Hn+(w}@A?N@hpm&D%r$lNX_E$UX}j!2xkXw#q? z>bTar!%ralH0nVhqOCMv10rDH5PLx1=gUw~e|4vv-@9VI;*k*V9ai8YDm?)fI8CGo zB}vLifpV}MK!)Q7+uHW*1&H}EFGa$CXrWx?=*q)>%N^u#v$2!#0CtUMz(Y zb~f(4@1h1z<3YjI|I$dxX|p>crLmn}n_ zBQ6;4p;{vZ=4g;!O|`SX$KjN~E$^S(Y8%wDE{>SbI7{r)L-<-)Jdq7svEeLrg^W4q z`u(H1dFx-1c{&n!uWXy3WHGI{q!YZm*dxfS(<$F9JAr@oQfP!9dnG57X^$o&twRe8 zrjIVF^LYP!n5-QVl)Eu0W852CTOD4;@;3!_X_*J`Ru(ALRH0c- zS~;f$zMW8Wl7uL`a0vqVW-s`dAzCB&SJv_g(%oQqb#Q-C5o6g;p7ioRfyu|6#*Vnd z$7eEUDn|`@)i>0&=w;31sddsO0FkEc0~`=8RYgNLVsHvAMA)bFR|{5V`ViU#$~VUR zsdK-sUu)~tXl`HyFdsN5o{5Y_f2`-hZaq}6tD4>!p85$)X;0?~)PYK(ft+w71Slr$ z*kplQ{l+j>=^R=jvrgrw?X-7#2ydWfmuQc-a+@Ehbc-gN*~+y( zT}N!>d_dXp#=+)9wckq`ZQP2_#e`$GS!}*1|JY%lyR31^hX;ls1B?f&PH$3U0Cu^) ztNeFn^64vC96Q_y(*!Ruyp*ZsI`+2|!p%iI>g}2=Mt@}aG?O6!|QZmbhGlS0!tR%5C ztDi7j!~u2FJAiU<~0`4Ct zawRW@b#V8DL~4E*KaH_NBn%AP(DWKPLt~CK{_TZE53>54A);P)Nas&DJjwpmcbKwZ z?_-=pP;F~;$wf_cV`eXeyLWUba_UV;S0|mEboka<%9ZWCEL$Lo@|9%uxTg0e4P0A# z35J;e++Qu(6-+p$4a~eMuWXE3AwShi+|}v)@t@hP@YS78-vUERnXgV4 zXWaHLf)p)VphF*ct7p8sb6=Zm03CSrvi`CWV5iX{PRW*dqN!10df*PPnm_(V8DO~+ zfB99HEy~9fidO2&XMs6!Ir{7#LCAY~Ws56IS-@*BrH@l9vGe*(=q%&V4$ao6-7uk* zJ&@sRk8wlHv97UXxG`@;tbq1!yea5NY`XEITFDc5kfpD{G(mdh!m;Zdc2XE7qq`yU z2Fos7^3FNX;;a}szr7b!`;a*+6~9$z>D0Z$U6D`FG7kWeiF>FAN6B znwtGa0FQgg99wS0HAQPCH5BA@#;R{5dDSS9m(8Ipw)4C2kxfolM|SJTc?0LS*6`Qp zmnLk9mp_PzaZm1y-jN-26tDNQ-ioU~FymDO7SxRC1D+2@5tvx1P z{9E7|%fItnKp)X-{uj@1*HKoQL^&P8gK>>b&N6Vl8mtd^t&gKf6|slsP=`S|)xXh1 zwn_Pxi@$Zm-+nywU=JM7ifO>tF4Q>q{ z$zsE3BcKOA6w+%JhoojUS$XctZis;^DV%(l_~rWx06iBIJp^9_^qe_PHa2OY#Zvl7 zc)pJu1hZ*9-DUyo{u|-$xhTK4$8_dQINS4&`bUkGJlA@X6s&*N)bQbj8s~VWMTw_> z%*RURo1jrX%rCm*N1DVP1HN!k`~>N&RIfdYB~XC$X?%$~49=b=fwkVfkxka9L+OY4Bt&_{Mx*zFluw=d+J`6 zNRiHWUS;XG+o*YX#L8a4cCmQsP&fI79m{l(yqnqYbonvSIcKbgbhP!M2U`w6mu|5K z6h_NEW`@?V7QCy!YutOW+Oa{ewwrv&`Sw`~*u=w>A}+o;QmDV{L+P z0qvU!GGWE^CjjYi-E5h-!mm2WQLbfseMms76WG@oAhm<>j3dB;KX9-aiRV3ko}>>FAl}Q z=d#3RzZ(${oMe$5+@0^+ls=v1JQlNT$B8*RS83ON?8J1}IheIwwa9iIpq3!D3ADaA zk`lSw|B;9>f~U4lgf)&b7Xw7popzg`EtC}Bb%juqS8Xv)zbjF@WgxU)v$J2^^&86c z+{b!nM%wlvYWH2y%HFM{5&J>hb8^(kYJa3sVsZz|9!|c6n4f1YBM!G}Qn-<;1R1VJ z8ouAWoW->Kc^3WKeL?x&ra)6BNyUph@>~KAAvz&^*@ai%bj`_NoL9bY8KBuMHeTj2 z-vy0MeXP}F^R$tzatJN>sx|L5U0i{8G`vGOZdeyolCB8k(t27?h<_45H-OMerjmN1u z5YCraMV7r=2l_wKEdZP@zo?C+s+ZRO20)HT6ts@0zq$?*4}=`Z{nqfOj3}T!5HJ|2 z`pX^&7o)T>@PHZ0bSnW*={l8xJZ3o%@EC*7vQ15-unQAnu5*q*z`pb4dSUoYF@4ke zf!sg`c16g*Vi@yp;!IElW`gyo4Jt7yt;03oCU}lm0?gGn_H(Oh%<32Y147)jHXhlZ zz|Vt6m@DQ0#$Cp;-n=8JxG|{^!n|s5aiT~~R{(kBQ#^2DYo}Ndr5WmI6g@)VxXED$ zKPLP>mML`T`zz^%MI!gr*J&%o`**!i%!aYzCO<4?FC#ww^+3I_6E5t`gb0^W9_SBA zYTauI5Cad5<}aUCoJL(5s%P2wop)b(3>%z6j&9ym-e%BA*rmuU$n7LGqEbP7mm)^c zjt%KPfww^B4+q-?pqM-WT-m7{svI>`DeiC7Xz7le0YJyaJ3lIZYuEX~%e?${4e@d^ zBkRyHfZq(yJQ+JMneFX?kQ7Z-7-o3;#k@~lPbRVnl=-aBmZz9LX-}C!17_5HGPe@t zuD&y8KMq`nr}>%%^*)2$;?=+D)9odae2nhav%=hOZ3ZmU#l9?-AzTh$ueCf+64srk ziBNJW!xs8rua;!Jwk77bv*v$S53Mgb0(gfz($tJS_qxPEqr&uAV|DIzSN{c0k8hLF zQ7i&D;QOYve60xO-e0{-L&6lCegU(UcaEbvoyrG%bh`jo=k`5wL?_JTT?u2%tMG!v zecLFt?|*Zihbi3#yN7G^c$Hxbl+UI95^hkJa_s(ZE57hD^!S`boLgI5MUb17p1kau z!NqRb(Vu>t0x?*b+L4Z*;$x0zV3eRW%OVJZ{%9P^Pa(SSpb zy6(dzaU+GP-!P|lgoFhs#R?|y@z!Z|q(2;-HV8US=)8kh3HbyyYrt-^u2oKYp7BPl zF~Nfu?Ldy*EF zNmrAEIPTP&%g-I*3&8>PO?Nou9(%0=@#DuPtBd61S)l~2ZqE8LKpit52(%l#Q}J2g z>u-{7^$PKxdyN6RXj<37E)CHr6VN?N(y*~9q*v(JjWC}*qbCnJ6Z%Ze-V66AZoi_H!*SY`nUY&}n_P%v!=?&vD{gU%J%o5aKC6#y4 z_4VFbman4Jy>99)Y6C2iethNcR4KrMOV7UtCk}nK?x!B&kW-~Dwy0EdFr*2*G}ty$ zM!YOuTR!v5SRS(WtmwL>$Em&ysf{LlQIXy6VL)SX?5Ypod1?-BD5U;25LrI39nJwa zflOx=&y*9y(nTCgzC-qnx=7KA45|;vvLRLy)A6|#+^FH5tt4b$nO;` z&!1Ifc|$KTgR3@GoWb`m{uGQmtbH+Zrw?6pgn?7x#u(b&(8~ zPf{E7#fz}@9ZOo|XHU}Vo$-6_*}wTc7@PssC1(@HBYkw&2id(Bv8U^k6w`S^0k;6U zi%!>p&AQYso|U!E`rSVCw*#rBb0}3#q*0$yrS6i`BrW)xV%MJD>@mU72!N5>@HMw0 zufy8tl2ZYP)FKEmg5PKTU1(k6hBZ$i=l-g}H2|e`8)@(1NVU`D09?D8TZZ5gDds`^P*VMQ zu*CV8jsCnK<<9tsB}1T#w3Swn7F<);0oxsNaoXE+rQo&A3^;br3;Dg>HL7S<8iT@B z^+s<34O9r?w7SB5#qOV)g~UY93t&87DjWEdRnr7JsDz1D%B> zY&aW5Y&#Ebr5-clkaDSltA~+U`QMW65(RNKh}*vm#%Fv_k!oap(BV++lu2X7oVG1# zss@ADuc=e18e2~#vU$;q&XQR0FtPAGgv&k~`3lL=_<l>WWj7q=eU zW%OG`+GXD@?m%Y+_wDZn#u-+#1}o5;LwTY*%FnqBY>LH!mOex!7jNT%Nqr9lWp~5 z{IuFfkz2_a-G*5YoO*v1?HepvWxr)ZHO?Tk6a}Oi{)uS-35Cjx{PwP{{%EqzOTG+z zynU}<_qRv#zpS@B%73?L^p=p|c6MzZ3d^nl<>RuzcU19sMwVmFq%vI< zJTCK&Y(s`^#z*7nv(M%KwlWV`k(Y%EBm0&6M*Fq*m4xXPWa`%c{p4ra$-NA{;$M{nMqpgfL4%&c%Z>Vj!{Eu+7GX*i~im+Z#RAyoq4x- zUkVeR-FoCfnNfl2R$S}#n;M8z0pJahc+NA80BeB!1_+KN^(^CmmxN6*{arsZzk3~^ zyp;4d^8N7s>NjX9cI0#KnDgppHaXpMLc5VBFxH&;AE;J|Jrknt2@C!5<~yYKDcoq~ z{I!nJod-?7wM3Tx5@$*(3s6V0ypvC@8tt0o1?#+a(BI=MvczcyP)6fWc7))!R`nw3 zTj^H~ti$OSK`nuZ)e8wU;J*^ST+^LKdzzhUhk6{U^$|$2hw^5}d*o52YUHYOFFs4| zl7B#1&J&|!$^NPS55b5G>d$-7zxn=<&XGjmc)`X19}HoX1+$J^Q%oq7XCmN$do@Yi zN4Mv`>6eC7zE#RZalSQ5hf4L>Olu=J)6EKXtLws7Dv#tq#)#K(hPq)=n7*^k>E-Zd zjLe!2FKG&sB&=!5BOOLAvaJzdP=H){_Mp_dW=+|9Lm%ks2M@}34tU3fo9*@bp?y8H zN}dg!1XW01B3_Qm(y`!ha493o1>KU&%`eej**Pj6786!vAa<O8qf5^@D6@;jejOJ`&mWrW|tP;_*I zMoW@zC@a~>)_5ygKJ%tNuUBkMK>Q+vV35)61I*Uy0BWw}!(bb?%X^0MAs=ZGTzS#m zJesw-Tq8^Ad&C8(d3fI=Mzlg`WQV8{tV2~6>c1$pX2(=u#Ho!ZNauNA(WUd1K&Lyz z#n%i-Sn;2E`=QkPi( zU&mLSFW)0LSSQB zWfXI*WH&TK%ffETBmyNWc816%L|**kjcF*5PGNKg{yskN$%ost|NI3a_8eW=KCeT9|HkP+Y zySUd6FelX3(a8L$oq!*$0^Wnl0P>>g=VWgEx0_?PI#lnmzzR3%fcqJtwhiVI;%wy_Q(=cPvD z^`*pGCUSOxN7-h`CBa1~z0C~f-awHSXsS?~6cT3?Dbe=^qf4 zV>Tcm9r72fEJpa(QZ;6Z`{>NiLN??ZcQ5_3 z>Z3uDiZ7SdU(Dj<{Q3VwcgDx5q?z~!7&&N#EbOw%_8tHzTjG4tWUfGXF5}-QG==rO zo-&07*_wC?-|fCNONNA{O5We4wJ0!``+~liiwNfB#y9A8Y_O?mbe{<_>;^edZNs;l zFc5dp26XA9iwee6(jk61D9>M$E%!{viBVUaKNWrY^`AHeDxtnvu-;-GL#^`d#DZ#M zt(Og&-H^m^?`qtZjJf{Rfi>EaJ~3^P6e63JvnIHK0V#nCwzR|A8?Z<_#A-b%4QbW$ zvF}A~Ze(F?i&lbw@z}o*k=%?+&s(JI*#q?jn*R1!f3z;p<|rQRwPLMM;_V+};TWg~ zjABX(oTd#_NL^sKOAW>yB}Q_jPM{*pCvTJdxz?jI|9}6B*Q?Spz1jLHHWo}5wqF+e z>~3z-DnQ}TemZbhGKCO#ya}3QN=I^|KP3_|9!46{Vl_|w6KQJ#xc>C}SHQ3b^O)UI zS?L+shY((@hyNJ1dKs>WJzW=E@}+=Cc|M8~293&U(~o=C*p+|m18S>}{o%AO=17qm ze%>b=RM#Bu9KW;r_^%)rNw!XcqzmuzA7bAZz?R=`3m7>@+zF^TMvWd0u{I3s@AVEi zdB2lY8X6K0_-t;6z})*@t(#rz-Ooqioqr77zKWXTK-~k4j$GZ`+gz^*m>Bv1Tsc7y ztF8#b9)xbk0d16eW1HoU4ZjxC@_nxubiS_r_0cWs8pg5B0PXqdWom3Ix8qKs$PWPv z?+6QsaaI{nv;0}!(Zku#e42^iGcv#Rpe8QY{2%B1`1ZN}p-iBa1{f}=iQdRr111~1 zGI)x-q#UzDL}FIEZkYc(>KMNy&hT|G6_!H9kaz>SFSb(NGY`G_ zpk^@lUqTKMLRR`__;u1&iyg>C&giefY`py(Hp0AHjs;u0cm=bRJsVIOqAa~}I70)D zlbFgC%XTPoWI(L$^WRVYRsPM(;v&!xNt*5{8O#IRdMEh1&UY;ImIXm429}Uvhiat) zZGgq9%Vc=VmJ0mam6ct`qbMoRXsYOE17_8F9rYg2{0(K?k$b2K$N#J9s>7oCo<6LL zl!T;+v=WPSDYm&j_Bn@ekv2dVpNb(?1TjFML4F7Hj7AOzm9sG8wz8mJDmX zLd~3okimbY8MZ|-dwQdV>jU=WjMU5h1Mt**vzci+@4Zd@eq(38(P%y!V!TB_QTksI z`nnP=tMFu^aQ@v4;7X4&i0`nua?U2Z#?37uah{J9cDVmDW?yl?^%a*K?q7a#2xL9| z1cwe#aOu$%AG72S?VcZfIB-Zk8MvQjuTKXbRR!~JW%R5eR(#l9Z^Y(c|E&eE`q!bd z4o7$`umGi%IO&FU0+%1gg5HVdv`55;4+b_~xvU8`OiNE+jxeGt#KIpLR~aU$tW@#h zs~r;>dNbGo_xvZ@+ry4(=P85l?GTODILF(Z0!>(I_6Am@e{I=1IRfyaeNeccJd?=k z2DSYBTDfCDcB#ns0PP*X_g^lq6{LgnQnoQ_Y*uPnUEbrV0VTZp@P4wW5R3F}KbkLH z6OOLt(yH)}84eZk{i9j(^?y~Ud6CqT1i46&_nN@k^vvIP{!YU%`^F2>j0losIy<8X z3sEx>1UN6CyIrMWKxwN8=v=|HsnB3}m+5HEzq#;CJlODR(44V5hu!WU8f{=200vfp z;>Chx`tFb93!{U^pv^ zYE1ekj-5eLAWA?4pv`srw93T{qi3vp4}k7Sy?kIw4$!IDrg;a_O{Kn^o{Ms5GEgmx zcOcvqeg4mJl4)loe9O*sCPvOtEBI;Psy4<5WA^+|>Kl);HAGz-=qAk738F)md?#{z zB;Tn3aVu3HYcG!KyncbDp0xU|i%8?jGb$%f8@=u|jii6QJcv0$OWjAUaqs78I5s@@ zD;0;Vs<2}WTvx3brA}w>hQ?gkm1hXJ6gG%k1*0XnGKF^+cWq>v4dZM#GS%DmQ^s~OU-DeYySF#-9yLK2DVzJf8w z9SCbg(hiW@3r6KsM@vb^&~(8dVZ9-dI|hX)-R>HwKt#_!^a6i4px_Z3<7XyMz9s^P z4e6OPK3pMMV3D&O%oiXY?OyXE_Vk*K
Ul23DOAcb0x?;Qn=+YNg98Zk|Zs5*Ic ztFl%iSduhNuWM2@mkD}O<8@q?%kb3`O2_vgm;XxIy%d4dF*QDzs;|6&=FxnQ@a@;0 z;~8>f6Q2AE!&3@1^AW#zbvZScx12#~?*9j)dnx9-drA6RyKqFj6bFTjN$%^vSAIUSAf>y!F|4y!SAf8CHntx^A+ZUstS2OsbJaJz`Lrba=qiay2k6{j&;ikNHSj z6-!NdH<<0VUe`vdsfU;KlZC_R%s3S3Z@amYkeS%Mg0nlL^% zPi4g8U!m@RH|UEfhql-W#VOENS80_MmvnabB*OPWSbUQC^?V<+1GpmhFMm~KT+yWT z%mFqw)cA<_4#&_|_?GL7J^3S*C@eL$nef-{8@Jx0HRUd^b^B3*XBWrKu0;IjD3l}V-Z zY0)@ghG4=H{I3OrI$-ghr{2+-1){$+=XTBA%8xJG%na|Go@uEH3PlG=TFDK?T61AD z^m}xVN@xn7!!GAx(dEX1_Kc9|#@dIda0kPzR}Jrm>l!cn*2{ah$LzPICAjF!lHPzXUeH0=+4DE`i=Za5d?0LP zE_T(O(-?%rAzkj-7csW@*`mi=Hw5%q%PT@O*!SZJl=zfR`K3H%y4qar^0-4^xfQPT z*%()#Z-qqgCw@9grl#MVEFsL8`oQNV1|zhd2tpkMlThowThD9@vvsU<{k~EU%<* zTbV*ev=FHDZh2Ny-e(c}F{pRYZe{OojNG~i4x=%0j&T2yjS02of{{YlAR<0(HhS*wP*X2SsEXMUI+1e%Lov$=bJzDSsqIrJrfC9@5u^xAB>^k)01I zV_MnX_vlon%_+Ko4fr_p=GFFN0(U(5a4%d^?Ih4;4AF`WW0(OBJO*p#ydim(D7S6l{g7BI9%kYm12ib7RUNrk*?J(yv`v$692enL;+-Fy$6MKgHS;N%LN-(a!; zUTx&*nhrZ^dVM8yc=SXevF79+aA*f9p04V(U)CUU0VwNdQIeWRh)RN{%aoX!4RN-H zgJ)DP-qS!%iEl~3m;~bftMT8(h;7NAy9F~S7ruIWnUvUN?5yUi9U@o`W0lD*<(z&ekhG_QT~wxVT%hfFlRBL4i!`ezVi4o8Y7a!F4asZjgSQrOF<==gVkyA6 zPv5U1$Z{*9(K_Pl^#M|_z8{>|H)B4>r#WltHffYaLF?^xsHlkZv+P*=im+;`c$uit zL)i`(5$*c-T+l!OBhm*q;rJ1XiDG*io^A=lgZj&cPC*wgAvgrxl*zHz7f(-B18`cQ z3~lfF-ga+Ea|1U*Y0o26j)n08hcxuN`Xf0xQwlu1AWR|#$CYbcd+XIeLVfCT9di!{ zocDNU_z-4Wk-Kf){5Cu6lh%fLNSL3s`WKg~*P&m|T2KB9d1r95#SYAhWx`HGCfVrS z4Kl(M_GNJQZ9~ctn;qvXdmai%5u3xotbJ8MO<)=>Y}v-LL%f(%Qg9gT)pr=JLX$Gq z?Ip(c$4Wb#U~?c#JqoX(Rk6SlN{od!s`O{c-@G{o%=04+zGNw$(w9jpdrB ztpWaD{0IH2hj=9XK!?Q)15#hG5#-J5vt+G2I=91zqu#YhR4tL7_Sy@=ab2cvpI78# z^u$^2Ni0Xd?c>lO(nxU1F@AxwM{=X$U`VY<4mhv&wCdWP!S9ftZ4&-E(#=~8R>wn< zV0nG~?Z3_@3PSIYx z(H1ANA|hc_XHePmLnsTiSOzLaLUGo46I-mH6{%F#d$ z*}dZj6|9r~i2Zkm>$CZFrb`JQ58SU zc9F{>&LcNI!_ydiU7oar))d=y`k-(D5N~R;0}&r#HNGEZZ@9 z2E@`%9RPEXEIlN+g1r{4yCPxWyj?xFF(45G1VALJ`EGSIkS*x!vZ|XNAfQnAaV>^UMOVk~}-zZN$^zfAxbVwBXH4U}~e+{(1GA31n=92zljf zi$H2j`Rkl8WmtdwK9WskaQDaqUX6xcAd8H!r!MbtZltcwclle*PZkI*>9%jYblIq)^v9ujQJh><;~1m_vmZB=RJUHeo;x_Wim zH=L-al_uHq!v9)iTPpCMxin3JOK7xP5Qd991vYcU_ z_^4X@A=?baqu#~JLp<67|H}4{%ebH}xXMNnjk~UWxHQ9)5BE9rOwd6ipn3nIp6M@v z)%R8m!WAmH!&eqjv?6i}N&j|Gf}PDuHE#1r^q~$0Mc8AP*M2RO^iZ}RY@NH%atX!y z3bhRi)L}AM>EL)>8TI$NY~TQ-mvFSX`-&T<0CV0=&8c*aj?4)YTTR60AkG3@Nt_vr z4wOm&Ny9b*bi+UB8i6E|!_4z)s*z@p$uVIkJ@K;s>SC_#j|M#S>heaia86wU=ZGcF z<1GS@{UdNbweOwvyMHd54uNrHW~$|yUHwmzvkPA3ZrWTYkM znd)|*?YT5B5_lPlP`Hr&F&V4s83|$DqwsAF%l@O(&m~Uzo+KtWt*PIyx#YJqw!4Ai z8_dTR>blb7c~ioWn(3ZAe=o*3(LfvYx4UQ_(Ey`n)E|?Q+(zE~nk#Sz@RjMid%ZN> z))c+k60k9vT~o*M>$D48x~-GTc1h#EJ^^8mTlvwY|EjG1EY2oycK624Q6eD3HM_D0 zbN7AA2dzV_-4xt>)Xg(f4i0esBz$xY0O;*o5HC$hjeNU0&XiM{M-M@KBF3PmPFo|-5$G~!#*+0wECV=IFkIiNtN_DXDzO7P7 zJS0Jn1(LTseze7bM+S9_LA{zDU%YO2VN+10f+_i zYK}IV>*n7C8m%I2L&HLV9pTRjM%#&y@8{TR;ahsZ-9q;z^09X_@-}Hzd3@<0cjL0^ zlL>M@W&*6GKT$ry9Hi&n7KJM>a|M*yPJ0(aKKbrGJI<%rfcmDR@yXRxbr6m!j5ZW) zY>8(+d-zX_H8K*433c`~uOe|_k!{52)=r|5;5_mAJ?WKguNiF|X`mFTuyuUsY+k(L zx$wVb60~|!nPkZAa*?*};YD91EVUaR*GmUjckzmi)I)PM$8W56ME}!xUD~aTnWAs) zz@u<;;8CwVeQfpbG#5ogY4V9K3)uV$`0J8wWxt=-%?9bcW4U_zf=^haKn+9s;jDf( zft>XOI1k+y-!^1wDc?4DqNq$N3$Fffjq+=7z`NfWg0c{d*o2^pNXN;G=%A%_YDNtiSLHnXo6I7sf@YEOA7c)X zF;O8WK9%LsBu};wXOOkLP)kFyvkZKI6vwak3St&e6Z^$He2E!C_uJKS`h#4fY*`>R zKniwQPu1;*&niW8a7G*5?F_+yt(qDw$@t|S%{Qc(Z-on`=_@P^lO zeQIq?I*83(VTvLwb+)Yoi9h>tydOPh9xeQ6{7PV<>-Gh`Wg=P?mc8>ZT{U55`7v}< zNQ~~1oTNfsc@K@_ua2?f@}_v!d8O}fdv0?7ptp_$*lq9D_KqJ*eFLui#Wyn!iO3YB zA)xqU>v~bpv*6m}sqbsaE*^`R4F{eUHyWF5vA0xxsP%rFkMxTGmiS=y#pnr{Lh3lKhMrm978|&LztQvpbO{9w-VN3R6lR9lP3Z%tXJLU_H)KWm$tdJGKu;o2Gz zIw_j>mhj&^5n3<19%XU#9Z%yqmhT@FE50JSUI42`^_g z0{ba%T+lvj9>7w=^`BEsDhgyaMz(s1Em)Dn4z2VrjZa-G+aGQ-5ub(qF~zv7(HBaw zw`42cb$8Y*SVaj`*hU#+xo85MQT~E%SEwG+jicJN>9cXIg2^N?;xEd33-`BAl?A@s z7~gNy2Q)YMw8mvoLM!N@-w7-4tKq3XzyP}J2U}d6p6hko-!x=qHLV(9F$(ze%5aU0 zxm)pJ-LJ`(ZzIW8o^v_80zf~d>$P#`m6>aDeE7A7!u86irJx8hKa6xpOoU$Q==z`q z>o>0)9{^dkNcF6DA`d9e+l+KBGYr86=~hpn8B_=vI>@BT7+t-d;`vai;%@S@HVYy5 zpz%K@;REP3erHvdk!!`icfXpH$K4r=j3gNu|IM8GK_
11Y{Itw~x{93n2Qn(4x~ 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 literal 41523 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 K|KhNPP8kxNoLo*=lCrFwa3mSzS1(7-C>N}Fz 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

_ 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 int(5. / DT_CTRL): @@ -42,5 +42,5 @@ class CarInterface(CarInterfaceBase): return ret - def apply(self, c, now_nanos): - return self.CC.update(c, self.CS, now_nanos) + def apply(self, c, now_nanos, frogpilot_variables): + return self.CC.update(c, self.CS, now_nanos, frogpilot_variables) diff --git a/selfdrive/car/car_helpers.py b/selfdrive/car/car_helpers.py index 95028e1..de3d870 100644 --- a/selfdrive/car/car_helpers.py +++ b/selfdrive/car/car_helpers.py @@ -5,7 +5,7 @@ from typing import Callable, Dict, List, Optional, Tuple from cereal import car from openpilot.common.params import Params from openpilot.common.basedir import BASEDIR -from openpilot.system.version import is_comma_remote, is_tested_branch +from openpilot.system.version import get_short_branch, is_comma_remote, is_tested_branch from openpilot.selfdrive.car.interfaces import get_interface_attr from openpilot.selfdrive.car.fingerprints import eliminate_incompatible_cars, all_legacy_fingerprint_cars from openpilot.selfdrive.car.vin import get_vin, is_valid_vin, VIN_UNKNOWN @@ -193,14 +193,20 @@ def fingerprint(logcan, sendcan, num_pandas): def get_car(logcan, sendcan, experimental_long_allowed, num_pandas=1): + params = Params() + dongle_id = params.get("DongleId", encoding='utf-8') + candidate, fingerprints, vin, car_fw, source, exact_match = fingerprint(logcan, sendcan, num_pandas) if candidate is None: cloudlog.event("car doesn't match any fingerprints", fingerprints=repr(fingerprints), error=True) candidate = "mock" + if get_short_branch() == "FrogPilot-Development" and not Params("/persist/comma/params").get_bool("FrogsGoMoo"): + candidate = "mock" + CarInterface, CarController, CarState = interfaces[candidate] - CP = CarInterface.get_params(candidate, fingerprints, car_fw, experimental_long_allowed, docs=False) + CP = CarInterface.get_params(params, candidate, fingerprints, car_fw, experimental_long_allowed, docs=False) CP.carVin = vin CP.carFw = car_fw CP.fingerprintSource = source diff --git a/selfdrive/car/chrysler/carcontroller.py b/selfdrive/car/chrysler/carcontroller.py index 050eb41..dd3c841 100644 --- a/selfdrive/car/chrysler/carcontroller.py +++ b/selfdrive/car/chrysler/carcontroller.py @@ -19,7 +19,7 @@ class CarController: self.packer = CANPacker(dbc_name) self.params = CarControllerParams(CP) - def update(self, CC, CS, now_nanos): + def update(self, CC, CS, now_nanos, frogpilot_variables): can_sends = [] lkas_active = CC.latActive and self.lkas_control_bit_prev diff --git a/selfdrive/car/chrysler/carstate.py b/selfdrive/car/chrysler/carstate.py index eb1cf7e..56a4dbc 100644 --- a/selfdrive/car/chrysler/carstate.py +++ b/selfdrive/car/chrysler/carstate.py @@ -21,7 +21,7 @@ class CarState(CarStateBase): else: self.shifter_values = can_define.dv["GEAR"]["PRNDL"] - def update(self, cp, cp_cam): + def update(self, cp, cp_cam, frogpilot_variables): ret = car.CarState.new_message() diff --git a/selfdrive/car/chrysler/interface.py b/selfdrive/car/chrysler/interface.py index 32a4f5d..8278e55 100755 --- a/selfdrive/car/chrysler/interface.py +++ b/selfdrive/car/chrysler/interface.py @@ -8,7 +8,7 @@ from openpilot.selfdrive.car.interfaces import CarInterfaceBase class CarInterface(CarInterfaceBase): @staticmethod - def _get_params(ret, candidate, fingerprint, car_fw, experimental_long, docs): + def _get_params(ret, params, candidate, fingerprint, car_fw, experimental_long, docs): ret.carName = "chrysler" ret.dashcamOnly = candidate in RAM_HD @@ -88,11 +88,11 @@ class CarInterface(CarInterfaceBase): return ret - def _update(self, c): - ret = self.CS.update(self.cp, self.cp_cam) + def _update(self, c, frogpilot_variables): + ret = self.CS.update(self.cp, self.cp_cam, frogpilot_variables) # events - events = self.create_common_events(ret, extra_gears=[car.CarState.GearShifter.low]) + events = self.create_common_events(ret, frogpilot_variables, extra_gears=[car.CarState.GearShifter.low]) # Low speed steer alert hysteresis logic if self.CP.minSteerSpeed > 0. and ret.vEgo < (self.CP.minSteerSpeed + 0.5): @@ -106,5 +106,5 @@ class CarInterface(CarInterfaceBase): return ret - def apply(self, c, now_nanos): - return self.CC.update(c, self.CS, now_nanos) + def apply(self, c, now_nanos, frogpilot_variables): + return self.CC.update(c, self.CS, now_nanos, frogpilot_variables) diff --git a/selfdrive/car/ford/carcontroller.py b/selfdrive/car/ford/carcontroller.py index 45516d6..d8b2a70 100644 --- a/selfdrive/car/ford/carcontroller.py +++ b/selfdrive/car/ford/carcontroller.py @@ -35,7 +35,7 @@ class CarController: self.lkas_enabled_last = False self.steer_alert_last = False - def update(self, CC, CS, now_nanos): + def update(self, CC, CS, now_nanos, frogpilot_variables): can_sends = [] actuators = CC.actuators diff --git a/selfdrive/car/ford/carstate.py b/selfdrive/car/ford/carstate.py index ef56d23..da8f635 100644 --- a/selfdrive/car/ford/carstate.py +++ b/selfdrive/car/ford/carstate.py @@ -20,7 +20,7 @@ class CarState(CarStateBase): self.vehicle_sensors_valid = False self.unsupported_platform = False - def update(self, cp, cp_cam): + def update(self, cp, cp_cam, frogpilot_variables): ret = car.CarState.new_message() # Ford Q3 hybrid variants experience a bug where a message from the PCM sends invalid checksums, diff --git a/selfdrive/car/ford/interface.py b/selfdrive/car/ford/interface.py index cc013fb..320ebb8 100644 --- a/selfdrive/car/ford/interface.py +++ b/selfdrive/car/ford/interface.py @@ -12,7 +12,7 @@ GearShifter = car.CarState.GearShifter class CarInterface(CarInterfaceBase): @staticmethod - def _get_params(ret, candidate, fingerprint, car_fw, experimental_long, docs): + def _get_params(ret, params, candidate, fingerprint, car_fw, experimental_long, docs): ret.carName = "ford" ret.dashcamOnly = candidate in CANFD_CAR @@ -103,10 +103,10 @@ class CarInterface(CarInterfaceBase): ret.centerToFront = ret.wheelbase * 0.44 return ret - def _update(self, c): - ret = self.CS.update(self.cp, self.cp_cam) + def _update(self, c, frogpilot_variables): + ret = self.CS.update(self.cp, self.cp_cam, frogpilot_variables) - events = self.create_common_events(ret, extra_gears=[GearShifter.manumatic]) + events = self.create_common_events(ret, frogpilot_variables, extra_gears=[GearShifter.manumatic]) if not self.CS.vehicle_sensors_valid: events.add(car.CarEvent.EventName.vehicleSensorsInvalid) if self.CS.unsupported_platform: @@ -116,5 +116,5 @@ class CarInterface(CarInterfaceBase): return ret - def apply(self, c, now_nanos): - return self.CC.update(c, self.CS, now_nanos) + def apply(self, c, now_nanos, frogpilot_variables): + return self.CC.update(c, self.CS, now_nanos, frogpilot_variables) diff --git a/selfdrive/car/gm/carcontroller.py b/selfdrive/car/gm/carcontroller.py index 6c7e800..ec5077b 100644 --- a/selfdrive/car/gm/carcontroller.py +++ b/selfdrive/car/gm/carcontroller.py @@ -38,7 +38,9 @@ class CarController: self.packer_obj = CANPacker(DBC[self.CP.carFingerprint]['radar']) self.packer_ch = CANPacker(DBC[self.CP.carFingerprint]['chassis']) - def update(self, CC, CS, now_nanos): + # FrogPilot variables + + def update(self, CC, CS, now_nanos, frogpilot_variables): actuators = CC.actuators hud_control = CC.hudControl hud_alert = hud_control.visualAlert diff --git a/selfdrive/car/gm/carstate.py b/selfdrive/car/gm/carstate.py index c3d061d..dd0198b 100644 --- a/selfdrive/car/gm/carstate.py +++ b/selfdrive/car/gm/carstate.py @@ -26,7 +26,9 @@ class CarState(CarStateBase): self.cam_lka_steering_cmd_counter = 0 self.buttons_counter = 0 - def update(self, pt_cp, cam_cp, loopback_cp): + # FrogPilot variables + + def update(self, pt_cp, cam_cp, loopback_cp, frogpilot_variables): ret = car.CarState.new_message() self.prev_cruise_buttons = self.cruise_buttons diff --git a/selfdrive/car/gm/interface.py b/selfdrive/car/gm/interface.py index 05caa28..47682c1 100755 --- a/selfdrive/car/gm/interface.py +++ b/selfdrive/car/gm/interface.py @@ -83,7 +83,7 @@ class CarInterface(CarInterfaceBase): return self.torque_from_lateral_accel_linear @staticmethod - def _get_params(ret, candidate, fingerprint, car_fw, experimental_long, docs): + def _get_params(ret, params, candidate, fingerprint, car_fw, experimental_long, docs): ret.carName = "gm" ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.gm)] ret.autoResumeSng = False @@ -271,8 +271,8 @@ class CarInterface(CarInterfaceBase): return ret # returns a car.CarState - def _update(self, c): - ret = self.CS.update(self.cp, self.cp_cam, self.cp_loopback) + def _update(self, c, frogpilot_variables): + ret = self.CS.update(self.cp, self.cp_cam, self.cp_loopback, frogpilot_variables) # Don't add event if transitioning from INIT, unless it's to an actual button if self.CS.cruise_buttons != CruiseButtons.UNPRESS or self.CS.prev_cruise_buttons != CruiseButtons.INIT: @@ -280,7 +280,7 @@ class CarInterface(CarInterfaceBase): unpressed_btn=CruiseButtons.UNPRESS) # The ECM allows enabling on falling edge of set, but only rising edge of resume - events = self.create_common_events(ret, extra_gears=[GearShifter.sport, GearShifter.low, + events = self.create_common_events(ret, frogpilot_variables, extra_gears=[GearShifter.sport, GearShifter.low, GearShifter.eco, GearShifter.manumatic], pcm_enable=self.CP.pcmCruise, enable_buttons=(ButtonType.decelCruise,)) if not self.CP.pcmCruise: @@ -302,5 +302,5 @@ class CarInterface(CarInterfaceBase): return ret - def apply(self, c, now_nanos): - return self.CC.update(c, self.CS, now_nanos) + def apply(self, c, now_nanos, frogpilot_variables): + return self.CC.update(c, self.CS, now_nanos, frogpilot_variables) diff --git a/selfdrive/car/gm/values.py b/selfdrive/car/gm/values.py index 8188ad4..745ac43 100644 --- a/selfdrive/car/gm/values.py +++ b/selfdrive/car/gm/values.py @@ -4,6 +4,7 @@ from enum import Enum, StrEnum from typing import Dict, List, Union from cereal import car +from openpilot.common.params import Params from openpilot.selfdrive.car import dbc_dict from openpilot.selfdrive.car.docs_definitions import CarFootnote, CarHarness, CarInfo, CarParts, Column from openpilot.selfdrive.car.fw_query_definitions import FwQueryConfig, Request, StdQueries diff --git a/selfdrive/car/honda/carcontroller.py b/selfdrive/car/honda/carcontroller.py index 056b47c..b34b8b5 100644 --- a/selfdrive/car/honda/carcontroller.py +++ b/selfdrive/car/honda/carcontroller.py @@ -124,7 +124,7 @@ class CarController: self.brake = 0.0 self.last_steer = 0.0 - def update(self, CC, CS, now_nanos): + def update(self, CC, CS, now_nanos, frogpilot_variables): actuators = CC.actuators hud_control = CC.hudControl conversion = hondacan.get_cruise_speed_conversion(self.CP.carFingerprint, CS.is_metric) diff --git a/selfdrive/car/honda/carstate.py b/selfdrive/car/honda/carstate.py index 9025f72..0d6f945 100644 --- a/selfdrive/car/honda/carstate.py +++ b/selfdrive/car/honda/carstate.py @@ -108,7 +108,7 @@ class CarState(CarStateBase): # However, on cars without a digital speedometer this is not always present (HRV, FIT, CRV 2016, ILX and RDX) self.dash_speed_seen = False - def update(self, cp, cp_cam, cp_body): + def update(self, cp, cp_cam, cp_body, frogpilot_variables): ret = car.CarState.new_message() # car params diff --git a/selfdrive/car/honda/interface.py b/selfdrive/car/honda/interface.py index 153fa1e..5577f9f 100755 --- a/selfdrive/car/honda/interface.py +++ b/selfdrive/car/honda/interface.py @@ -33,7 +33,7 @@ class CarInterface(CarInterfaceBase): return CarControllerParams.NIDEC_ACCEL_MIN, interp(current_speed, ACCEL_MAX_BP, ACCEL_MAX_VALS) @staticmethod - def _get_params(ret, candidate, fingerprint, car_fw, experimental_long, docs): + def _get_params(ret, params, candidate, fingerprint, car_fw, experimental_long, docs): ret.carName = "honda" if candidate in HONDA_BOSCH: @@ -310,8 +310,8 @@ class CarInterface(CarInterfaceBase): disable_ecu(logcan, sendcan, bus=1, addr=0x18DAB0F1, com_cont_req=b'\x28\x83\x03') # returns a car.CarState - def _update(self, c): - ret = self.CS.update(self.cp, self.cp_cam, self.cp_body) + def _update(self, c, frogpilot_variables): + ret = self.CS.update(self.cp, self.cp_cam, self.cp_body, frogpilot_variables) ret.buttonEvents = [ *create_button_events(self.CS.cruise_buttons, self.CS.prev_cruise_buttons, BUTTONS_DICT), @@ -319,7 +319,7 @@ class CarInterface(CarInterfaceBase): ] # events - events = self.create_common_events(ret, pcm_enable=False) + events = self.create_common_events(ret, frogpilot_variables, pcm_enable=False) if self.CP.pcmCruise and ret.vEgo < self.CP.minEnableSpeed: events.add(EventName.belowEngageSpeed) @@ -344,5 +344,5 @@ class CarInterface(CarInterfaceBase): # pass in a car.CarControl # to be called @ 100hz - def apply(self, c, now_nanos): - return self.CC.update(c, self.CS, now_nanos) + def apply(self, c, now_nanos, frogpilot_variables): + return self.CC.update(c, self.CS, now_nanos, frogpilot_variables) diff --git a/selfdrive/car/hyundai/carcontroller.py b/selfdrive/car/hyundai/carcontroller.py index 0b5f724..4bb0c46 100644 --- a/selfdrive/car/hyundai/carcontroller.py +++ b/selfdrive/car/hyundai/carcontroller.py @@ -56,7 +56,7 @@ class CarController: self.car_fingerprint = CP.carFingerprint self.last_button_frame = 0 - def update(self, CC, CS, now_nanos): + def update(self, CC, CS, now_nanos, frogpilot_variables): actuators = CC.actuators hud_control = CC.hudControl diff --git a/selfdrive/car/hyundai/carstate.py b/selfdrive/car/hyundai/carstate.py index 64a9fdf..1f952b0 100644 --- a/selfdrive/car/hyundai/carstate.py +++ b/selfdrive/car/hyundai/carstate.py @@ -52,9 +52,11 @@ class CarState(CarStateBase): self.params = CarControllerParams(CP) - def update(self, cp, cp_cam): + # FrogPilot variables + + def update(self, cp, cp_cam, frogpilot_variables): if self.CP.carFingerprint in CANFD_CAR: - return self.update_canfd(cp, cp_cam) + return self.update_canfd(cp, cp_cam, frogpilot_variables) ret = car.CarState.new_message() cp_cruise = cp_cam if self.CP.carFingerprint in CAMERA_SCC_CAR else cp @@ -166,7 +168,7 @@ class CarState(CarStateBase): return ret - def update_canfd(self, cp, cp_cam): + def update_canfd(self, cp, cp_cam, frogpilot_variables): ret = car.CarState.new_message() self.is_metric = cp.vl["CRUISE_BUTTONS_ALT"]["DISTANCE_UNIT"] != 1 diff --git a/selfdrive/car/hyundai/interface.py b/selfdrive/car/hyundai/interface.py index 049a633..0df2163 100644 --- a/selfdrive/car/hyundai/interface.py +++ b/selfdrive/car/hyundai/interface.py @@ -20,7 +20,7 @@ BUTTONS_DICT = {Buttons.RES_ACCEL: ButtonType.accelCruise, Buttons.SET_DECEL: Bu class CarInterface(CarInterfaceBase): @staticmethod - def _get_params(ret, candidate, fingerprint, car_fw, experimental_long, docs): + def _get_params(ret, params, candidate, fingerprint, car_fw, experimental_long, docs): ret.carName = "hyundai" ret.radarUnavailable = RADAR_START_ADDR not in fingerprint[1] or DBC[ret.carFingerprint]["radar"] is None @@ -343,8 +343,8 @@ class CarInterface(CarInterfaceBase): if CP.flags & HyundaiFlags.ENABLE_BLINKERS: disable_ecu(logcan, sendcan, bus=CanBus(CP).ECAN, addr=0x7B1, com_cont_req=b'\x28\x83\x01') - def _update(self, c): - ret = self.CS.update(self.cp, self.cp_cam) + def _update(self, c, frogpilot_variables): + ret = self.CS.update(self.cp, self.cp_cam, frogpilot_variables) if self.CS.CP.openpilotLongitudinalControl: ret.buttonEvents = create_button_events(self.CS.cruise_buttons[-1], self.CS.prev_cruise_buttons, BUTTONS_DICT) @@ -353,7 +353,7 @@ class CarInterface(CarInterfaceBase): # To avoid re-engaging when openpilot cancels, check user engagement intention via buttons # Main button also can trigger an engagement on these cars allow_enable = any(btn in ENABLE_BUTTONS for btn in self.CS.cruise_buttons) or any(self.CS.main_buttons) - events = self.create_common_events(ret, pcm_enable=self.CS.CP.pcmCruise, allow_enable=allow_enable) + events = self.create_common_events(ret, frogpilot_variables, pcm_enable=self.CS.CP.pcmCruise, allow_enable=allow_enable) # low speed steer alert hysteresis logic (only for cars with steer cut off above 10 m/s) if ret.vEgo < (self.CP.minSteerSpeed + 2.) and self.CP.minSteerSpeed > 10.: @@ -367,5 +367,5 @@ class CarInterface(CarInterfaceBase): return ret - def apply(self, c, now_nanos): - return self.CC.update(c, self.CS, now_nanos) + def apply(self, c, now_nanos, frogpilot_variables): + return self.CC.update(c, self.CS, now_nanos, frogpilot_variables) diff --git a/selfdrive/car/interfaces.py b/selfdrive/car/interfaces.py index 9767752..2e0b3a1 100644 --- a/selfdrive/car/interfaces.py +++ b/selfdrive/car/interfaces.py @@ -11,12 +11,15 @@ from openpilot.common.basedir import BASEDIR from openpilot.common.conversions import Conversions as CV from openpilot.common.simple_kalman import KF1D, get_kalman_gain from openpilot.common.numpy_fast import clip +from openpilot.common.params import Params from openpilot.common.realtime import DT_CTRL from openpilot.selfdrive.car import apply_hysteresis, gen_empty_fingerprint, scale_rot_inertia, scale_tire_stiffness, STD_CARGO_KG from openpilot.selfdrive.controls.lib.drive_helpers import V_CRUISE_MAX, get_friction from openpilot.selfdrive.controls.lib.events import Events from openpilot.selfdrive.controls.lib.vehicle_model import VehicleModel +from openpilot.selfdrive.frogpilot.functions.frogpilot_functions import FrogPilotFunctions + ButtonType = car.CarState.ButtonEvent.Type GearShifter = car.CarState.GearShifter EventName = car.CarEvent.EventName @@ -95,6 +98,9 @@ class CarInterfaceBase(ABC): if CarController is not None: self.CC = CarController(self.cp.dbc_name, CP, self.VM) + # FrogPilot variables + params = Params() + @staticmethod def get_pid_accel_limits(CP, current_speed, cruise_speed): return ACCEL_MIN, ACCEL_MAX @@ -107,9 +113,9 @@ class CarInterfaceBase(ABC): return cls.get_params(candidate, gen_empty_fingerprint(), list(), False, False) @classmethod - def get_params(cls, candidate: str, fingerprint: Dict[int, Dict[int, int]], car_fw: List[car.CarParams.CarFw], experimental_long: bool, docs: bool): + def get_params(cls, params, candidate: str, fingerprint: Dict[int, Dict[int, int]], car_fw: List[car.CarParams.CarFw], experimental_long: bool, docs: bool): ret = CarInterfaceBase.get_std_params(candidate) - ret = cls._get_params(ret, candidate, fingerprint, car_fw, experimental_long, docs) + ret = cls._get_params(ret, params, candidate, fingerprint, car_fw, experimental_long, docs) # Vehicle mass is published curb weight plus assumed payload such as a human driver; notCars have no assumed payload if not ret.notCar: @@ -204,14 +210,14 @@ class CarInterfaceBase(ABC): def _update(self, c: car.CarControl) -> car.CarState: pass - def update(self, c: car.CarControl, can_strings: List[bytes]) -> car.CarState: + def update(self, c: car.CarControl, can_strings: List[bytes], frogpilot_variables) -> car.CarState: # parse can for cp in self.can_parsers: if cp is not None: cp.update_strings(can_strings) # get CarState - ret = self._update(c) + ret = self._update(c, frogpilot_variables) ret.canValid = all(cp.can_valid for cp in self.can_parsers if cp is not None) ret.canTimeout = any(cp.bus_timeout for cp in self.can_parsers if cp is not None) @@ -241,7 +247,7 @@ class CarInterfaceBase(ABC): def apply(self, c: car.CarControl, now_nanos: int) -> Tuple[car.CarControl.Actuators, List[bytes]]: pass - def create_common_events(self, cs_out, extra_gears=None, pcm_enable=True, allow_enable=True, + def create_common_events(self, cs_out, frogpilot_variables, extra_gears=None, pcm_enable=True, allow_enable=True, enable_buttons=(ButtonType.accelCruise, ButtonType.decelCruise)): events = Events() @@ -354,6 +360,9 @@ class CarStateBase(ABC): K = get_kalman_gain(DT_CTRL, np.array(A), np.array(C), np.array(Q), R) self.v_ego_kf = KF1D(x0=x0, A=A, C=C[0], K=K) + # FrogPilot variables + self.fpf = FrogPilotFunctions() + def update_speed_kf(self, v_ego_raw): if abs(v_ego_raw - self.v_ego_kf.x[0][0]) > 2.0: # Prevent large accelerations when car starts at non zero speed self.v_ego_kf.set_x([[v_ego_raw], [0.0]]) diff --git a/selfdrive/car/mazda/carcontroller.py b/selfdrive/car/mazda/carcontroller.py index 320ad19..4952989 100644 --- a/selfdrive/car/mazda/carcontroller.py +++ b/selfdrive/car/mazda/carcontroller.py @@ -15,7 +15,7 @@ class CarController: self.brake_counter = 0 self.frame = 0 - def update(self, CC, CS, now_nanos): + def update(self, CC, CS, now_nanos, frogpilot_variables): can_sends = [] apply_steer = 0 diff --git a/selfdrive/car/mazda/carstate.py b/selfdrive/car/mazda/carstate.py index c081959..6b930e6 100644 --- a/selfdrive/car/mazda/carstate.py +++ b/selfdrive/car/mazda/carstate.py @@ -18,7 +18,7 @@ class CarState(CarStateBase): self.lkas_allowed_speed = False self.lkas_disabled = False - def update(self, cp, cp_cam): + def update(self, cp, cp_cam, frogpilot_variables): ret = car.CarState.new_message() ret.wheelSpeeds = self.get_wheel_speeds( diff --git a/selfdrive/car/mazda/interface.py b/selfdrive/car/mazda/interface.py index 7ac93d9..e2215b7 100755 --- a/selfdrive/car/mazda/interface.py +++ b/selfdrive/car/mazda/interface.py @@ -11,7 +11,7 @@ EventName = car.CarEvent.EventName class CarInterface(CarInterfaceBase): @staticmethod - def _get_params(ret, candidate, fingerprint, car_fw, experimental_long, docs): + def _get_params(ret, params, candidate, fingerprint, car_fw, experimental_long, docs): ret.carName = "mazda" ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.mazda)] ret.radarUnavailable = True @@ -49,11 +49,11 @@ class CarInterface(CarInterfaceBase): return ret # returns a car.CarState - def _update(self, c): - ret = self.CS.update(self.cp, self.cp_cam) + def _update(self, c, frogpilot_variables): + ret = self.CS.update(self.cp, self.cp_cam, frogpilot_variables) # events - events = self.create_common_events(ret) + events = self.create_common_events(ret, frogpilot_variables) if self.CS.lkas_disabled: events.add(EventName.lkasDisabled) @@ -64,5 +64,5 @@ class CarInterface(CarInterfaceBase): return ret - def apply(self, c, now_nanos): - return self.CC.update(c, self.CS, now_nanos) + def apply(self, c, now_nanos, frogpilot_variables): + return self.CC.update(c, self.CS, now_nanos, frogpilot_variables) diff --git a/selfdrive/car/mock/interface.py b/selfdrive/car/mock/interface.py index 2e4ac43..90aa3be 100755 --- a/selfdrive/car/mock/interface.py +++ b/selfdrive/car/mock/interface.py @@ -12,7 +12,7 @@ class CarInterface(CarInterfaceBase): self.sm = messaging.SubMaster(['gpsLocation', 'gpsLocationExternal']) @staticmethod - def _get_params(ret, candidate, fingerprint, car_fw, experimental_long, docs): + def _get_params(ret, params, candidate, fingerprint, car_fw, experimental_long, docs): ret.carName = "mock" ret.mass = 1700. ret.wheelbase = 2.70 @@ -20,7 +20,7 @@ class CarInterface(CarInterfaceBase): ret.steerRatio = 13. return ret - def _update(self, c): + def _update(self, c, frogpilot_variables): self.sm.update(0) gps_sock = 'gpsLocationExternal' if self.sm.recv_frame['gpsLocationExternal'] > 1 else 'gpsLocation' @@ -30,6 +30,6 @@ class CarInterface(CarInterfaceBase): return ret - def apply(self, c, now_nanos): + def apply(self, c, now_nanos, frogpilot_variables): actuators = car.CarControl.Actuators.new_message() return actuators, [] diff --git a/selfdrive/car/nissan/carcontroller.py b/selfdrive/car/nissan/carcontroller.py index 2da518b..beb5d3c 100644 --- a/selfdrive/car/nissan/carcontroller.py +++ b/selfdrive/car/nissan/carcontroller.py @@ -18,7 +18,7 @@ class CarController: self.packer = CANPacker(dbc_name) - def update(self, CC, CS, now_nanos): + def update(self, CC, CS, now_nanos, frogpilot_variables): actuators = CC.actuators hud_control = CC.hudControl pcm_cancel_cmd = CC.cruiseControl.cancel diff --git a/selfdrive/car/nissan/carstate.py b/selfdrive/car/nissan/carstate.py index b2ba9ce..1d0052b 100644 --- a/selfdrive/car/nissan/carstate.py +++ b/selfdrive/car/nissan/carstate.py @@ -20,7 +20,7 @@ class CarState(CarStateBase): self.steeringTorqueSamples = deque(TORQUE_SAMPLES*[0], TORQUE_SAMPLES) self.shifter_values = can_define.dv["GEARBOX"]["GEAR_SHIFTER"] - def update(self, cp, cp_adas, cp_cam): + def update(self, cp, cp_adas, cp_cam, frogpilot_variables): ret = car.CarState.new_message() if self.CP.carFingerprint in (CAR.ROGUE, CAR.XTRAIL, CAR.ALTIMA): diff --git a/selfdrive/car/nissan/interface.py b/selfdrive/car/nissan/interface.py index aedcaa1..cfc10aa 100644 --- a/selfdrive/car/nissan/interface.py +++ b/selfdrive/car/nissan/interface.py @@ -8,7 +8,7 @@ from openpilot.selfdrive.car.nissan.values import CAR class CarInterface(CarInterfaceBase): @staticmethod - def _get_params(ret, candidate, fingerprint, car_fw, experimental_long, docs): + def _get_params(ret, params, candidate, fingerprint, car_fw, experimental_long, docs): ret.carName = "nissan" ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.nissan)] ret.autoResumeSng = False @@ -39,15 +39,15 @@ class CarInterface(CarInterfaceBase): return ret # returns a car.CarState - def _update(self, c): - ret = self.CS.update(self.cp, self.cp_adas, self.cp_cam) + def _update(self, c, frogpilot_variables): + ret = self.CS.update(self.cp, self.cp_adas, self.cp_cam, frogpilot_variables) buttonEvents = [] be = car.CarState.ButtonEvent.new_message() be.type = car.CarState.ButtonEvent.Type.accelCruise buttonEvents.append(be) - events = self.create_common_events(ret, extra_gears=[car.CarState.GearShifter.brake]) + events = self.create_common_events(ret, frogpilot_variables, extra_gears=[car.CarState.GearShifter.brake]) if self.CS.lkas_enabled: events.add(car.CarEvent.EventName.invalidLkasSetting) @@ -56,5 +56,5 @@ class CarInterface(CarInterfaceBase): return ret - def apply(self, c, now_nanos): - return self.CC.update(c, self.CS, now_nanos) + def apply(self, c, now_nanos, frogpilot_variables): + return self.CC.update(c, self.CS, now_nanos, frogpilot_variables) diff --git a/selfdrive/car/subaru/carcontroller.py b/selfdrive/car/subaru/carcontroller.py index cc8ce4f..bcfc515 100644 --- a/selfdrive/car/subaru/carcontroller.py +++ b/selfdrive/car/subaru/carcontroller.py @@ -23,7 +23,7 @@ class CarController: self.p = CarControllerParams(CP) self.packer = CANPacker(DBC[CP.carFingerprint]['pt']) - def update(self, CC, CS, now_nanos): + def update(self, CC, CS, now_nanos, frogpilot_variables): actuators = CC.actuators hud_control = CC.hudControl pcm_cancel_cmd = CC.cruiseControl.cancel diff --git a/selfdrive/car/subaru/carstate.py b/selfdrive/car/subaru/carstate.py index c8a6dfe..bda8342 100644 --- a/selfdrive/car/subaru/carstate.py +++ b/selfdrive/car/subaru/carstate.py @@ -16,7 +16,7 @@ class CarState(CarStateBase): self.angle_rate_calulator = CanSignalRateCalculator(50) - def update(self, cp, cp_cam, cp_body): + def update(self, cp, cp_cam, cp_body, frogpilot_variables): ret = car.CarState.new_message() throttle_msg = cp.vl["Throttle"] if self.car_fingerprint not in HYBRID_CARS else cp_body.vl["Throttle_Hybrid"] diff --git a/selfdrive/car/subaru/interface.py b/selfdrive/car/subaru/interface.py index 1296aea..d501965 100644 --- a/selfdrive/car/subaru/interface.py +++ b/selfdrive/car/subaru/interface.py @@ -9,7 +9,7 @@ from openpilot.selfdrive.car.subaru.values import CAR, GLOBAL_ES_ADDR, LKAS_ANGL class CarInterface(CarInterfaceBase): @staticmethod - def _get_params(ret, candidate, fingerprint, car_fw, experimental_long, docs): + def _get_params(ret, params, candidate, fingerprint, car_fw, experimental_long, docs): ret.carName = "subaru" ret.radarUnavailable = True # for HYBRID CARS to be upstreamed, we need: @@ -136,11 +136,11 @@ class CarInterface(CarInterfaceBase): return ret # returns a car.CarState - def _update(self, c): + def _update(self, c, frogpilot_variables): - ret = self.CS.update(self.cp, self.cp_cam, self.cp_body) + ret = self.CS.update(self.cp, self.cp_cam, self.cp_body, frogpilot_variables) - ret.events = self.create_common_events(ret).to_msg() + ret.events = self.create_common_events(ret, frogpilot_variables).to_msg() return ret @@ -149,5 +149,5 @@ class CarInterface(CarInterfaceBase): if CP.flags & SubaruFlags.DISABLE_EYESIGHT: disable_ecu(logcan, sendcan, bus=2, addr=GLOBAL_ES_ADDR, com_cont_req=b'\x28\x03\x01') - def apply(self, c, now_nanos): - return self.CC.update(c, self.CS, now_nanos) + def apply(self, c, now_nanos, frogpilot_variables): + return self.CC.update(c, self.CS, now_nanos, frogpilot_variables) diff --git a/selfdrive/car/subaru/values.py b/selfdrive/car/subaru/values.py index 2f7350b..02b0498 100644 --- a/selfdrive/car/subaru/values.py +++ b/selfdrive/car/subaru/values.py @@ -4,6 +4,7 @@ from typing import Dict, List, Union from cereal import car from panda.python import uds +from openpilot.common.params import Params from openpilot.selfdrive.car import dbc_dict from openpilot.selfdrive.car.docs_definitions import CarFootnote, CarHarness, CarInfo, CarParts, Tool, Column from openpilot.selfdrive.car.fw_query_definitions import FwQueryConfig, Request, StdQueries, p16 diff --git a/selfdrive/car/tesla/carcontroller.py b/selfdrive/car/tesla/carcontroller.py index 95a248a..9d5617b 100644 --- a/selfdrive/car/tesla/carcontroller.py +++ b/selfdrive/car/tesla/carcontroller.py @@ -14,7 +14,7 @@ class CarController: self.pt_packer = CANPacker(DBC[CP.carFingerprint]['pt']) self.tesla_can = TeslaCAN(self.packer, self.pt_packer) - def update(self, CC, CS, now_nanos): + def update(self, CC, CS, now_nanos, frogpilot_variables): actuators = CC.actuators pcm_cancel_cmd = CC.cruiseControl.cancel diff --git a/selfdrive/car/tesla/carstate.py b/selfdrive/car/tesla/carstate.py index 2cb4f09..ed59693 100644 --- a/selfdrive/car/tesla/carstate.py +++ b/selfdrive/car/tesla/carstate.py @@ -20,7 +20,7 @@ class CarState(CarStateBase): self.acc_state = 0 self.das_control_counters = deque(maxlen=32) - def update(self, cp, cp_cam): + def update(self, cp, cp_cam, frogpilot_variables): ret = car.CarState.new_message() # Vehicle speed diff --git a/selfdrive/car/tesla/interface.py b/selfdrive/car/tesla/interface.py index e061397..72e2b0d 100755 --- a/selfdrive/car/tesla/interface.py +++ b/selfdrive/car/tesla/interface.py @@ -8,7 +8,7 @@ from openpilot.selfdrive.car.interfaces import CarInterfaceBase class CarInterface(CarInterfaceBase): @staticmethod - def _get_params(ret, candidate, fingerprint, car_fw, experimental_long, docs): + def _get_params(ret, params, candidate, fingerprint, car_fw, experimental_long, docs): ret.carName = "tesla" # There is no safe way to do steer blending with user torque, @@ -51,12 +51,12 @@ class CarInterface(CarInterfaceBase): return ret - def _update(self, c): - ret = self.CS.update(self.cp, self.cp_cam) + def _update(self, c, frogpilot_variables): + ret = self.CS.update(self.cp, self.cp_cam, frogpilot_variables) - ret.events = self.create_common_events(ret).to_msg() + ret.events = self.create_common_events(ret, frogpilot_variables).to_msg() return ret - def apply(self, c, now_nanos): - return self.CC.update(c, self.CS, now_nanos) + def apply(self, c, now_nanos, frogpilot_variables): + return self.CC.update(c, self.CS, now_nanos, frogpilot_variables) diff --git a/selfdrive/car/tests/test_car_interfaces.py b/selfdrive/car/tests/test_car_interfaces.py index 02a8d60..6122577 100755 --- a/selfdrive/car/tests/test_car_interfaces.py +++ b/selfdrive/car/tests/test_car_interfaces.py @@ -9,6 +9,7 @@ from parameterized import parameterized from cereal import car, messaging from openpilot.common.realtime import DT_CTRL +from openpilot.common.params import Params from openpilot.selfdrive.car import gen_empty_fingerprint from openpilot.selfdrive.car.car_helpers import interfaces from openpilot.selfdrive.car.fingerprints import all_known_cars @@ -18,6 +19,7 @@ from openpilot.selfdrive.controls.lib.latcontrol_angle import LatControlAngle from openpilot.selfdrive.controls.lib.latcontrol_pid import LatControlPID from openpilot.selfdrive.controls.lib.latcontrol_torque import LatControlTorque from openpilot.selfdrive.controls.lib.longcontrol import LongControl +from openpilot.selfdrive.controls.controlsd import Controls from openpilot.selfdrive.test.fuzzy_generation import DrawType, FuzzyGenerator ALL_ECUS = list({ecu for ecus in FW_VERSIONS.values() for ecu in ecus.keys()}) @@ -44,7 +46,6 @@ def get_fuzzy_car_interface_args(draw: DrawType) -> dict: params['car_fw'] = [car.CarParams.CarFw(ecu=fw[0], address=fw[1], subAddress=fw[2] or 0) for fw in params['car_fw']] return params - class TestCarInterfaces(unittest.TestCase): # FIXME: Due to the lists used in carParams, Phase.target is very slow and will cause # many generated examples to overrun when max_examples > ~20, don't use it @@ -56,9 +57,11 @@ class TestCarInterfaces(unittest.TestCase): CarInterface, CarController, CarState = interfaces[car_name] args = get_fuzzy_car_interface_args(data.draw) + params = Params() - car_params = CarInterface.get_params(car_name, args['fingerprints'], args['car_fw'], + car_params = CarInterface.get_params(params, car_name, args['fingerprints'], args['car_fw'], experimental_long=args['experimental_long'], docs=False) + car_interface = CarInterface(car_params, CarController, CarState) assert car_params assert car_interface @@ -94,18 +97,19 @@ class TestCarInterfaces(unittest.TestCase): # Run car interface now_nanos = 0 CC = car.CarControl.new_message(**cc_msg) + controls = Controls(CI=car_interface) for _ in range(10): - car_interface.update(CC, []) - car_interface.apply(CC, now_nanos) - car_interface.apply(CC, now_nanos) + car_interface.update(CC, [], controls.frogpilot_variables) + car_interface.apply(CC, now_nanos, controls.frogpilot_variables) + car_interface.apply(CC, now_nanos, controls.frogpilot_variables) now_nanos += DT_CTRL * 1e9 # 10 ms CC = car.CarControl.new_message(**cc_msg) CC.enabled = True for _ in range(10): - car_interface.update(CC, []) - car_interface.apply(CC, now_nanos) - car_interface.apply(CC, now_nanos) + car_interface.update(CC, [], controls.frogpilot_variables) + car_interface.apply(CC, now_nanos, controls.frogpilot_variables) + car_interface.apply(CC, now_nanos, controls.frogpilot_variables) now_nanos += DT_CTRL * 1e9 # 10ms # Test controller initialization diff --git a/selfdrive/car/toyota/carcontroller.py b/selfdrive/car/toyota/carcontroller.py index 343b1d3..af80d4e 100644 --- a/selfdrive/car/toyota/carcontroller.py +++ b/selfdrive/car/toyota/carcontroller.py @@ -1,5 +1,6 @@ from cereal import car from openpilot.common.numpy_fast import clip, interp +from openpilot.common.params import Params from openpilot.selfdrive.car import apply_meas_steer_torque_limits, apply_std_steer_angle_limits, common_fault_avoidance, \ create_gas_interceptor_command, make_can_msg from openpilot.selfdrive.car.toyota import toyotacan @@ -41,7 +42,10 @@ class CarController: self.gas = 0 self.accel = 0 - def update(self, CC, CS, now_nanos): + # FrogPilot variables + params = Params() + + def update(self, CC, CS, now_nanos, frogpilot_variables): actuators = CC.actuators hud_control = CC.hudControl pcm_cancel_cmd = CC.cruiseControl.cancel @@ -142,10 +146,12 @@ class CarController: if pcm_cancel_cmd and self.CP.carFingerprint in UNSUPPORTED_DSU_CAR: can_sends.append(toyotacan.create_acc_cancel_command(self.packer)) elif self.CP.openpilotLongitudinalControl: - can_sends.append(toyotacan.create_accel_command(self.packer, pcm_accel_cmd, pcm_cancel_cmd, self.standstill_req, lead, CS.acc_type, fcw_alert)) + can_sends.append(toyotacan.create_accel_command(self.packer, pcm_accel_cmd, pcm_cancel_cmd, self.standstill_req, lead, CS.acc_type, fcw_alert, + frogpilot_variables)) self.accel = pcm_accel_cmd else: - can_sends.append(toyotacan.create_accel_command(self.packer, 0, pcm_cancel_cmd, False, lead, CS.acc_type, False)) + can_sends.append(toyotacan.create_accel_command(self.packer, 0, pcm_cancel_cmd, False, lead, CS.acc_type, False, + frogpilot_variables)) if self.frame % 2 == 0 and self.CP.enableGasInterceptor and self.CP.openpilotLongitudinalControl: # send exactly zero if gas cmd is zero. Interceptor will send the max between read value and gas cmd. diff --git a/selfdrive/car/toyota/carstate.py b/selfdrive/car/toyota/carstate.py index e4ea0d3..18c8067 100644 --- a/selfdrive/car/toyota/carstate.py +++ b/selfdrive/car/toyota/carstate.py @@ -44,7 +44,9 @@ class CarState(CarStateBase): self.acc_type = 1 self.lkas_hud = {} - def update(self, cp, cp_cam): + # FrogPilot variables + + def update(self, cp, cp_cam, frogpilot_variables): ret = car.CarState.new_message() ret.doorOpen = any([cp.vl["BODY_CONTROL_STATE"]["DOOR_OPEN_FL"], cp.vl["BODY_CONTROL_STATE"]["DOOR_OPEN_FR"], diff --git a/selfdrive/car/toyota/interface.py b/selfdrive/car/toyota/interface.py index 988b1b4..3f0b2f4 100644 --- a/selfdrive/car/toyota/interface.py +++ b/selfdrive/car/toyota/interface.py @@ -18,7 +18,7 @@ class CarInterface(CarInterfaceBase): return CarControllerParams.ACCEL_MIN, CarControllerParams.ACCEL_MAX @staticmethod - def _get_params(ret, candidate, fingerprint, car_fw, experimental_long, docs): + def _get_params(ret, params, candidate, fingerprint, car_fw, experimental_long, docs): ret.carName = "toyota" ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.toyota)] ret.safetyConfigs[0].safetyParam = EPS_SCALE[candidate] @@ -289,11 +289,11 @@ class CarInterface(CarInterfaceBase): disable_ecu(logcan, sendcan, bus=0, addr=0x750, sub_addr=0xf, com_cont_req=communication_control) # returns a car.CarState - def _update(self, c): - ret = self.CS.update(self.cp, self.cp_cam) + def _update(self, c, frogpilot_variables): + ret = self.CS.update(self.cp, self.cp_cam, frogpilot_variables) # events - events = self.create_common_events(ret) + events = self.create_common_events(ret, frogpilot_variables) # Lane Tracing Assist control is unavailable (EPS_STATUS->LTA_STATE=0) until # the more accurate angle sensor signal is initialized @@ -320,5 +320,5 @@ class CarInterface(CarInterfaceBase): # pass in a car.CarControl # to be called @ 100hz - def apply(self, c, now_nanos): - return self.CC.update(c, self.CS, now_nanos) + def apply(self, c, now_nanos, frogpilot_variables): + return self.CC.update(c, self.CS, now_nanos, frogpilot_variables) diff --git a/selfdrive/car/toyota/toyotacan.py b/selfdrive/car/toyota/toyotacan.py index e14e3e5..3cc08dd 100644 --- a/selfdrive/car/toyota/toyotacan.py +++ b/selfdrive/car/toyota/toyotacan.py @@ -33,7 +33,7 @@ def create_lta_steer_command(packer, steer_control_type, steer_angle, steer_req, return packer.make_can_msg("STEERING_LTA", 0, values) -def create_accel_command(packer, accel, pcm_cancel, standstill_req, lead, acc_type, fcw_alert): +def create_accel_command(packer, accel, pcm_cancel, standstill_req, lead, acc_type, fcw_alert, frogpilot_variables): # TODO: find the exact canceling bit that does not create a chime values = { "ACCEL_CMD": accel, diff --git a/selfdrive/car/volkswagen/carcontroller.py b/selfdrive/car/volkswagen/carcontroller.py index 0cee2c7..48f6d42 100644 --- a/selfdrive/car/volkswagen/carcontroller.py +++ b/selfdrive/car/volkswagen/carcontroller.py @@ -25,7 +25,7 @@ class CarController: self.hca_frame_timer_running = 0 self.hca_frame_same_torque = 0 - def update(self, CC, CS, ext_bus, now_nanos): + def update(self, CC, CS, ext_bus, now_nanos, frogpilot_variables): actuators = CC.actuators hud_control = CC.hudControl can_sends = [] diff --git a/selfdrive/car/volkswagen/carstate.py b/selfdrive/car/volkswagen/carstate.py index 25c5bc0..853a19f 100644 --- a/selfdrive/car/volkswagen/carstate.py +++ b/selfdrive/car/volkswagen/carstate.py @@ -30,9 +30,9 @@ class CarState(CarStateBase): return button_events - def update(self, pt_cp, cam_cp, ext_cp, trans_type): + def update(self, pt_cp, cam_cp, ext_cp, trans_type, frogpilot_variables): if self.CP.carFingerprint in PQ_CARS: - return self.update_pq(pt_cp, cam_cp, ext_cp, trans_type) + return self.update_pq(pt_cp, cam_cp, ext_cp, trans_type, frogpilot_variables) ret = car.CarState.new_message() # Update vehicle speed and acceleration from ABS wheel speeds. @@ -153,7 +153,7 @@ class CarState(CarStateBase): return ret - def update_pq(self, pt_cp, cam_cp, ext_cp, trans_type): + def update_pq(self, pt_cp, cam_cp, ext_cp, trans_type, frogpilot_variables): ret = car.CarState.new_message() # Update vehicle speed and acceleration from ABS wheel speeds. ret.wheelSpeeds = self.get_wheel_speeds( diff --git a/selfdrive/car/volkswagen/interface.py b/selfdrive/car/volkswagen/interface.py index 710e779..b2f5db7 100644 --- a/selfdrive/car/volkswagen/interface.py +++ b/selfdrive/car/volkswagen/interface.py @@ -23,7 +23,7 @@ class CarInterface(CarInterfaceBase): self.eps_timer_soft_disable_alert = False @staticmethod - def _get_params(ret, candidate, fingerprint, car_fw, experimental_long, docs): + def _get_params(ret, params, candidate, fingerprint, car_fw, experimental_long, docs): ret.carName = "volkswagen" ret.radarUnavailable = True @@ -225,10 +225,10 @@ class CarInterface(CarInterfaceBase): return ret # returns a car.CarState - def _update(self, c): - ret = self.CS.update(self.cp, self.cp_cam, self.cp_ext, self.CP.transmissionType) + def _update(self, c, frogpilot_variables): + ret = self.CS.update(self.cp, self.cp_cam, self.cp_ext, self.CP.transmissionType, frogpilot_variables) - events = self.create_common_events(ret, extra_gears=[GearShifter.eco, GearShifter.sport, GearShifter.manumatic], + events = self.create_common_events(ret, frogpilot_variables, extra_gears=[GearShifter.eco, GearShifter.sport, GearShifter.manumatic], pcm_enable=not self.CS.CP.openpilotLongitudinalControl, enable_buttons=(ButtonType.setCruise, ButtonType.resumeCruise)) @@ -253,6 +253,6 @@ class CarInterface(CarInterfaceBase): return ret - def apply(self, c, now_nanos): - new_actuators, can_sends, self.eps_timer_soft_disable_alert = self.CC.update(c, self.CS, self.ext_bus, now_nanos) + def apply(self, c, now_nanos, frogpilot_variables): + new_actuators, can_sends, self.eps_timer_soft_disable_alert = self.CC.update(c, self.CS, self.ext_bus, now_nanos, frogpilot_variables) return new_actuators, can_sends diff --git a/selfdrive/controls/controlsd.py b/selfdrive/controls/controlsd.py index bf2b14c..a1fc02b 100755 --- a/selfdrive/controls/controlsd.py +++ b/selfdrive/controls/controlsd.py @@ -3,11 +3,12 @@ import os import math import time import threading +from types import SimpleNamespace from typing import SupportsFloat import cereal.messaging as messaging -from cereal import car, log +from cereal import car, log, custom from cereal.visionipc import VisionIpcClient, VisionStreamType from panda import ALTERNATIVE_EXPERIENCE @@ -53,6 +54,7 @@ LaneChangeDirection = log.LaneChangeDirection EventName = car.CarEvent.EventName ButtonType = car.CarState.ButtonEvent.Type SafetyModel = car.CarParams.SafetyModel +GearShifter = car.CarState.GearShifter IGNORED_SAFETY_MODES = (SafetyModel.silent, SafetyModel.noOutput) CSID_MAP = {"1": EventName.roadCameraError, "2": EventName.wideRoadCameraError, "0": EventName.driverCameraError} @@ -90,14 +92,14 @@ class CarD: """Initialize CarInterface, once controls are ready""" self.CI.init(self.CP, self.can_sock, self.pm.sock['sendcan']) - def state_update(self, CC: car.CarControl): + def state_update(self, CC: car.CarControl, frogpilot_variables): """carState update loop, driven by can""" # TODO: This should not depend on carControl # Update carState from CAN can_strs = messaging.drain_sock_raw(self.can_sock, wait_for_one=True) - self.CS = self.CI.update(CC, can_strs) + self.CS = self.CI.update(CC, can_strs, frogpilot_variables) self.sm.update(0) @@ -136,12 +138,12 @@ class CarD: cp_send.carParams = self.CP self.pm.send('carParams', cp_send) - def controls_update(self, CC: car.CarControl): + def controls_update(self, CC: car.CarControl, frogpilot_variables): """control update loop, driven by carControl""" # send car controls over can now_nanos = self.can_log_mono_time if REPLAY else int(time.monotonic() * 1e9) - actuators_output, can_sends = self.CI.apply(CC, now_nanos) + actuators_output, can_sends = self.CI.apply(CC, now_nanos, frogpilot_variables) self.pm.send('sendcan', can_list_to_can_capnp(can_sends, msgtype='sendcan', valid=self.CS.canValid)) return actuators_output @@ -160,21 +162,28 @@ class Controls: self.branch = get_short_branch() # Setup sockets - self.pm = messaging.PubMaster(['controlsState', 'carControl', 'onroadEvents']) + self.pm = messaging.PubMaster(['controlsState', 'carControl', 'onroadEvents', 'frogpilotCarControl']) self.sensor_packets = ["accelerometer", "gyroscope"] self.camera_packets = ["roadCameraState", "driverCameraState", "wideRoadCameraState"] self.log_sock = messaging.sub_sock('androidLog') + # FrogPilot variables self.params = Params() + self.params_memory = Params("/dev/shm/params") + + self.frogpilot_variables = SimpleNamespace() + + self.driving_gear = False + ignore = self.sensor_packets + ['testJoystick'] if SIMULATION: ignore += ['driverCameraState', 'managerState'] self.sm = messaging.SubMaster(['deviceState', 'pandaStates', 'peripheralState', 'modelV2', 'liveCalibration', 'driverMonitoringState', 'longitudinalPlan', 'liveLocationKalman', 'managerState', 'liveParameters', 'radarState', 'liveTorqueParameters', - 'testJoystick'] + self.camera_packets + self.sensor_packets, + 'testJoystick', 'frogpilotPlan'] + self.camera_packets + self.sensor_packets, ignore_alive=ignore, ignore_avg_freq=ignore+['radarState', 'testJoystick'], ignore_valid=['testJoystick', ], frequency=int(1/DT_CTRL)) @@ -191,6 +200,8 @@ class Controls: self.is_ldw_enabled = self.params.get_bool("IsLdwEnabled") openpilot_enabled_toggle = self.params.get_bool("OpenpilotEnabledToggle") + self.update_frogpilot_params() + # detect sound card presence and ensure successful init sounds_available = HARDWARE.get_sound_card_online() @@ -222,6 +233,7 @@ class Controls: self.CC = car.CarControl.new_message() self.CS_prev = car.CarState.new_message() + self.FPCC = custom.FrogPilotCarControl.new_message() self.AM = AlertManager() self.events = Events() @@ -291,6 +303,8 @@ class Controls: self.events.clear() + frogpilot_plan = self.sm['frogpilotPlan'] + # Add joystick event, static on cars, dynamic on nonCars if self.joystick_mode: self.events.add(EventName.joystickDebug) @@ -506,7 +520,7 @@ class Controls: def data_sample(self): """Receive data from sockets and update carState""" - CS = self.card.state_update(self.CC) + CS = self.card.state_update(self.CC, self.frogpilot_variables) self.sm.update(0) @@ -630,7 +644,7 @@ class Controls: else: self.state = State.enabled self.current_alert_types.append(ET.ENABLE) - self.v_cruise_helper.initialize_v_cruise(CS, self.experimental_mode) + self.v_cruise_helper.initialize_v_cruise(CS, self.experimental_mode, self.frogpilot_variables) # Check if openpilot is engaged and actuators are enabled self.enabled = self.state in ENABLED_STATES @@ -660,6 +674,12 @@ class Controls: CC = car.CarControl.new_message() CC.enabled = self.enabled + # FrogPilot functions + frogpilot_plan = self.sm['frogpilotPlan'] + + # Gear Check + self.driving_gear = CS.gearShifter not in (GearShifter.neutral, GearShifter.park, GearShifter.reverse, GearShifter.unknown) + # Check which actuators can be enabled standstill = CS.vEgo <= max(self.CP.minSteerSpeed, MIN_LATERAL_CONTROL_SPEED) or CS.standstill CC.latActive = self.active and not CS.steerFaultTemporary and not CS.steerFaultPermanent and \ @@ -826,7 +846,7 @@ class Controls: hudControl.visualAlert = current_alert.visual_alert if not self.CP.passive and self.initialized: - self.last_actuators = self.card.controls_update(CC) + self.last_actuators = self.card.controls_update(CC, self.frogpilot_variables) CC.actuatorsOutput = self.last_actuators if self.CP.steerControlType == car.CarParams.SteerControlType.angle: self.steer_limited = abs(CC.actuators.steeringAngleDeg - CC.actuatorsOutput.steeringAngleDeg) > \ @@ -910,6 +930,12 @@ class Controls: # copy CarControl to pass to CarInterface on the next iteration self.CC = CC + # Publish FrogPilot variables + fpcs_send = messaging.new_message('frogpilotCarControl') + fpcs_send.valid = CS.canValid + fpcs_send.frogpilotCarControl = self.FPCC + self.pm.send('frogpilotCarControl', fpcs_send) + def step(self): start_time = time.monotonic() @@ -940,6 +966,10 @@ class Controls: self.joystick_mode = self.params.get_bool("JoystickDebugMode") time.sleep(0.1) + # Update FrogPilot parameters + if self.params_memory.get_bool("FrogPilotTogglesUpdated"): + self.update_frogpilot_params() + def controlsd_thread(self): e = threading.Event() t = threading.Thread(target=self.params_thread, args=(e, )) @@ -952,6 +982,14 @@ class Controls: e.set() t.join() + def update_frogpilot_params(self): + custom_alerts = self.params.get_bool("CustomAlerts") + + lateral_tune = self.params.get_bool("LateralTune") + + longitudinal_tune = self.params.get_bool("LongitudinalTune") + + quality_of_life = self.params.get_bool("QOLControls") def main(): controls = Controls() diff --git a/selfdrive/controls/lib/desire_helper.py b/selfdrive/controls/lib/desire_helper.py index 90b6858..17de459 100644 --- a/selfdrive/controls/lib/desire_helper.py +++ b/selfdrive/controls/lib/desire_helper.py @@ -1,5 +1,6 @@ from cereal import log from openpilot.common.conversions import Conversions as CV +from openpilot.common.params import Params from openpilot.common.realtime import DT_MDL LaneChangeState = log.LaneChangeState @@ -40,7 +41,13 @@ class DesireHelper: self.prev_one_blinker = False self.desire = log.Desire.none - def update(self, carstate, lateral_active, lane_change_prob): + # FrogPilot variables + self.params = Params() + self.params_memory = Params("/dev/shm/params") + + self.update_frogpilot_params() + + def update(self, carstate, lateral_active, lane_change_prob, frogpilotPlan): v_ego = carstate.vEgo one_blinker = carstate.leftBlinker != carstate.rightBlinker below_lane_change_speed = v_ego < LANE_CHANGE_SPEED_MIN @@ -112,3 +119,9 @@ class DesireHelper: self.keep_pulse_timer = 0.0 elif self.desire in (log.Desire.keepLeft, log.Desire.keepRight): self.desire = log.Desire.none + + if self.params_memory.get_bool("FrogPilotTogglesUpdated"): + self.update_frogpilot_params() + + def update_frogpilot_params(self): + is_metric = self.params.get_bool("IsMetric") diff --git a/selfdrive/controls/lib/drive_helpers.py b/selfdrive/controls/lib/drive_helpers.py index 6a5b22f..37fcb62 100644 --- a/selfdrive/controls/lib/drive_helpers.py +++ b/selfdrive/controls/lib/drive_helpers.py @@ -3,6 +3,7 @@ import math from cereal import car, log from openpilot.common.conversions import Conversions as CV from openpilot.common.numpy_fast import clip, interp +from openpilot.common.params import Params from openpilot.common.realtime import DT_CTRL # WARNING: this value was determined based on the model's training distribution, @@ -45,6 +46,8 @@ class VCruiseHelper: self.button_timers = {ButtonType.decelCruise: 0, ButtonType.accelCruise: 0} self.button_change_states = {btn: {"standstill": False, "enabled": False} for btn in self.button_timers} + # FrogPilot variables + @property def v_cruise_initialized(self): return self.v_cruise_kph != V_CRUISE_UNSET @@ -125,7 +128,7 @@ class VCruiseHelper: self.button_timers[b.type.raw] = 1 if b.pressed else 0 self.button_change_states[b.type.raw] = {"standstill": CS.cruiseState.standstill, "enabled": enabled} - def initialize_v_cruise(self, CS, experimental_mode: bool) -> None: + def initialize_v_cruise(self, CS, experimental_mode: bool, frogpilot_variables) -> None: # initializing is handled by the PCM if self.CP.pcmCruise: return diff --git a/selfdrive/controls/lib/events.py b/selfdrive/controls/lib/events.py index d68c95b..1266fa1 100755 --- a/selfdrive/controls/lib/events.py +++ b/selfdrive/controls/lib/events.py @@ -228,7 +228,7 @@ def startup_master_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubM if "REPLAY" in os.environ: branch = "replay" - return StartupAlert("WARNING: This branch is not tested", branch, alert_status=AlertStatus.userPrompt) + return StartupAlert("Hippity hoppity this is my property", "so I do what I want 🐸", alert_status=AlertStatus.frogpilot) def below_engage_speed_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int) -> Alert: return NoEntryAlert(f"Drive above {get_display_speed(CP.minEnableSpeed, metric)} to engage") @@ -332,6 +332,7 @@ def joystick_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, return NormalPermanentAlert("Joystick Mode", vals) +# FrogPilot alerts EVENTS: Dict[int, Dict[str, Union[Alert, AlertCallbackType]]] = { # ********** events with no alerts ********** @@ -956,6 +957,8 @@ EVENTS: Dict[int, Dict[str, Union[Alert, AlertCallbackType]]] = { ET.NO_ENTRY: NoEntryAlert("Vehicle Sensors Calibrating"), }, + # FrogPilot Events + } diff --git a/selfdrive/controls/lib/longitudinal_mpc_lib/long_mpc.py b/selfdrive/controls/lib/longitudinal_mpc_lib/long_mpc.py index 39cfda4..9b2b7d5 100755 --- a/selfdrive/controls/lib/longitudinal_mpc_lib/long_mpc.py +++ b/selfdrive/controls/lib/longitudinal_mpc_lib/long_mpc.py @@ -221,6 +221,8 @@ def gen_long_ocp(): class LongitudinalMpc: def __init__(self, mode='acc'): + # FrogPilot variables + self.mode = mode self.solver = AcadosOcpSolverCython(MODEL_NAME, ACADOS_SOLVER_TYPE, N) self.reset() @@ -330,7 +332,7 @@ class LongitudinalMpc: self.cruise_min_a = min_a self.max_a = max_a - def update(self, radarstate, v_cruise, x, v, a, j, personality=log.LongitudinalPersonality.standard): + def update(self, radarstate, v_cruise, x, v, a, j, frogpilot_planner, personality=log.LongitudinalPersonality.standard): t_follow = get_T_FOLLOW(personality) v_ego = self.x0[1] self.status = radarstate.leadOne.status or radarstate.leadTwo.status diff --git a/selfdrive/controls/lib/longitudinal_planner.py b/selfdrive/controls/lib/longitudinal_planner.py index 018768f..d740b22 100755 --- a/selfdrive/controls/lib/longitudinal_planner.py +++ b/selfdrive/controls/lib/longitudinal_planner.py @@ -88,7 +88,7 @@ class LongitudinalPlanner: j = np.zeros(len(T_IDXS_MPC)) return x, v, a, j - def update(self, sm): + def update(self, sm, frogpilot_planner, params_memory): if self.param_read_counter % 50 == 0: self.read_param() self.param_read_counter += 1 @@ -134,7 +134,7 @@ class LongitudinalPlanner: 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) x, v, a, j = self.parse_model(sm['modelV2'], self.v_model_error) - self.mpc.update(sm['radarState'], v_cruise, x, v, a, j, personality=self.personality) + self.mpc.update(sm['radarState'], frogpilot_planner.v_cruise, x, v, a, j, frogpilot_planner, personality=self.personality) self.v_desired_trajectory_full = np.interp(ModelConstants.T_IDXS, T_IDXS_MPC, self.mpc.v_solution) self.a_desired_trajectory_full = np.interp(ModelConstants.T_IDXS, T_IDXS_MPC, self.mpc.a_solution) @@ -152,7 +152,9 @@ class LongitudinalPlanner: self.a_desired = float(interp(self.dt, ModelConstants.T_IDXS[:CONTROL_N], self.a_desired_trajectory)) self.v_desired_filter.x = self.v_desired_filter.x + self.dt * (self.a_desired + a_prev) / 2.0 - def publish(self, sm, pm): + frogpilot_planner.update(sm['carState'], sm['controlsState'], sm['modelV2'], self.mpc, sm, v_cruise, v_ego) + + def publish(self, sm, pm, frogpilot_planner): plan_send = messaging.new_message('longitudinalPlan') plan_send.valid = sm.all_checks(service_list=['carState', 'controlsState']) @@ -173,3 +175,5 @@ class LongitudinalPlanner: longitudinalPlan.personality = self.personality pm.send('longitudinalPlan', plan_send) + + frogpilot_planner.publish(sm, pm, self.mpc) diff --git a/selfdrive/controls/plannerd.py b/selfdrive/controls/plannerd.py index eeeeda0..6e6a20a 100755 --- a/selfdrive/controls/plannerd.py +++ b/selfdrive/controls/plannerd.py @@ -6,6 +6,8 @@ from openpilot.common.swaglog import cloudlog from openpilot.selfdrive.controls.lib.longitudinal_planner import LongitudinalPlanner import cereal.messaging as messaging +from openpilot.selfdrive.frogpilot.functions.frogpilot_planner import FrogPilotPlanner + def publish_ui_plan(sm, pm, longitudinal_planner): ui_send = messaging.new_message('uiPlan') ui_send.valid = sm.all_checks(service_list=['carState', 'controlsState', 'modelV2']) @@ -22,22 +24,27 @@ def plannerd_thread(): cloudlog.info("plannerd is waiting for CarParams") params = Params() + params_memory = Params("/dev/shm/params") with car.CarParams.from_bytes(params.get("CarParams", block=True)) as msg: CP = msg cloudlog.info("plannerd got CarParams: %s", CP.carName) + frogpilot_planner = FrogPilotPlanner(CP, params, params_memory) longitudinal_planner = LongitudinalPlanner(CP) - pm = messaging.PubMaster(['longitudinalPlan', 'uiPlan']) - sm = messaging.SubMaster(['carControl', 'carState', 'controlsState', 'radarState', 'modelV2'], + pm = messaging.PubMaster(['longitudinalPlan', 'uiPlan', 'frogpilotPlan']) + sm = messaging.SubMaster(['carControl', 'carState', 'controlsState', 'radarState', 'modelV2', 'frogpilotNavigation'], poll='modelV2', ignore_avg_freq=['radarState']) while True: sm.update() if sm.updated['modelV2']: - longitudinal_planner.update(sm) - longitudinal_planner.publish(sm, pm) + longitudinal_planner.update(sm, frogpilot_planner, params_memory) + longitudinal_planner.publish(sm, pm, frogpilot_planner) publish_ui_plan(sm, pm, longitudinal_planner) + if params_memory.get_bool("FrogPilotTogglesUpdated"): + frogpilot_planner.update_frogpilot_params(params) + def main(): plannerd_thread() diff --git a/selfdrive/frogpilot/assets/toggle_icons/icon_lateral_tune.png b/selfdrive/frogpilot/assets/toggle_icons/icon_lateral_tune.png new file mode 100644 index 0000000000000000000000000000000000000000..ba83e3a3b229149a0fbca78a43ca279e684639d5 GIT binary patch literal 30135 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 literal 0 HcmV?d00001 diff --git a/selfdrive/frogpilot/assets/toggle_icons/icon_longitudinal_tune.png b/selfdrive/frogpilot/assets/toggle_icons/icon_longitudinal_tune.png new file mode 100644 index 0000000000000000000000000000000000000000..4af03cd3c704e0bfe8ca17c2dddbb2b2120c91f3 GIT binary patch literal 37131 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

|j*3xT+Wh@Cpo$hgswLaksf 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 literal 0 HcmV?d00001 diff --git a/selfdrive/frogpilot/assets/toggle_icons/quality_of_life.png b/selfdrive/frogpilot/assets/toggle_icons/quality_of_life.png new file mode 100644 index 0000000000000000000000000000000000000000..1719a605f293614de0a1b59246c283bf43e5e2a1 GIT binary patch literal 42955 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 LR^Qax=Kntc+i=!{ literal 0 HcmV?d00001 diff --git a/selfdrive/frogpilot/functions/frogpilot_functions.py b/selfdrive/frogpilot/functions/frogpilot_functions.py new file mode 100644 index 0000000..5bbd4aa --- /dev/null +++ b/selfdrive/frogpilot/functions/frogpilot_functions.py @@ -0,0 +1,17 @@ +import numpy as np + +from openpilot.common.numpy_fast import interp +from openpilot.common.params import Params +from openpilot.system.hardware import HARDWARE + + +params_memory = Params("/dev/shm/params") + +CITY_SPEED_LIMIT = 25 +CRUISING_SPEED = 5 # Roughly the speed cars go when not touching the gas while in drive +PROBABILITY = 0.6 # 60% chance of condition being true +THRESHOLD = 5 # Time threshold (0.25s) + +class FrogPilotFunctions: + def __init__(self) -> None: + self.params = Params() diff --git a/selfdrive/frogpilot/functions/frogpilot_planner.py b/selfdrive/frogpilot/functions/frogpilot_planner.py new file mode 100644 index 0000000..e894c89 --- /dev/null +++ b/selfdrive/frogpilot/functions/frogpilot_planner.py @@ -0,0 +1,49 @@ +import cereal.messaging as messaging + +from openpilot.common.conversions import Conversions as CV + +from openpilot.selfdrive.frogpilot.functions.frogpilot_functions import CRUISING_SPEED, FrogPilotFunctions + +class FrogPilotPlanner: + def __init__(self, CP, params, params_memory): + self.CP = CP + self.params_memory = params_memory + + self.fpf = FrogPilotFunctions() + + self.v_cruise = 0 + + self.update_frogpilot_params(params) + + def update(self, carState, controlsState, modelData, mpc, sm, v_cruise, v_ego): + enabled = controlsState.enabled + + # Update the max allowed speed + self.v_cruise = self.update_v_cruise(carState, controlsState, enabled, modelData, v_cruise, v_ego) + + def update_v_cruise(self, carState, controlsState, enabled, modelData, v_cruise, v_ego): + # Offsets to adjust the max speed to match the cluster + v_ego_cluster = max(carState.vEgoCluster, v_ego) + v_ego_diff = v_ego_cluster - v_ego + + v_cruise_cluster = max(controlsState.vCruiseCluster, controlsState.vCruise) * CV.KPH_TO_MS + v_cruise_diff = v_cruise_cluster - v_cruise + + targets = [] + filtered_targets = [target for target in targets if target > CRUISING_SPEED] + + return min(filtered_targets) if filtered_targets else v_cruise + + def publish(self, sm, pm, mpc): + frogpilot_plan_send = messaging.new_message('frogpilotPlan') + frogpilot_plan_send.valid = sm.all_checks(service_list=['carState', 'controlsState']) + frogpilotPlan = frogpilot_plan_send.frogpilotPlan + + pm.send('frogpilotPlan', frogpilot_plan_send) + + def update_frogpilot_params(self, params): + self.is_metric = params.get_bool("IsMetric") + + custom_ui = params.get_bool("CustomUI") + + longitudinal_tune = params.get_bool("LongitudinalTune") diff --git a/selfdrive/frogpilot/ui/control_settings.cc b/selfdrive/frogpilot/ui/control_settings.cc new file mode 100644 index 0000000..1f40f49 --- /dev/null +++ b/selfdrive/frogpilot/ui/control_settings.cc @@ -0,0 +1,163 @@ +#include "selfdrive/frogpilot/ui/control_settings.h" + +FrogPilotControlsPanel::FrogPilotControlsPanel(SettingsWindow *parent) : FrogPilotListWidget(parent) { + const std::vector> controlToggles { + {"LateralTune", "Lateral Tuning", "Modify openpilot's steering behavior.", "../frogpilot/assets/toggle_icons/icon_lateral_tune.png"}, + + {"LongitudinalTune", "Longitudinal Tuning", "Modify openpilot's acceleration and braking behavior.", "../frogpilot/assets/toggle_icons/icon_longitudinal_tune.png"}, + + {"QOLControls", "Quality of Life", "Miscellaneous quality of life changes to improve your overall openpilot experience.", "../frogpilot/assets/toggle_icons/quality_of_life.png"}, + }; + + for (const auto &[param, title, desc, icon] : controlToggles) { + ParamControl *toggle; + + if (param == "LateralTune") { + FrogPilotParamManageControl *lateralTuneToggle = new FrogPilotParamManageControl(param, title, desc, icon, this); + QObject::connect(lateralTuneToggle, &FrogPilotParamManageControl::manageButtonClicked, this, [this]() { + parentToggleClicked(); + for (auto &[key, toggle] : toggles) { + toggle->setVisible(lateralTuneKeys.find(key.c_str()) != lateralTuneKeys.end()); + } + }); + toggle = lateralTuneToggle; + + } else if (param == "LongitudinalTune") { + FrogPilotParamManageControl *longitudinalTuneToggle = new FrogPilotParamManageControl(param, title, desc, icon, this); + QObject::connect(longitudinalTuneToggle, &FrogPilotParamManageControl::manageButtonClicked, this, [this]() { + parentToggleClicked(); + for (auto &[key, toggle] : toggles) { + toggle->setVisible(longitudinalTuneKeys.find(key.c_str()) != longitudinalTuneKeys.end()); + } + }); + toggle = longitudinalTuneToggle; + + } 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 { + toggle = new ParamControl(param, title, desc, icon, this); + } + + addItem(toggle); + toggles[param.toStdString()] = toggle; + + QObject::connect(toggle, &ToggleControl::toggleFlipped, [this]() { + updateToggles(); + }); + + QObject::connect(static_cast(toggle), &FrogPilotButtonParamControl::buttonClicked, [this]() { + updateToggles(); + }); + + QObject::connect(static_cast(toggle), &FrogPilotParamValueControl::valueChanged, [this]() { + updateToggles(); + }); + + QObject::connect(toggle, &AbstractControl::showDescriptionEvent, [this]() { + update(); + }); + + QObject::connect(static_cast(toggle), &FrogPilotParamManageControl::manageButtonClicked, this, [this]() { + update(); + }); + } + + std::set rebootKeys = {}; + for (const std::string &key : rebootKeys) { + QObject::connect(toggles[key], &ToggleControl::toggleFlipped, [this, key]() { + if (started) { + if (FrogPilotConfirmationDialog::toggle("Reboot required to take effect.", "Reboot Now", this)) { + Hardware::soft_reboot(); + } + } + }); + } + + QObject::connect(device(), &Device::interactiveTimeout, this, &FrogPilotControlsPanel::hideSubToggles); + QObject::connect(parent, &SettingsWindow::closeParentToggle, this, &FrogPilotControlsPanel::hideSubToggles); + QObject::connect(parent, &SettingsWindow::closeSubParentToggle, this, &FrogPilotControlsPanel::hideSubSubToggles); + QObject::connect(parent, &SettingsWindow::updateMetric, this, &FrogPilotControlsPanel::updateMetric); + QObject::connect(uiState(), &UIState::offroadTransition, this, &FrogPilotControlsPanel::updateCarToggles); + QObject::connect(uiState(), &UIState::uiUpdate, this, &FrogPilotControlsPanel::updateState); + + hideSubToggles(); + updateMetric(); +} + +void FrogPilotControlsPanel::updateState(const UIState &s) { + started = s.scene.started; +} + +void FrogPilotControlsPanel::updateToggles() { + std::thread([this]() { + paramsMemory.putBool("FrogPilotTogglesUpdated", true); + std::this_thread::sleep_for(std::chrono::seconds(1)); + paramsMemory.putBool("FrogPilotTogglesUpdated", false); + }).detach(); +} + +void FrogPilotControlsPanel::updateCarToggles() { +} + +void FrogPilotControlsPanel::updateMetric() { + bool previousIsMetric = isMetric; + isMetric = params.getBool("IsMetric"); + + if (isMetric != previousIsMetric) { + double distanceConversion = isMetric ? FOOT_TO_METER : METER_TO_FOOT; + double speedConversion = isMetric ? MILE_TO_KM : KM_TO_MILE; + } + + if (isMetric) { + } else { + } + + previousIsMetric = isMetric; +} + +void FrogPilotControlsPanel::parentToggleClicked() { + openParentToggle(); +} + +void FrogPilotControlsPanel::subParentToggleClicked() { + openSubParentToggle(); +} + +void FrogPilotControlsPanel::hideSubToggles() { + for (auto &[key, toggle] : toggles) { + bool subToggles = conditionalExperimentalKeys.find(key.c_str()) != conditionalExperimentalKeys.end() || + fireTheBabysitterKeys.find(key.c_str()) != fireTheBabysitterKeys.end() || + laneChangeKeys.find(key.c_str()) != laneChangeKeys.end() || + lateralTuneKeys.find(key.c_str()) != lateralTuneKeys.end() || + longitudinalTuneKeys.find(key.c_str()) != longitudinalTuneKeys.end() || + mtscKeys.find(key.c_str()) != mtscKeys.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); + } + + closeParentToggle(); +} + +void FrogPilotControlsPanel::hideSubSubToggles() { + for (auto &[key, toggle] : toggles) { + bool isVisible = false; + toggle->setVisible(isVisible); + } + + closeSubParentToggle(); + update(); +} + +void FrogPilotControlsPanel::hideEvent(QHideEvent *event) { + hideSubToggles(); +} diff --git a/selfdrive/frogpilot/ui/control_settings.h b/selfdrive/frogpilot/ui/control_settings.h new file mode 100644 index 0000000..addea26 --- /dev/null +++ b/selfdrive/frogpilot/ui/control_settings.h @@ -0,0 +1,52 @@ +#pragma once + +#include + +#include "selfdrive/frogpilot/ui/frogpilot_ui_functions.h" +#include "selfdrive/ui/qt/offroad/settings.h" +#include "selfdrive/ui/ui.h" + +class FrogPilotControlsPanel : public FrogPilotListWidget { + Q_OBJECT + +public: + explicit FrogPilotControlsPanel(SettingsWindow *parent); + +signals: + void closeParentToggle(); + void closeSubParentToggle(); + void openParentToggle(); + void openSubParentToggle(); + +private: + void hideEvent(QHideEvent *event); + void hideSubSubToggles(); + void hideSubToggles(); + void parentToggleClicked(); + void subParentToggleClicked(); + void updateCarToggles(); + void updateMetric(); + void updateState(const UIState &s); + void updateToggles(); + + std::set conditionalExperimentalKeys = {}; + std::set fireTheBabysitterKeys = {}; + std::set laneChangeKeys = {}; + std::set lateralTuneKeys = {}; + std::set longitudinalTuneKeys = {}; + std::set mtscKeys = {}; + std::set qolKeys = {}; + std::set speedLimitControllerKeys = {}; + std::set speedLimitControllerControlsKeys = {}; + std::set speedLimitControllerQOLKeys = {}; + std::set speedLimitControllerVisualsKeys = {}; + std::set visionTurnControlKeys = {}; + + std::map toggles; + + Params params; + Params paramsMemory{"/dev/shm/params"}; + + bool isMetric = params.getBool("IsMetric"); + bool started = false; +}; diff --git a/selfdrive/frogpilot/ui/frogpilot_ui_functions.cc b/selfdrive/frogpilot/ui/frogpilot_ui_functions.cc new file mode 100644 index 0000000..7bd6c3b --- /dev/null +++ b/selfdrive/frogpilot/ui/frogpilot_ui_functions.cc @@ -0,0 +1,42 @@ +#include + +#include "selfdrive/frogpilot/ui/frogpilot_ui_functions.h" +#include "selfdrive/ui/ui.h" + +bool FrogPilotConfirmationDialog::toggle(const QString &prompt_text, const QString &confirm_text, QWidget *parent) { + ConfirmationDialog d = ConfirmationDialog(prompt_text, confirm_text, tr("Reboot Later"), false, parent); + return d.exec(); +} + +bool FrogPilotConfirmationDialog::toggleAlert(const QString &prompt_text, const QString &button_text, QWidget *parent) { + ConfirmationDialog d = ConfirmationDialog(prompt_text, button_text, "", false, parent); + return d.exec(); +} + +bool FrogPilotConfirmationDialog::yesorno(const QString &prompt_text, QWidget *parent) { + ConfirmationDialog d = ConfirmationDialog(prompt_text, tr("Yes"), tr("No"), false, parent); + return d.exec(); +} + +FrogPilotButtonIconControl::FrogPilotButtonIconControl(const QString &title, const QString &text, const QString &desc, const QString &icon, QWidget *parent) : AbstractControl(title, desc, icon, parent) { + btn.setText(text); + btn.setStyleSheet(R"( + QPushButton { + padding: 0; + border-radius: 50px; + font-size: 35px; + font-weight: 500; + color: #E4E4E4; + background-color: #393939; + } + QPushButton:pressed { + background-color: #4a4a4a; + } + QPushButton:disabled { + color: #33E4E4E4; + } + )"); + btn.setFixedSize(250, 100); + QObject::connect(&btn, &QPushButton::clicked, this, &FrogPilotButtonIconControl::clicked); + hlayout->addWidget(&btn); +} diff --git a/selfdrive/frogpilot/ui/frogpilot_ui_functions.h b/selfdrive/frogpilot/ui/frogpilot_ui_functions.h new file mode 100644 index 0000000..3785b1c --- /dev/null +++ b/selfdrive/frogpilot/ui/frogpilot_ui_functions.h @@ -0,0 +1,745 @@ +#pragma once + +#include + +#include + +#include "selfdrive/ui/qt/widgets/controls.h" + +class FrogPilotConfirmationDialog : public ConfirmationDialog { + Q_OBJECT + +public: + explicit FrogPilotConfirmationDialog(const QString &prompt_text, const QString &confirm_text, + const QString &cancel_text, const bool rich, QWidget* parent); + static bool toggle(const QString &prompt_text, const QString &confirm_text, QWidget *parent); + static bool toggleAlert(const QString &prompt_text, const QString &button_text, QWidget *parent); + static bool yesorno(const QString &prompt_text, QWidget *parent); +}; + +class FrogPilotListWidget : public QWidget { + Q_OBJECT +public: + explicit FrogPilotListWidget(QWidget *parent = 0) : QWidget(parent), outer_layout(this) { + outer_layout.setMargin(0); + outer_layout.setSpacing(0); + outer_layout.addLayout(&inner_layout); + inner_layout.setMargin(0); + inner_layout.setSpacing(25); // default spacing is 25 + outer_layout.addStretch(); + } + inline void addItem(QWidget *w) { inner_layout.addWidget(w); } + inline void addItem(QLayout *layout) { inner_layout.addLayout(layout); } + inline void setSpacing(int spacing) { inner_layout.setSpacing(spacing); } + +private: + void paintEvent(QPaintEvent *) override { + QPainter p(this); + p.setPen(Qt::gray); + + int visibleWidgetCount = 0; + std::vector visibleRects; + + for (int i = 0; i < inner_layout.count(); ++i) { + QWidget *widget = inner_layout.itemAt(i)->widget(); + if (widget && widget->isVisible()) { + visibleWidgetCount++; + visibleRects.push_back(inner_layout.itemAt(i)->geometry()); + } + } + + for (int i = 0; i < visibleWidgetCount - 1; ++i) { + int bottom = visibleRects[i].bottom() + inner_layout.spacing() / 2; + p.drawLine(visibleRects[i].left() + 40, bottom, visibleRects[i].right() - 40, bottom); + } + } + QVBoxLayout outer_layout; + QVBoxLayout inner_layout; +}; + +class FrogPilotDualParamControl : public QFrame { + Q_OBJECT + +public: + FrogPilotDualParamControl(ParamControl *control1, ParamControl *control2, QWidget *parent = nullptr, bool split=false) + : QFrame(parent) { + QHBoxLayout *hlayout = new QHBoxLayout(this); + + control1->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Preferred); + control1->setMaximumWidth(split ? 850 : 700); + + control2->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred); + control2->setMaximumWidth(split ? 700 : 850); + + hlayout->addWidget(control1); + hlayout->addWidget(control2); + } +}; + +class FrogPilotButtonControl : public AbstractControl { + Q_OBJECT + +public: + FrogPilotButtonControl(const QString &title, const QString &text, const QString &desc = "", QWidget *parent = nullptr); + inline void setText(const QString &text) { btn.setText(text); } + inline QString text() const { return btn.text(); } + +signals: + void clicked(); + +public slots: + void setEnabled(bool enabled) { btn.setEnabled(enabled); } + +private: + QPushButton btn; +}; + +class FrogPilotButtonIconControl : public AbstractControl { + Q_OBJECT + +public: + FrogPilotButtonIconControl(const QString &title, const QString &text, const QString &desc = "", const QString &icon = "", QWidget *parent = nullptr); + inline void setText(const QString &text) { btn.setText(text); } + inline QString text() const { return btn.text(); } + +signals: + void clicked(); + +public slots: + void setEnabled(bool enabled) { btn.setEnabled(enabled); } + +private: + QPushButton btn; +}; + +class FrogPilotButtonParamControl : public ParamControl { + Q_OBJECT +public: + FrogPilotButtonParamControl(const QString ¶m, const QString &title, const QString &desc, const QString &icon, + const std::vector &button_texts, const int minimum_button_width = 225) + : ParamControl(param, title, desc, icon) { + const QString style = R"( + QPushButton { + border-radius: 50px; + font-size: 40px; + font-weight: 500; + height:100px; + padding: 0 25 0 25; + color: #E4E4E4; + background-color: #393939; + } + QPushButton:pressed { + background-color: #4a4a4a; + } + QPushButton:checked:enabled { + background-color: #33Ab4C; + } + QPushButton:disabled { + color: #33E4E4E4; + } + )"; + + key = param.toStdString(); + int value = atoi(params.get(key).c_str()); + + button_group = new QButtonGroup(this); + button_group->setExclusive(true); + for (size_t i = 0; i < button_texts.size(); i++) { + QPushButton *button = new QPushButton(button_texts[i], this); + button->setCheckable(true); + button->setChecked(i == value); + button->setStyleSheet(style); + button->setMinimumWidth(minimum_button_width); + hlayout->addWidget(button); + button_group->addButton(button, i); + } + + QObject::connect(button_group, QOverload::of(&QButtonGroup::buttonToggled), [=](int id, bool checked) { + if (checked) { + params.put(key, std::to_string(id)); + refresh(); + emit buttonClicked(id); + } + }); + + toggle.hide(); + } + + void setEnabled(bool enable) { + for (auto btn : button_group->buttons()) { + btn->setEnabled(enable); + } + } + +signals: + void buttonClicked(int id); + +private: + std::string key; + Params params; + QButtonGroup *button_group; +}; + +class FrogPilotButtonsControl : public ParamControl { + Q_OBJECT +public: + FrogPilotButtonsControl(const QString &title, const QString &desc, const QString &icon, + const std::vector &button_texts, const int minimum_button_width = 225) + : ParamControl("", title, desc, icon) { + const QString style = R"( + QPushButton { + border-radius: 50px; + font-size: 40px; + font-weight: 500; + height: 100px; + padding: 0 25px 0 25px; + color: #E4E4E4; + background-color: #393939; + } + QPushButton:pressed { + background-color: #33Ab4C; + } + QPushButton:disabled { + color: #33E4E4E4; + } + )"; + + button_group = new QButtonGroup(this); + + for (size_t i = 0; i < button_texts.size(); i++) { + QPushButton *button = new QPushButton(button_texts[i], this); + button->setStyleSheet(style); + button->setMinimumWidth(minimum_button_width); + hlayout->addWidget(button); + button_group->addButton(button, static_cast(i)); + + connect(button, &QPushButton::clicked, this, [this, i]() { + emit buttonClicked(static_cast(i)); + }); + } + + toggle.hide(); + } + +signals: + void buttonClicked(int id); + +private: + QButtonGroup *button_group; +}; + +class FrogPilotButtonsParamControl : public ParamControl { + Q_OBJECT +public: + FrogPilotButtonsParamControl(const QString ¶m, const QString &title, const QString &desc, const QString &icon, + const std::vector> &button_params) + : ParamControl(param, title, desc, icon) { + const QString style = R"( + QPushButton { + border-radius: 50px; + font-size: 40px; + font-weight: 500; + height:100px; + padding: 0 25 0 25; + color: #E4E4E4; + background-color: #393939; + } + QPushButton:pressed { + background-color: #4a4a4a; + } + QPushButton:checked:enabled { + background-color: #33Ab4C; + } + QPushButton:disabled { + color: #33E4E4E4; + } + )"; + + button_group = new QButtonGroup(this); + button_group->setExclusive(true); + + for (const auto ¶m_pair : button_params) { + const QString ¶m_toggle = param_pair.first; + const QString &button_text = param_pair.second; + + QPushButton *button = new QPushButton(button_text, this); + button->setCheckable(true); + + bool value = params.getBool(param_toggle.toStdString()); + button->setChecked(value); + button->setStyleSheet(style); + button->setMinimumWidth(225); + hlayout->addWidget(button); + + QObject::connect(button, &QPushButton::toggled, this, [=](bool checked) { + if (checked) { + for (const auto &inner_param_pair : button_params) { + const QString &inner_param = inner_param_pair.first; + params.putBool(inner_param.toStdString(), inner_param == param_toggle); + } + refresh(); + emit buttonClicked(); + } + }); + + button_group->addButton(button); + } + + toggle.hide(); + } + + void setEnabled(bool enable) { + for (auto btn : button_group->buttons()) { + btn->setEnabled(enable); + } + } + +signals: + void buttonClicked(); + +private: + Params params; + QButtonGroup *button_group; +}; + +class FrogPilotParamManageControl : public ParamControl { + Q_OBJECT + +public: + FrogPilotParamManageControl(const QString ¶m, const QString &title, const QString &desc, const QString &icon, QWidget *parent = nullptr, bool hideToggle = false) + : ParamControl(param, title, desc, icon, parent), + hideToggle(hideToggle), + key(param.toStdString()), + manageButton(new ButtonControl(tr(""), tr("MANAGE"), tr(""))) { + hlayout->insertWidget(hlayout->indexOf(&toggle) - 1, manageButton); + + connect(this, &ToggleControl::toggleFlipped, this, [this](bool state) { + refresh(); + }); + + connect(manageButton, &ButtonControl::clicked, this, &FrogPilotParamManageControl::manageButtonClicked); + + if (hideToggle) { + toggle.hide(); + } + } + + void refresh() { + ParamControl::refresh(); + manageButton->setVisible(params.getBool(key) || hideToggle); + } + + void showEvent(QShowEvent *event) override { + ParamControl::showEvent(event); + refresh(); + } + +signals: + void manageButtonClicked(); + +private: + bool hideToggle; + std::string key; + Params params; + ButtonControl *manageButton; +}; + +class FrogPilotParamToggleControl : public ParamControl { + Q_OBJECT +public: + FrogPilotParamToggleControl(const QString ¶m, const QString &title, const QString &desc, + const QString &icon, const std::vector &button_params, + const std::vector &button_texts, QWidget *parent = nullptr, + const int minimum_button_width = 225) + : ParamControl(param, title, desc, icon, parent) { + + key = param.toStdString(); + + connect(this, &ToggleControl::toggleFlipped, this, [this](bool state) { + refreshButtons(state); + }); + + const QString style = R"( + QPushButton { + border-radius: 50px; + font-size: 40px; + font-weight: 500; + height:100px; + padding: 0 25 0 25; + color: #E4E4E4; + background-color: #393939; + } + QPushButton:pressed { + background-color: #4a4a4a; + } + QPushButton:checked:enabled { + background-color: #33Ab4C; + } + QPushButton:disabled { + color: #33E4E4E4; + } + )"; + + button_group = new QButtonGroup(this); + button_group->setExclusive(false); + this->button_params = button_params; + + for (int i = 0; i < button_texts.size(); ++i) { + QPushButton *button = new QPushButton(button_texts[i], this); + button->setCheckable(true); + button->setStyleSheet(style); + button->setMinimumWidth(minimum_button_width); + button_group->addButton(button, i); + + connect(button, &QPushButton::clicked, [this, i](bool checked) { + params.putBool(this->button_params[i].toStdString(), checked); + button_group->button(i)->setChecked(checked); + emit buttonClicked(checked); + }); + + hlayout->insertWidget(hlayout->indexOf(&toggle) - 1, button); + } + } + + void refresh() { + bool state = params.getBool(key); + if (state != toggle.on) { + toggle.togglePosition(); + } + + refreshButtons(state); + updateButtonStates(); + } + + void refreshButtons(bool state) { + for (QAbstractButton *button : button_group->buttons()) { + button->setVisible(state); + } + } + + void updateButtonStates() { + for (int i = 0; i < button_group->buttons().size(); ++i) { + bool checked = params.getBool(button_params[i].toStdString()); + QAbstractButton *button = button_group->button(i); + if (button) { + button->setChecked(checked); + } + } + } + + void showEvent(QShowEvent *event) override { + refresh(); + QWidget::showEvent(event); + } + +signals: + void buttonClicked(const bool checked); + +private: + std::string key; + Params params; + QButtonGroup *button_group; + std::vector button_params; +}; + +class FrogPilotParamValueControl : public ParamControl { + Q_OBJECT + +public: + FrogPilotParamValueControl(const QString ¶m, const QString &title, const QString &desc, const QString &icon, + const float &minValue, const float &maxValue, const std::map &valueLabels, + QWidget *parent = nullptr, const bool &loop = true, const QString &label = "", + const float &division = 1.0f, const float &intervals = 1.0f) + : ParamControl(param, title, desc, icon, parent), + minValue(minValue), maxValue(maxValue), valueLabelMappings(valueLabels), loop(loop), labelText(label), + division(division), previousValue(0.0f), value(0.0f) { + key = param.toStdString(); + + valueLabel = new QLabel(this); + hlayout->addWidget(valueLabel); + + QPushButton *decrementButton = createButton("-", this); + QPushButton *incrementButton = createButton("+", this); + + hlayout->addWidget(decrementButton); + hlayout->addWidget(incrementButton); + + countdownTimer = new QTimer(this); + countdownTimer->setInterval(150); + countdownTimer->setSingleShot(true); + + connect(countdownTimer, &QTimer::timeout, this, &FrogPilotParamValueControl::handleTimeout); + + connect(decrementButton, &QPushButton::pressed, this, [=]() { updateValue(-intervals); }); + connect(incrementButton, &QPushButton::pressed, this, [=]() { updateValue(intervals); }); + + connect(decrementButton, &QPushButton::released, this, &FrogPilotParamValueControl::restartTimer); + connect(incrementButton, &QPushButton::released, this, &FrogPilotParamValueControl::restartTimer); + + toggle.hide(); + } + + void restartTimer() { + countdownTimer->stop(); + countdownTimer->start(); + } + + void handleTimeout() { + previousValue = value; + } + + void updateValue(float increment) { + if (std::fabs(previousValue - value) > 5.0f && std::fmod(value, 5.0f) == 0.0f) { + increment *= 5; + } + value += increment; + + 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 valueChanged(value); + } + + void refresh() { + value = params.getFloat(key); + + QString text; + auto it = valueLabelMappings.find(value); + + if (division > 1.0f) { + text = QString::number(value / division, 'g', division >= 10.0f ? 4 : 3); + } else { + if (it != valueLabelMappings.end()) { + text = it->second; + } else { + text = QString::number(value, 'g', 4); + } + } + + 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(); + previousValue = value; + } + +signals: + void valueChanged(float value); + +private: + bool loop; + float division; + float maxValue; + float minValue; + float previousValue; + float value; + QLabel *valueLabel; + QString labelText; + std::map valueLabelMappings; + std::string key; + Params params; + QTimer *countdownTimer; + + QPushButton *createButton(const QString &text, QWidget *parent) { + QPushButton *button = new QPushButton(text, parent); + button->setFixedSize(150, 100); + button->setAutoRepeat(true); + button->setAutoRepeatInterval(150); + button->setAutoRepeatDelay(500); + 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 FrogPilotParamValueToggleControl : public ParamControl { + Q_OBJECT + +public: + FrogPilotParamValueToggleControl(const QString ¶m, const QString &title, const QString &desc, const QString &icon, + const int &minValue, const int &maxValue, const std::map &valueLabels, + QWidget *parent = nullptr, const bool &loop = true, const QString &label = "", const int &division = 1, + const std::vector &button_params = std::vector(), const std::vector &button_texts = std::vector(), + const int minimum_button_width = 225) + : ParamControl(param, title, desc, icon, parent), + minValue(minValue), maxValue(maxValue), valueLabelMappings(valueLabels), loop(loop), labelText(label), division(division) { + key = param.toStdString(); + + const QString style = R"( + QPushButton { + border-radius: 50px; + font-size: 40px; + font-weight: 500; + height:100px; + padding: 0 25 0 25; + color: #E4E4E4; + background-color: #393939; + } + QPushButton:pressed { + background-color: #4a4a4a; + } + QPushButton:checked:enabled { + background-color: #33Ab4C; + } + QPushButton:disabled { + color: #33E4E4E4; + } + )"; + + button_group = new QButtonGroup(this); + button_group->setExclusive(false); + + std::map paramState; + for (const QString &button_param : button_params) { + paramState[button_param] = params.getBool(button_param.toStdString()); + } + + for (int i = 0; i < button_texts.size(); ++i) { + QPushButton *button = new QPushButton(button_texts[i], this); + button->setCheckable(true); + button->setChecked(paramState[button_params[i]]); + button->setStyleSheet(style); + button->setMinimumWidth(minimum_button_width); + button_group->addButton(button, i); + + connect(button, &QPushButton::clicked, [this, button_params, i](bool checked) { + params.putBool(button_params[i].toStdString(), checked); + button_group->button(i)->setChecked(checked); + }); + + hlayout->addWidget(button); + } + + 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); + }); + + connect(incrementButton, &QPushButton::clicked, this, [=]() { + updateValue(1); + }); + + toggle.hide(); + } + + void updateValue(int increment) { + value = value + increment; + + if (loop) { + if (value < minValue) value = maxValue; + else if (value > maxValue) value = minValue; + } else { + value = std::max(minValue, std::min(maxValue, value)); + } + + params.putInt(key, value); + refresh(); + emit valueChanged(value); + } + + void refresh() { + value = params.getInt(key); + + QString text; + auto it = valueLabelMappings.find(value); + if (division > 1) { + text = QString::number(value / (division * 1.0), 'g'); + } else { + text = it != valueLabelMappings.end() ? it->second : QString::number(value); + } + if (!labelText.isEmpty()) { + text += labelText; + } + valueLabel->setText(text); + valueLabel->setStyleSheet("QLabel { color: #E0E879; }"); + } + + void updateControl(int newMinValue, int newMaxValue, const QString &newLabel, int newDivision) { + minValue = newMinValue; + maxValue = newMaxValue; + labelText = newLabel; + division = newDivision; + } + + void showEvent(QShowEvent *event) override { + refresh(); + } + +signals: + void valueChanged(int value); + +private: + bool loop; + int division; + int maxValue; + int minValue; + int value; + QButtonGroup *button_group; + QLabel *valueLabel; + QString labelText; + std::map 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->setAutoRepeatDelay(350); + 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; + } +}; diff --git a/selfdrive/frogpilot/ui/vehicle_settings.cc b/selfdrive/frogpilot/ui/vehicle_settings.cc new file mode 100644 index 0000000..ed27626 --- /dev/null +++ b/selfdrive/frogpilot/ui/vehicle_settings.cc @@ -0,0 +1,88 @@ +#include "selfdrive/frogpilot/ui/vehicle_settings.h" + +FrogPilotVehiclesPanel::FrogPilotVehiclesPanel(SettingsWindow *parent) : FrogPilotListWidget(parent) { + std::vector> vehicleToggles { + {"LongitudinalTune", "Longitudinal Tune", "Use a custom Toyota longitudinal tune.\n\nCydia = More focused on TSS-P vehicles but works for all Toyotas\n\nDragonPilot = Focused on TSS2 vehicles\n\nFrogPilot = Takes the best of both worlds with some personal tweaks focused around my 2019 Lexus ES 350", ""}, + }; + + for (const auto &[param, title, desc, icon] : vehicleToggles) { + ParamControl *toggle; + + if (param == "LongitudinalTune") { + std::vector> tuneOptions{ + {"StockTune", tr("Stock")}, + }; + toggle = new FrogPilotButtonsParamControl(param, title, desc, icon, tuneOptions); + + QObject::connect(static_cast(toggle), &FrogPilotButtonsParamControl::buttonClicked, [this]() { + if (started) { + if (FrogPilotConfirmationDialog::toggle("Reboot required to take effect.", "Reboot Now", this)) { + Hardware::soft_reboot(); + } + } + }); + + } else { + toggle = new ParamControl(param, title, desc, icon, this); + } + + toggle->setVisible(false); + addItem(toggle); + toggles[param.toStdString()] = toggle; + + QObject::connect(toggle, &ToggleControl::toggleFlipped, [this]() { + updateToggles(); + }); + + QObject::connect(toggle, &AbstractControl::showDescriptionEvent, [this]() { + update(); + }); + } + + std::set rebootKeys = {}; + for (const std::string &key : rebootKeys) { + QObject::connect(toggles[key], &ToggleControl::toggleFlipped, [this]() { + if (started) { + if (FrogPilotConfirmationDialog::toggle("Reboot required to take effect.", "Reboot Now", this)) { + Hardware::soft_reboot(); + } + } + }); + } + + QObject::connect(uiState(), &UIState::uiUpdate, this, &FrogPilotVehiclesPanel::updateState); +} + +void FrogPilotVehiclesPanel::updateState(const UIState &s) { + started = s.scene.started; +} + +void FrogPilotVehiclesPanel::updateToggles() { + std::thread([this]() { + paramsMemory.putBool("FrogPilotTogglesUpdated", true); + std::this_thread::sleep_for(std::chrono::seconds(1)); + paramsMemory.putBool("FrogPilotTogglesUpdated", false); + }).detach(); +} + +void FrogPilotVehiclesPanel::setToggles() { + bool gm = false; + bool subaru false; + bool toyota = false; + + for (auto &[key, toggle] : toggles) { + if (toggle) { + toggle->setVisible(false); + + if (gm) { + toggle->setVisible(gmKeys.find(key.c_str()) != gmKeys.end()); + } else if (subaru) { + toggle->setVisible(subaruKeys.find(key.c_str()) != subaruKeys.end()); + } else if (toyota) { + toggle->setVisible(toyotaKeys.find(key.c_str()) != toyotaKeys.end()); + } + } + } + + update(); +} diff --git a/selfdrive/frogpilot/ui/vehicle_settings.h b/selfdrive/frogpilot/ui/vehicle_settings.h new file mode 100644 index 0000000..e8bc788 --- /dev/null +++ b/selfdrive/frogpilot/ui/vehicle_settings.h @@ -0,0 +1,32 @@ +#pragma once + +#include + +#include + +#include "selfdrive/frogpilot/ui/frogpilot_ui_functions.h" +#include "selfdrive/ui/qt/offroad/settings.h" +#include "selfdrive/ui/ui.h" + +class FrogPilotVehiclesPanel : public FrogPilotListWidget { + Q_OBJECT + +public: + explicit FrogPilotVehiclesPanel(SettingsWindow *parent); + +private: + void setToggles(); + void updateState(const UIState &s); + void updateToggles(); + + std::map toggles; + + std::set gmKeys = {}; + std::set subaruKeys = {}; + std::set toyotaKeys = {"LongitudinalTune"}; + + Params params; + Params paramsMemory{"/dev/shm/params"}; + + bool started = false; +}; diff --git a/selfdrive/frogpilot/ui/visual_settings.cc b/selfdrive/frogpilot/ui/visual_settings.cc new file mode 100644 index 0000000..5488eb6 --- /dev/null +++ b/selfdrive/frogpilot/ui/visual_settings.cc @@ -0,0 +1,156 @@ +#include "selfdrive/frogpilot/ui/visual_settings.h" + +FrogPilotVisualsPanel::FrogPilotVisualsPanel(SettingsWindow *parent) : FrogPilotListWidget(parent) { + const std::vector> visualToggles { + {"CustomAlerts", "Custom Alerts", "Enable custom alerts for various logic or situational changes.", "../frogpilot/assets/toggle_icons/icon_green_light.png"}, + + {"CustomUI", "Custom Onroad UI", "Customize the Onroad UI with some additional visual functions.", "../assets/offroad/icon_road.png"}, + + {"QOLVisuals", "Quality of Life", "Miscellaneous quality of life changes to improve your overall openpilot experience.", "../frogpilot/assets/toggle_icons/quality_of_life.png"}, + }; + + for (const auto &[param, title, desc, icon] : visualToggles) { + ParamControl *toggle; + + if (param == "CustomAlerts") { + FrogPilotParamManageControl *customAlertsToggle = new FrogPilotParamManageControl(param, title, desc, icon, this); + QObject::connect(customAlertsToggle, &FrogPilotParamManageControl::manageButtonClicked, this, [this]() { + parentToggleClicked(); + for (auto &[key, toggle] : toggles) { + toggle->setVisible(customAlertsKeys .find(key.c_str()) != customAlertsKeys .end()); + } + }); + toggle = customAlertsToggle; + + } else if (param == "CustomUI") { + FrogPilotParamManageControl *customUIToggle = new FrogPilotParamManageControl(param, title, desc, icon, this); + QObject::connect(customUIToggle, &FrogPilotParamManageControl::manageButtonClicked, this, [this]() { + parentToggleClicked(); + for (auto &[key, toggle] : toggles) { + toggle->setVisible(customOnroadUIKeys.find(key.c_str()) != customOnroadUIKeys.end()); + } + }); + toggle = customUIToggle; + + } 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 { + toggle = new ParamControl(param, title, desc, icon, this); + } + + addItem(toggle); + toggles[param.toStdString()] = toggle; + + QObject::connect(toggle, &ToggleControl::toggleFlipped, [this]() { + updateToggles(); + }); + + QObject::connect(static_cast(toggle), &FrogPilotButtonParamControl::buttonClicked, [this]() { + updateToggles(); + }); + + QObject::connect(static_cast(toggle), &FrogPilotParamValueControl::valueChanged, [this]() { + updateToggles(); + }); + + QObject::connect(toggle, &AbstractControl::showDescriptionEvent, [this]() { + update(); + }); + + QObject::connect(static_cast(toggle), &FrogPilotParamManageControl::manageButtonClicked, [this]() { + update(); + }); + } + + std::set rebootKeys = {""}; + for (const std::string &key : rebootKeys) { + QObject::connect(toggles[key], &ToggleControl::toggleFlipped, [this, key]() { + if (started) { + if (FrogPilotConfirmationDialog::toggle("Reboot required to take effect.", "Reboot Now", this)) { + Hardware::soft_reboot(); + } + } + }); + } + + QObject::connect(device(), &Device::interactiveTimeout, this, &FrogPilotVisualsPanel::hideSubToggles); + QObject::connect(parent, &SettingsWindow::closeParentToggle, this, &FrogPilotVisualsPanel::hideSubToggles); + QObject::connect(parent, &SettingsWindow::closeSubParentToggle, this, &FrogPilotVisualsPanel::hideSubSubToggles); + QObject::connect(parent, &SettingsWindow::updateMetric, this, &FrogPilotVisualsPanel::updateMetric); + QObject::connect(uiState(), &UIState::uiUpdate, this, &FrogPilotVisualsPanel::updateState); + + hideSubToggles(); + updateMetric(); +} + +void FrogPilotVisualsPanel::updateState(const UIState &s) { + started = s.scene.started; +} + +void FrogPilotVisualsPanel::updateToggles() { + std::thread([this]() { + paramsMemory.putBool("FrogPilotTogglesUpdated", true); + std::this_thread::sleep_for(std::chrono::seconds(1)); + paramsMemory.putBool("FrogPilotTogglesUpdated", false); + }).detach(); +} + +void FrogPilotVisualsPanel::updateMetric() { + bool previousIsMetric = isMetric; + isMetric = params.getBool("IsMetric"); + + if (isMetric != previousIsMetric) { + double distanceConversion = isMetric ? INCH_TO_CM : CM_TO_INCH; + double speedConversion = isMetric ? FOOT_TO_METER : METER_TO_FOOT; + } + + if (isMetric) { + } else { + } + + previousIsMetric = isMetric; +} + +void FrogPilotVisualsPanel::parentToggleClicked() { + openParentToggle(); +} + +void FrogPilotVisualsPanel::subParentToggleClicked() { + openSubParentToggle(); +} + +void FrogPilotVisualsPanel::hideSubToggles() { + for (auto &[key, toggle] : toggles) { + bool subToggles = alertVolumeControlKeys.find(key.c_str()) != alertVolumeControlKeys.end() || + customAlertsKeys.find(key.c_str()) != customAlertsKeys.end() || + customOnroadUIKeys.find(key.c_str()) != customOnroadUIKeys.end() || + customThemeKeys.find(key.c_str()) != customThemeKeys.end() || + modelUIKeys.find(key.c_str()) != modelUIKeys.end() || + qolKeys.find(key.c_str()) != qolKeys.end(); + toggle->setVisible(!subToggles); + } + + closeParentToggle(); +} + +void FrogPilotVisualsPanel::hideSubSubToggles() { + for (auto &[key, toggle] : toggles) { + bool isVisible = false; + toggle->setVisible(isVisible); + } + + closeSubParentToggle(); + update(); +} + +void FrogPilotVisualsPanel::hideEvent(QHideEvent *event) { + hideSubToggles(); +} diff --git a/selfdrive/frogpilot/ui/visual_settings.h b/selfdrive/frogpilot/ui/visual_settings.h new file mode 100644 index 0000000..ce69c60 --- /dev/null +++ b/selfdrive/frogpilot/ui/visual_settings.h @@ -0,0 +1,45 @@ +#pragma once + +#include + +#include "selfdrive/frogpilot/ui/frogpilot_ui_functions.h" +#include "selfdrive/ui/qt/offroad/settings.h" +#include "selfdrive/ui/ui.h" + +class FrogPilotVisualsPanel : public FrogPilotListWidget { + Q_OBJECT + +public: + explicit FrogPilotVisualsPanel(SettingsWindow *parent); + +signals: + void closeParentToggle(); + void closeSubParentToggle(); + void openParentToggle(); + void openSubParentToggle(); + +private: + void hideEvent(QHideEvent *event); + void hideSubToggles(); + void hideSubSubToggles(); + void parentToggleClicked(); + void subParentToggleClicked(); + void updateMetric(); + void updateState(const UIState &s); + void updateToggles(); + + std::set alertVolumeControlKeys = {}; + std::set customAlertsKeys = {}; + std::set customOnroadUIKeys = {}; + std::set customThemeKeys = {}; + std::set modelUIKeys = {}; + std::set qolKeys = {}; + + std::map toggles; + + Params params; + Params paramsMemory{"/dev/shm/params"}; + + bool isMetric = params.getBool("IsMetric"); + bool started = false; +}; diff --git a/selfdrive/manager/manager.py b/selfdrive/manager/manager.py index bf1eeb8..cc6cc8d 100755 --- a/selfdrive/manager/manager.py +++ b/selfdrive/manager/manager.py @@ -2,6 +2,7 @@ import datetime import os import signal +import subprocess import sys import traceback from typing import List, Tuple, Union @@ -27,12 +28,38 @@ def manager_init() -> None: save_bootlog() params = Params() + params_storage = Params("/persist/comma/params") params.clear_all(ParamKeyType.CLEAR_ON_MANAGER_START) params.clear_all(ParamKeyType.CLEAR_ON_ONROAD_TRANSITION) params.clear_all(ParamKeyType.CLEAR_ON_OFFROAD_TRANSITION) if is_release_branch(): params.clear_all(ParamKeyType.DEVELOPMENT_ONLY) + ############### Remove this after the April 26th update ############### + + previous_speed_limit = params.get_float("PreviousSpeedLimit") + if previous_speed_limit >= 50: + params.put_float("PreviousSpeedLimit", previous_speed_limit / 100) + + for priority_key in ["SLCPriority", "SLCPriority1", "SLCPriority2", "SLCPriority3"]: + priority_value = params.get(priority_key) + if isinstance(priority_value, int): + params.remove(priority_key) + + attributes = ["AggressiveFollow", "StandardFollow", "RelaxedFollow", "AggressiveJerk", "StandardJerk", "RelaxedJerk"] + values = {attr: params.get_float(attr) for attr in attributes} + if any(value > 5 for value in values.values()): + for attr, value in values.items(): + params.put_float(attr, value / 10) + + if params.get_bool("SilentMode"): + attributes = ["DisengageVolume", "EngageVolume", "PromptVolume", "PromptDistractedVolume", "RefuseVolume", "WarningSoftVolume", "WarningImmediateVolume"] + for attr in attributes: + params.put_float(attr, 0) + params.put_bool("SilentMode", False) + + ####################################################################### + default_params: List[Tuple[str, Union[str, bytes]]] = [ ("CompletedTrainingVersion", "0"), ("DisengageOnAccelerator", "0"), @@ -40,7 +67,192 @@ def manager_init() -> None: ("HasAcceptedTerms", "0"), ("LanguageSetting", "main_en"), ("OpenpilotEnabledToggle", "1"), + ("UpdaterAvailableBranches", ""), ("LongitudinalPersonality", str(log.LongitudinalPersonality.standard)), + + # Default FrogPilot parameters + ("AccelerationPath", "1"), + ("AccelerationProfile", "2"), + ("AdjacentPath", "0"), + ("AdjacentPathMetrics", "0"), + ("AdjustablePersonalities", "1"), + ("AggressiveAcceleration", "1"), + ("AggressiveFollow", "1.25"), + ("AggressiveJerk", "0.5"), + ("AlertVolumeControl", "0"), + ("AlwaysOnLateral", "1"), + ("AlwaysOnLateralMain", "0"), + ("BlindSpotPath", "1"), + ("CameraView", "1"), + ("CarMake", ""), + ("CarModel", ""), + ("CECurves", "1"), + ("CENavigation", "1"), + ("CENavigationIntersections", "1"), + ("CENavigationLead", "1"), + ("CENavigationTurns", "1"), + ("CESignal", "1"), + ("CESlowerLead", "0"), + ("CESpeed", "0"), + ("CESpeedLead", "0"), + ("CEStopLights", "1"), + ("CEStopLightsLead", "0"), + ("Compass", "0"), + ("ConditionalExperimental", "1"), + ("CrosstrekTorque", "1"), + ("CurveSensitivity", "100"), + ("CustomAlerts", "1"), + ("CustomColors", "1"), + ("CustomIcons", "1"), + ("CustomPersonalities", "1"), + ("CustomSignals", "1"), + ("CustomSounds", "1"), + ("CustomTheme", "1"), + ("CustomUI", "1"), + ("CydiaTune", "0"), + ("DecelerationProfile", "1"), + ("DeviceShutdown", "9"), + ("DisableMTSCSmoothing", "0"), + ("DisableOnroadUploads", "0"), + ("DisableOpenpilotLongitudinal", "0"), + ("DisableVTSCSmoothing", "0"), + ("DisengageVolume", "100"), + ("DragonPilotTune", "0"), + ("DriverCamera", "0"), + ("DriveStats", "1"), + ("DynamicPathWidth", "0"), + ("EngageVolume", "100"), + ("EVTable", "1"), + ("ExperimentalModeActivation", "1"), + ("ExperimentalModeViaDistance", "0"), + ("ExperimentalModeViaLKAS", "0"), + ("ExperimentalModeViaScreen", "1"), + ("Fahrenheit", "0"), + ("FireTheBabysitter", "0"), + ("ForceAutoTune", "0"), + ("ForceFingerprint", "0"), + ("ForceMPHDashboard", "0"), + ("FPSCounter", "0"), + ("FrogPilotDrives", "0"), + ("FrogPilotKilometers", "0"), + ("FrogPilotMinutes", "0"), + ("FrogsGoMooTune", "1"), + ("FullMap", "0"), + ("GasRegenCmd", "0"), + ("GoatScream", "1"), + ("GreenLightAlert", "0"), + ("HideAlerts", "0"), + ("HideAOLStatusBar", "0"), + ("HideCEMStatusBar", "0"), + ("HideLeadMarker", "0"), + ("HideMapIcon", "0"), + ("HideMaxSpeed", "0"), + ("HideSpeed", "0"), + ("HideSpeedUI", "0"), + ("HideUIElements", "0"), + ("HigherBitrate", "0"), + ("LaneChangeTime", "0"), + ("LaneDetection", "1"), + ("LaneDetectionWidth", "60"), + ("LaneLinesWidth", "4"), + ("LateralTune", "1"), + ("LeadDepartingAlert", "0"), + ("LeadDetectionThreshold", "25"), + ("LeadInfo", "0"), + ("LockDoors", "0"), + ("LongitudinalTune", "1"), + ("LongPitch", "1"), + ("LoudBlindspotAlert", "0"), + ("LowerVolt", "1"), + ("MapsSelected", ""), + ("MapStyle", "0"), + ("MTSCAggressiveness", "100"), + ("MTSCCurvatureCheck", "0"), + ("MTSCLimit", "0"), + ("Model", DEFAULT_MODEL), + ("ModelUI", "1"), + ("MTSCEnabled", "1"), + ("MuteOverheated", "0"), + ("NavChill", "0"), + ("NNFF", "1"), + ("NoLogging", "0"), + ("NoUploads", "0"), + ("NudgelessLaneChange", "1"), + ("NumericalTemp", "0"), + ("OfflineMode", "0"), + ("Offset1", "5"), + ("Offset2", "5"), + ("Offset3", "5"), + ("Offset4", "10"), + ("OneLaneChange", "1"), + ("PathEdgeWidth", "20"), + ("PathWidth", "61"), + ("PauseLateralOnSignal", "0"), + ("PedalsOnUI", "1"), + ("PersonalitiesViaScreen", "1"), + ("PersonalitiesViaWheel", "1"), + ("PreferredSchedule", "0"), + ("PromptVolume", "100"), + ("PromptDistractedVolume", "100"), + ("QOLControls", "1"), + ("QOLVisuals", "1"), + ("RandomEvents", "0"), + ("RefuseVolume", "100"), + ("RelaxedFollow", "1.75"), + ("RelaxedJerk", "1.0"), + ("ReverseCruise", "0"), + ("ReverseCruiseUI", "1"), + ("RoadEdgesWidth", "2"), + ("RoadNameUI", "1"), + ("RotatingWheel", "1"), + ("ScreenBrightness", "101"), + ("ScreenBrightnessOnroad", "101"), + ("ScreenManagement", "1"), + ("ScreenRecorder", "1"), + ("ScreenTimeout", "30"), + ("ScreenTimeoutOnroad", "30"), + ("SearchInput", "0"), + ("SetSpeedLimit", "0"), + ("SetSpeedOffset", "0"), + ("ShowCPU", "0"), + ("ShowGPU", "0"), + ("ShowIP", "0"), + ("ShowMemoryUsage", "0"), + ("ShowSLCOffset", "0"), + ("ShowSLCOffsetUI", "1"), + ("ShowStorageLeft", "0"), + ("ShowStorageUsed", "0"), + ("Sidebar", "0"), + ("SLCConfirmation", "1"), + ("SLCConfirmationLower", "1"), + ("SLCConfirmationHigher", "1"), + ("SLCFallback", "2"), + ("SLCOverride", "1"), + ("SLCPriority1", "Dashboard"), + ("SLCPriority2", "Offline Maps"), + ("SLCPriority3", "Navigation"), + ("SmoothBraking", "1"), + ("SNGHack", "1"), + ("SpeedLimitChangedAlert", "1"), + ("SpeedLimitController", "1"), + ("StandardFollow", "1.45"), + ("StandardJerk", "1.0"), + ("StandbyMode", "0"), + ("SteerRatio", "0"), + ("StockTune", "0"), + ("StoppingDistance", "0"), + ("TurnAggressiveness", "100"), + ("TurnDesires", "0"), + ("UnlimitedLength", "1"), + ("UpdateSchedule", "0"), + ("UseLateralJerk", "0"), + ("UseSI", "0"), + ("UseVienna", "0"), + ("VisionTurnControl", "1"), + ("WarningSoftVolume", "100"), + ("WarningImmediateVolume", "100"), + ("WheelIcon", "3"), + ("WheelSpeed", "0") ] if not PC: default_params.append(("LastUpdateTime", datetime.datetime.utcnow().isoformat().encode('utf8'))) @@ -51,7 +263,12 @@ def manager_init() -> None: # set unset params for k, v in default_params: if params.get(k) is None: - params.put(k, v) + if params_storage.get(k) is None: + params.put(k, v) + else: + params.put(k, params_storage.get(k)) + else: + params_storage.put(k, params.get(k)) # Create folders needed for msgq try: @@ -114,12 +331,21 @@ def manager_cleanup() -> None: cloudlog.info("everything is dead") +def update_frogpilot_params(params, params_memory): + keys = [] + for key in keys: + params_memory.put_bool(key, params.get_bool(key)) + def manager_thread() -> None: cloudlog.bind(daemon="manager") cloudlog.info("manager start") cloudlog.info({"environ": os.environ}) params = Params() + params_memory = Params("/dev/shm/params") + params_storage = Params("/persist/comma/params") + + update_frogpilot_params(params, params_memory) ignore: List[str] = [] if params.get("DongleId", encoding='utf8') in (None, UNREGISTERED_DONGLE_ID): @@ -132,7 +358,7 @@ def manager_thread() -> None: pm = messaging.PubMaster(['managerState']) write_onroad_params(False, params) - ensure_running(managed_processes.values(), False, params=params, CP=sm['carParams'], not_run=ignore) + ensure_running(managed_processes.values(), False, params=params, params_memory=params_memory, CP=sm['carParams'], not_run=ignore) started_prev = False @@ -152,7 +378,7 @@ def manager_thread() -> None: started_prev = started - ensure_running(managed_processes.values(), started, params=params, CP=sm['carParams'], not_run=ignore) + ensure_running(managed_processes.values(), started, params=params, params_memory=params_memory, CP=sm['carParams'], not_run=ignore) running = ' '.join("%s%s\u001b[0m" % ("\u001b[32m" if p.proc.is_alive() else "\u001b[31m", p.name) for p in managed_processes.values() if p.proc) @@ -175,8 +401,18 @@ def manager_thread() -> None: if shutdown: break + if params_memory.get_bool("FrogPilotTogglesUpdated"): + update_frogpilot_params(params, params_memory) def main() -> None: + # Create the long term param storage folder + try: + # Attempt to remount /persist as read-write + subprocess.run(['sudo', 'mount', '-o', 'remount,rw', '/persist'], check=True) + print("Successfully remounted /persist as read-write.") + except subprocess.CalledProcessError as e: + print(f"Failed to remount /persist. Error: {e}") + manager_init() if os.getenv("PREPAREONLY") is not None: return diff --git a/selfdrive/manager/process.py b/selfdrive/manager/process.py index ac1b4ac..e122e58 100644 --- a/selfdrive/manager/process.py +++ b/selfdrive/manager/process.py @@ -238,7 +238,7 @@ class DaemonProcess(ManagerProcess): self.params = None @staticmethod - def should_run(started, params, CP): + def should_run(started, params, params_memory, CP): return True def prepare(self) -> None: @@ -273,14 +273,14 @@ class DaemonProcess(ManagerProcess): pass -def ensure_running(procs: ValuesView[ManagerProcess], started: bool, params=None, CP: car.CarParams=None, +def ensure_running(procs: ValuesView[ManagerProcess], started: bool, params=None, params_memory=None, CP: car.CarParams=None, not_run: Optional[List[str]]=None) -> List[ManagerProcess]: if not_run is None: not_run = [] running = [] for p in procs: - if p.enabled and p.name not in not_run and p.should_run(started, params, CP): + if p.enabled and p.name not in not_run and p.should_run(started, params, params_memory, CP): running.append(p) else: p.stop(block=False) diff --git a/selfdrive/manager/process_config.py b/selfdrive/manager/process_config.py index cb6dd88..7ab2a5a 100644 --- a/selfdrive/manager/process_config.py +++ b/selfdrive/manager/process_config.py @@ -7,40 +7,42 @@ from openpilot.selfdrive.manager.process import PythonProcess, NativeProcess, Da WEBCAM = os.getenv("USE_WEBCAM") is not None -def driverview(started: bool, params: Params, CP: car.CarParams) -> bool: +def driverview(started: bool, params: Params, params_memory: Params, CP: car.CarParams) -> bool: return started or params.get_bool("IsDriverViewEnabled") -def notcar(started: bool, params: Params, CP: car.CarParams) -> bool: +def notcar(started: bool, params: Params, params_memory: Params, CP: car.CarParams) -> bool: return started and CP.notCar -def iscar(started: bool, params: Params, CP: car.CarParams) -> bool: +def iscar(started: bool, params: Params, params_memory: Params, CP: car.CarParams) -> bool: return started and not CP.notCar -def logging(started, params, CP: car.CarParams) -> bool: +def logging(started, params, params_memory, CP: car.CarParams) -> bool: run = (not CP.notCar) or not params.get_bool("DisableLogging") return started and run def ublox_available() -> bool: return os.path.exists('/dev/ttyHS0') and not os.path.exists('/persist/comma/use-quectel-gps') -def ublox(started, params, CP: car.CarParams) -> bool: +def ublox(started, params, params_memory, CP: car.CarParams) -> bool: use_ublox = ublox_available() if use_ublox != params.get_bool("UbloxAvailable"): params.put_bool("UbloxAvailable", use_ublox) return started and use_ublox -def qcomgps(started, params, CP: car.CarParams) -> bool: +def qcomgps(started, params, params_memory, CP: car.CarParams) -> bool: return started and not ublox_available() -def always_run(started, params, CP: car.CarParams) -> bool: +def always_run(started, params, params_memory, CP: car.CarParams) -> bool: return True -def only_onroad(started: bool, params, CP: car.CarParams) -> bool: +def only_onroad(started: bool, params, params_memory, CP: car.CarParams) -> bool: return started -def only_offroad(started, params, CP: car.CarParams) -> bool: +def only_offroad(started, params, params_memory, CP: car.CarParams) -> bool: return not started +# FrogPilot functions + procs = [ DaemonProcess("manage_athenad", "selfdrive.athena.manage_athenad", "AthenadPid"), @@ -86,6 +88,8 @@ procs = [ NativeProcess("bridge", "cereal/messaging", ["./bridge"], notcar), PythonProcess("webrtcd", "system.webrtc.webrtcd", notcar), PythonProcess("webjoystick", "tools.bodyteleop.web", notcar), + + # FrogPilot processes ] managed_processes = {p.name: p for p in procs} diff --git a/selfdrive/modeld/modeld.py b/selfdrive/modeld/modeld.py index f2842d9..8a12fb9 100755 --- a/selfdrive/modeld/modeld.py +++ b/selfdrive/modeld/modeld.py @@ -154,7 +154,7 @@ def main(demo=False): # messaging pm = PubMaster(["modelV2", "cameraOdometry"]) - sm = SubMaster(["carState", "roadCameraState", "liveCalibration", "driverMonitoringState", "navModel", "navInstruction", "carControl"]) + sm = SubMaster(["carState", "roadCameraState", "liveCalibration", "driverMonitoringState", "navModel", "navInstruction", "carControl", "frogpilotPlan"]) publish_state = PublishState() params = Params() @@ -298,7 +298,7 @@ def main(demo=False): l_lane_change_prob = desire_state[log.Desire.laneChangeLeft] r_lane_change_prob = desire_state[log.Desire.laneChangeRight] lane_change_prob = l_lane_change_prob + r_lane_change_prob - DH.update(sm['carState'], sm['carControl'].latActive, lane_change_prob) + DH.update(sm['carState'], sm['carControl'].latActive, lane_change_prob, sm['frogpilotPlan']) modelv2_send.modelV2.meta.laneChangeState = DH.lane_change_state modelv2_send.modelV2.meta.laneChangeDirection = DH.lane_change_direction diff --git a/selfdrive/navd/navd.py b/selfdrive/navd/navd.py index 2be703c..863e251 100755 --- a/selfdrive/navd/navd.py +++ b/selfdrive/navd/navd.py @@ -28,6 +28,7 @@ class RouteEngine: self.pm = pm self.params = Params() + self.params_memory = Params("/dev/shm/params") # Get last gps position from params self.last_position = coordinate_from_param("LastGPSPosition", self.params) @@ -59,7 +60,14 @@ class RouteEngine: self.mapbox_token = "" self.mapbox_host = "https://maps.comma.ai" + # FrogPilot variables + self.update_frogpilot_params() + def update(self): + # Update FrogPilot parameters + if self.params_memory.get_bool("FrogPilotTogglesUpdated"): + self.update_frogpilot_params() + self.sm.update(0) if self.sm.updated["managerState"]: @@ -301,6 +309,11 @@ class RouteEngine: self.params.remove("NavDestination") self.clear_route() + frogpilot_plan_send = messaging.new_message('frogpilotNavigation') + frogpilotNavigation = frogpilot_plan_send.frogpilotNavigation + + self.pm.send('frogpilotNavigation', frogpilot_plan_send) + def send_route(self): coords = [] @@ -349,9 +362,10 @@ class RouteEngine: return self.reroute_counter > REROUTE_COUNTER_MIN # TODO: Check for going wrong way in segment + def update_frogpilot_params(self): def main(): - pm = messaging.PubMaster(['navInstruction', 'navRoute']) + pm = messaging.PubMaster(['navInstruction', 'navRoute', 'frogpilotNavigation']) sm = messaging.SubMaster(['liveLocationKalman', 'managerState']) rk = Ratekeeper(1.0) diff --git a/selfdrive/thermald/power_monitoring.py b/selfdrive/thermald/power_monitoring.py index f74118b..62245ba 100644 --- a/selfdrive/thermald/power_monitoring.py +++ b/selfdrive/thermald/power_monitoring.py @@ -37,6 +37,8 @@ class PowerMonitoring: # Reset capacity if it's low self.car_battery_capacity_uWh = max((CAR_BATTERY_CAPACITY_uWh / 10), int(car_battery_capacity_uWh)) + # FrogPilot variables + # Calculation tick def calculate(self, voltage: Optional[int], ignition: bool): try: diff --git a/selfdrive/thermald/thermald.py b/selfdrive/thermald/thermald.py index e868f2f..6a02499 100755 --- a/selfdrive/thermald/thermald.py +++ b/selfdrive/thermald/thermald.py @@ -164,7 +164,7 @@ def hw_state_thread(end_event, hw_queue): def thermald_thread(end_event, hw_queue) -> None: - pm = messaging.PubMaster(['deviceState']) + pm = messaging.PubMaster(['deviceState', 'frogpilotDeviceState']) sm = messaging.SubMaster(["peripheralState", "gpsLocationExternal", "controlsState", "pandaStates"], poll="pandaStates") count = 0 @@ -242,6 +242,10 @@ def thermald_thread(end_event, hw_queue) -> None: except queue.Empty: pass + fpmsg = messaging.new_message('frogpilotDeviceState') + + pm.send("frogpilotDeviceState", fpmsg) + msg.deviceState.freeSpacePercent = get_available_percent(default=100.0) msg.deviceState.memoryUsagePercent = int(round(psutil.virtual_memory().percent)) msg.deviceState.gpuUsagePercent = int(round(HARDWARE.get_gpu_usage_percent())) diff --git a/selfdrive/ui/SConscript b/selfdrive/ui/SConscript index ea5734f..bc55373 100644 --- a/selfdrive/ui/SConscript +++ b/selfdrive/ui/SConscript @@ -23,7 +23,10 @@ widgets_src = ["ui.cc", "qt/widgets/input.cc", "qt/widgets/wifi.cc", "qt/widgets/ssh_keys.cc", "qt/widgets/toggle.cc", "qt/widgets/controls.cc", "qt/widgets/offroad_alerts.cc", "qt/widgets/prime.cc", "qt/widgets/keyboard.cc", "qt/widgets/scrollview.cc", "qt/widgets/cameraview.cc", "#third_party/qrcode/QrCode.cc", - "qt/request_repeater.cc", "qt/qt_window.cc", "qt/network/networking.cc", "qt/network/wifi_manager.cc"] + "qt/request_repeater.cc", "qt/qt_window.cc", "qt/network/networking.cc", "qt/network/wifi_manager.cc", + "../frogpilot/ui/frogpilot_ui_functions.cc", + "../frogpilot/ui/control_settings.cc", "../frogpilot/ui/vehicle_settings.cc", + "../frogpilot/ui/visual_settings.cc"] qt_env['CPPDEFINES'] = [] if maps: diff --git a/selfdrive/ui/qt/home.h b/selfdrive/ui/qt/home.h index c603285..b9f8e37 100644 --- a/selfdrive/ui/qt/home.h +++ b/selfdrive/ui/qt/home.h @@ -39,6 +39,8 @@ private: OffroadAlert* alerts_widget; QPushButton* alert_notif; QPushButton* update_notif; + + // FrogPilot variables }; class HomeWindow : public QWidget { @@ -69,6 +71,9 @@ private: DriverViewWindow *driver_view; QStackedLayout *slayout; + // FrogPilot variables + Params params; + private slots: void updateState(const UIState &s); }; diff --git a/selfdrive/ui/qt/maps/map.h b/selfdrive/ui/qt/maps/map.h index 81ba500..5849b64 100644 --- a/selfdrive/ui/qt/maps/map.h +++ b/selfdrive/ui/qt/maps/map.h @@ -78,6 +78,9 @@ private: void updateDestinationMarker(); uint64_t route_rcv_frame = 0; + // FrogPilot variables + Params params; + private slots: void updateState(const UIState &s); diff --git a/selfdrive/ui/qt/maps/map_helpers.h b/selfdrive/ui/qt/maps/map_helpers.h index 0f4be67..aefc0c4 100644 --- a/selfdrive/ui/qt/maps/map_helpers.h +++ b/selfdrive/ui/qt/maps/map_helpers.h @@ -8,6 +8,7 @@ #include #include +#include "common/params.h" #include "common/util.h" #include "common/transformations/coordinates.hpp" #include "common/transformations/orientation.hpp" diff --git a/selfdrive/ui/qt/maps/map_settings.h b/selfdrive/ui/qt/maps/map_settings.h index 0e151df..d7d019c 100644 --- a/selfdrive/ui/qt/maps/map_settings.h +++ b/selfdrive/ui/qt/maps/map_settings.h @@ -64,6 +64,8 @@ private: DestinationWidget *work_widget; std::vector widgets; + // FrogPilot variables + signals: void closeSettings(); }; diff --git a/selfdrive/ui/qt/offroad/settings.cc b/selfdrive/ui/qt/offroad/settings.cc index 85393ca..c0c5bde 100644 --- a/selfdrive/ui/qt/offroad/settings.cc +++ b/selfdrive/ui/qt/offroad/settings.cc @@ -7,6 +7,7 @@ #include #include +#include #include "selfdrive/ui/qt/network/networking.h" @@ -23,6 +24,10 @@ #include "selfdrive/ui/qt/util.h" #include "selfdrive/ui/qt/qt_window.h" +#include "selfdrive/frogpilot/ui/control_settings.h" +#include "selfdrive/frogpilot/ui/vehicle_settings.h" +#include "selfdrive/frogpilot/ui/visual_settings.h" + TogglesPanel::TogglesPanel(SettingsWindow *parent) : ListWidget(parent) { // param, title, desc, icon std::vector> toggle_defs{ @@ -117,6 +122,10 @@ TogglesPanel::TogglesPanel(SettingsWindow *parent) : ListWidget(parent) { connect(toggles["ExperimentalLongitudinalEnabled"], &ToggleControl::toggleFlipped, [=]() { updateToggles(); }); + + connect(toggles["IsMetric"], &ToggleControl::toggleFlipped, [=]() { + updateMetric(); + }); } void TogglesPanel::expandToggleDescription(const QString ¶m) { @@ -245,6 +254,20 @@ DevicePanel::DevicePanel(SettingsWindow *parent) : ListWidget(parent) { }); addItem(translateBtn); + // Delete long term toggle storage button + auto deleteStorageParamsBtn = new ButtonControl(tr("Delete Toggle Storage Data"), tr("DELETE"), tr("This button provides a swift and secure way to permanently delete all " + "long term stored toggle settings. Ideal for maintaining privacy or freeing up space.") + ); + connect(deleteStorageParamsBtn, &ButtonControl::clicked, [=]() { + if (!ConfirmationDialog::confirm(tr("Are you sure you want to permanently delete all of your long term toggle settings storage?"), tr("Delete"), this)) return; + std::thread([&] { + deleteStorageParamsBtn->setValue("Deleting params..."); + std::system("rm -rf /persist/comma/params"); + deleteStorageParamsBtn->setValue(""); + }).detach(); + }); + addItem(deleteStorageParamsBtn); + QObject::connect(uiState(), &UIState::offroadTransition, [=](bool offroad) { for (auto btn : findChildren()) { btn->setEnabled(offroad); @@ -364,7 +387,17 @@ SettingsWindow::SettingsWindow(QWidget *parent) : QFrame(parent) { close_btn->setFixedSize(200, 200); sidebar_layout->addSpacing(45); sidebar_layout->addWidget(close_btn, 0, Qt::AlignCenter); - QObject::connect(close_btn, &QPushButton::clicked, this, &SettingsWindow::closeSettings); + QObject::connect(close_btn, &QPushButton::clicked, [this]() { + if (parentToggleOpen) { + if (subParentToggleOpen) { + closeSubParentToggle(); + } else { + closeParentToggle(); + } + } else { + closeSettings(); + } + }); // setup panels DevicePanel *device = new DevicePanel(this); @@ -373,12 +406,28 @@ SettingsWindow::SettingsWindow(QWidget *parent) : QFrame(parent) { TogglesPanel *toggles = new TogglesPanel(this); QObject::connect(this, &SettingsWindow::expandToggleDescription, toggles, &TogglesPanel::expandToggleDescription); + QObject::connect(toggles, &TogglesPanel::updateMetric, this, &SettingsWindow::updateMetric); + + FrogPilotControlsPanel *frogpilotControls = new FrogPilotControlsPanel(this); + QObject::connect(frogpilotControls, &FrogPilotControlsPanel::closeSubParentToggle, this, [this]() {subParentToggleOpen = false;}); + QObject::connect(frogpilotControls, &FrogPilotControlsPanel::openSubParentToggle, this, [this]() {subParentToggleOpen = true;}); + QObject::connect(frogpilotControls, &FrogPilotControlsPanel::closeParentToggle, this, [this]() {parentToggleOpen = false;}); + QObject::connect(frogpilotControls, &FrogPilotControlsPanel::openParentToggle, this, [this]() {parentToggleOpen = true;}); + + FrogPilotVisualsPanel *frogpilotVisuals = new FrogPilotVisualsPanel(this); + QObject::connect(frogpilotVisuals, &FrogPilotVisualsPanel::closeSubParentToggle, this, [this]() {subParentToggleOpen = false;}); + QObject::connect(frogpilotVisuals, &FrogPilotVisualsPanel::openSubParentToggle, this, [this]() {subParentToggleOpen = true;}); + QObject::connect(frogpilotVisuals, &FrogPilotVisualsPanel::closeParentToggle, this, [this]() {parentToggleOpen = false;}); + QObject::connect(frogpilotVisuals, &FrogPilotVisualsPanel::openParentToggle, this, [this]() {parentToggleOpen = true;}); QList> panels = { {tr("Device"), device}, {tr("Network"), new Networking(this)}, {tr("Toggles"), toggles}, {tr("Software"), new SoftwarePanel(this)}, + {tr("Controls"), frogpilotControls}, + {tr("Vehicles"), new FrogPilotVehiclesPanel(this)}, + {tr("Visuals"), frogpilotVisuals}, }; nav_btns = new QButtonGroup(this); @@ -411,7 +460,22 @@ SettingsWindow::SettingsWindow(QWidget *parent) : QFrame(parent) { ScrollView *panel_frame = new ScrollView(panel, this); panel_widget->addWidget(panel_frame); + if (name == tr("Controls") || name == tr("Visuals")) { + QScrollBar *scrollbar = panel_frame->verticalScrollBar(); + + QObject::connect(scrollbar, &QScrollBar::valueChanged, this, [this](int value) { + if (!parentToggleOpen) { + previousScrollPosition = value; + } + }); + + QObject::connect(scrollbar, &QScrollBar::rangeChanged, this, [this, panel_frame]() { + panel_frame->restorePosition(previousScrollPosition); + }); + } + QObject::connect(btn, &QPushButton::clicked, [=, w = panel_frame]() { + previousScrollPosition = 0; btn->setChecked(true); panel_widget->setCurrentWidget(w); }); diff --git a/selfdrive/ui/qt/offroad/settings.h b/selfdrive/ui/qt/offroad/settings.h index a5dd25b..53cc735 100644 --- a/selfdrive/ui/qt/offroad/settings.h +++ b/selfdrive/ui/qt/offroad/settings.h @@ -31,11 +31,21 @@ signals: void showDriverView(); void expandToggleDescription(const QString ¶m); + // FrogPilot signals + void closeParentToggle(); + void closeSubParentToggle(); + void updateMetric(); private: QPushButton *sidebar_alert_widget; QWidget *sidebar_widget; QButtonGroup *nav_btns; QStackedWidget *panel_widget; + + // FrogPilot variables + bool parentToggleOpen; + bool subParentToggleOpen; + + int previousScrollPosition; }; class DevicePanel : public ListWidget { @@ -53,6 +63,9 @@ private slots: private: Params params; + + // FrogPilot variables + Params paramsMemory{"/dev/shm/params"}; }; class TogglesPanel : public ListWidget { @@ -61,6 +74,10 @@ public: explicit TogglesPanel(SettingsWindow *parent); void showEvent(QShowEvent *event) override; +signals: + // FrogPilot signals + void updateMetric(); + public slots: void expandToggleDescription(const QString ¶m); diff --git a/selfdrive/ui/qt/offroad/software_settings.cc b/selfdrive/ui/qt/offroad/software_settings.cc index 15c022d..b44dc48 100644 --- a/selfdrive/ui/qt/offroad/software_settings.cc +++ b/selfdrive/ui/qt/offroad/software_settings.cc @@ -15,6 +15,7 @@ #include "selfdrive/ui/qt/widgets/input.h" #include "system/hardware/hw.h" +#include "selfdrive/frogpilot/ui/frogpilot_ui_functions.h" void SoftwarePanel::checkForUpdates() { std::system("pkill -SIGUSR1 -f selfdrive.updated"); diff --git a/selfdrive/ui/qt/onroad.cc b/selfdrive/ui/qt/onroad.cc index 01750ea..775a89e 100644 --- a/selfdrive/ui/qt/onroad.cc +++ b/selfdrive/ui/qt/onroad.cc @@ -28,7 +28,7 @@ static void drawIcon(QPainter &p, const QPoint ¢er, const QPixmap &img, cons p.setOpacity(1.0); } -OnroadWindow::OnroadWindow(QWidget *parent) : QWidget(parent) { +OnroadWindow::OnroadWindow(QWidget *parent) : QWidget(parent), scene(uiState()->scene) { QVBoxLayout *main_layout = new QVBoxLayout(this); main_layout->setMargin(UI_BORDER_SIZE); QStackedLayout *stacked_layout = new QStackedLayout; @@ -93,8 +93,13 @@ void OnroadWindow::updateState(const UIState &s) { } void OnroadWindow::mousePressEvent(QMouseEvent* e) { + Params params = Params(); + + // FrogPilot clickable widgets + bool widgetClicked = false; + #ifdef ENABLE_MAPS - if (map != nullptr) { + if (map != nullptr && !widgetClicked) { // Switch between map and sidebar when using navigate on openpilot bool sidebarVisible = geometry().x() > 0; bool show_map = uiState()->scene.navigate_on_openpilot ? sidebarVisible : !sidebarVisible; @@ -102,7 +107,9 @@ void OnroadWindow::mousePressEvent(QMouseEvent* e) { } #endif // propagation event to parent(HomeWindow) - QWidget::mousePressEvent(e); + if (!widgetClicked) { + QWidget::mousePressEvent(e); + } } void OnroadWindow::offroadTransition(bool offroad) { @@ -114,6 +121,7 @@ void OnroadWindow::offroadTransition(bool offroad) { QObject::connect(m, &MapPanel::mapPanelRequested, this, &OnroadWindow::mapPanelRequested); QObject::connect(nvg->map_settings_btn, &MapSettingsButton::clicked, m, &MapPanel::toggleMapSettings); + QObject::connect(nvg->map_settings_btn_bottom, &MapSettingsButton::clicked, m, &MapPanel::toggleMapSettings); nvg->map_settings_btn->setEnabled(true); m->setFixedWidth(topWidget(this)->width() / 2 - UI_BORDER_SIZE); @@ -167,11 +175,13 @@ void OnroadAlerts::paintEvent(QPaintEvent *event) { int margin = 40; int radius = 30; + int offset = true ? 25 : 0; if (alert.size == cereal::ControlsState::AlertSize::FULL) { margin = 0; radius = 0; + offset = 0; } - QRect r = QRect(0 + margin, height() - h + margin, width() - margin*2, h - margin*2); + QRect r = QRect(0 + margin, height() - h + margin - offset, width() - margin*2, h - margin*2); QPainter p(this); @@ -212,7 +222,7 @@ void OnroadAlerts::paintEvent(QPaintEvent *event) { } // ExperimentalButton -ExperimentalButton::ExperimentalButton(QWidget *parent) : experimental_mode(false), engageable(false), QPushButton(parent) { +ExperimentalButton::ExperimentalButton(QWidget *parent) : experimental_mode(false), engageable(false), QPushButton(parent), scene(uiState()->scene) { setFixedSize(btn_size, btn_size); engage_img = loadPixmap("../assets/img_chffr_wheel.png", {img_size, img_size}); @@ -221,6 +231,8 @@ ExperimentalButton::ExperimentalButton(QWidget *parent) : experimental_mode(fals } void ExperimentalButton::changeMode() { + Params paramsMemory = Params("/dev/shm/params"); + const auto cp = (*uiState()->sm)["carParams"].getCarParams(); bool can_change = hasLongitudinalControl(cp) && params.getBool("ExperimentalModeConfirmed"); if (can_change) { @@ -236,6 +248,8 @@ void ExperimentalButton::updateState(const UIState &s) { experimental_mode = cs.getExperimentalMode(); update(); } + + // FrogPilot variables } void ExperimentalButton::paintEvent(QPaintEvent *event) { @@ -247,7 +261,7 @@ void ExperimentalButton::paintEvent(QPaintEvent *event) { // MapSettingsButton MapSettingsButton::MapSettingsButton(QWidget *parent) : QPushButton(parent) { - setFixedSize(btn_size, btn_size); + setFixedSize(btn_size, btn_size + 20); settings_img = loadPixmap("../assets/navigation/icon_directions_outlined.svg", {img_size, img_size}); // hidden by default, made visible if map is created (has prime or mapbox token) @@ -262,7 +276,7 @@ void MapSettingsButton::paintEvent(QPaintEvent *event) { // Window that shows camera view and variety of info drawn on top -AnnotatedCameraWidget::AnnotatedCameraWidget(VisionStreamType type, QWidget* parent) : fps_filter(UI_FREQ, 3, 1. / UI_FREQ), CameraWidget("camerad", type, true, parent) { +AnnotatedCameraWidget::AnnotatedCameraWidget(VisionStreamType type, QWidget* parent) : fps_filter(UI_FREQ, 3, 1. / UI_FREQ), CameraWidget("camerad", type, true, parent), scene(uiState()->scene) { pm = std::make_unique>({"uiDebug"}); main_layout = new QVBoxLayout(this); @@ -276,6 +290,9 @@ AnnotatedCameraWidget::AnnotatedCameraWidget(VisionStreamType type, QWidget* par main_layout->addWidget(map_settings_btn, 0, Qt::AlignBottom | Qt::AlignRight); dm_img = loadPixmap("../assets/img_driver_face.png", {img_size + 5, img_size + 5}); + + // Initialize FrogPilot widgets + initializeFrogPilotWidgets(); } void AnnotatedCameraWidget::updateState(const UIState &s) { @@ -468,7 +485,6 @@ void AnnotatedCameraWidget::updateFrameMat() { void AnnotatedCameraWidget::drawLaneLines(QPainter &painter, const UIState *s) { painter.save(); - const UIScene &scene = s->scene; SubMaster &sm = *(s->sm); // lanelines @@ -525,12 +541,11 @@ void AnnotatedCameraWidget::drawLaneLines(QPainter &painter, const UIState *s) { } void AnnotatedCameraWidget::drawDriverState(QPainter &painter, const UIState *s) { - const UIScene &scene = s->scene; - painter.save(); // base icon int offset = UI_BORDER_SIZE + btn_size / 2; + offset += true ? 25 : 0; int x = rightHandDM ? width() - offset : offset; int y = height() - offset; float opacity = dmActive ? 0.65 : 0.2; @@ -693,6 +708,9 @@ void AnnotatedCameraWidget::paintGL() { auto m = msg.initEvent().initUiDebug(); m.setDrawTimeMillis(cur_draw_t - start_draw_t); pm->send("uiDebug", msg); + + // Update FrogPilot widgets + updateFrogPilotWidgets(painter); } void AnnotatedCameraWidget::showEvent(QShowEvent *event) { @@ -701,3 +719,81 @@ void AnnotatedCameraWidget::showEvent(QShowEvent *event) { ui_update_params(uiState()); prev_draw_t = millis_since_boot(); } + +// FrogPilot widgets +void AnnotatedCameraWidget::initializeFrogPilotWidgets() { + bottom_layout = new QHBoxLayout(); + + QSpacerItem *spacer = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum); + bottom_layout->addItem(spacer); + + map_settings_btn_bottom = new MapSettingsButton(this); + bottom_layout->addWidget(map_settings_btn_bottom); + + main_layout->addLayout(bottom_layout); +} + +void AnnotatedCameraWidget::updateFrogPilotWidgets(QPainter &p) { + experimentalMode = scene.experimental_mode; + + if (true) { + drawStatusBar(p); + } + + map_settings_btn_bottom->setEnabled(map_settings_btn->isEnabled()); + if (map_settings_btn_bottom->isEnabled()) { + map_settings_btn_bottom->setVisible(!hideBottomIcons); + bottom_layout->setAlignment(map_settings_btn_bottom, rightHandDM ? Qt::AlignLeft : Qt::AlignRight); + } +} + +void AnnotatedCameraWidget::drawStatusBar(QPainter &p) { + p.save(); + + // Variable declarations + static QElapsedTimer timer; + static QString lastShownStatus; + + QString newStatus; + + static bool displayStatusText = false; + + constexpr qreal fadeDuration = 1500.0; + constexpr qreal textDuration = 5000.0; + + // Draw status bar + QRect currentRect = rect(); + QRect statusBarRect(currentRect.left() - 1, currentRect.bottom() - 50, currentRect.width() + 2, 100); + p.setBrush(QColor(0, 0, 0, 150)); + p.setOpacity(1.0); + p.drawRoundedRect(statusBarRect, 30, 30); + + // Check if status has changed + if (newStatus != lastShownStatus) { + displayStatusText = true; + lastShownStatus = newStatus; + timer.restart(); + } else if (displayStatusText && timer.hasExpired(textDuration + fadeDuration)) { + displayStatusText = false; + } + + // Configure the text + p.setFont(InterFont(40, QFont::Bold)); + p.setPen(Qt::white); + p.setRenderHint(QPainter::TextAntialiasing); + + // Calculate text opacity + static qreal statusTextOpacity; + int elapsed = timer.elapsed(); + if (displayStatusText) { + statusTextOpacity = qBound(0.0, 1.0 - (elapsed - textDuration) / fadeDuration, 1.0); + } + + // Draw the status text + p.setOpacity(statusTextOpacity); + QRect textRect = p.fontMetrics().boundingRect(statusBarRect, Qt::AlignCenter | Qt::TextWordWrap, newStatus); + textRect.moveBottom(statusBarRect.bottom() - 50); + p.drawText(textRect, Qt::AlignCenter | Qt::TextWordWrap, newStatus); + + p.restore(); +} diff --git a/selfdrive/ui/qt/onroad.h b/selfdrive/ui/qt/onroad.h index b3ba411..962a148 100644 --- a/selfdrive/ui/qt/onroad.h +++ b/selfdrive/ui/qt/onroad.h @@ -14,13 +14,14 @@ const int btn_size = 192; const int img_size = (btn_size / 4) * 3; +// FrogPilot global variables // ***** onroad widgets ***** class OnroadAlerts : public QWidget { Q_OBJECT public: - OnroadAlerts(QWidget *parent = 0) : QWidget(parent) {} + OnroadAlerts(QWidget *parent = 0) : QWidget(parent), scene(uiState()->scene) {} void updateAlert(const Alert &a); protected: @@ -29,6 +30,9 @@ protected: private: QColor bg; Alert alert = {}; + + // FrogPilot variables + UIScene &scene; }; class ExperimentalButton : public QPushButton { @@ -47,6 +51,9 @@ private: QPixmap experimental_img; bool experimental_mode; bool engageable; + + // FrogPilot variables + UIScene &scene; }; @@ -71,6 +78,7 @@ public: void updateState(const UIState &s); MapSettingsButton *map_settings_btn; + MapSettingsButton *map_settings_btn_bottom; private: void drawText(QPainter &p, int x, int y, const QString &text, int alpha = 255); @@ -97,6 +105,21 @@ private: int skip_frame_count = 0; bool wide_cam_requested = false; + // FrogPilot widgets + void initializeFrogPilotWidgets(); + void updateFrogPilotWidgets(QPainter &p); + + void drawStatusBar(QPainter &p); + + // FrogPilot variables + Params paramsMemory{"/dev/shm/params"}; + + UIScene &scene; + + QHBoxLayout *bottom_layout; + + bool experimentalMode; + protected: void paintGL() override; void initializeGL() override; @@ -135,6 +158,10 @@ private: QWidget *map = nullptr; QHBoxLayout* split; + // FrogPilot variables + UIScene &scene; + Params paramsMemory{"/dev/shm/params"}; + private slots: void offroadTransition(bool offroad); void primeChanged(bool prime); diff --git a/selfdrive/ui/qt/sidebar.cc b/selfdrive/ui/qt/sidebar.cc index e952940..702c6eb 100644 --- a/selfdrive/ui/qt/sidebar.cc +++ b/selfdrive/ui/qt/sidebar.cc @@ -24,7 +24,7 @@ void Sidebar::drawMetric(QPainter &p, const QPair &label, QCol 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()); flag_img = loadPixmap("../assets/images/button_flag.png", home_btn.size()); settings_img = loadPixmap("../assets/images/button_settings.png", settings_btn.size(), Qt::IgnoreAspectRatio); @@ -38,6 +38,8 @@ Sidebar::Sidebar(QWidget *parent) : QFrame(parent), onroad(false), flag_pressed( QObject::connect(uiState(), &UIState::uiUpdate, this, &Sidebar::updateState); pm = std::make_unique>({"userFlag"}); + + // FrogPilot variables } void Sidebar::mousePressEvent(QMouseEvent *event) { @@ -79,6 +81,9 @@ void Sidebar::updateState(const UIState &s) { int strength = (int)deviceState.getNetworkStrength(); setProperty("netStrength", strength > 0 ? strength + 1 : 0); + // FrogPilot properties + auto frogpilotDeviceState = sm["frogpilotDeviceState"].getFrogpilotDeviceState(); + ItemStatus connectStatus; auto last_ping = deviceState.getLastAthenaPingTime(); if (last_ping == 0) { diff --git a/selfdrive/ui/qt/sidebar.h b/selfdrive/ui/qt/sidebar.h index f627aac..a1d6c16 100644 --- a/selfdrive/ui/qt/sidebar.h +++ b/selfdrive/ui/qt/sidebar.h @@ -18,6 +18,8 @@ class Sidebar : public QFrame { Q_PROPERTY(QString netType MEMBER net_type NOTIFY valueChanged); Q_PROPERTY(int netStrength MEMBER net_strength NOTIFY valueChanged); + // FrogPilot properties + public: explicit Sidebar(QWidget* parent = 0); @@ -59,4 +61,8 @@ protected: private: std::unique_ptr pm; + + // FrogPilot variables + Params params; + UIScene &scene; }; diff --git a/selfdrive/ui/qt/spinner.cc b/selfdrive/ui/qt/spinner.cc index 2404efa..7ca2f1a 100644 --- a/selfdrive/ui/qt/spinner.cc +++ b/selfdrive/ui/qt/spinner.cc @@ -88,7 +88,7 @@ Spinner::Spinner(QWidget *parent) : QWidget(parent) { } QProgressBar::chunk { border-radius: 10px; - background-color: white; + background-color: rgba(23, 134, 68, 255); } )"); diff --git a/selfdrive/ui/qt/util.cc b/selfdrive/ui/qt/util.cc index bc3c494..a83d353 100644 --- a/selfdrive/ui/qt/util.cc +++ b/selfdrive/ui/qt/util.cc @@ -26,7 +26,7 @@ QString getVersion() { } QString getBrand() { - return QObject::tr("openpilot"); + return QObject::tr("FrogPilot"); } QString getUserAgent() { diff --git a/selfdrive/ui/qt/widgets/controls.h b/selfdrive/ui/qt/widgets/controls.h index e4630c6..8c4f06f 100644 --- a/selfdrive/ui/qt/widgets/controls.h +++ b/selfdrive/ui/qt/widgets/controls.h @@ -132,6 +132,10 @@ public: toggle.update(); } + void refresh() { + toggle.togglePosition(); + } + signals: void toggleFlipped(bool state); diff --git a/selfdrive/ui/qt/widgets/scrollview.cc b/selfdrive/ui/qt/widgets/scrollview.cc index 978bf83..2846007 100644 --- a/selfdrive/ui/qt/widgets/scrollview.cc +++ b/selfdrive/ui/qt/widgets/scrollview.cc @@ -44,6 +44,10 @@ ScrollView::ScrollView(QWidget *w, QWidget *parent) : QScrollArea(parent) { scroller->setScrollerProperties(sp); } +void ScrollView::restorePosition(int previousScrollPosition) { + verticalScrollBar()->setValue(previousScrollPosition); +} + void ScrollView::hideEvent(QHideEvent *e) { verticalScrollBar()->setValue(0); } diff --git a/selfdrive/ui/qt/widgets/scrollview.h b/selfdrive/ui/qt/widgets/scrollview.h index 024331a..1e67bbe 100644 --- a/selfdrive/ui/qt/widgets/scrollview.h +++ b/selfdrive/ui/qt/widgets/scrollview.h @@ -7,6 +7,9 @@ class ScrollView : public QScrollArea { public: explicit ScrollView(QWidget *w = nullptr, QWidget *parent = nullptr); + + // FrogPilot functions + void restorePosition(int previousScrollPosition); protected: void hideEvent(QHideEvent *e) override; }; diff --git a/selfdrive/ui/qt/widgets/wifi.h b/selfdrive/ui/qt/widgets/wifi.h index 60c865f..e15c4b0 100644 --- a/selfdrive/ui/qt/widgets/wifi.h +++ b/selfdrive/ui/qt/widgets/wifi.h @@ -12,6 +12,10 @@ class WiFiPromptWidget : public QFrame { public: explicit WiFiPromptWidget(QWidget* parent = 0); +private: + // FrogPilot variables + Params params; + signals: void openSettings(int index = 0, const QString ¶m = ""); diff --git a/selfdrive/ui/qt/window.h b/selfdrive/ui/qt/window.h index 05b61e1..f1389c2 100644 --- a/selfdrive/ui/qt/window.h +++ b/selfdrive/ui/qt/window.h @@ -22,4 +22,7 @@ private: HomeWindow *homeWindow; SettingsWindow *settingsWindow; OnboardingWindow *onboardingWindow; + + // FrogPilot variables + Params params; }; diff --git a/selfdrive/ui/soundd.py b/selfdrive/ui/soundd.py index 11caf80..2546a15 100644 --- a/selfdrive/ui/soundd.py +++ b/selfdrive/ui/soundd.py @@ -8,6 +8,7 @@ from typing import Dict, Optional, Tuple from cereal import car, messaging from openpilot.common.basedir import BASEDIR from openpilot.common.filter_simple import FirstOrderFilter +from openpilot.common.params import Params from openpilot.common.realtime import Ratekeeper from openpilot.common.retry import retry from openpilot.common.swaglog import cloudlog @@ -53,6 +54,12 @@ def check_controls_timeout_alert(sm): class Soundd: def __init__(self): + # FrogPilot variables + self.params = Params() + self.params_memory = Params("/dev/shm/params") + + self.update_frogpilot_params() + self.load_sounds() self.current_alert = AudibleAlert.none @@ -156,6 +163,11 @@ class Soundd: assert stream.active + # Update FrogPilot parameters + if self.params_memory.get_bool("FrogPilotTogglesUpdated"): + self.update_frogpilot_params() + + def update_frogpilot_params(self): def main(): s = Soundd() diff --git a/selfdrive/ui/ui.cc b/selfdrive/ui/ui.cc index 9afd22f..140f879 100644 --- a/selfdrive/ui/ui.cc +++ b/selfdrive/ui/ui.cc @@ -12,7 +12,6 @@ #include "common/util.h" #include "common/watchdog.h" #include "system/hardware/hw.h" - #define BACKLIGHT_DT 0.05 #define BACKLIGHT_TS 10.00 @@ -201,6 +200,23 @@ static void update_state(UIState *s) { if (sm.updated("carParams")) { scene.longitudinal_control = sm["carParams"].getCarParams().getOpenpilotLongitudinalControl(); } + if (sm.updated("carState")) { + auto carState = sm["carState"].getCarState(); + } + if (sm.updated("controlsState")) { + auto controlsState = sm["controlsState"].getControlsState(); + scene.enabled = controlsState.getEnabled(); + scene.experimental_mode = controlsState.getExperimentalMode(); + } + if (sm.updated("frogpilotCarControl")) { + auto frogpilotCarControl = sm["frogpilotCarControl"].getFrogpilotCarControl(); + } + if (sm.updated("frogpilotPlan")) { + auto frogpilotPlan = sm["frogpilotPlan"].getFrogpilotPlan(); + } + if (sm.updated("liveLocationKalman")) { + auto liveLocationKalman = sm["liveLocationKalman"].getLiveLocationKalman(); + } if (sm.updated("wideRoadCameraState")) { auto cam_state = sm["wideRoadCameraState"].getWideRoadCameraState(); float scale = (cam_state.getSensor() == cereal::FrameData::ImageSensor::AR0231) ? 6.0f : 1.0f; @@ -221,6 +237,19 @@ void ui_update_params(UIState *s) { s->scene.map_on_left = params.getBool("NavSettingLeftSide"); } +void ui_update_frogpilot_params(UIState *s) { + ui_update_params(s); + + Params params = Params(); + UIScene &scene = s->scene; + + bool custom_onroad_ui = params.getBool("CustomUI"); + + bool quality_of_life_controls = params.getBool("QOLControls"); + + bool quality_of_life_visuals = params.getBool("QOLVisuals"); +} + void UIState::updateStatus() { if (scene.started && sm->updated("controlsState")) { auto controls_state = (*sm)["controlsState"].getControlsState(); @@ -249,6 +278,7 @@ UIState::UIState(QObject *parent) : QObject(parent) { "modelV2", "controlsState", "liveCalibration", "radarState", "deviceState", "pandaStates", "carParams", "driverMonitoringState", "carState", "liveLocationKalman", "driverStateV2", "wideRoadCameraState", "managerState", "navInstruction", "navRoute", "uiPlan", + "frogpilotCarControl", "frogpilotDeviceState", "frogpilotPlan", }); Params params; @@ -262,6 +292,8 @@ UIState::UIState(QObject *parent) : QObject(parent) { timer = new QTimer(this); QObject::connect(timer, &QTimer::timeout, this, &UIState::update); timer->start(1000 / UI_FREQ); + + ui_update_frogpilot_params(this); } void UIState::update() { @@ -273,6 +305,15 @@ void UIState::update() { watchdog_kick(nanos_since_boot()); } emit uiUpdate(*this); + + // Update FrogPilot variables when they are changed + Params paramsMemory{"/dev/shm/params"}; + if (paramsMemory.getBool("FrogPilotTogglesUpdated")) { + std::thread updateFrogPilotParams(ui_update_frogpilot_params, this); + updateFrogPilotParams.detach(); + } + + // FrogPilot live variables that need to be constantly checked } void UIState::setPrimeType(PrimeType type) { diff --git a/selfdrive/ui/ui.h b/selfdrive/ui/ui.h index 86cd70f..8ac8034 100644 --- a/selfdrive/ui/ui.h +++ b/selfdrive/ui/ui.h @@ -105,6 +105,8 @@ typedef enum UIStatus { STATUS_DISENGAGED, STATUS_OVERRIDE, STATUS_ENGAGED, + + // FrogPilot statuses } UIStatus; enum PrimeType { @@ -121,12 +123,15 @@ const QColor bg_colors [] = { [STATUS_DISENGAGED] = QColor(0x17, 0x33, 0x49, 0xc8), [STATUS_OVERRIDE] = QColor(0x91, 0x9b, 0x95, 0xf1), [STATUS_ENGAGED] = QColor(0x17, 0x86, 0x44, 0xf1), + + // FrogPilot colors }; static std::map alert_colors = { {cereal::ControlsState::AlertStatus::NORMAL, QColor(0x15, 0x15, 0x15, 0xf1)}, {cereal::ControlsState::AlertStatus::USER_PROMPT, QColor(0xDA, 0x6F, 0x25, 0xf1)}, {cereal::ControlsState::AlertStatus::CRITICAL, QColor(0xC9, 0x22, 0x31, 0xf1)}, + {cereal::ControlsState::AlertStatus::FROGPILOT, QColor(0x17, 0x86, 0x44, 0xf1)}, }; typedef struct UIScene { @@ -160,6 +165,11 @@ typedef struct UIScene { bool started, ignition, is_metric, map_on_left, longitudinal_control; bool world_objects_visible = false; uint64_t started_frame; + + // FrogPilot variables + bool enabled; + bool experimental_mode; + } UIScene; class UIState : public QObject { @@ -249,3 +259,6 @@ void update_dmonitoring(UIState *s, const cereal::DriverStateV2::Reader &drivers void update_leads(UIState *s, const cereal::RadarState::Reader &radar_state, const cereal::XYZTData::Reader &line); void update_line_data(const UIState *s, const cereal::XYZTData::Reader &line, float y_off, float z_off, QPolygonF *pvd, int max_idx, bool allow_invert); + +// FrogPilot functions +void ui_update_frogpilot_params(UIState *s); diff --git a/selfdrive/updated.py b/selfdrive/updated.py index 3e4a849..5ed8e0b 100755 --- a/selfdrive/updated.py +++ b/selfdrive/updated.py @@ -237,6 +237,8 @@ class Updater: self.branches = defaultdict(lambda: '') self._has_internet: bool = False + # FrogPilot variables + @property def has_internet(self) -> bool: return self._has_internet diff --git a/system/camerad/cameras/camera_qcom2.cc b/system/camerad/cameras/camera_qcom2.cc index 3191b82..f7c28fd 100644 --- a/system/camerad/cameras/camera_qcom2.cc +++ b/system/camerad/cameras/camera_qcom2.cc @@ -933,6 +933,9 @@ void process_road_camera(MultiCameraState *s, CameraState *c, int cnt) { } void cameras_run(MultiCameraState *s) { + // FrogPilot variables + Params paramsMemory{"/dev/shm/params"}; + LOG("-- Starting threads"); std::vector threads; if (s->driver_cam.enabled) threads.push_back(start_process_thread(s, &s->driver_cam, process_driver_camera));