IQ.Pilot Release Commit @ 661a2de

This commit is contained in:
IQ.Lvbs CI [bot]
2026-08-08 14:37:51 -05:00
parent a6c27ac169
commit a1ef7d6c80
211 changed files with 7332 additions and 2756 deletions

View File

@@ -14,3 +14,9 @@ if TICI:
HARDWARE = cast(HardwareBase, Tici())
else:
HARDWARE = cast(HardwareBase, Pc())
# Only comma 3/3X expose the DMA-BUF EGL extensions used by the zero-copy
# camera renderer and the direct EGL frame-pacing calls. /TICI is also present
# on comma 4, so it identifies the AGNOS hardware family rather than this GPU
# capability.
EGL_DMA_BUF_SUPPORTED = TICI and HARDWARE.get_device_type() in ("tici", "tizi")

View File

@@ -1,15 +1,25 @@
#pragma once
#include <cstdint>
#include <cstdlib>
#include <fstream>
#include <map>
#include <optional>
#include <string>
#include <vector>
#include "cereal/gen/cpp/log.capnp.h"
// no-op base hw class
class HardwareNone {
public:
struct UfsHealth {
uint8_t pre_eol_info;
uint8_t life_time_estimate_a;
uint8_t life_time_estimate_b;
std::vector<uint8_t> vendor_health_report;
};
static std::string get_name() { return ""; }
static cereal::InitData::DeviceType get_device_type() { return cereal::InitData::DeviceType::UNKNOWN; }
static int get_voltage() { return 0; }
@@ -21,6 +31,8 @@ public:
return {};
}
static std::optional<UfsHealth> get_ufs_health() { return std::nullopt; }
static void set_ir_power(int percentage) {}
static bool PC() { return false; }

View File

@@ -6,7 +6,11 @@ class FanController:
def __init__(self) -> None:
self.last_ignition = False
def update(self, cur_temp: float, ignition: bool) -> int:
def update(self, cur_temp: float, ignition: bool, max_cool: bool = False) -> int:
if max_cool:
self.last_ignition = ignition
return 100
if cur_temp < 70.0:
fan_pwr_out = 0
elif cur_temp > 85.0:

View File

@@ -432,8 +432,6 @@ def hardware_thread(end_event, hw_queue) -> None:
all_comp_temp = all_temp_filter.update(max(temp_sources))
msg.deviceState.maxTempC = all_comp_temp
msg.deviceState.fanSpeedPercentDesired = fan_controller.update(all_comp_temp, onroad_conditions["ignition"])
is_offroad_for_5_min = (started_ts is None) and ((not started_seen) or (off_ts is None) or (time.monotonic() - off_ts > 60 * 5))
if is_offroad_for_5_min and offroad_comp_temp > OFFROAD_DANGER_TEMP:
# if device is offroad and already hot without the extra onroad load,
@@ -447,6 +445,10 @@ def hardware_thread(end_event, hw_queue) -> None:
elif current_band.max_temp is not None and all_comp_temp > current_band.max_temp:
thermal_status = list(THERMAL_BANDS.keys())[band_idx + 1]
# the car is running but temperature is blocking the start, so cool as fast as we can
max_cool = (started_ts is None) and onroad_conditions["ignition"] and thermal_status >= ThermalStatus.red
msg.deviceState.fanSpeedPercentDesired = fan_controller.update(all_comp_temp, onroad_conditions["ignition"], max_cool)
# **** starting logic ****
startup_conditions["up_to_date"] = True

View File

@@ -41,6 +41,13 @@ class TestFanController:
self.wind_up(controller, True)
assert controller.update(100, True) == 100
@pytest.mark.parametrize("controller_class", ALL_CONTROLLERS)
def test_max_cool(self, mocker, controller_class):
controller = patched_controller(mocker, controller_class)
self.wind_down(controller)
assert controller.update(80, True, True) == 100
assert controller.update(80, False, True) == 100
@pytest.mark.parametrize("controller_class", ALL_CONTROLLERS)
def test_windup_speed(self, mocker, controller_class):
controller = patched_controller(mocker, controller_class)

View File

