diff --git a/cereal b/cereal index bd2f7fa56..513dfc7ee 160000 --- a/cereal +++ b/cereal @@ -1 +1 @@ -Subproject commit bd2f7fa56706bcec3c9906bd57c2ec46f0666ac5 +Subproject commit 513dfc7ee001243cd68a57a9d92fe3170fc49c7d diff --git a/common/params.cc b/common/params.cc index 5c8c94be5..7b2d4490e 100644 --- a/common/params.cc +++ b/common/params.cc @@ -3,6 +3,7 @@ #include #include +#include #include #include @@ -154,18 +155,24 @@ std::unordered_map keys = { {"PrimeType", PERSISTENT}, {"RecordFront", PERSISTENT}, {"RecordFrontLock", PERSISTENT}, // for the internal fleet - {"ReleaseNotes", PERSISTENT}, {"ReplayControlsState", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_ON}, {"ShouldDoUpdate", CLEAR_ON_MANAGER_START}, {"SnoozeUpdate", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_OFF}, {"SshEnabled", PERSISTENT}, {"SubscriberInfo", PERSISTENT}, - {"SwitchToBranch", CLEAR_ON_MANAGER_START}, {"TermsVersion", PERSISTENT}, {"Timezone", PERSISTENT}, {"TrainingVersion", PERSISTENT}, {"UpdateAvailable", CLEAR_ON_MANAGER_START}, {"UpdateFailedCount", CLEAR_ON_MANAGER_START}, + {"UpdaterState", CLEAR_ON_MANAGER_START}, + {"UpdaterFetchAvailable", CLEAR_ON_MANAGER_START}, + {"UpdaterTargetBranch", CLEAR_ON_MANAGER_START}, + {"UpdaterAvailableBranches", CLEAR_ON_MANAGER_START}, + {"UpdaterCurrentDescription", CLEAR_ON_MANAGER_START}, + {"UpdaterCurrentReleaseNotes", CLEAR_ON_MANAGER_START}, + {"UpdaterNewDescription", CLEAR_ON_MANAGER_START}, + {"UpdaterNewReleaseNotes", CLEAR_ON_MANAGER_START}, {"Version", PERSISTENT}, {"VisionRadarToggle", PERSISTENT}, {"WideCameraOnly", PERSISTENT}, @@ -197,6 +204,14 @@ Params::Params(const std::string &path) { params_path = path.empty() ? default_param_path : ensure_params_path(prefix, path); } +std::vector Params::allKeys() const { + std::vector ret; + for (auto &p : keys) { + ret.push_back(p.first); + } + return ret; +} + bool Params::checkKey(const std::string &key) { return keys.find(key) != keys.end(); } diff --git a/common/params.h b/common/params.h index aa4b1d7af..7758a015f 100644 --- a/common/params.h +++ b/common/params.h @@ -2,6 +2,7 @@ #include #include +#include enum ParamKeyType { PERSISTENT = 0x02, @@ -15,6 +16,7 @@ enum ParamKeyType { class Params { public: Params(const std::string &path = {}); + std::vector allKeys() const; bool checkKey(const std::string &key); ParamKeyType getKeyType(const std::string &key); inline std::string getParamPath(const std::string &key = {}) { diff --git a/common/params_pyx.pyx b/common/params_pyx.pyx index 8d52b8d3f..bbddda46e 100755 --- a/common/params_pyx.pyx +++ b/common/params_pyx.pyx @@ -2,6 +2,7 @@ # cython: language_level = 3 from libcpp cimport bool from libcpp.string cimport string +from libcpp.vector cimport vector import threading cdef extern from "common/params.h": @@ -22,6 +23,7 @@ cdef extern from "common/params.h": bool checkKey(string) nogil string getParamPath(string) nogil void clearAll(ParamKeyType) + vector[string] allKeys() def ensure_bytes(v): @@ -99,6 +101,9 @@ cdef class Params: cdef string key_bytes = ensure_bytes(key) return self.p.getParamPath(key_bytes).decode("utf-8") + def all_keys(self): + return self.p.allKeys() + def put_nonblocking(key, val, d=""): threading.Thread(target=lambda: Params(d).put(key, val)).start() diff --git a/common/tests/test_params.py b/common/tests/test_params.py index 899a47fe3..ec13e8221 100644 --- a/common/tests/test_params.py +++ b/common/tests/test_params.py @@ -98,6 +98,14 @@ class TestParams(unittest.TestCase): assert q.get("CarParams") is None assert q.get("CarParams", True) == b"1" + def test_params_all_keys(self): + keys = Params().all_keys() + + # sanity checks + assert len(keys) > 20 + assert len(keys) == len(set(keys)) + assert b"CarParams" in keys + if __name__ == "__main__": unittest.main() diff --git a/docs/CARS.md b/docs/CARS.md index 4831d9685..648849cac 100644 --- a/docs/CARS.md +++ b/docs/CARS.md @@ -11,27 +11,27 @@ A supported vehicle is one that just works when you install a comma three. All s |Acura|ILX 2016-19|AcuraWatch Plus|openpilot|25 mph|25 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Honda Nidec| |Acura|RDX 2016-18|AcuraWatch Plus|openpilot|25 mph|12 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Honda Nidec| |Acura|RDX 2019-22|All|openpilot|0 mph|3 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Honda Bosch A| -|Audi|A3 2014-19|ACC + Lane Assist|openpilot[8](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533| -|Audi|A3 Sportback e-tron 2017-18|ACC + Lane Assist|openpilot[8](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533| -|Audi|Q2 2018|ACC + Lane Assist|openpilot[8](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533| -|Audi|Q3 2020-21|ACC + Lane Assist|openpilot[8](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533| -|Audi|RS3 2018|ACC + Lane Assist|openpilot[8](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533| -|Audi|S3 2015-17|ACC + Lane Assist|openpilot[8](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533| +|Audi|A3 2014-19|Adaptive Cruise Control (ACC) & Lane Assist|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|VW| +|Audi|A3 Sportback e-tron 2017-18|Adaptive Cruise Control (ACC) & Lane Assist|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|VW| +|Audi|Q2 2018|Adaptive Cruise Control (ACC) & Lane Assist|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|VW| +|Audi|Q3 2020-21|Adaptive Cruise Control (ACC) & Lane Assist|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|VW| +|Audi|RS3 2018|Adaptive Cruise Control (ACC) & Lane Assist|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|VW| +|Audi|S3 2015-17|Adaptive Cruise Control (ACC) & Lane Assist|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|VW| |Cadillac|Escalade ESV 2016[1](#footnotes)|Adaptive Cruise Control (ACC) & LKAS|openpilot|0 mph|6 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|OBD-II| |Chevrolet|Bolt EUV 2022-23|Premier or Premier Redline Trim without Super Cruise Package|Stock|0 mph|6 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|GM| |Chevrolet|Silverado 1500 2020-21|Safety Package II|Stock|0 mph|6 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|GM| -|Chevrolet|Volt 2017-18[1](#footnotes)|Adaptive Cruise Control|openpilot|0 mph|6 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|OBD-II| -|Chrysler|Pacifica 2017-18|Adaptive Cruise Control|Stock|0 mph|9 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|FCA| -|Chrysler|Pacifica 2019-20|Adaptive Cruise Control|Stock|0 mph|39 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|FCA| +|Chevrolet|Volt 2017-18[1](#footnotes)|Adaptive Cruise Control (ACC)|openpilot|0 mph|6 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|OBD-II| +|Chrysler|Pacifica 2017-18|Adaptive Cruise Control (ACC)|Stock|0 mph|9 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|FCA| +|Chrysler|Pacifica 2019-20|Adaptive Cruise Control (ACC)|Stock|0 mph|39 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|FCA| |Chrysler|Pacifica 2021|All|Stock|0 mph|39 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|FCA| -|Chrysler|Pacifica Hybrid 2017-18|Adaptive Cruise Control|Stock|0 mph|9 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|FCA| -|Chrysler|Pacifica Hybrid 2019-22|Adaptive Cruise Control|Stock|0 mph|39 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|FCA| +|Chrysler|Pacifica Hybrid 2017-18|Adaptive Cruise Control (ACC)|Stock|0 mph|9 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|FCA| +|Chrysler|Pacifica Hybrid 2019-22|Adaptive Cruise Control (ACC)|Stock|0 mph|39 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|FCA| |comma|body|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|None| |Genesis|G70 2018-19|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai F| |Genesis|G70 2020|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai F| |Genesis|G80 2017-19|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai H| |Genesis|G90 2017-18|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai C| -|GMC|Acadia 2018[1](#footnotes)|Adaptive Cruise Control|openpilot|0 mph|6 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|OBD-II| +|GMC|Acadia 2018[1](#footnotes)|Adaptive Cruise Control (ACC)|openpilot|0 mph|6 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|OBD-II| |GMC|Sierra 1500 2020-21|Driver Alert Package II|Stock|0 mph|6 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|GM| |Honda|Accord 2018-22|All|openpilot|0 mph|3 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Honda Bosch A| |Honda|Accord Hybrid 2018-22|All|openpilot|0 mph|3 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Honda Bosch A| @@ -80,8 +80,8 @@ A supported vehicle is one that just works when you install a comma three. All s |Hyundai|Tucson Diesel 2019|Smart Cruise Control (SCC)|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai L| |Hyundai|Tucson Hybrid 2022|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai N| |Hyundai|Veloster 2019-20|Smart Cruise Control (SCC)|Stock|5 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai E| -|Jeep|Grand Cherokee 2016-18|Adaptive Cruise Control|Stock|0 mph|9 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|FCA| -|Jeep|Grand Cherokee 2019-21|Adaptive Cruise Control|Stock|0 mph|39 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|FCA| +|Jeep|Grand Cherokee 2016-18|Adaptive Cruise Control (ACC)|Stock|0 mph|9 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|FCA| +|Jeep|Grand Cherokee 2019-21|Adaptive Cruise Control (ACC)|Stock|0 mph|39 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|FCA| |Kia|Ceed 2019|Smart Cruise Control (SCC) & LKAS|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai E| |Kia|EV6 2022|Highway Driving Assist II|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai P| |Kia|Forte 2018|Smart Cruise Control (SCC) & LKAS|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Hyundai B| @@ -122,9 +122,9 @@ A supported vehicle is one that just works when you install a comma three. All s |Nissan|Leaf 2018-22|ProPILOT Assist|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Nissan A| |Nissan|Rogue 2018-20|ProPILOT Assist|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Nissan A| |Nissan|X-Trail 2017|ProPILOT Assist|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Nissan A| -|Ram|1500 2019-22|Adaptive Cruise Control|Stock|0 mph|32 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Ram| -|SEAT|Ateca 2018|Driver Assistance|openpilot[8](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533| -|SEAT|Leon 2014-20|Driver Assistance|openpilot[8](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533| +|Ram|1500 2019-22|Adaptive Cruise Control (ACC)|Stock|0 mph|32 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Ram| +|SEAT|Ateca 2018|Adaptive Cruise Control (ACC) & Lane Assist|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|VW| +|SEAT|Leon 2014-20|Adaptive Cruise Control (ACC) & Lane Assist|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|VW| |Subaru|Ascent 2019-21|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Subaru A| |Subaru|Crosstrek 2018-19|EyeSight Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Subaru A| |Subaru|Crosstrek 2020-21|EyeSight Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Subaru A| @@ -135,13 +135,13 @@ A supported vehicle is one that just works when you install a comma three. All s |Subaru|Outback 2020-22|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Subaru B| |Subaru|XV 2018-19|EyeSight Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Subaru A| |Subaru|XV 2020-21|EyeSight Driver Assistance|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Subaru A| -|Škoda|Kamiq 2021[5](#footnotes)|Driver Assistance|openpilot[8](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533| -|Škoda|Karoq 2019-21|Driver Assistance|openpilot[8](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533| -|Škoda|Kodiaq 2018-19|Driver Assistance|openpilot[8](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533| -|Škoda|Octavia 2015, 2018-19|Driver Assistance|openpilot[8](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533| -|Škoda|Octavia RS 2016|Driver Assistance|openpilot[8](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533| -|Škoda|Scala 2020|Driver Assistance|openpilot[8](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533| -|Škoda|Superb 2015-18|Driver Assistance|openpilot[8](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533| +|Škoda|Kamiq 2021[5](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|VW| +|Škoda|Karoq 2019-21[7](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|VW| +|Škoda|Kodiaq 2018-19|Adaptive Cruise Control (ACC) & Lane Assist|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|VW| +|Škoda|Octavia 2015, 2018-19|Adaptive Cruise Control (ACC) & Lane Assist|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|VW| +|Škoda|Octavia RS 2016|Adaptive Cruise Control (ACC) & Lane Assist|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|VW| +|Škoda|Scala 2020|Adaptive Cruise Control (ACC) & Lane Assist|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|VW| +|Škoda|Superb 2015-18|Adaptive Cruise Control (ACC) & Lane Assist|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|VW| |Toyota|Alphard 2019-20|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Toyota| |Toyota|Alphard Hybrid 2021|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Toyota| |Toyota|Avalon 2016|Toyota Safety Sense P|Stock[3](#footnotes)|19 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Toyota| @@ -182,37 +182,37 @@ A supported vehicle is one that just works when you install a comma three. All s |Toyota|RAV4 Hybrid 2019-21|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|Toyota| |Toyota|RAV4 Hybrid 2022|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Toyota| |Toyota|Sienna 2018-20|All|Stock[3](#footnotes)|19 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|Toyota| -|Volkswagen|Arteon 2018-22[7](#footnotes)|Driver Assistance|openpilot[8](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533| -|Volkswagen|Arteon eHybrid 2020-22[7](#footnotes)|Driver Assistance|openpilot[8](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533| -|Volkswagen|Arteon R 2020-22[7](#footnotes)|Driver Assistance|openpilot[8](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533| -|Volkswagen|Atlas 2018-23|Driver Assistance|openpilot[8](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533| -|Volkswagen|Atlas Cross Sport 2021-22|Driver Assistance|openpilot[8](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533| -|Volkswagen|California 2021|Driver Assistance|openpilot[8](#footnotes)|0 mph|31 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533| -|Volkswagen|Caravelle 2020|Driver Assistance|openpilot[8](#footnotes)|0 mph|31 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533| -|Volkswagen|CC 2018-22[7](#footnotes)|Driver Assistance|openpilot[8](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533| -|Volkswagen|e-Golf 2014-20|Driver Assistance|openpilot[8](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533| -|Volkswagen|Golf 2015-20[7](#footnotes)|Driver Assistance|openpilot[8](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533| -|Volkswagen|Golf Alltrack 2015-19|Driver Assistance|openpilot[8](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533| -|Volkswagen|Golf GTD 2015-20|Driver Assistance|openpilot[8](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533| -|Volkswagen|Golf GTE 2015-20|Driver Assistance|openpilot[8](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533| -|Volkswagen|Golf GTI 2015-21|Driver Assistance|openpilot[8](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533| -|Volkswagen|Golf R 2015-19[7](#footnotes)|Driver Assistance|openpilot[8](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533| -|Volkswagen|Golf SportsVan 2015-20|Driver Assistance|openpilot[8](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533| -|Volkswagen|Jetta 2018-22|Driver Assistance|openpilot[8](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533| -|Volkswagen|Jetta GLI 2021-22|Driver Assistance|openpilot[8](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533| -|Volkswagen|Passat 2015-22[6,7](#footnotes)|Driver Assistance|openpilot[8](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533| -|Volkswagen|Passat Alltrack 2015-22|Driver Assistance|openpilot[8](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533| -|Volkswagen|Passat GTE 2015-22[7](#footnotes)|Driver Assistance|openpilot[8](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533| -|Volkswagen|Polo 2020-22|Driver Assistance|openpilot[8](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533| -|Volkswagen|Polo GTI 2020-22|Driver Assistance|openpilot[8](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533| -|Volkswagen|T-Cross 2021|Driver Assistance|openpilot[8](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533| -|Volkswagen|T-Roc 2021|Driver Assistance|openpilot[8](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533| -|Volkswagen|Taos 2022|Driver Assistance|openpilot[8](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533| -|Volkswagen|Teramont 2018-22|Driver Assistance|openpilot[8](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533| -|Volkswagen|Teramont Cross Sport 2021-22|Driver Assistance|openpilot[8](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533| -|Volkswagen|Teramont X 2021-22|Driver Assistance|openpilot[8](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533| -|Volkswagen|Tiguan 2019-22|Driver Assistance|openpilot[8](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533| -|Volkswagen|Touran 2017|Driver Assistance|openpilot[8](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533| +|Volkswagen|Arteon 2018-22[7,8](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533| +|Volkswagen|Arteon eHybrid 2020-22[7,8](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533| +|Volkswagen|Arteon R 2020-22[7,8](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533| +|Volkswagen|Atlas 2018-23[7](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533| +|Volkswagen|Atlas Cross Sport 2021-22[7](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533| +|Volkswagen|California 2021[7](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot|0 mph|31 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533| +|Volkswagen|Caravelle 2020[7](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot|0 mph|31 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533| +|Volkswagen|CC 2018-22[7,8](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533| +|Volkswagen|e-Golf 2014-20|Adaptive Cruise Control (ACC) & Lane Assist|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|VW| +|Volkswagen|Golf 2015-20[8](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|VW| +|Volkswagen|Golf Alltrack 2015-19|Adaptive Cruise Control (ACC) & Lane Assist|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|VW| +|Volkswagen|Golf GTD 2015-20|Adaptive Cruise Control (ACC) & Lane Assist|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|VW| +|Volkswagen|Golf GTE 2015-20|Adaptive Cruise Control (ACC) & Lane Assist|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|VW| +|Volkswagen|Golf GTI 2015-21|Adaptive Cruise Control (ACC) & Lane Assist|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|VW| +|Volkswagen|Golf R 2015-19[8](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|VW| +|Volkswagen|Golf SportsVan 2015-20|Adaptive Cruise Control (ACC) & Lane Assist|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|VW| +|Volkswagen|Jetta 2018-22[7](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533| +|Volkswagen|Jetta GLI 2021-22[7](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533| +|Volkswagen|Passat 2015-22[6,7,8](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533| +|Volkswagen|Passat Alltrack 2015-22[7](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533| +|Volkswagen|Passat GTE 2015-22[7,8](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533| +|Volkswagen|Polo 2020-22[7](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533| +|Volkswagen|Polo GTI 2020-22[7](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533| +|Volkswagen|T-Cross 2021[7](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533| +|Volkswagen|T-Roc 2021[7](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533| +|Volkswagen|Taos 2022[7](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533| +|Volkswagen|Teramont 2018-22[7](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533| +|Volkswagen|Teramont Cross Sport 2021-22[7](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533| +|Volkswagen|Teramont X 2021-22[7](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533| +|Volkswagen|Tiguan 2019-22[7](#footnotes)|Adaptive Cruise Control (ACC) & Lane Assist|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|J533| +|Volkswagen|Touran 2017|Adaptive Cruise Control (ACC) & Lane Assist|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|VW| 1Requires a community built ASCM harness. NOTE: disconnecting the ASCM disables Automatic Emergency Braking (AEB).
@@ -221,8 +221,8 @@ A supported vehicle is one that just works when you install a comma three. All s 4openpilot operates above 28mph for Camry 4CYL L, 4CYL LE and 4CYL SE which don't have Full-Speed Range Dynamic Radar Cruise Control.
5Not including the China market Kamiq, which is based on the (currently) unsupported PQ34 platform.
6Refers only to the MQB-based European B8 Passat, not the NMS Passat in the USA/China/Mideast markets.
-7Includes versions with extra rear cargo space (may be called Variant, Estate, SportWagen, Shooting Brake, etc.)
-8Requires gateway (J533) harness. Camera harness integrations can only use stock ACC at this time.
+7Model-years 2021 and beyond may have a new camera harness design, which isn't yet available from the comma store. Before ordering, remove the Lane Assist camera cover and check to see if the connector is black (older design) or light brown (newer design). In the interim, if your car has a J533 connector CAN gateway inside the dashboard, choose "VW J533 Development" from the vehicle drop-down for a suitable harness. (Some newer models are also observed to not have a J533 connector.)
+8Includes versions with extra rear cargo space (may be called Variant, Estate, SportWagen, Shooting Brake, etc.)
## Community Maintained Cars Although they're not upstream, the community has openpilot running on other makes and models. See the 'Community Supported Models' section of each make [on our wiki](https://wiki.comma.ai/). diff --git a/selfdrive/boardd/boardd.cc b/selfdrive/boardd/boardd.cc index 5ff6d56e6..0872a9471 100644 --- a/selfdrive/boardd/boardd.cc +++ b/selfdrive/boardd/boardd.cc @@ -346,14 +346,14 @@ std::optional send_panda_states(PubMaster *pm, const std::vector auto ps = pss[i]; ps.setUptime(health.uptime_pkt); - ps.setBlockedCnt(health.blocked_msg_cnt_pkt); + ps.setSafetyTxBlocked(health.safety_tx_blocked_pkt); + ps.setSafetyRxInvalid(health.safety_rx_invalid_pkt); ps.setIgnitionLine(health.ignition_line_pkt); ps.setIgnitionCan(health.ignition_can_pkt); ps.setControlsAllowed(health.controls_allowed_pkt); ps.setGasInterceptorDetected(health.gas_interceptor_detected_pkt); - ps.setCanRxErrs(health.can_rx_errs_pkt); - ps.setCanSendErrs(health.can_send_errs_pkt); - ps.setCanFwdErrs(health.can_fwd_errs_pkt); + ps.setTxBufferOverflow(health.tx_buffer_overflow_pkt); + ps.setRxBufferOverflow(health.rx_buffer_overflow_pkt); ps.setGmlanSendErrs(health.gmlan_send_errs_pkt); ps.setPandaType(panda->hw_type); ps.setSafetyModel(cereal::CarParams::SafetyModel(health.safety_mode_pkt)); diff --git a/selfdrive/car/chrysler/values.py b/selfdrive/car/chrysler/values.py index d4ac9f6f0..7180ace52 100644 --- a/selfdrive/car/chrysler/values.py +++ b/selfdrive/car/chrysler/values.py @@ -52,7 +52,7 @@ RAM_CARS = RAM_DT | RAM_HD @dataclass class ChryslerCarInfo(CarInfo): - package: str = "Adaptive Cruise Control" + package: str = "Adaptive Cruise Control (ACC)" harness: Enum = Harness.fca CAR_INFO: Dict[str, Optional[Union[ChryslerCarInfo, List[ChryslerCarInfo]]]] = { diff --git a/selfdrive/car/gm/values.py b/selfdrive/car/gm/values.py index 21ede171e..a84cbdc91 100644 --- a/selfdrive/car/gm/values.py +++ b/selfdrive/car/gm/values.py @@ -71,7 +71,7 @@ class Footnote(Enum): @dataclass class GMCarInfo(CarInfo): - package: str = "Adaptive Cruise Control" + package: str = "Adaptive Cruise Control (ACC)" harness: Enum = Harness.obd_ii footnotes: List[Enum] = field(default_factory=lambda: [Footnote.OBD_II]) diff --git a/selfdrive/car/hyundai/values.py b/selfdrive/car/hyundai/values.py index 7fb8363a6..b81661487 100644 --- a/selfdrive/car/hyundai/values.py +++ b/selfdrive/car/hyundai/values.py @@ -29,6 +29,8 @@ class CarControllerParams: self.STEER_DRIVER_ALLOWANCE = 250 self.STEER_DRIVER_MULTIPLIER = 2 self.STEER_THRESHOLD = 250 + self.STEER_DELTA_UP = 2 + self.STEER_DELTA_DOWN = 3 # To determine the limit for your car, find the maximum value that the stock LKAS will request. # If the max stock LKAS request is <384, add your car to this list. diff --git a/selfdrive/car/subaru/carstate.py b/selfdrive/car/subaru/carstate.py index 7fc5456d9..128e4245b 100644 --- a/selfdrive/car/subaru/carstate.py +++ b/selfdrive/car/subaru/carstate.py @@ -32,9 +32,8 @@ class CarState(CarStateBase): cp_wheels.vl["Wheel_Speeds"]["RR"], ) ret.vEgoRaw = (ret.wheelSpeeds.fl + ret.wheelSpeeds.fr + ret.wheelSpeeds.rl + ret.wheelSpeeds.rr) / 4. - # Kalman filter, even though Subaru raw wheel speed is heaviliy filtered by default ret.vEgo, ret.aEgo = self.update_speed_kf(ret.vEgoRaw) - ret.standstill = ret.vEgoRaw < 0.01 + ret.standstill = ret.vEgoRaw == 0 # continuous blinker signals for assisted lane change ret.leftBlinker, ret.rightBlinker = self.update_blinker_from_lamp(50, cp.vl["Dashlights"]["LEFT_BLINKER"], @@ -50,7 +49,7 @@ class CarState(CarStateBase): ret.steeringAngleDeg = cp.vl["Steering_Torque"]["Steering_Angle"] ret.steeringTorque = cp.vl["Steering_Torque"]["Steer_Torque_Sensor"] ret.steeringTorqueEps = cp.vl["Steering_Torque"]["Steer_Torque_Output"] - + steer_threshold = 75 if self.CP.carFingerprint in PREGLOBAL_CARS else 80 ret.steeringPressed = abs(ret.steeringTorque) > steer_threshold @@ -313,4 +312,4 @@ class CarState(CarStateBase): checks += CarState.get_global_es_distance_signals()[1] return CANParser(DBC[CP.carFingerprint]["pt"], signals, checks, 1) - return None \ No newline at end of file + return None diff --git a/selfdrive/car/tests/routes.py b/selfdrive/car/tests/routes.py index 920785934..1f5d3edaf 100644 --- a/selfdrive/car/tests/routes.py +++ b/selfdrive/car/tests/routes.py @@ -194,7 +194,7 @@ routes = [ CarTestRoute("c321c6b697c5a5ff|2020-06-23--11-04-33", SUBARU.FORESTER), CarTestRoute("791340bc01ed993d|2019-03-10--16-28-08", SUBARU.IMPREZA), CarTestRoute("8bf7e79a3ce64055|2021-05-24--09-36-27", SUBARU.IMPREZA_2020), - CarTestRoute("1bbe6bf2d62f58a8|2022-07-14--17-11-43", SUBARU.OUTBACK, segment=3), + CarTestRoute("1bbe6bf2d62f58a8|2022-07-14--17-11-43", SUBARU.OUTBACK, segment=10), CarTestRoute("c56e69bbc74b8fad|2022-08-18--09-43-51", SUBARU.LEGACY, segment=3), # Pre-global, dashcam CarTestRoute("95441c38ae8c130e|2020-06-08--12-10-17", SUBARU.FORESTER_PREGLOBAL), diff --git a/selfdrive/car/tests/test_models.py b/selfdrive/car/tests/test_models.py index 50370f079..bab9f859e 100755 --- a/selfdrive/car/tests/test_models.py +++ b/selfdrive/car/tests/test_models.py @@ -234,7 +234,7 @@ class TestCarModelBase(unittest.TestCase): checks['gasPressed'] += CS.gasPressed != self.safety.get_gas_pressed_prev() checks['cruiseState'] += CS.cruiseState.enabled and not CS.cruiseState.available - if self.CP.carName not in ("hyundai", "volkswagen", "subaru", "gm", "body"): + if self.CP.carName not in ("hyundai", "volkswagen", "gm", "body"): # TODO: fix standstill mismatches for other makes checks['standstill'] += CS.standstill == self.safety.get_vehicle_moving() diff --git a/selfdrive/car/torque_data/override.yaml b/selfdrive/car/torque_data/override.yaml index fcc762c2b..20fb5f7a6 100644 --- a/selfdrive/car/torque_data/override.yaml +++ b/selfdrive/car/torque_data/override.yaml @@ -21,7 +21,7 @@ FORD FOCUS 4TH GEN: [.nan, 1.5, .nan] COMMA BODY: [.nan, 1000, .nan] # Totally new cars -KIA EV6 2022: [3.5, 2.5, 0.0] +KIA EV6 2022: [3.5, 3.0, 0.0] RAM 1500 5TH GEN: [2.0, 2.0, 0.0] RAM HD 5TH GEN: [1.4, 1.4, 0.0] SUBARU OUTBACK 6TH GEN: [2.3, 2.3, 0.11] diff --git a/selfdrive/car/volkswagen/interface.py b/selfdrive/car/volkswagen/interface.py index 22558d095..5bc683f41 100644 --- a/selfdrive/car/volkswagen/interface.py +++ b/selfdrive/car/volkswagen/interface.py @@ -90,6 +90,7 @@ class CarInterface(CarInterfaceBase): ret.pcmCruise = not ret.openpilotLongitudinalControl ret.experimentalLongitudinalAvailable = ret.networkLocation == NetworkLocation.gateway + ret.experimentalLongitudinalAvailable &= bool(fingerprint[0]) # FIXME: hack to deal with CI/doc/harness stuff later ret.stoppingControl = True ret.startingState = True ret.startAccel = 1.0 diff --git a/selfdrive/car/volkswagen/values.py b/selfdrive/car/volkswagen/values.py index 0203f00bb..4f4d2b8b8 100755 --- a/selfdrive/car/volkswagen/values.py +++ b/selfdrive/car/volkswagen/values.py @@ -150,88 +150,93 @@ class Footnote(Enum): PASSAT = CarFootnote( "Refers only to the MQB-based European B8 Passat, not the NMS Passat in the USA/China/Mideast markets.", Column.MODEL) + VW_HARNESS = CarFootnote( + "Model-years 2021 and beyond may have a new camera harness design, which isn't yet available from the comma " + + "store. Before ordering, remove the Lane Assist camera cover and check to see if the connector is black " + + "(older design) or light brown (newer design). In the interim, if your car has a J533 connector CAN gateway " + + "inside the dashboard, choose \"VW J533 Development\" from the vehicle drop-down for a suitable harness. " + + "(Some newer models are also observed to not have a J533 connector.)", + Column.MODEL) VW_VARIANT = CarFootnote( "Includes versions with extra rear cargo space (may be called Variant, Estate, SportWagen, Shooting Brake, etc.)", Column.MODEL) - VW_LONG = CarFootnote( - "Requires gateway (J533) harness. Camera harness integrations can only use stock ACC at this time.", - Column.LONGITUDINAL) @dataclass class VWCarInfo(CarInfo): - package: str = "Driver Assistance" - harness: Enum = Harness.j533 + package: str = "Adaptive Cruise Control (ACC) & Lane Assist" + harness: Enum = Harness.vw CAR_INFO: Dict[str, Union[VWCarInfo, List[VWCarInfo]]] = { CAR.ARTEON_MK1: [ - VWCarInfo("Volkswagen Arteon 2018-22", footnotes=[Footnote.VW_LONG, Footnote.VW_VARIANT], video_link="https://youtu.be/FAomFKPFlDA"), - VWCarInfo("Volkswagen Arteon R 2020-22", footnotes=[Footnote.VW_LONG, Footnote.VW_VARIANT], video_link="https://youtu.be/FAomFKPFlDA"), - VWCarInfo("Volkswagen Arteon eHybrid 2020-22", footnotes=[Footnote.VW_LONG, Footnote.VW_VARIANT], video_link="https://youtu.be/FAomFKPFlDA"), - VWCarInfo("Volkswagen CC 2018-22", footnotes=[Footnote.VW_LONG, Footnote.VW_VARIANT], video_link="https://youtu.be/FAomFKPFlDA"), + VWCarInfo("Volkswagen Arteon 2018-22", footnotes=[Footnote.VW_HARNESS, Footnote.VW_VARIANT], harness=Harness.j533, video_link="https://youtu.be/FAomFKPFlDA"), + VWCarInfo("Volkswagen Arteon R 2020-22", footnotes=[Footnote.VW_HARNESS, Footnote.VW_VARIANT], harness=Harness.j533, video_link="https://youtu.be/FAomFKPFlDA"), + VWCarInfo("Volkswagen Arteon eHybrid 2020-22", footnotes=[Footnote.VW_HARNESS, Footnote.VW_VARIANT], harness=Harness.j533, video_link="https://youtu.be/FAomFKPFlDA"), + VWCarInfo("Volkswagen CC 2018-22", footnotes=[Footnote.VW_HARNESS, Footnote.VW_VARIANT], harness=Harness.j533, video_link="https://youtu.be/FAomFKPFlDA"), ], CAR.ATLAS_MK1: [ - VWCarInfo("Volkswagen Atlas 2018-23", footnotes=[Footnote.VW_LONG]), - VWCarInfo("Volkswagen Atlas Cross Sport 2021-22", footnotes=[Footnote.VW_LONG]), - VWCarInfo("Volkswagen Teramont 2018-22", footnotes=[Footnote.VW_LONG]), - VWCarInfo("Volkswagen Teramont Cross Sport 2021-22", footnotes=[Footnote.VW_LONG]), - VWCarInfo("Volkswagen Teramont X 2021-22", footnotes=[Footnote.VW_LONG]), + VWCarInfo("Volkswagen Atlas 2018-23", footnotes=[Footnote.VW_HARNESS], harness=Harness.j533), + VWCarInfo("Volkswagen Atlas Cross Sport 2021-22", footnotes=[Footnote.VW_HARNESS], harness=Harness.j533), + VWCarInfo("Volkswagen Teramont 2018-22", footnotes=[Footnote.VW_HARNESS], harness=Harness.j533), + VWCarInfo("Volkswagen Teramont Cross Sport 2021-22", footnotes=[Footnote.VW_HARNESS], harness=Harness.j533), + VWCarInfo("Volkswagen Teramont X 2021-22", footnotes=[Footnote.VW_HARNESS], harness=Harness.j533), ], CAR.GOLF_MK7: [ - VWCarInfo("Volkswagen e-Golf 2014-20", footnotes=[Footnote.VW_LONG]), - VWCarInfo("Volkswagen Golf 2015-20", footnotes=[Footnote.VW_LONG, Footnote.VW_VARIANT]), - VWCarInfo("Volkswagen Golf Alltrack 2015-19", footnotes=[Footnote.VW_LONG]), - VWCarInfo("Volkswagen Golf GTD 2015-20", footnotes=[Footnote.VW_LONG]), - VWCarInfo("Volkswagen Golf GTE 2015-20", footnotes=[Footnote.VW_LONG]), - VWCarInfo("Volkswagen Golf GTI 2015-21", footnotes=[Footnote.VW_LONG]), - VWCarInfo("Volkswagen Golf R 2015-19", footnotes=[Footnote.VW_LONG, Footnote.VW_VARIANT]), - VWCarInfo("Volkswagen Golf SportsVan 2015-20", footnotes=[Footnote.VW_LONG]), + VWCarInfo("Volkswagen e-Golf 2014-20"), + VWCarInfo("Volkswagen Golf 2015-20", footnotes=[Footnote.VW_VARIANT]), + VWCarInfo("Volkswagen Golf Alltrack 2015-19"), + VWCarInfo("Volkswagen Golf GTD 2015-20"), + VWCarInfo("Volkswagen Golf GTE 2015-20"), + VWCarInfo("Volkswagen Golf GTI 2015-21"), + VWCarInfo("Volkswagen Golf R 2015-19", footnotes=[Footnote.VW_VARIANT]), + VWCarInfo("Volkswagen Golf SportsVan 2015-20"), ], CAR.JETTA_MK7: [ - VWCarInfo("Volkswagen Jetta 2018-22", footnotes=[Footnote.VW_LONG]), - VWCarInfo("Volkswagen Jetta GLI 2021-22", footnotes=[Footnote.VW_LONG]), + VWCarInfo("Volkswagen Jetta 2018-22", footnotes=[Footnote.VW_HARNESS], harness=Harness.j533), + VWCarInfo("Volkswagen Jetta GLI 2021-22", footnotes=[Footnote.VW_HARNESS], harness=Harness.j533), ], CAR.PASSAT_MK8: [ - VWCarInfo("Volkswagen Passat 2015-22", footnotes=[Footnote.VW_LONG, Footnote.PASSAT, Footnote.VW_VARIANT]), - VWCarInfo("Volkswagen Passat Alltrack 2015-22", footnotes=[Footnote.VW_LONG]), - VWCarInfo("Volkswagen Passat GTE 2015-22", footnotes=[Footnote.VW_LONG, Footnote.VW_VARIANT]), + VWCarInfo("Volkswagen Passat 2015-22", footnotes=[Footnote.VW_HARNESS, Footnote.PASSAT, Footnote.VW_VARIANT], harness=Harness.j533), + VWCarInfo("Volkswagen Passat Alltrack 2015-22", footnotes=[Footnote.VW_HARNESS], harness=Harness.j533), + VWCarInfo("Volkswagen Passat GTE 2015-22", footnotes=[Footnote.VW_HARNESS, Footnote.VW_VARIANT], harness=Harness.j533), ], - CAR.PASSAT_NMS: VWCarInfo("Volkswagen Passat NMS 2017-22", footnotes=[Footnote.VW_LONG]), + CAR.PASSAT_NMS: VWCarInfo("Volkswagen Passat NMS 2017-22", harness=Harness.j533), CAR.POLO_MK6: [ - VWCarInfo("Volkswagen Polo 2020-22", footnotes=[Footnote.VW_LONG]), - VWCarInfo("Volkswagen Polo GTI 2020-22", footnotes=[Footnote.VW_LONG]), + VWCarInfo("Volkswagen Polo 2020-22", footnotes=[Footnote.VW_HARNESS], harness=Harness.j533), + VWCarInfo("Volkswagen Polo GTI 2020-22", footnotes=[Footnote.VW_HARNESS], harness=Harness.j533), ], - CAR.TAOS_MK1: VWCarInfo("Volkswagen Taos 2022", footnotes=[Footnote.VW_LONG]), - CAR.TCROSS_MK1: VWCarInfo("Volkswagen T-Cross 2021", footnotes=[Footnote.VW_LONG]), - CAR.TIGUAN_MK2: VWCarInfo("Volkswagen Tiguan 2019-22", footnotes=[Footnote.VW_LONG]), - CAR.TOURAN_MK2: VWCarInfo("Volkswagen Touran 2017", footnotes=[Footnote.VW_LONG]), + CAR.TAOS_MK1: VWCarInfo("Volkswagen Taos 2022", footnotes=[Footnote.VW_HARNESS], harness=Harness.j533), + CAR.TCROSS_MK1: VWCarInfo("Volkswagen T-Cross 2021", footnotes=[Footnote.VW_HARNESS], harness=Harness.j533), + CAR.TIGUAN_MK2: VWCarInfo("Volkswagen Tiguan 2019-22", footnotes=[Footnote.VW_HARNESS], harness=Harness.j533), + CAR.TOURAN_MK2: VWCarInfo("Volkswagen Touran 2017"), CAR.TRANSPORTER_T61: [ - VWCarInfo("Volkswagen Caravelle 2020", footnotes=[Footnote.VW_LONG]), - VWCarInfo("Volkswagen California 2021", footnotes=[Footnote.VW_LONG]), + VWCarInfo("Volkswagen Caravelle 2020", footnotes=[Footnote.VW_HARNESS], harness=Harness.j533), + VWCarInfo("Volkswagen California 2021", footnotes=[Footnote.VW_HARNESS], harness=Harness.j533), ], - CAR.TROC_MK1: VWCarInfo("Volkswagen T-Roc 2021", footnotes=[Footnote.VW_LONG]), + CAR.TROC_MK1: VWCarInfo("Volkswagen T-Roc 2021", footnotes=[Footnote.VW_HARNESS], harness=Harness.j533), CAR.AUDI_A3_MK3: [ - VWCarInfo("Audi A3 2014-19", "ACC + Lane Assist", footnotes=[Footnote.VW_LONG]), - VWCarInfo("Audi A3 Sportback e-tron 2017-18", "ACC + Lane Assist", footnotes=[Footnote.VW_LONG]), - VWCarInfo("Audi RS3 2018", "ACC + Lane Assist", footnotes=[Footnote.VW_LONG]), - VWCarInfo("Audi S3 2015-17", "ACC + Lane Assist", footnotes=[Footnote.VW_LONG]), + VWCarInfo("Audi A3 2014-19"), + VWCarInfo("Audi A3 Sportback e-tron 2017-18"), + VWCarInfo("Audi RS3 2018"), + VWCarInfo("Audi S3 2015-17"), ], - CAR.AUDI_Q2_MK1: VWCarInfo("Audi Q2 2018", "ACC + Lane Assist", footnotes=[Footnote.VW_LONG]), - CAR.AUDI_Q3_MK2: VWCarInfo("Audi Q3 2020-21", "ACC + Lane Assist", footnotes=[Footnote.VW_LONG]), - CAR.SEAT_ATECA_MK1: VWCarInfo("SEAT Ateca 2018", footnotes=[Footnote.VW_LONG]), - CAR.SEAT_LEON_MK3: VWCarInfo("SEAT Leon 2014-20", footnotes=[Footnote.VW_LONG]), - CAR.SKODA_KAMIQ_MK1: VWCarInfo("Škoda Kamiq 2021", footnotes=[Footnote.VW_LONG, Footnote.KAMIQ]), - CAR.SKODA_KAROQ_MK1: VWCarInfo("Škoda Karoq 2019-21", footnotes=[Footnote.VW_LONG]), - CAR.SKODA_KODIAQ_MK1: VWCarInfo("Škoda Kodiaq 2018-19", footnotes=[Footnote.VW_LONG]), - CAR.SKODA_SCALA_MK1: VWCarInfo("Škoda Scala 2020", footnotes=[Footnote.VW_LONG]), - CAR.SKODA_SUPERB_MK3: VWCarInfo("Škoda Superb 2015-18", footnotes=[Footnote.VW_LONG]), + CAR.AUDI_Q2_MK1: VWCarInfo("Audi Q2 2018"), + CAR.AUDI_Q3_MK2: VWCarInfo("Audi Q3 2020-21"), + CAR.SEAT_ATECA_MK1: VWCarInfo("SEAT Ateca 2018"), + CAR.SEAT_LEON_MK3: VWCarInfo("SEAT Leon 2014-20"), + CAR.SKODA_KAMIQ_MK1: VWCarInfo("Škoda Kamiq 2021", footnotes=[Footnote.KAMIQ]), + CAR.SKODA_KAROQ_MK1: VWCarInfo("Škoda Karoq 2019-21", footnotes=[Footnote.VW_HARNESS]), + CAR.SKODA_KODIAQ_MK1: VWCarInfo("Škoda Kodiaq 2018-19"), + CAR.SKODA_SCALA_MK1: VWCarInfo("Škoda Scala 2020"), + CAR.SKODA_SUPERB_MK3: VWCarInfo("Škoda Superb 2015-18"), CAR.SKODA_OCTAVIA_MK3: [ - VWCarInfo("Škoda Octavia 2015, 2018-19", footnotes=[Footnote.VW_LONG]), - VWCarInfo("Škoda Octavia RS 2016", footnotes=[Footnote.VW_LONG]), + VWCarInfo("Škoda Octavia 2015, 2018-19"), + VWCarInfo("Škoda Octavia RS 2016"), ], } + # All supported cars should return FW from the engine, srs, eps, and fwdRadar. Cars # with a manual trans won't return transmission firmware, but all other cars will. # diff --git a/selfdrive/manager/test/test_manager.py b/selfdrive/manager/test/test_manager.py index f2e5319e8..7ac2c5f50 100755 --- a/selfdrive/manager/test/test_manager.py +++ b/selfdrive/manager/test/test_manager.py @@ -12,7 +12,7 @@ from system.hardware import HARDWARE os.environ['FAKEUPLOAD'] = "1" MAX_STARTUP_TIME = 3 -ALL_PROCESSES = [p.name for p in managed_processes.values() if (type(p) is not DaemonProcess) and p.enabled and (p.name not in ['updated', 'pandad'])] +ALL_PROCESSES = [p.name for p in managed_processes.values() if (type(p) is not DaemonProcess) and p.enabled and (p.name not in ['pandad', ])] class TestManager(unittest.TestCase): diff --git a/selfdrive/sensord/tests/test_sensord.py b/selfdrive/sensord/tests/test_sensord.py index 84582518f..837fe8883 100755 --- a/selfdrive/sensord/tests/test_sensord.py +++ b/selfdrive/sensord/tests/test_sensord.py @@ -121,6 +121,10 @@ class TestSensord(unittest.TestCase): cls.events = read_sensor_events(5) managed_processes["sensord"].stop() + def tearDown(self): + # interrupt check might leave sensord running + managed_processes["sensord"].stop() + def test_sensors_present(self): # verify correct sensors configuration diff --git a/selfdrive/test/process_replay/ref_commit b/selfdrive/test/process_replay/ref_commit index d0c769a0b..739061025 100644 --- a/selfdrive/test/process_replay/ref_commit +++ b/selfdrive/test/process_replay/ref_commit @@ -1 +1 @@ -3ad478bf44f50815d05acc5b12ff2f01a6cb42ff +ef5395e5f36550d2b485216eee5406bf6062e9c9 \ No newline at end of file diff --git a/selfdrive/ui/.gitignore b/selfdrive/ui/.gitignore index e5b27adce..60eb4b43c 100644 --- a/selfdrive/ui/.gitignore +++ b/selfdrive/ui/.gitignore @@ -1,6 +1,8 @@ moc_* *.moc +translations/main_test_en.* + _mui watch3 installer/installers/* diff --git a/selfdrive/ui/SConscript b/selfdrive/ui/SConscript index c62a6b19d..92f6578df 100644 --- a/selfdrive/ui/SConscript +++ b/selfdrive/ui/SConscript @@ -56,7 +56,8 @@ qt_env.Program("qt/spinner", ["qt/spinner.cc"], LIBS=qt_libs) # build main UI qt_src = ["main.cc", "qt/sidebar.cc", "qt/onroad.cc", "qt/body.cc", "qt/window.cc", "qt/home.cc", "qt/offroad/settings.cc", - "qt/offroad/onboarding.cc", "qt/offroad/driverview.cc"] + "qt/offroad/software_settings.cc", "qt/offroad/onboarding.cc", + "qt/offroad/driverview.cc"] qt_env.Program("_ui", qt_src + [asset_obj], LIBS=qt_libs) if GetOption('test'): qt_src.remove("main.cc") # replaced by test_runner diff --git a/selfdrive/ui/qt/offroad/settings.cc b/selfdrive/ui/qt/offroad/settings.cc index 7a5a40c19..52df247a2 100644 --- a/selfdrive/ui/qt/offroad/settings.cc +++ b/selfdrive/ui/qt/offroad/settings.cc @@ -159,7 +159,7 @@ DevicePanel::DevicePanel(SettingsWindow *parent) : ListWidget(parent) { addItem(dcamBtn); auto resetCalibBtn = new ButtonControl(tr("Reset Calibration"), tr("RESET"), ""); - connect(resetCalibBtn, &ButtonControl::showDescription, this, &DevicePanel::updateCalibDescription); + connect(resetCalibBtn, &ButtonControl::showDescriptionEvent, this, &DevicePanel::updateCalibDescription); connect(resetCalibBtn, &ButtonControl::clicked, [&]() { if (ConfirmationDialog::confirm(tr("Are you sure you want to reset calibration?"), this)) { params.remove("CalibrationParams"); @@ -282,85 +282,6 @@ void DevicePanel::poweroff() { } } -SoftwarePanel::SoftwarePanel(QWidget* parent) : ListWidget(parent) { - gitBranchLbl = new LabelControl(tr("Git Branch")); - gitCommitLbl = new LabelControl(tr("Git Commit")); - osVersionLbl = new LabelControl(tr("OS Version")); - versionLbl = new LabelControl(tr("Version"), "", QString::fromStdString(params.get("ReleaseNotes")).trimmed()); - lastUpdateLbl = new LabelControl(tr("Last Update Check"), "", tr("The last time openpilot successfully checked for an update. The updater only runs while the car is off.")); - updateBtn = new ButtonControl(tr("Check for Update"), ""); - connect(updateBtn, &ButtonControl::clicked, [=]() { - if (params.getBool("IsOffroad")) { - fs_watch->addPath(QString::fromStdString(params.getParamPath("LastUpdateTime"))); - fs_watch->addPath(QString::fromStdString(params.getParamPath("UpdateFailedCount"))); - updateBtn->setText(tr("CHECKING")); - updateBtn->setEnabled(false); - } - std::system("pkill -1 -f selfdrive.updated"); - }); - connect(uiState(), &UIState::offroadTransition, updateBtn, &QPushButton::setEnabled); - - branchSwitcherBtn = new ButtonControl(tr("Switch Branch"), tr("ENTER"), tr("The new branch will be pulled the next time the updater runs.")); - connect(branchSwitcherBtn, &ButtonControl::clicked, [=]() { - QString branch = InputDialog::getText(tr("Enter branch name"), this, tr("The new branch will be pulled the next time the updater runs."), - false, -1, QString::fromStdString(params.get("SwitchToBranch"))); - if (branch.isEmpty()) { - params.remove("SwitchToBranch"); - } else { - params.put("SwitchToBranch", branch.toStdString()); - } - std::system("pkill -1 -f selfdrive.updated"); - }); - connect(uiState(), &UIState::offroadTransition, branchSwitcherBtn, &QPushButton::setEnabled); - - auto uninstallBtn = new ButtonControl(tr("Uninstall %1").arg(getBrand()), tr("UNINSTALL")); - connect(uninstallBtn, &ButtonControl::clicked, [&]() { - if (ConfirmationDialog::confirm(tr("Are you sure you want to uninstall?"), this)) { - params.putBool("DoUninstall", true); - } - }); - connect(uiState(), &UIState::offroadTransition, uninstallBtn, &QPushButton::setEnabled); - - QWidget *widgets[] = {versionLbl, lastUpdateLbl, updateBtn, branchSwitcherBtn, gitBranchLbl, gitCommitLbl, osVersionLbl, uninstallBtn}; - for (QWidget* w : widgets) { - if (w == branchSwitcherBtn && params.getBool("IsTestedBranch")) { - continue; - } - addItem(w); - } - - fs_watch = new QFileSystemWatcher(this); - QObject::connect(fs_watch, &QFileSystemWatcher::fileChanged, [=](const QString path) { - if (path.contains("UpdateFailedCount") && std::atoi(params.get("UpdateFailedCount").c_str()) > 0) { - lastUpdateLbl->setText(tr("failed to fetch update")); - updateBtn->setText(tr("CHECK")); - updateBtn->setEnabled(true); - } else if (path.contains("LastUpdateTime")) { - updateLabels(); - } - }); -} - -void SoftwarePanel::showEvent(QShowEvent *event) { - updateLabels(); -} - -void SoftwarePanel::updateLabels() { - QString lastUpdate = ""; - auto tm = params.get("LastUpdateTime"); - if (!tm.empty()) { - lastUpdate = timeAgo(QDateTime::fromString(QString::fromStdString(tm + "Z"), Qt::ISODate)); - } - - versionLbl->setText(getBrandVersion()); - lastUpdateLbl->setText(lastUpdate); - updateBtn->setText(tr("CHECK")); - updateBtn->setEnabled(true); - gitBranchLbl->setText(QString::fromStdString(params.get("GitBranch"))); - gitCommitLbl->setText(QString::fromStdString(params.get("GitCommit")).left(10)); - osVersionLbl->setText(QString::fromStdString(Hardware::get_os_version()).trimmed()); -} - void SettingsWindow::showEvent(QShowEvent *event) { panel_widget->setCurrentIndex(0); nav_btns->buttons()[0]->setChecked(true); diff --git a/selfdrive/ui/qt/offroad/settings.h b/selfdrive/ui/qt/offroad/settings.h index 1f823851f..4177f28cf 100644 --- a/selfdrive/ui/qt/offroad/settings.h +++ b/selfdrive/ui/qt/offroad/settings.h @@ -71,14 +71,15 @@ public: private: void showEvent(QShowEvent *event) override; void updateLabels(); + void checkForUpdates(); - LabelControl *gitBranchLbl; - LabelControl *gitCommitLbl; - LabelControl *osVersionLbl; + bool is_onroad = false; + + QLabel *onroadLbl; LabelControl *versionLbl; - LabelControl *lastUpdateLbl; - ButtonControl *updateBtn; - ButtonControl *branchSwitcherBtn; + ButtonControl *installBtn; + ButtonControl *downloadBtn; + ButtonControl *targetBranchBtn; Params params; QFileSystemWatcher *fs_watch; diff --git a/selfdrive/ui/qt/offroad/software_settings.cc b/selfdrive/ui/qt/offroad/software_settings.cc new file mode 100644 index 000000000..c9deef2ec --- /dev/null +++ b/selfdrive/ui/qt/offroad/software_settings.cc @@ -0,0 +1,156 @@ +#include "selfdrive/ui/qt/offroad/settings.h" + +#include +#include +#include + +#include +#include + +#include "common/params.h" +#include "common/util.h" +#include "selfdrive/ui/ui.h" +#include "selfdrive/ui/qt/util.h" +#include "selfdrive/ui/qt/widgets/controls.h" +#include "selfdrive/ui/qt/widgets/input.h" +#include "system/hardware/hw.h" + + +void SoftwarePanel::checkForUpdates() { + std::system("pkill -SIGUSR1 -f selfdrive.updated"); +} + +SoftwarePanel::SoftwarePanel(QWidget* parent) : ListWidget(parent) { + onroadLbl = new QLabel(tr("Updates are only downloaded while the car is off.")); + onroadLbl->setStyleSheet("font-size: 50px; font-weight: 400; text-align: left; padding-top: 30px; padding-bottom: 30px;"); + addItem(onroadLbl); + + // current version + versionLbl = new LabelControl(tr("Current Version"), ""); + addItem(versionLbl); + + // download update btn + downloadBtn = new ButtonControl(tr("Download"), tr("CHECK")); + connect(downloadBtn, &ButtonControl::clicked, [=]() { + downloadBtn->setEnabled(false); + if (downloadBtn->text() == tr("CHECK")) { + checkForUpdates(); + } else { + std::system("pkill -SIGHUP -f selfdrive.updated"); + } + }); + addItem(downloadBtn); + + // install update btn + installBtn = new ButtonControl(tr("Install Update"), tr("INSTALL")); + connect(installBtn, &ButtonControl::clicked, [=]() { + installBtn->setEnabled(false); + params.putBool("DoShutdown", true); + }); + addItem(installBtn); + + // branch selecting + targetBranchBtn = new ButtonControl(tr("Target Branch"), tr("SELECT")); + connect(targetBranchBtn, &ButtonControl::clicked, [=]() { + auto current = params.get("GitBranch"); + QStringList branches = QString::fromStdString(params.get("UpdaterAvailableBranches")).split(","); + for (QString b : {current.c_str(), "devel-staging", "devel", "master-ci", "master"}) { + auto i = branches.indexOf(b); + if (i >= 0) { + branches.removeAt(i); + branches.insert(0, b); + } + } + + QString cur = QString::fromStdString(params.get("UpdaterTargetBranch")); + QString selection = MultiOptionDialog::getSelection(tr("Select a branch"), branches, cur, this); + if (!selection.isEmpty()) { + params.put("UpdaterTargetBranch", selection.toStdString()); + targetBranchBtn->setValue(QString::fromStdString(params.get("UpdaterTargetBranch"))); + checkForUpdates(); + } + }); + if (!params.getBool("IsTestedBranch")) { + addItem(targetBranchBtn); + } + + // uninstall button + auto uninstallBtn = new ButtonControl(tr("Uninstall %1").arg(getBrand()), tr("UNINSTALL")); + connect(uninstallBtn, &ButtonControl::clicked, [&]() { + if (ConfirmationDialog::confirm(tr("Are you sure you want to uninstall?"), this)) { + params.putBool("DoUninstall", true); + } + }); + addItem(uninstallBtn); + + fs_watch = new QFileSystemWatcher(this); + QObject::connect(fs_watch, &QFileSystemWatcher::fileChanged, [=](const QString path) { + updateLabels(); + }); + + connect(uiState(), &UIState::offroadTransition, [=](bool offroad) { + is_onroad = !offroad; + updateLabels(); + }); + + updateLabels(); +} + +void SoftwarePanel::showEvent(QShowEvent *event) { + // nice for testing on PC + installBtn->setEnabled(true); + + updateLabels(); +} + +void SoftwarePanel::updateLabels() { + // add these back in case the files got removed + fs_watch->addPath(QString::fromStdString(params.getParamPath("LastUpdateTime"))); + fs_watch->addPath(QString::fromStdString(params.getParamPath("UpdateFailedCount"))); + fs_watch->addPath(QString::fromStdString(params.getParamPath("UpdaterState"))); + fs_watch->addPath(QString::fromStdString(params.getParamPath("UpdateAvailable"))); + + if (!isVisible()) { + return; + } + + // updater only runs offroad + onroadLbl->setVisible(is_onroad); + downloadBtn->setVisible(!is_onroad); + + // download update + QString updater_state = QString::fromStdString(params.get("UpdaterState")); + bool failed = std::atoi(params.get("UpdateFailedCount").c_str()) > 0; + if (updater_state != "idle") { + downloadBtn->setEnabled(false); + downloadBtn->setValue(updater_state); + } else { + if (failed) { + downloadBtn->setText("CHECK"); + downloadBtn->setValue("failed to check for update"); + } else if (params.getBool("UpdaterFetchAvailable")) { + downloadBtn->setText("DOWNLOAD"); + downloadBtn->setValue("update available"); + } else { + QString lastUpdate = "never"; + auto tm = params.get("LastUpdateTime"); + if (!tm.empty()) { + lastUpdate = timeAgo(QDateTime::fromString(QString::fromStdString(tm + "Z"), Qt::ISODate)); + } + downloadBtn->setText("CHECK"); + downloadBtn->setValue("up to date, last checked " + lastUpdate); + } + downloadBtn->setEnabled(true); + } + targetBranchBtn->setValue(QString::fromStdString(params.get("UpdaterTargetBranch"))); + + // current + new versions + versionLbl->setText(QString::fromStdString(params.get("UpdaterCurrentDescription")).left(40)); + versionLbl->setDescription(QString::fromStdString(params.get("UpdaterCurrentReleaseNotes"))); + + installBtn->setVisible(!is_onroad && params.getBool("UpdateAvailable")); + installBtn->setValue(QString::fromStdString(params.get("UpdaterNewDescription")).left(35)); + installBtn->setDescription(QString::fromStdString(params.get("UpdaterNewReleaseNotes"))); + + update(); +} diff --git a/selfdrive/ui/qt/widgets/controls.cc b/selfdrive/ui/qt/widgets/controls.cc index 3264fd3aa..b5f646c37 100644 --- a/selfdrive/ui/qt/widgets/controls.cc +++ b/selfdrive/ui/qt/widgets/controls.cc @@ -42,6 +42,12 @@ AbstractControl::AbstractControl(const QString &title, const QString &desc, cons title_label->setStyleSheet("font-size: 50px; font-weight: 400; text-align: left"); hlayout->addWidget(title_label); + // value next to control button + value = new QLabel(); + value->setAlignment(Qt::AlignRight | Qt::AlignVCenter); + value->setStyleSheet("color: #aaaaaa"); + hlayout->addWidget(value); + main_layout->addLayout(hlayout); // description @@ -54,7 +60,7 @@ AbstractControl::AbstractControl(const QString &title, const QString &desc, cons connect(title_label, &QPushButton::clicked, [=]() { if (!description->isVisible()) { - emit showDescription(); + emit showDescriptionEvent(); } if (!description->text().isEmpty()) { diff --git a/selfdrive/ui/qt/widgets/controls.h b/selfdrive/ui/qt/widgets/controls.h index d8546bb3b..c42716828 100644 --- a/selfdrive/ui/qt/widgets/controls.h +++ b/selfdrive/ui/qt/widgets/controls.h @@ -45,8 +45,17 @@ public: title_label->setText(title); } + void setValue(const QString &val) { + value->setText(val); + } + +public slots: + void showDescription() { + description->setVisible(true); + }; + signals: - void showDescription(); + void showDescriptionEvent(); protected: AbstractControl(const QString &title, const QString &desc = "", const QString &icon = "", QWidget *parent = nullptr); @@ -54,6 +63,9 @@ protected: QHBoxLayout *hlayout; QPushButton *title_label; + +private: + QLabel *value; QLabel *description = nullptr; }; diff --git a/selfdrive/ui/qt/widgets/offroad_alerts.cc b/selfdrive/ui/qt/widgets/offroad_alerts.cc index 937ea02f8..ceb823fb2 100644 --- a/selfdrive/ui/qt/widgets/offroad_alerts.cc +++ b/selfdrive/ui/qt/widgets/offroad_alerts.cc @@ -112,7 +112,7 @@ UpdateAlert::UpdateAlert(QWidget *parent) : AbstractAlert(true, parent) { bool UpdateAlert::refresh() { bool updateAvailable = params.getBool("UpdateAvailable"); if (updateAvailable) { - releaseNotes->setText(params.get("ReleaseNotes").c_str()); + releaseNotes->setText(params.get("UpdaterNewReleaseNotes").c_str()); } return updateAvailable; } diff --git a/selfdrive/ui/qt/widgets/ssh_keys.cc b/selfdrive/ui/qt/widgets/ssh_keys.cc index f17604b3e..1097a8926 100644 --- a/selfdrive/ui/qt/widgets/ssh_keys.cc +++ b/selfdrive/ui/qt/widgets/ssh_keys.cc @@ -5,10 +5,6 @@ #include "selfdrive/ui/qt/widgets/input.h" SshControl::SshControl() : ButtonControl(tr("SSH Keys"), "", tr("Warning: This grants SSH access to all public keys in your GitHub settings. Never enter a GitHub username other than your own. A comma employee will NEVER ask you to add their GitHub username.")) { - username_label.setAlignment(Qt::AlignRight | Qt::AlignVCenter); - username_label.setStyleSheet("color: #aaaaaa"); - hlayout->insertWidget(1, &username_label); - QObject::connect(this, &ButtonControl::clicked, [=]() { if (text() == tr("ADD")) { QString username = InputDialog::getText(tr("Enter your GitHub username"), this); @@ -30,10 +26,10 @@ SshControl::SshControl() : ButtonControl(tr("SSH Keys"), "", tr("Warning: This g void SshControl::refresh() { QString param = QString::fromStdString(params.get("GithubSshKeys")); if (param.length()) { - username_label.setText(QString::fromStdString(params.get("GithubUsername"))); + setValue(QString::fromStdString(params.get("GithubUsername"))); setText(tr("REMOVE")); } else { - username_label.setText(""); + setValue(""); setText(tr("ADD")); } setEnabled(true); diff --git a/selfdrive/ui/qt/widgets/ssh_keys.h b/selfdrive/ui/qt/widgets/ssh_keys.h index 01e2ab83c..920bd651e 100644 --- a/selfdrive/ui/qt/widgets/ssh_keys.h +++ b/selfdrive/ui/qt/widgets/ssh_keys.h @@ -27,8 +27,6 @@ public: private: Params params; - QLabel username_label; - void refresh(); void getUserKeys(const QString &username); }; diff --git a/selfdrive/ui/tests/cycle_offroad_alerts.py b/selfdrive/ui/tests/cycle_offroad_alerts.py index 6b6aea447..8a3d9ec45 100755 --- a/selfdrive/ui/tests/cycle_offroad_alerts.py +++ b/selfdrive/ui/tests/cycle_offroad_alerts.py @@ -20,7 +20,7 @@ if __name__ == "__main__": params.put_bool("UpdateAvailable", True) r = open(os.path.join(BASEDIR, "RELEASES.md")).read() r = r[:r.find('\n\n')] # Slice latest release notes - params.put("ReleaseNotes", r + "\n") + params.put("UpdaterNewReleaseNotes", r + "\n") time.sleep(t) params.put_bool("UpdateAvailable", False) diff --git a/selfdrive/ui/translations/main_ja.ts b/selfdrive/ui/translations/main_ja.ts index 9be6658d1..4262473fb 100644 --- a/selfdrive/ui/translations/main_ja.ts +++ b/selfdrive/ui/translations/main_ja.ts @@ -193,7 +193,7 @@ 変更 - + Select a language 言語を選択 @@ -418,7 +418,7 @@ prime subscription. Sign up now: https://connect.comma.ai 詳しくはこちら:https://connect.comma.ai - + No home location set 自宅の住所はまだ @@ -432,7 +432,7 @@ location set 設定されていません - + no recent destinations 最近の目的地履歴がありません @@ -718,7 +718,7 @@ location set SettingsWindow - + × × @@ -983,68 +983,47 @@ location set SoftwarePanel - - Git Branch - Git ブランチ + + Updates are only downloaded while the car is off. + - - Git Commit - Git コミット - - - - OS Version - OS バージョン + + Current Version + - - Version - バージョン + + Download + - - Last Update Check - 最終更新確認 + + Install Update + - The last time openpilot successfully checked for an update. The updater only runs while the car is off. - openpilotが最後にアップデートの確認に成功してからの時間です。アップデート処理は、車の電源が切れているときのみ実行されます。 - - - - Check for Update - 更新プログラムをチェック - - - - CHECKING - 確認中 + INSTALL + - - Switch Branch - ブランチの切り替え + + Target Branch + - ENTER - 切替 + SELECT + - - - The new branch will be pulled the next time the updater runs. - updater を実行する時にブランチを切り替えます。 - - - - Enter branch name - ブランチ名を入力 + + Select a branch + - + UNINSTALL アンインストール @@ -1059,13 +1038,8 @@ location set アンインストールしてもよろしいですか? - - failed to fetch update - 更新のダウンロードにエラーが発生しました - - - - + + CHECK 確認 @@ -1083,7 +1057,7 @@ location set 警告: これは、GitHub の設定にあるすべての公開鍵への SSH アクセスを許可するものです。自分以外の GitHub のユーザー名を入力しないでください。コンマのスタッフが GitHub のユーザー名を追加するようお願いすることはありません。 - + ADD 追加 @@ -1153,7 +1127,7 @@ location set TogglesPanel - + Enable openpilot openpilot を有効化 @@ -1290,12 +1264,11 @@ location set WifiUI - Scanning for networks... ネットワークをスキャン中... - + CONNECTING... 接続中... diff --git a/selfdrive/ui/translations/main_ko.ts b/selfdrive/ui/translations/main_ko.ts index 3e329a72a..b517c8320 100644 --- a/selfdrive/ui/translations/main_ko.ts +++ b/selfdrive/ui/translations/main_ko.ts @@ -193,7 +193,7 @@ 변경 - + Select a language 언어를 선택하세요 @@ -418,7 +418,7 @@ prime subscription. Sign up now: https://connect.comma.ai 등록:https://connect.comma.ai - + No home location set 집 @@ -432,7 +432,7 @@ location set 설정되지않음 - + no recent destinations 최근 목적지 없음 @@ -718,7 +718,7 @@ location set SettingsWindow - + × × @@ -983,68 +983,47 @@ location set SoftwarePanel - - Git Branch - Git 브렌치 + + Updates are only downloaded while the car is off. + - - Git Commit - Git 커밋 - - - - OS Version - OS 버전 + + Current Version + - - Version - 버전 + + Download + - - Last Update Check - 최신 업데이트 검사 + + Install Update + - The last time openpilot successfully checked for an update. The updater only runs while the car is off. - 최근에 openpilot이 업데이트를 성공적으로 확인했습니다. 업데이트 프로그램은 차량 연결이 해제되었을때만 작동합니다. - - - - Check for Update - 업데이트 확인 - - - - CHECKING - 확인중 + INSTALL + - - Switch Branch - 브랜치 변경 + + Target Branch + - ENTER - 입력하세요 + SELECT + - - - The new branch will be pulled the next time the updater runs. - 다음 업데이트 프로그램이 실행될 때 새 브랜치가 적용됩니다. - - - - Enter branch name - 브랜치명 입력 + + Select a branch + - + UNINSTALL 제거 @@ -1059,13 +1038,8 @@ location set 제거하시겠습니까? - - failed to fetch update - 업데이트를 가져올수없습니다 - - - - + + CHECK 확인 @@ -1083,7 +1057,7 @@ location set 경고: 허용으로 설정하면 GitHub 설정의 모든 공용 키에 대한 SSH 액세스 권한이 부여됩니다. GitHub 사용자 ID 이외에는 입력하지 마십시오. comma에서는 GitHub ID를 추가하라는 요청을 하지 않습니다. - + ADD 추가 @@ -1153,7 +1127,7 @@ location set TogglesPanel - + Enable openpilot openpilot 사용 @@ -1290,12 +1264,11 @@ location set WifiUI - Scanning for networks... 네트워크 검색 중... - + CONNECTING... 연결중... diff --git a/selfdrive/ui/translations/main_pt-BR.ts b/selfdrive/ui/translations/main_pt-BR.ts index b729678a2..91ffabc62 100644 --- a/selfdrive/ui/translations/main_pt-BR.ts +++ b/selfdrive/ui/translations/main_pt-BR.ts @@ -193,7 +193,7 @@ ALTERAR - + Select a language Selecione o Idioma @@ -419,7 +419,7 @@ prime subscription. Sign up now: https://connect.comma.ai uma assinatura prime Inscreva-se agora: https://connect.comma.ai - + No home location set Sem local @@ -433,7 +433,7 @@ location set trabalho definido - + no recent destinations sem destinos recentes @@ -722,7 +722,7 @@ trabalho definido SettingsWindow - + × × @@ -987,68 +987,47 @@ trabalho definido SoftwarePanel - - Git Branch - Git Branch - - - - Git Commit - Último Commit + + Updates are only downloaded while the car is off. + - - OS Version - Versão do Sistema + + Current Version + - - Version - Versão + + Download + - - Last Update Check - Verificação da última atualização + + Install Update + - The last time openpilot successfully checked for an update. The updater only runs while the car is off. - A última vez que o openpilot verificou com sucesso uma atualização. O atualizador só funciona com o carro desligado. - - - - Check for Update - Verifique atualizações - - - - CHECKING - VERIFICANDO - - - - Switch Branch - Alterar Branch + INSTALL + - - ENTER - INSERIR + + Target Branch + - - The new branch will be pulled the next time the updater runs. - A nova branch será aplicada ao verificar atualizações. + SELECT + - - Enter branch name - Inserir o nome da branch + + Select a branch + - + UNINSTALL DESINSTALAR @@ -1063,13 +1042,8 @@ trabalho definido Tem certeza que quer desinstalar? - - failed to fetch update - falha ao buscar atualização - - - - + + CHECK VERIFICAR @@ -1087,7 +1061,7 @@ trabalho definido Aviso: isso concede acesso SSH a todas as chaves públicas nas configurações do GitHub. Nunca insira um nome de usuário do GitHub que não seja o seu. Um funcionário da comma NUNCA pedirá que você adicione seu nome de usuário do GitHub. - + ADD ADICIONAR @@ -1157,7 +1131,7 @@ trabalho definido TogglesPanel - + Enable openpilot Ativar openpilot @@ -1294,12 +1268,11 @@ trabalho definido WifiUI - Scanning for networks... Procurando redes... - + CONNECTING... CONECTANDO... diff --git a/selfdrive/ui/translations/main_zh-CHS.ts b/selfdrive/ui/translations/main_zh-CHS.ts index 606e70726..8fce4e01a 100644 --- a/selfdrive/ui/translations/main_zh-CHS.ts +++ b/selfdrive/ui/translations/main_zh-CHS.ts @@ -193,7 +193,7 @@ 切换 - + Select a language 选择语言 @@ -418,7 +418,7 @@ prime subscription. Sign up now: https://connect.comma.ai 立即注册:https://connect.comma.ai - + No home location set 家:未设定 @@ -430,7 +430,7 @@ location set 工作:未设定 - + no recent destinations 无最近目的地 @@ -716,7 +716,7 @@ location set SettingsWindow - + × × @@ -981,68 +981,47 @@ location set SoftwarePanel - - Git Branch - Git Branch - - - - Git Commit - Git Commit + + Updates are only downloaded while the car is off. + - - OS Version - 系统版本 + + Current Version + - - Version - 软件版本 + + Download + - - Last Update Check - 上次检查更新 + + Install Update + - The last time openpilot successfully checked for an update. The updater only runs while the car is off. - 上一次成功检查更新的时间。更新程序仅在汽车熄火时运行。 - - - - Check for Update - 检查更新 - - - - CHECKING - 正在检查更新 - - - - Switch Branch - 切换分支 + INSTALL + - - ENTER - 输入 + + Target Branch + - - The new branch will be pulled the next time the updater runs. - 分支将在更新服务下次启动时自动切换。 + SELECT + - - Enter branch name - 输入分支名称 + + Select a branch + - + UNINSTALL 卸载 @@ -1057,13 +1036,8 @@ location set 您确定要卸载吗? - - failed to fetch update - 获取更新失败 - - - - + + CHECK 查看 @@ -1081,7 +1055,7 @@ location set 警告:这将授予SSH访问权限给您GitHub设置中的所有公钥。切勿输入您自己以外的GitHub用户名。comma员工永远不会要求您添加他们的GitHub用户名。 - + ADD 添加 @@ -1151,7 +1125,7 @@ location set TogglesPanel - + Enable openpilot 启用openpilot @@ -1288,12 +1262,11 @@ location set WifiUI - Scanning for networks... 正在扫描网络…… - + CONNECTING... 正在连接…… diff --git a/selfdrive/ui/translations/main_zh-CHT.ts b/selfdrive/ui/translations/main_zh-CHT.ts index b5b737ca2..022d41be8 100644 --- a/selfdrive/ui/translations/main_zh-CHT.ts +++ b/selfdrive/ui/translations/main_zh-CHT.ts @@ -193,7 +193,7 @@ 更改 - + Select a language 選擇語言 @@ -418,7 +418,7 @@ prime subscription. Sign up now: https://connect.comma.ai 立即註冊:https://connect.comma.ai - + No home location set 未設定 @@ -432,7 +432,7 @@ location set 工作位置 - + no recent destinations 沒有最近的導航記錄 @@ -718,7 +718,7 @@ location set SettingsWindow - + × × @@ -983,68 +983,47 @@ location set SoftwarePanel - - Git Branch - Git 分支 - - - - Git Commit - Git 提交 + + Updates are only downloaded while the car is off. + - - OS Version - 系統版本 + + Current Version + - - Version - 版本 + + Download + - - Last Update Check - 上次檢查時間 + + Install Update + - The last time openpilot successfully checked for an update. The updater only runs while the car is off. - 上次成功檢查更新的時間。更新系統只會在車子熄火時執行。 - - - - Check for Update - 檢查更新 - - - - CHECKING - 檢查中 - - - - Switch Branch - 切換分支 + INSTALL + - - ENTER - 切換 + + Target Branch + - - The new branch will be pulled the next time the updater runs. - 新的分支將會在下次檢查更新時切換過去。 + SELECT + - - Enter branch name - 輸入分支名稱 + + Select a branch + - + UNINSTALL 卸載 @@ -1059,13 +1038,8 @@ location set 您確定您要卸載嗎? - - failed to fetch update - 下載更新失敗 - - - - + + CHECK 檢查 @@ -1083,7 +1057,7 @@ location set 警告:這將授權給 GitHub 帳號中所有公鑰 SSH 訪問權限。切勿輸入非您自己的 GitHub 用戶名。comma 員工「永遠不會」要求您添加他們的 GitHub 用戶名。 - + ADD 新增 @@ -1153,7 +1127,7 @@ location set TogglesPanel - + Enable openpilot 啟用 openpilot @@ -1290,12 +1264,11 @@ location set WifiUI - Scanning for networks... 掃描無線網路中... - + CONNECTING... 連線中... diff --git a/selfdrive/updated.py b/selfdrive/updated.py index 403ea2172..79b759a90 100755 --- a/selfdrive/updated.py +++ b/selfdrive/updated.py @@ -23,6 +23,7 @@ # disable this service. import os +import re import datetime import subprocess import psutil @@ -31,8 +32,9 @@ import signal import fcntl import time import threading +from collections import defaultdict from pathlib import Path -from typing import List, Tuple, Optional +from typing import List, Union, Optional from markdown_it import MarkdownIt from common.basedir import BASEDIR @@ -54,38 +56,27 @@ DAYS_NO_CONNECTIVITY_MAX = 14 # do not allow to engage after this many days DAYS_NO_CONNECTIVITY_PROMPT = 10 # send an offroad prompt after this many days class WaitTimeHelper: - def __init__(self, proc): - self.proc = proc + def __init__(self): self.ready_event = threading.Event() - self.shutdown = False - signal.signal(signal.SIGTERM, self.graceful_shutdown) - signal.signal(signal.SIGINT, self.graceful_shutdown) + self.only_check_for_update = False signal.signal(signal.SIGHUP, self.update_now) + signal.signal(signal.SIGUSR1, self.check_now) - def graceful_shutdown(self, signum: int, frame) -> None: - # umount -f doesn't appear effective in avoiding "device busy" on NEOS, - # so don't actually die until the next convenient opportunity in main(). - cloudlog.info("caught SIGINT/SIGTERM, dismounting overlay at next opportunity") - - # forward the signal to all our child processes - child_procs = self.proc.children(recursive=True) - for p in child_procs: - p.send_signal(signum) - - self.shutdown = True + def update_now(self, signum: int, frame) -> None: + cloudlog.info("caught SIGHUP, attempting to downloading update") + self.only_check_for_update = False self.ready_event.set() - def update_now(self, signum: int, frame) -> None: - cloudlog.info("caught SIGHUP, running update check immediately") + def check_now(self, signum: int, frame) -> None: + cloudlog.info("caught SIGUSR1, checking for updates") + self.only_check_for_update = True self.ready_event.set() def sleep(self, t: float) -> None: self.ready_event.wait(timeout=t) -def run(cmd: List[str], cwd: Optional[str] = None, low_priority: bool = False): - if low_priority: - cmd = ["nice", "-n", "19"] + cmd +def run(cmd: List[str], cwd: Optional[str] = None) -> str: return subprocess.check_output(cmd, cwd=cwd, stderr=subprocess.STDOUT, encoding='utf8') @@ -98,59 +89,19 @@ def set_consistent_flag(consistent: bool) -> None: consistent_file.unlink(missing_ok=True) os.sync() - -def set_params(new_version: bool, failed_count: int, exception: Optional[str]) -> None: - params = Params() - - params.put("UpdateFailedCount", str(failed_count)) - - last_update = datetime.datetime.utcnow() - if failed_count == 0: - t = last_update.isoformat() - params.put("LastUpdateTime", t.encode('utf8')) - else: - try: - t = params.get("LastUpdateTime", encoding='utf8') - last_update = datetime.datetime.fromisoformat(t) - except (TypeError, ValueError): - pass - - if exception is None: - params.remove("LastUpdateException") - else: - params.put("LastUpdateException", exception) - - # Write out release notes for new versions - if new_version: +def parse_release_notes(basedir: str) -> bytes: + try: + with open(os.path.join(basedir, "RELEASES.md"), "rb") as f: + r = f.read().split(b'\n\n', 1)[0] # Slice latest release notes try: - with open(os.path.join(FINALIZED, "RELEASES.md"), "rb") as f: - r = f.read().split(b'\n\n', 1)[0] # Slice latest release notes - try: - params.put("ReleaseNotes", MarkdownIt().render(r.decode("utf-8"))) - except Exception: - params.put("ReleaseNotes", r + b"\n") + return bytes(MarkdownIt().render(r.decode("utf-8")), encoding="utf-8") except Exception: - params.put("ReleaseNotes", "") - params.put_bool("UpdateAvailable", True) - - # Handle user prompt - for alert in ("Offroad_UpdateFailed", "Offroad_ConnectivityNeeded", "Offroad_ConnectivityNeededPrompt"): - set_offroad_alert(alert, False) - - now = datetime.datetime.utcnow() - dt = now - last_update - if failed_count > 15 and exception is not None: - if is_tested_branch(): - extra_text = "Ensure the software is correctly installed" - else: - extra_text = exception - set_offroad_alert("Offroad_UpdateFailed", True, extra_text=extra_text) - elif dt.days > DAYS_NO_CONNECTIVITY_MAX and failed_count > 1: - set_offroad_alert("Offroad_ConnectivityNeeded", True) - elif dt.days > DAYS_NO_CONNECTIVITY_PROMPT: - remaining = max(DAYS_NO_CONNECTIVITY_MAX - dt.days, 1) - set_offroad_alert("Offroad_ConnectivityNeededPrompt", True, extra_text=f"{remaining} day{'' if remaining == 1 else 's'}.") - + return r + b"\n" + except FileNotFoundError: + pass + except Exception: + cloudlog.exception("failed to parse release notes") + return b"" def setup_git_options(cwd: str) -> None: # We sync FS object atimes (which NEOS doesn't use) and mtimes, but ctimes @@ -228,12 +179,12 @@ def init_overlay() -> None: run(["sudo"] + mount_cmd) run(["sudo", "chmod", "755", os.path.join(OVERLAY_METADATA, "work")]) - git_diff = run(["git", "diff"], OVERLAY_MERGED, low_priority=True) + git_diff = run(["git", "diff"], OVERLAY_MERGED) params.put("GitDiff", git_diff) cloudlog.info(f"git diff output:\n{git_diff}") -def finalize_update(wait_helper: WaitTimeHelper) -> None: +def finalize_update() -> None: """Take the current OverlayFS merged view and finalize a copy outside of OverlayFS, ready to be swapped-in at BASEDIR. Copy using shutil.copytree""" @@ -258,14 +209,11 @@ def finalize_update(wait_helper: WaitTimeHelper) -> None: except subprocess.CalledProcessError: cloudlog.exception(f"Failed git cleanup, took {time.monotonic() - t:.3f} s") - if wait_helper.shutdown: - cloudlog.info("got interrupted finalizing overlay") - else: - set_consistent_flag(True) - cloudlog.info("done finalizing overlay") + set_consistent_flag(True) + cloudlog.info("done finalizing overlay") -def handle_agnos_update(wait_helper: WaitTimeHelper) -> None: +def handle_agnos_update() -> None: from system.hardware.tici.agnos import flash_agnos_update, get_target_slot_number cur_version = HARDWARE.get_os_version() @@ -288,65 +236,161 @@ def handle_agnos_update(wait_helper: WaitTimeHelper) -> None: set_offroad_alert("Offroad_NeosUpdate", False) -def check_git_fetch_result(fetch_txt: str) -> bool: - err_msg = "Failed to add the host to the list of known hosts (/data/data/com.termux/files/home/.ssh/known_hosts).\n" - return len(fetch_txt) > 0 and (fetch_txt != err_msg) +class Updater: + def __init__(self): + self.params = Params() + self.branches = defaultdict(lambda: None) + + @property + def target_branch(self) -> str: + b: Union[str, None] = self.params.get("UpdaterTargetBranch", encoding='utf-8') + if b is None: + b = self.get_branch(BASEDIR) + self.params.put("UpdaterTargetBranch", b) + return b + + @property + def update_ready(self) -> bool: + consistent_file = Path(os.path.join(FINALIZED, ".overlay_consistent")) + if consistent_file.is_file(): + hash_mismatch = self.get_commit_hash(BASEDIR) != self.branches[self.target_branch] + branch_mismatch = self.get_branch(BASEDIR) != self.target_branch + on_target_branch = self.get_branch(FINALIZED) == self.target_branch + return ((hash_mismatch or branch_mismatch) and on_target_branch) + return False + + @property + def update_available(self) -> bool: + if os.path.isdir(OVERLAY_MERGED): + hash_mismatch = self.get_commit_hash(OVERLAY_MERGED) != self.branches[self.target_branch] + branch_mismatch = self.get_branch(OVERLAY_MERGED) != self.target_branch + return hash_mismatch or branch_mismatch + return False + + def get_branch(self, path: str) -> str: + return run(["git", "rev-parse", "--abbrev-ref", "HEAD"], path).rstrip() + + def get_commit_hash(self, path: str = OVERLAY_MERGED) -> str: + return run(["git", "rev-parse", "HEAD"], path).rstrip() + + def set_params(self, failed_count: int, exception: Optional[str]) -> None: + self.params.put("UpdateFailedCount", str(failed_count)) + + self.params.put_bool("UpdaterFetchAvailable", self.update_available) + self.params.put("UpdaterAvailableBranches", ','.join(self.branches.keys())) + + last_update = datetime.datetime.utcnow() + if failed_count == 0: + t = last_update.isoformat() + self.params.put("LastUpdateTime", t.encode('utf8')) + else: + try: + t = self.params.get("LastUpdateTime", encoding='utf8') + last_update = datetime.datetime.fromisoformat(t) + except (TypeError, ValueError): + pass -def check_for_update() -> Tuple[bool, bool]: - setup_git_options(OVERLAY_MERGED) - try: - git_fetch_output = run(["git", "fetch", "--dry-run"], OVERLAY_MERGED, low_priority=True) - return True, check_git_fetch_result(git_fetch_output) - except subprocess.CalledProcessError: - return False, False - + if exception is None: + self.params.remove("LastUpdateException") + else: + self.params.put("LastUpdateException", exception) -def fetch_update(wait_helper: WaitTimeHelper) -> bool: - cloudlog.info("attempting git fetch inside staging overlay") + # Write out current and new version info + def get_description(basedir: str) -> str: + version = "" + branch = "" + commit = "" + try: + branch = self.get_branch(basedir) + commit = self.get_commit_hash(basedir) + with open(os.path.join(basedir, "common", "version.h")) as f: + version = f.read().split('"')[1] + except Exception: + pass + return f"{version} / {branch} / {commit[:7]}" + self.params.put("UpdaterCurrentDescription", get_description(BASEDIR)) + self.params.put("UpdaterCurrentReleaseNotes", parse_release_notes(BASEDIR)) + self.params.put("UpdaterNewDescription", get_description(FINALIZED)) + self.params.put("UpdaterNewReleaseNotes", parse_release_notes(FINALIZED)) + self.params.put_bool("UpdateAvailable", self.update_ready) + + # Handle user prompt + for alert in ("Offroad_UpdateFailed", "Offroad_ConnectivityNeeded", "Offroad_ConnectivityNeededPrompt"): + set_offroad_alert(alert, False) + + now = datetime.datetime.utcnow() + dt = now - last_update + if failed_count > 15 and exception is not None: + if is_tested_branch(): + extra_text = "Ensure the software is correctly installed. Uninstall and re-install if this error persists." + else: + extra_text = exception + set_offroad_alert("Offroad_UpdateFailed", True, extra_text=extra_text) + elif dt.days > DAYS_NO_CONNECTIVITY_MAX and failed_count > 1: + set_offroad_alert("Offroad_ConnectivityNeeded", True) + elif dt.days > DAYS_NO_CONNECTIVITY_PROMPT: + remaining = max(DAYS_NO_CONNECTIVITY_MAX - dt.days, 1) + set_offroad_alert("Offroad_ConnectivityNeededPrompt", True, extra_text=f"{remaining} day{'' if remaining == 1 else 's'}.") + + def check_for_update(self) -> None: + cloudlog.info("checking for updates") + + excluded_branches = ('release2', 'release2-staging', 'dashcam', 'dashcam-staging') + + setup_git_options(OVERLAY_MERGED) + output = run(["git", "ls-remote", "--heads"], OVERLAY_MERGED) + + self.branches = defaultdict(lambda: None) + for line in output.split('\n'): + ls_remotes_re = r'(?P\b[0-9a-f]{5,40}\b)(\s+)(refs\/heads\/)(?P.*$)' + x = re.fullmatch(ls_remotes_re, line.strip()) + if x is not None and x.group('branch_name') not in excluded_branches: + self.branches[x.group('branch_name')] = x.group('commit_sha') + + cur_branch = self.get_branch(OVERLAY_MERGED) + cur_commit = self.get_commit_hash(OVERLAY_MERGED) + new_branch = self.target_branch + new_commit = self.branches[new_branch] + if (cur_branch, cur_commit) != (new_branch, new_commit): + cloudlog.info(f"update available, {cur_branch} ({cur_commit[:7]}) -> {new_branch} ({new_commit[:7]})") + else: + cloudlog.info(f"up to date on {cur_branch} ({cur_commit[:7]})") - setup_git_options(OVERLAY_MERGED) + def fetch_update(self) -> None: + cloudlog.info("attempting git fetch inside staging overlay") - git_fetch_output = run(["git", "fetch"], OVERLAY_MERGED, low_priority=True) - cloudlog.info("git fetch success: %s", git_fetch_output) + self.params.put("UpdaterState", "downloading...") - cur_hash = run(["git", "rev-parse", "HEAD"], OVERLAY_MERGED).rstrip() - upstream_hash = run(["git", "rev-parse", "@{u}"], OVERLAY_MERGED).rstrip() - new_version: bool = cur_hash != upstream_hash - git_fetch_result = check_git_fetch_result(git_fetch_output) + # TODO: cleanly interrupt this and invalidate old update + set_consistent_flag(False) + self.params.put_bool("UpdateAvailable", False) - new_branch = Params().get("SwitchToBranch", encoding='utf8') - if new_branch is not None: - new_version = True + setup_git_options(OVERLAY_MERGED) - cloudlog.info(f"comparing {cur_hash} to {upstream_hash}") - if new_version or git_fetch_result: - cloudlog.info("Running update") + branch = self.target_branch + git_fetch_output = run(["git", "fetch", "origin", branch], OVERLAY_MERGED) + cloudlog.info("git fetch success: %s", git_fetch_output) - if new_version: - cloudlog.info("git reset in progress") - cmds = [ - ["git", "reset", "--hard", "@{u}"], - ["git", "clean", "-xdf"], - ["git", "submodule", "init"], - ["git", "submodule", "update"], - ] - if new_branch is not None: - cloudlog.info(f"switching to branch {repr(new_branch)}") - cmds.insert(0, ["git", "checkout", "-f", new_branch]) - r = [run(cmd, OVERLAY_MERGED, low_priority=True) for cmd in cmds] - cloudlog.info("git reset success: %s", '\n'.join(r)) + cloudlog.info("git reset in progress") + cmds = [ + ["git", "checkout", "--force", "--no-recurse-submodules", branch], + ["git", "reset", "--hard", f"origin/{branch}"], + ["git", "clean", "-xdf"], + ["git", "submodule", "init"], + ["git", "submodule", "update"], + ] + r = [run(cmd, OVERLAY_MERGED) for cmd in cmds] + cloudlog.info("git reset success: %s", '\n'.join(r)) - if AGNOS: - handle_agnos_update(wait_helper) + # TODO: show agnos download progress + if AGNOS: + handle_agnos_update() # Create the finalized, ready-to-swap update - finalize_update(wait_helper) - cloudlog.info("openpilot update successful!") - else: - cloudlog.info("nothing new from git at this time") - - return new_version + self.params.put("UpdaterState", "finalizing update...") + finalize_update() + cloudlog.info("finalize success!") def main() -> None: @@ -378,30 +422,37 @@ def main() -> None: overlay_init = Path(os.path.join(BASEDIR, ".overlay_init")) overlay_init.unlink(missing_ok=True) + updater = Updater() update_failed_count = 0 # TODO: Load from param? - wait_helper = WaitTimeHelper(proc) + + # no fetch on the first time + wait_helper = WaitTimeHelper() + wait_helper.only_check_for_update = True # Run the update loop - while not wait_helper.shutdown: + while True: wait_helper.ready_event.clear() # Attempt an update exception = None - new_version = False - update_failed_count += 1 try: + # TODO: reuse overlay from previous updated instance if it looks clean init_overlay() - # TODO: still needed? skip this and just fetch? - # Lightweight internt check - internet_ok, update_available = check_for_update() - if internet_ok and not update_available: - update_failed_count = 0 + # ensure we have some params written soon after startup + updater.set_params(update_failed_count, exception) + update_failed_count += 1 + + # check for update + params.put("UpdaterState", "checking...") + updater.check_for_update() - # Fetch update - if internet_ok: - new_version = fetch_update(wait_helper) - update_failed_count = 0 + # download update + if wait_helper.only_check_for_update: + cloudlog.info("skipping fetch this cycle") + else: + updater.fetch_update() + update_failed_count = 0 except subprocess.CalledProcessError as e: cloudlog.event( "update process failed", @@ -416,16 +467,15 @@ def main() -> None: exception = str(e) overlay_init.unlink(missing_ok=True) - if not wait_helper.shutdown: - try: - set_params(new_version, update_failed_count, exception) - except Exception: - cloudlog.exception("uncaught updated exception while setting params, shouldn't happen") + try: + params.put("UpdaterState", "idle") + updater.set_params(update_failed_count, exception) + except Exception: + cloudlog.exception("uncaught updated exception while setting params, shouldn't happen") # infrequent attempts if we successfully updated recently - wait_helper.sleep(5*60 if update_failed_count > 0 else 90*60) - - dismount_overlay() + wait_helper.only_check_for_update = False + wait_helper.sleep(5*60 if update_failed_count > 0 else 1.5*60*60) if __name__ == "__main__": diff --git a/system/camerad/cameras/camera_qcom2.cc b/system/camerad/cameras/camera_qcom2.cc index 9bdd71b5d..544d65367 100644 --- a/system/camerad/cameras/camera_qcom2.cc +++ b/system/camerad/cameras/camera_qcom2.cc @@ -61,39 +61,48 @@ const float DC_GAIN_OX03C10 = 7.32; const float DC_GAIN_ON_GREY_AR0231= 0.2; const float DC_GAIN_OFF_GREY_AR0231 = 0.3; -const float DC_GAIN_ON_GREY_OX03C10= 0.3; -const float DC_GAIN_OFF_GREY_OX03C10 = 0.375; +const float DC_GAIN_ON_GREY_OX03C10= 0.25; +const float DC_GAIN_OFF_GREY_OX03C10 = 0.35; -const int DC_GAIN_MIN_WEIGHT = 0; +const int DC_GAIN_MIN_WEIGHT_AR0231 = 0; const int DC_GAIN_MAX_WEIGHT_AR0231 = 1; +const int DC_GAIN_MIN_WEIGHT_OX03C10 = 16; const int DC_GAIN_MAX_WEIGHT_OX03C10 = 32; +const float TARGET_GREY_FACTOR_AR0231 = 1.0; +const float TARGET_GREY_FACTOR_OX03C10 = 0.02; + const float sensor_analog_gains_AR0231[] = { 1.0/8.0, 2.0/8.0, 2.0/7.0, 3.0/7.0, // 0, 1, 2, 3 3.0/6.0, 4.0/6.0, 4.0/5.0, 5.0/5.0, // 4, 5, 6, 7 5.0/4.0, 6.0/4.0, 6.0/3.0, 7.0/3.0, // 8, 9, 10, 11 7.0/2.0, 8.0/2.0, 8.0/1.0}; // 12, 13, 14, 15 = bypass -// similar gain curve to AR const float sensor_analog_gains_OX03C10[] = { - 1.0, 1.25, 1.3125, 1.5625, - 1.6875, 2.0, 2.25, 2.625, - 3.125, 3.625, 4.5, 5.0, - 7.25, 8.5, 12.0, 15.5}; + 1.0, 1.125, 1.25, 1.3125, 1.5625, + 1.6875, 2.0, 2.25, 2.625, 3.125, + 3.625, 4.0, 4.5, 5.0, 5.5, + 6.0, 6.5, 7.0, 7.5, 8.0, + 8.5, 9.0, 9.5, 10.0, 10.5, + 11.0, 11.5, 12.0, 12.5, 13.0, + 13.5, 14.0, 14.5, 15.0, 15.5}; const uint32_t ox03c10_analog_gains_reg[] = { - 0x100, 0x140, 0x150, 0x190, - 0x1B0, 0x200, 0x240, 0x2A0, - 0x320, 0x3A0, 0x480, 0x500, - 0x740, 0x880, 0xC00, 0xF80}; + 0x100, 0x120, 0x140, 0x150, 0x190, + 0x1B0, 0x200, 0x240, 0x2A0, 0x320, + 0x3A0, 0x400, 0x480, 0x500, 0x580, + 0x600, 0x680, 0x700, 0x780, 0x800, + 0x880, 0x900, 0x980, 0xA00, 0xA80, + 0xB00, 0xB80, 0xC00, 0xC80, 0xD00, + 0xD80, 0xE00, 0xE80, 0xF00, 0xF80}; const int ANALOG_GAIN_MIN_IDX_AR0231 = 0x1; // 0.25x const int ANALOG_GAIN_REC_IDX_AR0231 = 0x6; // 0.8x const int ANALOG_GAIN_MAX_IDX_AR0231 = 0xD; // 4.0x const int ANALOG_GAIN_MIN_IDX_OX03C10 = 0x0; -const int ANALOG_GAIN_REC_IDX_OX03C10 = 0x5; // 2x -const int ANALOG_GAIN_MAX_IDX_OX03C10 = 0xF; +const int ANALOG_GAIN_REC_IDX_OX03C10 = 0x6; // 2x +const int ANALOG_GAIN_MAX_IDX_OX03C10 = 0x22; const int EXPOSURE_TIME_MIN_AR0231 = 2; // with HDR, fastest ss const int EXPOSURE_TIME_MAX_AR0231 = 0x0855; // with HDR, slowest ss, 40ms @@ -517,6 +526,7 @@ void CameraState::enqueue_req_multi(int start, int n, bool dp) { void CameraState::camera_set_parameters() { if (camera_id == CAMERA_ID_AR0231) { dc_gain_factor = DC_GAIN_AR0231; + dc_gain_min_weight = DC_GAIN_MIN_WEIGHT_AR0231; dc_gain_max_weight = DC_GAIN_MAX_WEIGHT_AR0231; dc_gain_on_grey = DC_GAIN_ON_GREY_AR0231; dc_gain_off_grey = DC_GAIN_OFF_GREY_AR0231; @@ -529,8 +539,10 @@ void CameraState::camera_set_parameters() { sensor_analog_gains[i] = sensor_analog_gains_AR0231[i]; } min_ev = exposure_time_min * sensor_analog_gains[analog_gain_min_idx]; + target_grey_factor = TARGET_GREY_FACTOR_AR0231; } else if (camera_id == CAMERA_ID_OX03C10) { dc_gain_factor = DC_GAIN_OX03C10; + dc_gain_min_weight = DC_GAIN_MIN_WEIGHT_OX03C10; dc_gain_max_weight = DC_GAIN_MAX_WEIGHT_OX03C10; dc_gain_on_grey = DC_GAIN_ON_GREY_OX03C10; dc_gain_off_grey = DC_GAIN_OFF_GREY_OX03C10; @@ -543,6 +555,7 @@ void CameraState::camera_set_parameters() { sensor_analog_gains[i] = sensor_analog_gains_OX03C10[i]; } min_ev = (exposure_time_min + VS_TIME_MIN_OX03C10) * sensor_analog_gains[analog_gain_min_idx]; + target_grey_factor = TARGET_GREY_FACTOR_OX03C10; } else { assert(false); } @@ -551,7 +564,7 @@ void CameraState::camera_set_parameters() { target_grey_fraction = 0.3; dc_gain_enabled = false; - dc_gain_weight = DC_GAIN_MIN_WEIGHT; + dc_gain_weight = dc_gain_min_weight; gain_idx = analog_gain_rec_idx; exposure_time = 5; cur_ev[0] = cur_ev[1] = cur_ev[2] = (1 + dc_gain_weight * (dc_gain_factor-1) / dc_gain_max_weight) * sensor_analog_gains[gain_idx] * exposure_time; @@ -1037,7 +1050,7 @@ void CameraState::set_camera_exposure(float grey_frac) { const float cur_ev_ = cur_ev[buf.cur_frame_data.frame_id % 3]; // Scale target grey between 0.1 and 0.4 depending on lighting conditions - float new_target_grey = std::clamp(0.4 - 0.3 * log2(1.0 + cur_ev_) / log2(6000.0), 0.1, 0.4); + float new_target_grey = std::clamp(0.4 - 0.3 * log2(1.0 + target_grey_factor*cur_ev_) / log2(6000.0), 0.1, 0.4); float target_grey = (1.0 - k_grey) * target_grey_fraction + k_grey * new_target_grey; float desired_ev = std::clamp(cur_ev_ * target_grey / grey_frac, min_ev, max_ev); @@ -1053,14 +1066,14 @@ void CameraState::set_camera_exposure(float grey_frac) { bool enable_dc_gain = dc_gain_enabled; if (!enable_dc_gain && target_grey < dc_gain_on_grey) { enable_dc_gain = true; - dc_gain_weight = DC_GAIN_MIN_WEIGHT; + dc_gain_weight = dc_gain_min_weight; } else if (enable_dc_gain && target_grey > dc_gain_off_grey) { enable_dc_gain = false; dc_gain_weight = dc_gain_max_weight; } if (enable_dc_gain && dc_gain_weight < dc_gain_max_weight) {dc_gain_weight += 1;} - if (!enable_dc_gain && dc_gain_weight > DC_GAIN_MIN_WEIGHT) {dc_gain_weight -= 1;} + if (!enable_dc_gain && dc_gain_weight > dc_gain_min_weight) {dc_gain_weight -= 1;} std::string gain_bytes, time_bytes; if (env_ctrl_exp_from_params) { @@ -1145,10 +1158,12 @@ void CameraState::set_camera_exposure(float grey_frac) { // t_HCG + t_LCG + t_VS on LPD, t_SPD on SPD uint32_t hcg_time = std::max((dc_gain_weight * exposure_time / dc_gain_max_weight), 0); uint32_t lcg_time = std::max(((dc_gain_max_weight - dc_gain_weight) * exposure_time / dc_gain_max_weight), 0); - uint32_t spd_time = std::max(hcg_time / 16, (uint32_t)exposure_time_min); - uint32_t vs_time = std::min(std::max(hcg_time / 64, VS_TIME_MIN_OX03C10), VS_TIME_MAX_OX03C10); + // uint32_t spd_time = std::max(hcg_time / 16, (uint32_t)exposure_time_min); + uint32_t vs_time = std::min(std::max((uint32_t)exposure_time / 128, VS_TIME_MIN_OX03C10), VS_TIME_MAX_OX03C10); + uint32_t spd_time = vs_time; uint32_t real_gain = ox03c10_analog_gains_reg[new_g]; + uint32_t min_gain = ox03c10_analog_gains_reg[0]; struct i2c_random_wr_payload exp_reg_array[] = { {0x3501, hcg_time>>8}, {0x3502, hcg_time&0xFF}, @@ -1157,9 +1172,9 @@ void CameraState::set_camera_exposure(float grey_frac) { {0x35c1, vs_time>>8}, {0x35c2, vs_time&0xFF}, {0x3508, real_gain>>8}, {0x3509, real_gain&0xFF}, - {0x3588, real_gain>>8}, {0x3589, real_gain&0xFF}, - {0x3548, real_gain>>8}, {0x3549, real_gain&0xFF}, - {0x35c8, real_gain>>8}, {0x35c9, real_gain&0xFF}, + {0x3588, min_gain>>8}, {0x3589, min_gain&0xFF}, + {0x3548, min_gain>>8}, {0x3549, min_gain&0xFF}, + {0x35c8, min_gain>>8}, {0x35c9, min_gain&0xFF}, }; sensors_i2c(exp_reg_array, sizeof(exp_reg_array)/sizeof(struct i2c_random_wr_payload), CAM_SENSOR_PACKET_OPCODE_SENSOR_CONFIG, false); } diff --git a/system/camerad/cameras/camera_qcom2.h b/system/camerad/cameras/camera_qcom2.h index 1b792e7e9..5023c8245 100644 --- a/system/camerad/cameras/camera_qcom2.h +++ b/system/camerad/cameras/camera_qcom2.h @@ -31,11 +31,12 @@ public: int exposure_time_max; float dc_gain_factor; + int dc_gain_min_weight; int dc_gain_max_weight; float dc_gain_on_grey; float dc_gain_off_grey; - float sensor_analog_gains[16]; + float sensor_analog_gains[35]; int analog_gain_min_idx; int analog_gain_max_idx; int analog_gain_rec_idx; @@ -45,6 +46,7 @@ public: float measured_grey_fraction; float target_grey_fraction; + float target_grey_factor; unique_fd sensor_fd; unique_fd csiphy_fd; diff --git a/system/camerad/cameras/sensor2_i2c.h b/system/camerad/cameras/sensor2_i2c.h index 9df99552e..209e2d76d 100644 --- a/system/camerad/cameras/sensor2_i2c.h +++ b/system/camerad/cameras/sensor2_i2c.h @@ -129,13 +129,13 @@ struct i2c_random_wr_payload init_array_ox03c10[] = { {0x350a, 0x04}, {0x350b, 0x00}, {0x350c, 0x00}, // hcg digital gain {0x3586, 0x40}, {0x3587, 0x00}, // lcg fine exposure - {0x358a, 0x04}, {0x358b, 0x00}, {0x358c, 0x00}, // lcg digital gain + {0x358a, 0x01}, {0x358b, 0x00}, {0x358c, 0x00}, // lcg digital gain {0x3546, 0x20}, {0x3547, 0x00}, // spd fine exposure - {0x354a, 0x04}, {0x354b, 0x00}, {0x354c, 0x00}, // spd digital gain + {0x354a, 0x01}, {0x354b, 0x00}, {0x354c, 0x00}, // spd digital gain {0x35c6, 0xb0}, {0x35c7, 0x00}, // vs fine exposure - {0x35ca, 0x04}, {0x35cb, 0x00}, {0x35cc, 0x00}, // vs digital gain + {0x35ca, 0x01}, {0x35cb, 0x00}, {0x35cc, 0x00}, // vs digital gain // also RSVD {0x3600, 0x8f}, {0x3605, 0x16}, {0x3609, 0xf0}, {0x360a, 0x01},