Compare commits

..

9 Commits

Author SHA1 Message Date
firestar5683 a497c0f839 Add AGNOS download mirrors 2026-08-25 09:26:39 -05:00
firestar5683 c186cd8232 Reapply build 2026-08-24 22:08:18 -05:00
firestar5683 e1bd3db8ac Reapply Agnos 19.6.10 2026-08-24 22:08:17 -05:00
firestar5683 c883f6f9b4 Revert "Agnos 19.6.10"
This reverts commit 9263fd7c44.
2026-08-24 21:39:18 -05:00
firestar5683 06bd9fec31 Revert "build"
This reverts commit 5dc9c57f4f.
2026-08-24 21:39:16 -05:00
firestar5683 5dc9c57f4f build 2026-08-24 21:36:57 -05:00
firestar5683 9263fd7c44 Agnos 19.6.10 2026-08-24 21:34:51 -05:00
firestar5683 28ec3ccb80 squeak squeak 2026-08-23 10:41:13 -05:00
firestar5683 5f65219aed name 2026-08-21 20:26:21 -05:00
204 changed files with 4731 additions and 6809 deletions
+51 -4
View File
@@ -1,4 +1,5 @@
import os
import importlib
import shutil
import subprocess
import sys
@@ -128,6 +129,41 @@ elif arch == "aarch64" and AGNOS:
arch = "larch64"
assert arch in ["larch64", "aarch64", "x86_64", "Darwin"]
# AGNOS 19.6 ships native dependencies as versioned Python packages. Link
# Cap'n Proto statically from that managed package so release binaries don't
# depend on the removed libcapnp-1.0.2.so system library.
try:
capnproto = importlib.import_module("capnproto")
except ModuleNotFoundError:
capnproto = None
try:
ffmpeg = importlib.import_module("ffmpeg")
except ModuleNotFoundError:
ffmpeg = None
capnproto_include_dirs = [capnproto.INCLUDE_DIR] if capnproto is not None else []
capnproto_lib_dirs = [capnproto.LIB_DIR] if capnproto is not None else []
ffmpeg_include_dirs = [ffmpeg.INCLUDE_DIR] if ffmpeg is not None else []
ffmpeg_lib_dirs = [ffmpeg.LIB_DIR] if ffmpeg is not None else []
# Cross-builds install managed dependencies in /work/.venv-linux-arm64, but
# comma devices expose the same packages from /usr/local/venv. Never embed the
# host/container mount path in release binaries.
ffmpeg_runtime_lib_dirs = ffmpeg_lib_dirs
if arch == "larch64" and ffmpeg is not None:
ffmpeg_runtime_lib_dirs = [os.path.join("/usr/local/venv", os.path.relpath(ffmpeg.LIB_DIR, sys.prefix))]
# The managed native-dependency packages keep their tools inside the package
# instead of installing them into /usr/local/venv/bin. cereal invokes capnpc
# directly while SConscript files are evaluated, so make the packaged tools
# discoverable to both SCons actions and configure-time subprocesses.
dependency_bin_dirs = [
package.BIN_DIR for package in (capnproto, ffmpeg)
if package is not None and os.path.isdir(package.BIN_DIR)
]
if dependency_bin_dirs:
os.environ["PATH"] = os.pathsep.join([*dependency_bin_dirs, os.environ["PATH"]])
# Homebrew llvm can shadow Apple clang and break macOS SDK header resolution.
# Use the system toolchain explicitly on macOS for reliable local builds.
cc = '/usr/bin/clang' if arch == "Darwin" else 'clang'
@@ -269,7 +305,10 @@ env = Environment(
"-Wno-vla-cxx-extension",
] + cflags + ccflags,
CPPPATH=cpppath + [
# Managed dependencies must precede the compatibility sysroot. The sysroot
# can intentionally retain legacy libraries for C3 support, but new release
# binaries must link against the versions shipped in the managed venv.
CPPPATH=capnproto_include_dirs + ffmpeg_include_dirs + cpppath + [
"#",
"#third_party/acados/include",
"#third_party/acados/include/blasfeo/include",
@@ -288,11 +327,11 @@ env = Environment(
RANLIB=ranlib,
LINKFLAGS=ldflags,
RPATH=rpath,
RPATH=ffmpeg_runtime_lib_dirs + rpath,
CFLAGS=["-std=gnu11"] + cflags,
CXXFLAGS=["-std=c++1z"] + cxxflags,
LIBPATH=libpath + [
LIBPATH=capnproto_lib_dirs + ffmpeg_lib_dirs + libpath + [
"#msgq_repo",
"#third_party",
"#selfdrive/pandad",
@@ -371,7 +410,15 @@ SConscript(['opendbc_repo/SConscript'], exports={'env': env_swaglog})
SConscript(['cereal/SConscript'])
Import('socketmaster', 'msgq')
messaging = [socketmaster, msgq, 'capnp', 'kj',]
if capnproto is not None:
messaging = [
socketmaster,
msgq,
File(os.path.join(capnproto.LIB_DIR, "libcapnp.a")),
File(os.path.join(capnproto.LIB_DIR, "libkj.a")),
]
else:
messaging = [socketmaster, msgq, 'capnp', 'kj']
Export('messaging')
-1
View File
@@ -265,7 +265,6 @@ struct StarPilotSelfdriveState @0xf416ec09499d9d19 {
alertSize @3 :AlertSize;
alertType @4 :Text;
alertSound @5 :Car.CarControl.HUDControl.AudibleAlert;
vEgo @6 :Float32;
enum AlertStatus {
normal @0;
Binary file not shown.
Binary file not shown.
Binary file not shown.
+1 -6
View File
@@ -66,6 +66,7 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
{"HondaLateralPidKiScale", {PERSISTENT, FLOAT, "1.0", "1.0", 3}},
{"HondaLateralPidKpScale", {PERSISTENT, FLOAT, "1.0", "1.0", 3}},
{"HondaWindFactorParams", {PERSISTENT, FLOAT}},
{"HomeScreenName", {PERSISTENT, STRING, "StarPilot", "StarPilot", 3}},
{"InstallDate", {PERSISTENT, TIME}},
{"IsDriverViewEnabled", {CLEAR_ON_MANAGER_START, BOOL}},
{"IsEngaged", {PERSISTENT, BOOL}},
@@ -238,10 +239,6 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
{"CommunityFavorites", {PERSISTENT, STRING, "", "", 1}},
{"ConditionalChill", {PERSISTENT, BOOL, "0", "0", 1}},
{"ConditionalExperimental", {PERSISTENT, BOOL, "1", "0", 1, SETTINGS_SIMPLE}},
{"HybridExpBias", {PERSISTENT, FLOAT, "0", "0", 1}},
{"HybridExperimental", {PERSISTENT, BOOL, "0", "0", 1}},
{"HybridVisionBrakeSensitivity", {PERSISTENT, FLOAT, "1", "1", 1}},
{"HEMExpDominant", {CLEAR_ON_MANAGER_START, BOOL, "0", "0", 2}},
{"CurvatureData", {PERSISTENT | DONT_LOG, JSON, "{}", "{}"}},
{"CurveSpeedController", {PERSISTENT, BOOL, "1", "0", 1, SETTINGS_SIMPLE}},
{"CurveSpeedControllerNoLead", {PERSISTENT, BOOL, "0", "0", 1, SETTINGS_SIMPLE}},
@@ -349,7 +346,6 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
{"FordCurvatureBlendHigh", {PERSISTENT, FLOAT, "0.4", "0.4", 2}},
{"FordCurvatureBlendLow", {PERSISTENT, FLOAT, "0.4", "0.4", 2}},
{"FordCurvatureLaneChangeFactor", {PERSISTENT, FLOAT, "0.85", "0.85", 2}},
{"FordHandsFreeCluster", {PERSISTENT, BOOL, "0", "0", 2}},
{"FordHumanTurnDetection", {PERSISTENT, BOOL, "1", "1", 2}},
{"FordLateralMode", {PERSISTENT, INT, "1", "1", 2}},
{"FLMActiveOverrides", {PERSISTENT, JSON, "{}", "{}", 2}},
@@ -684,7 +680,6 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
{"TuningLevel", {PERSISTENT, INT, "0", "0", 0}},
{"TuningLevelConfirmed", {PERSISTENT, BOOL, "0", "0", 0}},
{"TurnDesires", {PERSISTENT, BOOL, "0", "0", 2}},
{"TurnSteeringLimitMuteSpeed", {PERSISTENT, INT, "0", "0", 0}},
{"UnlockDoors", {PERSISTENT, BOOL, "1", "0", 0}},
{"Updated", {PERSISTENT, STRING, "0", "0"}},
{"UpdateSpeedLimits", {CLEAR_ON_MANAGER_START, BOOL, "0", "0"}},
Binary file not shown.
Binary file not shown.
+94 -3
View File
@@ -147,10 +147,101 @@ function launch {
while true; do sleep 1; done
fi
function prebuilt_runtime_compatible {
python3 - <<'PY'
import importlib
import os
from pathlib import Path
import sys
import time
from openpilot.common.file_chunker import get_existing_chunks
start = time.monotonic()
last = start
log_path = os.environ.get("SP_BOOT_TIMING_LOG")
def emit(line):
print(line, flush=True)
if log_path:
try:
with open(log_path, "a") as f:
f.write(line + "\n")
except OSError:
pass
def log_step(label):
global last
now = time.monotonic()
emit(f"SP_BOOT_TIMING prebuilt_compat {label} +{now - last:.3f}s total={now - start:.3f}s")
last = now
mods = [
"openpilot.common.params_pyx",
"msgq.ipc_pyx",
"msgq.visionipc.visionipc_pyx",
"openpilot.common.transformations.transformations",
"openpilot.selfdrive.pandad.pandad_api_impl",
"openpilot.selfdrive.controls.lib.lateral_mpc_lib.c_generated_code.acados_ocp_solver_pyx",
"openpilot.selfdrive.controls.lib.longitudinal_mpc_lib.c_generated_code.acados_ocp_solver_pyx",
]
for mod in mods:
try:
importlib.import_module(mod)
except Exception as e:
print(f"Prebuilt compatibility failure in {mod}: {e}", file=sys.stderr)
raise
log_step(f"import:{mod}")
repo_root = Path.cwd().parents[1]
required_model_artifacts = [
repo_root / "selfdrive/modeld/models/driving_tinygrad.pkl",
repo_root / "selfdrive/modeld/models/dmonitoring_model_metadata.pkl",
repo_root / "selfdrive/modeld/models/dmonitoring_model_tinygrad.pkl",
repo_root / "selfdrive/modeld/models/dm_warp_1928x1208_tinygrad.pkl",
repo_root / "selfdrive/modeld/models/dm_warp_1344x760_tinygrad.pkl",
]
required_files = [
repo_root / "selfdrive/pandad/pandad_api_impl.so",
repo_root / "selfdrive/controls/lib/lateral_mpc_lib/c_generated_code/acados_ocp_solver_pyx.so",
repo_root / "selfdrive/controls/lib/lateral_mpc_lib/c_generated_code/libacados_ocp_solver_lat.so",
repo_root / "selfdrive/controls/lib/longitudinal_mpc_lib/c_generated_code/acados_ocp_solver_pyx.so",
repo_root / "selfdrive/controls/lib/longitudinal_mpc_lib/c_generated_code/libacados_ocp_solver_long.so",
repo_root / "opendbc_repo/opendbc/dbc/gm_global_a_powertrain_generated.dbc",
]
for path in required_model_artifacts:
try:
artifact_paths = [Path(p) for p in get_existing_chunks(path)]
except Exception as e:
raise FileNotFoundError(f"Missing prebuilt runtime artifact: {path}") from e
missing_chunks = [p for p in artifact_paths if not p.is_file()]
if missing_chunks:
missing = ", ".join(str(p) for p in missing_chunks)
raise FileNotFoundError(f"Missing prebuilt runtime artifact chunks for {path}: {missing}")
log_step("required_model_artifacts")
for path in required_files:
if not path.is_file():
raise FileNotFoundError(f"Missing prebuilt runtime artifact: {path}")
log_step("required_files")
PY
}
USE_PREBUILT=1
if [ -f /data/params/d/UsePrebuilt ]; then
USE_PREBUILT=$(tr -d '\n' < /data/params/d/UsePrebuilt)
fi
sp_launch_timing "prebuilt_decision_done"
# Published trees carry this marker and must never compile on-device.
# Developers can remove it explicitly when working from a source tree.
if [ ! -f "$DIR/prebuilt" ]; then
if [ "$USE_PREBUILT" = "1" ] && [ -f $DIR/prebuilt ] && ! prebuilt_runtime_compatible; then
echo "Prebuilt runtime artifacts are incompatible on this device; rebuilding locally."
USE_PREBUILT=0
fi
sp_launch_timing "prebuilt_compat_done"
if [ "$USE_PREBUILT" != "1" ] || [ ! -f $DIR/prebuilt ]; then
sp_launch_timing "build_start"
./build.py
sp_launch_timing "build_done"
+1 -1
View File
@@ -21,7 +21,7 @@ fi
export QCOM_PRIORITY=12
if [ -z "$AGNOS_VERSION" ]; then
export AGNOS_VERSION="19.6.2"
export AGNOS_VERSION="19.6.10"
fi
if [ -z "$AGNOS_ACCEPTED_VERSIONS" ]; then
Binary file not shown.
Binary file not shown.
@@ -255,15 +255,9 @@ class CarController(CarControllerBase):
if (self.frame % CarControllerParams.ACC_UI_STEP) == 0 or send_ui:
show_distance_bars = self.frame - self.distance_bar_frame < 400
hands_free_cluster = bool(
self.ford_lateral is not None
and self.ford_lateral.mode != FordLateralMode.native
and self.ford_lateral.mode == self.ford_lateral_announced_mode
and self.ford_lateral.hands_free_cluster_enabled)
can_sends.append(fordcan.create_acc_ui_msg(self.packer, self.CAN, self.CP, main_on, CC.latActive,
fcw_alert, CS.out.cruiseState.standstill, show_distance_bars,
hud_control, CS.acc_tja_status_stock_values,
hands_free_cluster))
hud_control, CS.acc_tja_status_stock_values))
self.main_on_last = main_on
self.lkas_enabled_last = CC.latActive
+1 -3
View File
@@ -181,7 +181,7 @@ def create_acc_msg(packer, CAN: CanBus, long_active: bool, gas: float, accel: fl
def create_acc_ui_msg(packer, CAN: CanBus, CP, main_on: bool, enabled: bool, fcw_alert: bool, standstill: bool,
show_distance_bars: bool, hud_control, stock_values: dict, hands_free_cluster: bool = False):
show_distance_bars: bool, hud_control, stock_values: dict):
"""
Creates a CAN message for the Ford IPC adaptive cruise, forward collision warning and traffic jam
assist status.
@@ -197,8 +197,6 @@ def create_acc_ui_msg(packer, CAN: CanBus, CP, main_on: bool, enabled: bool, fcw
status = 3 # ActiveInterventionLeft
elif hud_control.rightLaneDepart:
status = 4 # ActiveInterventionRight
elif hands_free_cluster:
status = 7 # Hands-free assistance display
else:
status = 2 # Active
elif main_on:
@@ -1,13 +1,10 @@
import random
from collections.abc import Iterable
from types import SimpleNamespace
from hypothesis import settings, given, strategies as st
from parameterized import parameterized
from opendbc.car import gen_empty_fingerprint
from opendbc.can import CANPacker
from opendbc.car.ford import fordcan
from opendbc.car.structs import CarParams
from opendbc.car.fw_versions import build_fw_dict
from opendbc.car.ford.interface import CarInterface
@@ -175,29 +172,3 @@ def test_mach_e_longitudinal_toggle_controls_stock_acc_selection():
assert enhanced.alphaLongitudinalAvailable
assert enhanced.openpilotLongitudinalControl
assert enhanced.safetyConfigs[-1].safetyParam & FordSafetyFlags.LONG_CONTROL
def test_hands_free_cluster_status_is_opt_in():
packer = CANPacker("ford_lincoln_base_pt")
CAN = SimpleNamespace(main=0)
CP = SimpleNamespace(openpilotLongitudinalControl=False)
hud = SimpleNamespace(leftLaneDepart=False, rightLaneDepart=False)
stock_values = dict.fromkeys([
"HaDsply_No_Cs", "HaDsply_No_Cnt", "AccStopStat_D_Dsply", "AccTrgDist2_D_Dsply",
"AccStopRes_B_Dsply", "TjaWarn_D_Rq", "TjaMsgTxt_D_Dsply", "IaccLamp_D_Rq",
"AccMsgTxt_D2_Rq", "FcwDeny_B_Dsply", "FcwMemStat_B_Actl", "AccTGap_B_Dsply",
"CadsAlignIncplt_B_Actl", "AccFllwMde_B_Dsply", "CadsRadrBlck_B_Actl",
"CmbbPostEvnt_B_Dsply", "AccStopMde_B_Dsply", "FcwMemSens_D_Actl",
"FcwMsgTxt_D_Rq", "AccWarn_D_Dsply", "FcwVisblWarn_B_Rq", "FcwAudioWarn_B_Rq",
"AccTGap_D_Dsply", "AccMemEnbl_B_RqDrv", "FdaMem_B_Stat",
], 0)
regular = fordcan.create_acc_ui_msg(
packer, CAN, CP, True, True, False, False, False, hud, stock_values)
hands_free = fordcan.create_acc_ui_msg(
packer, CAN, CP, True, True, False, False, False, hud, stock_values, True)
expected_regular = packer.make_can_msg("ACCDATA_3", 0, {"Tja_D_Stat": 2})
expected_hands_free = packer.make_can_msg("ACCDATA_3", 0, {"Tja_D_Stat": 7})
assert regular == expected_regular
assert hands_free == expected_hands_free
@@ -988,45 +988,6 @@ class TestHyundaiFingerprint:
assert long_xceed.safetyConfigs[-1].safetyParam & HyundaiSafetyFlags.HYBRID_GAS
assert long_xceed.safetyConfigs[-1].safetyParam & HyundaiSafetyFlags.LONG
def test_g80_alpha_long_preserves_legacy_safety(self):
toggles = get_test_toggles()
stock_g80 = CarInterface.get_params(CAR.GENESIS_G80, gen_empty_fingerprint(), [], False, False, False, toggles)
assert CAR.GENESIS_G80 in LEGACY_LONGITUDINAL_CAR
assert stock_g80.alphaLongitudinalAvailable
assert not stock_g80.openpilotLongitudinalControl
assert stock_g80.pcmCruise
assert stock_g80.safetyConfigs[-1].safetyModel == CarParams.SafetyModel.hyundaiLegacy
assert not (stock_g80.safetyConfigs[-1].safetyParam & HyundaiSafetyFlags.LONG)
long_g80 = CarInterface.get_params(CAR.GENESIS_G80, gen_empty_fingerprint(), [], True, False, False, toggles)
assert long_g80.alphaLongitudinalAvailable
assert long_g80.openpilotLongitudinalControl
assert not long_g80.pcmCruise
assert long_g80.safetyConfigs[-1].safetyModel == CarParams.SafetyModel.hyundaiLegacy
assert long_g80.safetyConfigs[-1].safetyParam & HyundaiSafetyFlags.LONG
@pytest.mark.parametrize("ecu_disabled", (True, False))
def test_g80_alpha_long_disables_stock_scc(self, monkeypatch, ecu_disabled):
toggles = get_test_toggles()
CP = CarInterface.get_params(CAR.GENESIS_G80, gen_empty_fingerprint(), [], True, False, False, toggles)
called = {}
def fake_disable_ecu(*args, **kwargs):
called.update(kwargs)
return ecu_disabled
monkeypatch.setattr("opendbc.car.hyundai.interface.disable_ecu", fake_disable_ecu)
CarInterface.init(CP, None, None)
assert called["addr"] == 0x7d0
assert called["bus"] == 0
assert called["reset"] is False
assert CP.openpilotLongitudinalControl == ecu_disabled
assert CP.pcmCruise != ecu_disabled
assert bool(CP.safetyConfigs[-1].safetyParam & HyundaiSafetyFlags.LONG) == ecu_disabled
def test_xceed_phev_disable_failure_falls_back_to_stock_acc(self, monkeypatch):
toggles = get_test_toggles()
CP = CarInterface.get_params(CAR.KIA_XCEED_PHEV, gen_empty_fingerprint(), [], True, False, False, toggles)
+1 -4
View File
@@ -1213,9 +1213,6 @@ NON_SCC_CAR = CAR.with_flags(HyundaiFlags.NON_SCC)
# HyundaiFlags.CANFD_RADAR_SCC | HyundaiFlags.CANFD_NO_RADAR_DISABLE | )
UNSUPPORTED_LONGITUDINAL_CAR = CAR.with_flags(HyundaiFlags.LEGACY) | CAR.with_flags(HyundaiFlags.UNSUPPORTED_LONGITUDINAL)
LEGACY_LONGITUDINAL_CAR = {
CAR.GENESIS_G80,
CAR.KIA_XCEED_PHEV,
}
LEGACY_LONGITUDINAL_CAR = {CAR.KIA_XCEED_PHEV}
DBC = CAR.create_dbc_map()
+1 -2
View File
@@ -15,7 +15,6 @@ LEAF_ADAS_ECU_BUS = 0
LEAF_ADAS_COMMAND_BUS = 1
LEAF_ADAS_COMMAND_ADDRS = frozenset((0x1C3, 0x2B0))
LEAF_2025_SV_PLUS_CAMERA_FW = b'6WK2CDB\x04\x18\x00\x00\x00\x00\x00R=1\x18\x99\x10\x00\x00\x00\x80'
LEAF_2025_SV_PLUS_ALPHA_LONG_ENABLED = False
LEAF_KWP_EXTENDED_REQUEST = b"\x10\xC0"
LEAF_KWP_EXTENDED_RESPONSE = b"\x50\xC0"
@@ -27,7 +26,7 @@ LEAF_KWP_TAKEOVER_SESSIONS = (
def is_leaf_2025_sv_plus_longitudinal(candidate, car_fw):
return LEAF_2025_SV_PLUS_ALPHA_LONG_ENABLED and candidate == CAR.NISSAN_LEAF and any(
return candidate == CAR.NISSAN_LEAF and any(
fw.address == LEAF_ADAS_ECU_ADDR and bytes(fw.fwVersion) == LEAF_2025_SV_PLUS_CAMERA_FW
for fw in car_fw
)
@@ -4,7 +4,6 @@ import pytest
from opendbc.car import Bus, ButtonType, gen_empty_fingerprint, structs
from opendbc.car.can_definitions import CanData
from opendbc.car.nissan import interface as nissan_interface
from opendbc.car.nissan.carstate import CarState
from opendbc.car.nissan.interface import CarInterface, LEAF_2025_SV_PLUS_CAMERA_FW, leaf_adas_commands_present, \
leaf_adas_commands_silent, restore_leaf_adas_tx
@@ -19,12 +18,6 @@ SUPPORTED_LEAF_FW = [structs.CarParams.CarFw(
)]
@pytest.fixture
def experimental_leaf_long(monkeypatch):
"""Exercise the dormant implementation without making it available in production."""
monkeypatch.setattr(nissan_interface, "LEAF_2025_SV_PLUS_ALPHA_LONG_ENABLED", True)
def run_controller(alpha_long, accel=0.0, long_active=True, long_state=structs.CarControl.Actuators.LongControlState.pid):
CP = CarInterface.get_params(CAR.NISSAN_LEAF, gen_empty_fingerprint(), SUPPORTED_LEAF_FW, alpha_long, False, False, TEST_TOGGLES)
FPCP = CarInterface.get_starpilot_params(CAR.NISSAN_LEAF, gen_empty_fingerprint(), SUPPORTED_LEAF_FW, CP, TEST_TOGGLES)
@@ -40,28 +33,7 @@ def run_controller(alpha_long, accel=0.0, long_active=True, long_state=structs.C
return {msg[0]: msg for msg in can_sends}
def test_leaf_2025_sv_plus_alpha_long_is_disabled(monkeypatch):
stock = CarInterface.get_params(CAR.NISSAN_LEAF, gen_empty_fingerprint(), SUPPORTED_LEAF_FW, False, False, False, None)
alpha_long = CarInterface.get_params(CAR.NISSAN_LEAF, gen_empty_fingerprint(), SUPPORTED_LEAF_FW, True, False, False, None)
assert not stock.alphaLongitudinalAvailable
assert not stock.openpilotLongitudinalControl
assert stock.pcmCruise
assert not (stock.safetyConfigs[-1].safetyParam & NissanSafetyFlags.LONG_CONTROL)
assert not alpha_long.alphaLongitudinalAvailable
assert not alpha_long.openpilotLongitudinalControl
assert alpha_long.pcmCruise
assert not alpha_long.autoResumeSng
assert not (alpha_long.safetyConfigs[-1].safetyParam & NissanSafetyFlags.LONG_CONTROL)
disable_calls = []
monkeypatch.setattr("opendbc.car.nissan.interface.disable_ecu", lambda *args, **kwargs: disable_calls.append((args, kwargs)))
CarInterface.init(alpha_long, None, None)
assert not disable_calls
def test_dormant_leaf_2025_sv_plus_alpha_long_params(experimental_leaf_long):
def test_leaf_2025_sv_plus_alpha_long_params():
stock = CarInterface.get_params(CAR.NISSAN_LEAF, gen_empty_fingerprint(), SUPPORTED_LEAF_FW, False, False, False, None)
alpha_long = CarInterface.get_params(CAR.NISSAN_LEAF, gen_empty_fingerprint(), SUPPORTED_LEAF_FW, True, False, False, None)
@@ -107,13 +79,7 @@ def test_stock_controller_does_not_send_longitudinal_messages():
assert not ({0x2B0, 0x1C3, 0x707} & can_sends.keys())
def test_disabled_alpha_long_controller_does_not_send_longitudinal_messages():
can_sends = run_controller(True)
assert not ({0x2B0, 0x1C3, 0x707} & can_sends.keys())
def test_alpha_long_controller_sends_stock_shaped_commands_and_keepalive(experimental_leaf_long):
def test_alpha_long_controller_sends_stock_shaped_commands_and_keepalive():
can_sends = run_controller(True)
assert can_sends[0x2B0][1].hex() == "ff6090ac5b000e03"
@@ -123,13 +89,13 @@ def test_alpha_long_controller_sends_stock_shaped_commands_and_keepalive(experim
assert can_sends[0x707][2] == 0
def test_alpha_long_controller_clamps_to_panda_accel_limit(experimental_leaf_long):
def test_alpha_long_controller_clamps_to_panda_accel_limit():
can_sends = run_controller(True, accel=5.0)
assert can_sends[0x2B0][1].hex() == "007f8fac5b000e0c"
def test_alpha_long_controller_blends_friction_brake_below_regen_limit(experimental_leaf_long):
def test_alpha_long_controller_blends_friction_brake_below_regen_limit():
can_sends = run_controller(True, accel=-2.0)
assert can_sends[0x2B0][1].hex() == "a827d5ac5b000e09"
@@ -138,7 +104,7 @@ def test_alpha_long_controller_blends_friction_brake_below_regen_limit(experimen
assert brake[5] & 0x84 == 0x84
def test_alpha_long_controller_sends_inactive_commands_when_disengaged(experimental_leaf_long):
def test_alpha_long_controller_sends_inactive_commands_when_disengaged():
can_sends = run_controller(True, accel=1.0, long_active=False)
assert can_sends[0x2B0][1].hex() == "dc53a2ac1b000e03"
@@ -147,7 +113,7 @@ def test_alpha_long_controller_sends_inactive_commands_when_disengaged(experimen
@pytest.mark.parametrize(("signal", "button_type"), [("SET_BUTTON", ButtonType.decelCruise),
("RES_BUTTON", ButtonType.accelCruise)])
def test_leaf_set_resume_release_enables_alpha_long(signal, button_type, experimental_leaf_long):
def test_leaf_set_resume_release_enables_alpha_long(signal, button_type):
CP = CarInterface.get_params(CAR.NISSAN_LEAF, gen_empty_fingerprint(), SUPPORTED_LEAF_FW, True, False, False, TEST_TOGGLES)
FPCP = CarInterface.get_starpilot_params(CAR.NISSAN_LEAF, gen_empty_fingerprint(), SUPPORTED_LEAF_FW, CP, TEST_TOGGLES)
CS = CarState(CP, FPCP)
@@ -164,7 +130,7 @@ def test_leaf_set_resume_release_enables_alpha_long(signal, button_type, experim
@pytest.mark.parametrize("ecu_disabled", [False, True])
def test_leaf_ecu_disable_is_strict_and_falls_back(monkeypatch, ecu_disabled, experimental_leaf_long):
def test_leaf_ecu_disable_is_strict_and_falls_back(monkeypatch, ecu_disabled):
CP = CarInterface.get_params(CAR.NISSAN_LEAF, gen_empty_fingerprint(), SUPPORTED_LEAF_FW, True, False, False, None)
calls = []
@@ -192,7 +158,7 @@ def test_leaf_ecu_disable_is_strict_and_falls_back(monkeypatch, ecu_disabled, ex
assert bool(CP.safetyConfigs[-1].safetyParam & NissanSafetyFlags.LONG_CONTROL) is ecu_disabled
def test_leaf_kwp_no_response_disable_can_confirm_ecu_silence(monkeypatch, experimental_leaf_long):
def test_leaf_kwp_no_response_disable_can_confirm_ecu_silence(monkeypatch):
CP = CarInterface.get_params(CAR.NISSAN_LEAF, gen_empty_fingerprint(), SUPPORTED_LEAF_FW, True, False, False, None)
monkeypatch.setattr("opendbc.car.nissan.interface.disable_ecu", lambda *args, **kwargs: True)
@@ -205,7 +171,7 @@ def test_leaf_kwp_no_response_disable_can_confirm_ecu_silence(monkeypatch, exper
assert CP.safetyConfigs[-1].safetyParam & NissanSafetyFlags.LONG_CONTROL
def test_leaf_positive_disable_response_without_command_silence_falls_back(monkeypatch, experimental_leaf_long):
def test_leaf_positive_disable_response_without_command_silence_falls_back(monkeypatch):
CP = CarInterface.get_params(CAR.NISSAN_LEAF, gen_empty_fingerprint(), SUPPORTED_LEAF_FW, True, False, False, None)
restore_calls = []
@@ -165,18 +165,13 @@ class TestCarInterfaces:
"Center_Stack_2": {"LKAS_Button": 1},
}, is_ram=True)
@pytest.mark.parametrize("candidate", (
CHRYSLER_CAR.CHRYSLER_PACIFICA_2020,
CHRYSLER_CAR.JEEP_GRAND_CHEROKEE,
CHRYSLER_CAR.JEEP_GRAND_CHEROKEE_2019,
))
def test_chrysler_steer_to_zero_module(self, candidate):
def test_chrysler_wd_mod_enables_steer_to_zero(self):
fingerprint = {bus: {} for bus in range(8)}
fingerprint[0][0x4FF] = 8
toggles = get_test_starpilot_toggles()
car_params = ChryslerCarInterface.get_params(
candidate,
CHRYSLER_CAR.CHRYSLER_PACIFICA_2020,
fingerprint,
[],
alpha_long=False,
@@ -187,7 +182,7 @@ class TestCarInterfaces:
assert car_params.minSteerSpeed > 0.
fp_car_params = ChryslerCarInterface.get_starpilot_params(
candidate,
CHRYSLER_CAR.CHRYSLER_PACIFICA_2020,
fingerprint,
[],
car_params,
@@ -211,14 +206,11 @@ class TestCarInterfaces:
button_message="CRUISE_BUTTONS",
auto_high_beam=0,
)
controller.update(CC, CS, 0, toggles)
controller.update(CC, CS, 0, toggles)
_, can_sends = controller.update(CC, CS, 0, toggles)
lkas_parser = CANParser(CHRYSLER_DBC[car_params.carFingerprint][Bus.pt], [("LKAS_COMMAND", 50)], 0)
lkas_parser.update([0, can_sends])
assert lkas_parser.vl["LKAS_COMMAND"]["LKAS_CONTROL_BIT"] == 1
assert lkas_parser.vl["LKAS_COMMAND"]["STEERING_TORQUE"] != 0
@pytest.mark.parametrize("candidate", (CHRYSLER_CAR.JEEP_GRAND_CHEROKEE, CHRYSLER_CAR.JEEP_GRAND_CHEROKEE_2019))
def test_jeep_brake_hold_safety_capability_is_provisioned(self, candidate):
@@ -518,7 +518,7 @@ class CarController(CarControllerBase):
main_accel_cmd = 0. if self.CP.flags & ToyotaFlags.SECOC.value else pcm_accel_cmd
can_sends.append(toyotacan.create_accel_command(self.packer, main_accel_cmd, pcm_cancel_cmd, self.permit_braking, self.standstill_req, lead,
CS.acc_type, fcw_alert, self.distance_button, getattr(starpilot_toggles, "reverse_cruise_increase", False)))
CS.acc_type, fcw_alert, self.distance_button, starpilot_toggles.reverse_cruise_increase))
if self.CP.flags & ToyotaFlags.SECOC.value:
acc_cmd_2 = toyotacan.create_accel_command_2(self.packer, pcm_accel_cmd)
acc_cmd_2 = add_mac(self.secoc_key,
@@ -538,7 +538,7 @@ class CarController(CarControllerBase):
can_sends.append(toyotacan.create_acc_cancel_command(self.packer))
else:
can_sends.append(toyotacan.create_accel_command(self.packer, 0, pcm_cancel_cmd, True, False, lead, CS.acc_type, False,
self.distance_button, getattr(starpilot_toggles, "reverse_cruise_increase", False)))
self.distance_button, starpilot_toggles.reverse_cruise_increase))
# *** hud ui ***
if self.CP.carFingerprint != CAR.TOYOTA_PRIUS_V:
@@ -1103,7 +1103,6 @@ class SafetyTest(SafetyTestBase):
'TestHyundaiSafetyFCEVLong', 'TestHyundaiLongitudinalAolLkasOnEngageSafety',
'TestHyundaiSafetyCanRefreshLong', 'TestHyundaiSafetyCanRefreshLongCameraSCC',
'TestHyundaiCanCanfdBlendedLongitudinalSafety',
'TestHyundaiLegacyLongitudinalSafety',
'TestHyundaiLegacyLongitudinalSafetyHEV'}):
continue
volkswagen_shared = ('TestVolkswagenMqb', 'TestVolkswagenMlb', 'TestVolkswagenMeb')
@@ -1157,7 +1156,6 @@ class SafetyTest(SafetyTestBase):
if attr.startswith('TestHyundaiLongitudinal') or attr in ('TestHyundaiSafetyFCEVLong',
'TestHyundaiLongitudinalAolLkasOnEngageSafety',
'TestHyundaiCanCanfdBlendedLongitudinalSafety',
'TestHyundaiLegacyLongitudinalSafety',
'TestHyundaiLegacyLongitudinalSafetyHEV'):
# exceptions for common msgs across different Hyundai CAN platforms
tx = list(filter(lambda m: m[0] not in [0x420, 0x50A, 0x389, 0x4A2], tx))
@@ -597,14 +597,6 @@ class TestHyundaiSafetyFCEVLong(TestHyundaiLongitudinalSafety, TestHyundaiSafety
self.safety.init_tests()
class TestHyundaiLegacyLongitudinalSafety(TestHyundaiLongitudinalSafety, TestHyundaiLegacySafety):
def setUp(self):
self.packer = CANPackerSafety("hyundai_kia_generic")
self.safety = libsafety_py.libsafety
self.safety.set_safety_hooks(CarParams.SafetyModel.hyundaiLegacy, HyundaiSafetyFlags.LONG)
self.safety.init_tests()
class TestHyundaiLegacyLongitudinalSafetyHEV(TestHyundaiLongitudinalSafety, TestHyundaiLegacySafetyHEV):
def setUp(self):
self.packer = CANPackerSafety("hyundai_kia_generic")
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+1 -1
View File
@@ -1,2 +1,2 @@
extern const uint8_t gitversion[19];
const uint8_t gitversion[19] = "DEV-e28f72c6-DEBUG";
const uint8_t gitversion[19] = "DEV-590fcdd9-DEBUG";
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+1 -1
View File
@@ -1 +1 @@
DEV-e28f72c6-DEBUG
DEV-590fcdd9-DEBUG
+5
View File
@@ -29,6 +29,11 @@ dependencies = [
"setuptools",
"numpy >=2.0",
# AGNOS 19.6 native build dependencies
"comma-deps-capnproto; python_version >= '3.12'",
"comma-deps-ffmpeg; python_version >= '3.12'",
"libdatachannel-py>=2026.1.0.dev2; python_version >= '3.12'",
# body / webrtcd
"aiohttp",
"aiortc",
Binary file not shown.
+61
View File
@@ -467,6 +467,66 @@ EOF
echo "==> larch64 scons completed in $(( $(date +%s) - started_at ))s"
}
validate_larch64_artifacts() {
local engine
engine="$(detect_engine)"
echo "==> Validating larch64 runtime dependencies"
"${engine}" run --rm --platform linux/arm64 \
--user "${DOCKER_RUN_USER}" \
-v "${HOST_ROOT_DIR}:/work" \
-v "${HOST_VENV_DIR}:/work/.venv-linux-arm64:ro" \
-v "${HOST_SYSROOT_DIR}:/opt/tici-sysroot:ro" \
-v "${HOST_SYSROOT_DIR}/system/vendor/lib64:/system/vendor/lib64:ro" \
-w /work \
"${IMAGE_NAME}" bash -lc '
set -euo pipefail
ffmpeg_lib_dir="/work/.venv-linux-arm64/lib/python3.12/site-packages/ffmpeg/install/lib"
target_ffmpeg_runpath="/usr/local/venv/lib/python3.12/site-packages/ffmpeg/install/lib"
runtime_library_path="${ffmpeg_lib_dir}:/work/third_party/acados/larch64/lib:/work/third_party/libyuv/larch64/lib:/work/selfdrive/controls/lib/lateral_mpc_lib/c_generated_code:/work/selfdrive/controls/lib/longitudinal_mpc_lib/c_generated_code:/opt/tici-sysroot/usr/local/lib:/opt/tici-sysroot/lib/aarch64-linux-gnu:/opt/tici-sysroot/usr/lib/aarch64-linux-gnu:/system/vendor/lib64"
failures=0
while IFS= read -r -d "" artifact; do
if ! readelf -h "${artifact}" 2>/dev/null | grep -q "Machine:.*AArch64"; then
continue
fi
dynamic="$(readelf -d "${artifact}" 2>/dev/null || true)"
if grep -Eq "(RPATH|RUNPATH).*\/work\/" <<<"${dynamic}"; then
echo "ERROR: ${artifact} embeds a build-host runtime path" >&2
failures=1
fi
has_ffmpeg=0
while IFS= read -r needed; do
case "${needed}" in
libavformat.so.*|libavcodec.so.*|libswresample.so.*|libavutil.so.*)
has_ffmpeg=1
if [[ ! -e "${ffmpeg_lib_dir}/${needed}" ]]; then
echo "ERROR: ${artifact} links ${needed}, which is not shipped by the managed FFmpeg package" >&2
failures=1
fi
;;
esac
done < <(sed -n "s/.*Shared library: \[\([^]]*\)\].*/\1/p" <<<"${dynamic}")
if [[ "${has_ffmpeg}" -eq 1 ]] && ! grep -Fq "${target_ffmpeg_runpath}" <<<"${dynamic}"; then
echo "ERROR: ${artifact} links FFmpeg without the target managed-venv RUNPATH" >&2
failures=1
fi
missing="$(LD_LIBRARY_PATH="${runtime_library_path}" ldd "${artifact}" 2>&1 | grep "not found" || true)"
if [[ -n "${missing}" ]]; then
echo "ERROR: ${artifact} has unresolved target dependencies:" >&2
echo "${missing}" >&2
failures=1
fi
done < <(git ls-files -z)
exit "${failures}"
'
}
setup_host_venv() {
if [[ ! -f "${ROOT_DIR}/.venv/bin/activate" ]]; then
if [[ -x "${ROOT_DIR}/tools/install_python_dependencies.sh" ]]; then
@@ -516,6 +576,7 @@ run_larch64_build() {
cereal/messaging/bridge \
msgq_repo/msgq/ipc_pyx.so \
msgq_repo/msgq/visionipc/visionipc_pyx.so
validate_larch64_artifacts
touch "${ROOT_DIR}/prebuilt"
}
+96 -14
View File
@@ -1,17 +1,99 @@
info face="como-heavy" size=-200 bold=0 italic=0 charset="" unicode=1 stretchH=100 smooth=0 aa=1 padding=0,0,0,0 spacing=0,0 outline=0
common lineHeight=200 base=200 scaleW=1024 scaleH=512 pages=1 packed=0 alphaChnl=0 redChnl=4 greenChnl=4 blueChnl=4
common lineHeight=200 base=200 scaleW=2048 scaleH=2048 pages=1 packed=0 alphaChnl=0 redChnl=4 greenChnl=4 blueChnl=4
page id=0 file="como-heavy.png"
chars count=13
chars count=95
char id=32 x=6 y=6 width=39 height=200 xoffset=0 yoffset=0 xadvance=39 page=0 chnl=15
char id=63 x=57 y=6 width=81 height=115 xoffset=0 yoffset=47 xadvance=83 page=0 chnl=15
char id=80 x=150 y=6 width=100 height=113 xoffset=8 yoffset=49 xadvance=110 page=0 chnl=15
char id=83 x=262 y=6 width=101 height=116 xoffset=4 yoffset=47 xadvance=108 page=0 chnl=15
char id=97 x=375 y=6 width=88 height=85 xoffset=5 yoffset=78 xadvance=100 page=0 chnl=15
char id=105 x=475 y=6 width=31 height=121 xoffset=6 yoffset=41 xadvance=43 page=0 chnl=15
char id=108 x=518 y=6 width=29 height=119 xoffset=7 yoffset=43 xadvance=43 page=0 chnl=15
char id=111 x=559 y=6 width=88 height=85 xoffset=5 yoffset=78 xadvance=98 page=0 chnl=15
char id=112 x=659 y=6 width=88 height=115 xoffset=7 yoffset=78 xadvance=100 page=0 chnl=15
char id=114 x=759 y=6 width=63 height=83 xoffset=7 yoffset=79 xadvance=69 page=0 chnl=15
char id=115 x=834 y=6 width=77 height=85 xoffset=4 yoffset=78 xadvance=84 page=0 chnl=15
char id=116 x=923 y=6 width=63 height=111 xoffset=6 yoffset=52 xadvance=70 page=0 chnl=15
char id=122 x=6 y=218 width=79 height=81 xoffset=3 yoffset=80 xadvance=85 page=0 chnl=15
char id=33 x=57 y=6 width=32 height=114 xoffset=8 yoffset=48 xadvance=48 page=0 chnl=15
char id=34 x=101 y=6 width=68 height=64 xoffset=6 yoffset=48 xadvance=80 page=0 chnl=15
char id=35 x=181 y=6 width=101 height=111 xoffset=3 yoffset=51 xadvance=107 page=0 chnl=15
char id=36 x=294 y=6 width=90 height=136 xoffset=8 yoffset=40 xadvance=107 page=0 chnl=15
char id=37 x=396 y=6 width=115 height=113 xoffset=3 yoffset=50 xadvance=121 page=0 chnl=15
char id=38 x=523 y=6 width=109 height=116 xoffset=3 yoffset=47 xadvance=113 page=0 chnl=15
char id=39 x=644 y=6 width=30 height=64 xoffset=6 yoffset=48 xadvance=42 page=0 chnl=15
char id=40 x=686 y=6 width=53 height=131 xoffset=8 yoffset=48 xadvance=67 page=0 chnl=15
char id=41 x=751 y=6 width=53 height=131 xoffset=6 yoffset=48 xadvance=67 page=0 chnl=15
char id=42 x=816 y=6 width=82 height=79 xoffset=4 yoffset=43 xadvance=90 page=0 chnl=15
char id=43 x=910 y=6 width=97 height=98 xoffset=5 yoffset=63 xadvance=107 page=0 chnl=15
char id=44 x=1019 y=6 width=42 height=60 xoffset=-3 yoffset=129 xadvance=48 page=0 chnl=15
char id=45 x=1073 y=6 width=61 height=29 xoffset=5 yoffset=102 xadvance=71 page=0 chnl=15
char id=46 x=1146 y=6 width=33 height=33 xoffset=8 yoffset=129 xadvance=48 page=0 chnl=15
char id=47 x=1191 y=6 width=57 height=114 xoffset=1 yoffset=48 xadvance=59 page=0 chnl=15
char id=48 x=1260 y=6 width=95 height=113 xoffset=6 yoffset=50 xadvance=107 page=0 chnl=15
char id=49 x=1367 y=6 width=63 height=110 xoffset=20 yoffset=52 xadvance=107 page=0 chnl=15
char id=50 x=1442 y=6 width=87 height=111 xoffset=11 yoffset=50 xadvance=107 page=0 chnl=15
char id=51 x=1541 y=6 width=87 height=113 xoffset=11 yoffset=50 xadvance=107 page=0 chnl=15
char id=52 x=1640 y=6 width=99 height=111 xoffset=5 yoffset=51 xadvance=107 page=0 chnl=15
char id=53 x=1751 y=6 width=88 height=111 xoffset=10 yoffset=52 xadvance=107 page=0 chnl=15
char id=54 x=1851 y=6 width=91 height=113 xoffset=8 yoffset=50 xadvance=107 page=0 chnl=15
char id=55 x=6 y=218 width=92 height=110 xoffset=9 yoffset=52 xadvance=107 page=0 chnl=15
char id=56 x=110 y=218 width=94 height=113 xoffset=7 yoffset=50 xadvance=107 page=0 chnl=15
char id=57 x=216 y=218 width=90 height=113 xoffset=9 yoffset=50 xadvance=107 page=0 chnl=15
char id=58 x=318 y=218 width=33 height=83 xoffset=8 yoffset=79 xadvance=48 page=0 chnl=15
char id=59 x=363 y=218 width=44 height=110 xoffset=-3 yoffset=79 xadvance=48 page=0 chnl=15
char id=60 x=419 y=218 width=95 height=90 xoffset=6 yoffset=67 xadvance=107 page=0 chnl=15
char id=61 x=526 y=218 width=95 height=66 xoffset=6 yoffset=79 xadvance=107 page=0 chnl=15
char id=62 x=633 y=218 width=94 height=90 xoffset=7 yoffset=67 xadvance=107 page=0 chnl=15
char id=63 x=739 y=218 width=81 height=115 xoffset=0 yoffset=47 xadvance=83 page=0 chnl=15
char id=64 x=832 y=218 width=115 height=117 xoffset=5 yoffset=55 xadvance=124 page=0 chnl=15
char id=65 x=959 y=218 width=107 height=115 xoffset=7 yoffset=47 xadvance=120 page=0 chnl=15
char id=66 x=1078 y=218 width=103 height=112 xoffset=8 yoffset=49 xadvance=114 page=0 chnl=15
char id=67 x=1193 y=218 width=110 height=116 xoffset=5 yoffset=47 xadvance=116 page=0 chnl=15
char id=68 x=1315 y=218 width=108 height=112 xoffset=8 yoffset=49 xadvance=121 page=0 chnl=15
char id=69 x=1435 y=218 width=99 height=112 xoffset=8 yoffset=49 xadvance=109 page=0 chnl=15
char id=70 x=1546 y=218 width=97 height=113 xoffset=8 yoffset=49 xadvance=105 page=0 chnl=15
char id=71 x=1655 y=218 width=114 height=116 xoffset=5 yoffset=47 xadvance=123 page=0 chnl=15
char id=72 x=1781 y=218 width=108 height=114 xoffset=8 yoffset=48 xadvance=124 page=0 chnl=15
char id=73 x=1901 y=218 width=32 height=114 xoffset=8 yoffset=48 xadvance=48 page=0 chnl=15
char id=74 x=6 y=430 width=95 height=115 xoffset=1 yoffset=48 xadvance=102 page=0 chnl=15
char id=75 x=113 y=430 width=101 height=114 xoffset=8 yoffset=48 xadvance=112 page=0 chnl=15
char id=76 x=226 y=430 width=96 height=113 xoffset=8 yoffset=48 xadvance=103 page=0 chnl=15
char id=77 x=334 y=430 width=129 height=114 xoffset=8 yoffset=48 xadvance=145 page=0 chnl=15
char id=78 x=475 y=430 width=107 height=114 xoffset=8 yoffset=48 xadvance=123 page=0 chnl=15
char id=79 x=594 y=430 width=119 height=116 xoffset=5 yoffset=47 xadvance=128 page=0 chnl=15
char id=80 x=725 y=430 width=100 height=113 xoffset=8 yoffset=49 xadvance=110 page=0 chnl=15
char id=81 x=837 y=430 width=119 height=129 xoffset=5 yoffset=47 xadvance=128 page=0 chnl=15
char id=82 x=968 y=430 width=100 height=113 xoffset=8 yoffset=49 xadvance=112 page=0 chnl=15
char id=83 x=1080 y=430 width=101 height=116 xoffset=4 yoffset=47 xadvance=108 page=0 chnl=15
char id=84 x=1193 y=430 width=111 height=113 xoffset=0 yoffset=49 xadvance=110 page=0 chnl=15
char id=85 x=1316 y=430 width=101 height=116 xoffset=7 yoffset=48 xadvance=114 page=0 chnl=15
char id=86 x=1429 y=430 width=115 height=114 xoffset=0 yoffset=48 xadvance=115 page=0 chnl=15
char id=87 x=1556 y=430 width=162 height=114 xoffset=1 yoffset=48 xadvance=164 page=0 chnl=15
char id=88 x=1730 y=430 width=106 height=114 xoffset=3 yoffset=48 xadvance=112 page=0 chnl=15
char id=89 x=1848 y=430 width=111 height=114 xoffset=0 yoffset=48 xadvance=110 page=0 chnl=15
char id=90 x=6 y=642 width=102 height=112 xoffset=3 yoffset=49 xadvance=108 page=0 chnl=15
char id=91 x=120 y=642 width=51 height=129 xoffset=10 yoffset=49 xadvance=67 page=0 chnl=15
char id=92 x=183 y=642 width=57 height=114 xoffset=1 yoffset=48 xadvance=59 page=0 chnl=15
char id=93 x=252 y=642 width=52 height=129 xoffset=6 yoffset=49 xadvance=67 page=0 chnl=15
char id=94 x=316 y=642 width=97 height=75 xoffset=5 yoffset=48 xadvance=107 page=0 chnl=15
char id=95 x=425 y=642 width=84 height=14 xoffset=0 yoffset=168 xadvance=83 page=0 chnl=15
char id=96 x=521 y=642 width=40 height=36 xoffset=16 yoffset=36 xadvance=83 page=0 chnl=15
char id=97 x=573 y=642 width=88 height=85 xoffset=5 yoffset=78 xadvance=100 page=0 chnl=15
char id=98 x=673 y=642 width=88 height=120 xoffset=7 yoffset=43 xadvance=100 page=0 chnl=15
char id=99 x=773 y=642 width=80 height=85 xoffset=5 yoffset=78 xadvance=87 page=0 chnl=15
char id=100 x=865 y=642 width=88 height=120 xoffset=5 yoffset=43 xadvance=100 page=0 chnl=15
char id=101 x=965 y=642 width=85 height=85 xoffset=5 yoffset=78 xadvance=93 page=0 chnl=15
char id=102 x=1062 y=642 width=64 height=120 xoffset=7 yoffset=42 xadvance=69 page=0 chnl=15
char id=103 x=1138 y=642 width=88 height=116 xoffset=5 yoffset=78 xadvance=100 page=0 chnl=15
char id=104 x=1238 y=642 width=83 height=119 xoffset=7 yoffset=43 xadvance=96 page=0 chnl=15
char id=105 x=1333 y=642 width=31 height=121 xoffset=6 yoffset=41 xadvance=43 page=0 chnl=15
char id=106 x=1376 y=642 width=46 height=152 xoffset=-9 yoffset=41 xadvance=43 page=0 chnl=15
char id=107 x=1434 y=642 width=79 height=119 xoffset=7 yoffset=43 xadvance=88 page=0 chnl=15
char id=108 x=1525 y=642 width=29 height=119 xoffset=7 yoffset=43 xadvance=43 page=0 chnl=15
char id=109 x=1566 y=642 width=126 height=84 xoffset=7 yoffset=78 xadvance=138 page=0 chnl=15
char id=110 x=1704 y=642 width=83 height=84 xoffset=7 yoffset=78 xadvance=96 page=0 chnl=15
char id=111 x=1799 y=642 width=88 height=85 xoffset=5 yoffset=78 xadvance=98 page=0 chnl=15
char id=112 x=1899 y=642 width=88 height=115 xoffset=7 yoffset=78 xadvance=100 page=0 chnl=15
char id=113 x=6 y=854 width=88 height=115 xoffset=5 yoffset=78 xadvance=100 page=0 chnl=15
char id=114 x=106 y=854 width=63 height=83 xoffset=7 yoffset=79 xadvance=69 page=0 chnl=15
char id=115 x=181 y=854 width=77 height=85 xoffset=4 yoffset=78 xadvance=84 page=0 chnl=15
char id=116 x=270 y=854 width=63 height=111 xoffset=6 yoffset=52 xadvance=70 page=0 chnl=15
char id=117 x=345 y=854 width=83 height=84 xoffset=6 yoffset=79 xadvance=96 page=0 chnl=15
char id=118 x=440 y=854 width=86 height=83 xoffset=0 yoffset=79 xadvance=86 page=0 chnl=15
char id=119 x=538 y=854 width=129 height=83 xoffset=0 yoffset=79 xadvance=128 page=0 chnl=15
char id=120 x=679 y=854 width=81 height=83 xoffset=3 yoffset=79 xadvance=87 page=0 chnl=15
char id=121 x=772 y=854 width=83 height=115 xoffset=6 yoffset=79 xadvance=96 page=0 chnl=15
char id=122 x=867 y=854 width=79 height=81 xoffset=3 yoffset=80 xadvance=85 page=0 chnl=15
char id=123 x=958 y=854 width=62 height=129 xoffset=2 yoffset=49 xadvance=70 page=0 chnl=15
char id=124 x=1032 y=854 width=22 height=150 xoffset=16 yoffset=43 xadvance=53 page=0 chnl=15
char id=125 x=1066 y=854 width=62 height=129 xoffset=6 yoffset=49 xadvance=70 page=0 chnl=15
char id=126 x=1140 y=854 width=97 height=38 xoffset=5 yoffset=92 xadvance=107 page=0 chnl=15
Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 192 KiB

Some files were not shown because too many files have changed in this diff Show More