@@ -67,28 +67,28 @@
},
{
"name": "boot",
"url": "https://sdn.konn3kt.com/agnos/16-iqlvbs/boot-024e5c1f1785b2190520e57c7f88e41436fc22cae32a52d1d68dab65e1370500.img.xz",
"hash": "024e5c1f1785b2190520e57c7f88e41436fc22cae32a52d1d68dab65e1370500",
"hash_raw": "024e5c1f1785b2190520e57c7f88e41436fc22cae32a52d1d68dab65e1370500",
"url": "https://sdn.konn3kt.com/agnos/16-iqlvbs/boot-50b102d3dfa5d0eea506d9586745470cd59bcea9a723408a6abc20ffd6493a89.img.xz",
"hash": "50b102d3dfa5d0eea506d9586745470cd59bcea9a723408a6abc20ffd6493a89",
"hash_raw": "50b102d3dfa5d0eea506d9586745470cd59bcea9a723408a6abc20ffd6493a89",
"size": 18216960,
"sparse": false,
"full_check": true,
"has_ab": true,
"ondevice_hash": "737126dfeaa85870b4615e6310d4686bd049eac8176fc54608b88ecde590f21a"
"ondevice_hash": "fdcb135e8412a896c4a882738a7022f6b7779939d8716f24b9a566b0b3ff3757"
},
{
"name": "system",
"url": "https://sdn.konn3kt.com/agnos/16-iqlvbs/system-640f36a79dc2a3237d9dd253e55cee3ea9cb55988468482d489f38f6b893fb3b.img.xz",
"hash": "e6f7a840437bae56ca49b1f1709f6ba9645ed83484cd02494c05327c6910761b",
"hash_raw": "640f36a79dc2a3237d9dd253e55cee3ea9cb55988468482d489f38f6b893fb3b",
"url": "https://sdn.konn3kt.com/agnos/16-iqlvbs/system-a473962357e3c0c7639af17006def4567f02e64d578b00e2e0037012755be5cd.img.xz",
"hash": "62a08bdf79f6dc0075eba8b93b55cbac6eeee0ecd2b6e8ab05d51ef61a9a880a",
"hash_raw": "a473962357e3c0c7639af17006def4567f02e64d578b00e2e0037012755be5cd",
"size": 6291456000,
"sparse": true,
"full_check": false,
"has_ab": true,
"ondevice_hash": "f7ebe73504e5c2b5f9d3b1f9db5b120badfa313dc78b4d50e6cd26463697aa2c",
"ondevice_hash": "9ed5bc147a6d4c2e0a89562f31096a7802485ee8e740defeab7674abbf6d4baa",
"alt": {
"hash": "640f36a79dc2a3237d9dd253e55cee3ea9cb55988468482d489f38f6b893fb3b",
"url": "https://sdn.konn3kt.com/agnos/16-iqlvbs/system-640f36a79dc2a3237d9dd253e55cee3ea9cb55988468482d489f38f6b893fb3b.img",
"hash": "a473962357e3c0c7639af17006def4567f02e64d578b00e2e0037012755be5cd",
"url": "https://sdn.konn3kt.com/agnos/16-iqlvbs/system-a473962357e3c0c7639af17006def4567f02e64d578b00e2e0037012755be5cd.img",
"size": 6291456000
}
}

View File

@@ -1 +1 @@
bEKwMhJJ7QIhYyXKRLIVyH5xr5c9sjcUf8XS4+/Q9PN6BI23V8OXOkuuX0zREs1Hz4qPPQ9+kKjNoaKydrSwDg==
LxtrHkl5DFbSWnd1DZCkinmXiKFUVUausf0oYpa97dyAp3QGpWx7wrEAUZuJbrERQtdIV72ZU2eKOaQwGMBQBg==

View File

@@ -56,28 +56,28 @@
},
{
"name": "boot",
"url": "https://sdn.konn3kt.com/agnos/16-iqlvbs/boot-024e5c1f1785b2190520e57c7f88e41436fc22cae32a52d1d68dab65e1370500.img.xz",
"hash": "024e5c1f1785b2190520e57c7f88e41436fc22cae32a52d1d68dab65e1370500",
"hash_raw": "024e5c1f1785b2190520e57c7f88e41436fc22cae32a52d1d68dab65e1370500",
"url": "https://sdn.konn3kt.com/agnos/16-iqlvbs/boot-50b102d3dfa5d0eea506d9586745470cd59bcea9a723408a6abc20ffd6493a89.img.xz",
"hash": "50b102d3dfa5d0eea506d9586745470cd59bcea9a723408a6abc20ffd6493a89",
"hash_raw": "50b102d3dfa5d0eea506d9586745470cd59bcea9a723408a6abc20ffd6493a89",
"size": 18216960,
"sparse": false,
"full_check": true,
"has_ab": true,
"ondevice_hash": "737126dfeaa85870b4615e6310d4686bd049eac8176fc54608b88ecde590f21a"
"ondevice_hash": "fdcb135e8412a896c4a882738a7022f6b7779939d8716f24b9a566b0b3ff3757"
},
{
"name": "system",
"url": "https://sdn.konn3kt.com/agnos/16-iqlvbs/system-640f36a79dc2a3237d9dd253e55cee3ea9cb55988468482d489f38f6b893fb3b.img.xz",
"hash": "e6f7a840437bae56ca49b1f1709f6ba9645ed83484cd02494c05327c6910761b",
"hash_raw": "640f36a79dc2a3237d9dd253e55cee3ea9cb55988468482d489f38f6b893fb3b",
"url": "https://sdn.konn3kt.com/agnos/16-iqlvbs/system-a473962357e3c0c7639af17006def4567f02e64d578b00e2e0037012755be5cd.img.xz",
"hash": "62a08bdf79f6dc0075eba8b93b55cbac6eeee0ecd2b6e8ab05d51ef61a9a880a",
"hash_raw": "a473962357e3c0c7639af17006def4567f02e64d578b00e2e0037012755be5cd",
"size": 6291456000,
"sparse": true,
"full_check": false,
"has_ab": true,
"ondevice_hash": "f7ebe73504e5c2b5f9d3b1f9db5b120badfa313dc78b4d50e6cd26463697aa2c",
"ondevice_hash": "9ed5bc147a6d4c2e0a89562f31096a7802485ee8e740defeab7674abbf6d4baa",
"alt": {
"hash": "640f36a79dc2a3237d9dd253e55cee3ea9cb55988468482d489f38f6b893fb3b",
"url": "https://sdn.konn3kt.com/agnos/16-iqlvbs/system-640f36a79dc2a3237d9dd253e55cee3ea9cb55988468482d489f38f6b893fb3b.img",
"hash": "a473962357e3c0c7639af17006def4567f02e64d578b00e2e0037012755be5cd",
"url": "https://sdn.konn3kt.com/agnos/16-iqlvbs/system-a473962357e3c0c7639af17006def4567f02e64d578b00e2e0037012755be5cd.img",
"size": 6291456000
}
}

View File

@@ -1 +1 @@
A9eBPajhAHUyx3wzPP/pZn2VRIMS2UNtSoeuIZTCAFkbV5HhAkD8HlLSemijmRQtMR62adjV+HUwZ0eRaZpdCg==
mKCTfzNHr1d0BYPdmXQRPGpnVuLaDLGZGLbq+86ZJQaGIK1ekcKeYeycoX8BTMNFr+89Tnd77M/CvmjM8yteCg==

View File

@@ -1,17 +1,63 @@
#pragma once
#include <cstdlib>
#include <array>
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <cstdlib>
#include <fcntl.h>
#include <fstream>
#include <map>
#include <string>
#include <algorithm> // for std::clamp
#include <sys/ioctl.h>
#include <unistd.h>
#include "common/util.h"
#include "system/hardware/base.h"
class HardwareTici : public HardwareNone {
public:
static std::optional<UfsHealth> get_ufs_health() {
constexpr unsigned long UFS_IOCTL_QUERY = 0x5388;
constexpr uint32_t UPIU_QUERY_OPCODE_READ_DESC = 0x1;
constexpr uint8_t QUERY_DESC_IDN_HEALTH = 0x9;
constexpr uint16_t QUERY_DESC_HEALTH_SIZE = 0x25;
struct UfsQuery {
uint32_t opcode;
uint8_t idn;
uint8_t reserved;
uint16_t buf_size;
std::array<uint8_t, QUERY_DESC_HEALTH_SIZE> buffer;
};
static_assert(offsetof(UfsQuery, buffer) == 8);
UfsQuery query = {};
query.opcode = UPIU_QUERY_OPCODE_READ_DESC;
query.idn = QUERY_DESC_IDN_HEALTH;
query.buf_size = QUERY_DESC_HEALTH_SIZE;
int fd = open("/dev/sda", O_RDONLY | O_CLOEXEC);
if (fd < 0) {
return std::nullopt;
}
int ret = ioctl(fd, UFS_IOCTL_QUERY, &query);
close(fd);
if (ret != 0 || query.buf_size < 5 || query.buf_size > query.buffer.size() ||
query.buffer[0] != query.buf_size || query.buffer[1] != QUERY_DESC_IDN_HEALTH) {
return std::nullopt;
}
return UfsHealth{
query.buffer[2],
query.buffer[3],
query.buffer[4],
std::vector<uint8_t>(query.buffer.begin() + 5, query.buffer.begin() + query.buf_size),
};
}
static std::string get_name() {
std::string model = util::read_file("/sys/firmware/devicetree/base/model");
return util::strip(model.substr(std::string("comma ").size()));

View File

@@ -85,8 +85,13 @@ def affine_irq(val, action):
@lru_cache
def get_device_type():
# lru_cache and cache can cause memory leaks when used in classes
with open("/sys/firmware/devicetree/base/model") as f:
model = f.read().strip('\x00')
try:
with open("/sys/firmware/devicetree/base/model") as f:
model = f.read().strip('\x00')
except FileNotFoundError:
# off-device (e.g. the prebuilt build container fakes /TICI but has no
# devicetree); import must not crash. Not a real device type.
return "unknown"
return model.split('comma ')[-1]
class Tici(HardwareBase):