diff --git a/Jenkinsfile b/Jenkinsfile index 9d6828000b..b47a3884a0 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -92,11 +92,20 @@ def deviceStage(String stageName, String deviceType, List extra_env, def steps) device(device_ip, "git checkout", extra + "\n" + readFile("selfdrive/test/setup_device_ci.sh")) } steps.each { item -> - if (branch != "master" && item.size() == 3 && !hasPathChanged(gitDiff, item[2])) { - println "Skipping ${item[0]}: no changes in ${item[2]}." + def name = item[0] + def cmd = item[1] + + def args = item[2] + def diffPaths = args.diffPaths ?: [] + def cmdTimeout = args.timeout ?: 9999 + + if (branch != "master" && diffPaths && !hasPathChanged(gitDiff, diffPaths)) { + println "Skipping ${name}: no changes in ${diffPaths}." return } else { - device(device_ip, item[0], item[1]) + timeout(time: cmdTimeout, unit: 'SECONDS') { + device(device_ip, name, cmd) + } } } } @@ -134,6 +143,9 @@ def setupCredentials() { } } +def step(String name, String cmd, Map args = [:]) { + return [name, cmd, args] +} node { env.CI = "1" @@ -158,15 +170,23 @@ node { try { if (env.BRANCH_NAME == 'devel-staging') { deviceStage("build release3-staging", "tici-needs-can", [], [ - ["build release3-staging", "RELEASE_BRANCH=release3-staging $SOURCE_DIR/release/build_release.sh"], + step("build release3-staging", "RELEASE_BRANCH=release3-staging $SOURCE_DIR/release/build_release.sh"), ]) } if (env.BRANCH_NAME == 'master-ci') { - deviceStage("build nightly", "tici-needs-can", [], [ - ["build nightly", "RELEASE_BRANCH=nightly $SOURCE_DIR/release/build_release.sh"], - ["build nightly-dev", "PANDA_DEBUG_BUILD=1 RELEASE_BRANCH=nightly-dev $SOURCE_DIR/release/build_release.sh"], - ]) + parallel ( + 'nightly': { + deviceStage("build nightly", "tici-needs-can", [], [ + step("build nightly", "RELEASE_BRANCH=nightly $SOURCE_DIR/release/build_release.sh"), + ]) + }, + 'nightly-dev': { + deviceStage("build nightly-dev", "tici-needs-can", [], [ + step("build nightly-dev", "PANDA_DEBUG_BUILD=1 RELEASE_BRANCH=nightly-dev $SOURCE_DIR/release/build_release.sh"), + ]) + }, + ) } if (!env.BRANCH_NAME.matches(excludeRegex)) { @@ -176,64 +196,64 @@ node { deviceStage("onroad", "tici-needs-can", [], [ // TODO: ideally, this test runs in master-ci, but it takes 5+m to build it //["build master-ci", "cd $SOURCE_DIR/release && TARGET_DIR=$TEST_DIR $SOURCE_DIR/scripts/retry.sh ./build_devel.sh"], - ["build openpilot", "cd system/manager && ./build.py"], - ["check dirty", "release/check-dirty.sh"], - ["onroad tests", "pytest selfdrive/test/test_onroad.py -s"], + step("build openpilot", "cd system/manager && ./build.py"), + step("check dirty", "release/check-dirty.sh"), + step("onroad tests", "pytest selfdrive/test/test_onroad.py -s"), //["time to onroad", "pytest selfdrive/test/test_time_to_onroad.py"], ]) }, 'HW + Unit Tests': { deviceStage("tici-hardware", "tici-common", ["UNSAFE=1"], [ - ["build", "cd system/manager && ./build.py"], - ["test pandad", "pytest selfdrive/pandad/tests/test_pandad.py", ["panda/", "selfdrive/pandad/"]], - ["test power draw", "pytest -s system/hardware/tici/tests/test_power_draw.py"], - ["test encoder", "LD_LIBRARY_PATH=/usr/local/lib pytest system/loggerd/tests/test_encoder.py"], - ["test pigeond", "pytest system/ubloxd/tests/test_pigeond.py"], - ["test manager", "pytest system/manager/test/test_manager.py"], + step("build", "cd system/manager && ./build.py"), + step("test pandad", "pytest selfdrive/pandad/tests/test_pandad.py", [diffPaths: ["panda/", "selfdrive/pandad/"]]), + step("test power draw", "pytest -s system/hardware/tici/tests/test_power_draw.py"), + step("test encoder", "LD_LIBRARY_PATH=/usr/local/lib pytest system/loggerd/tests/test_encoder.py"), + step("test pigeond", "pytest system/ubloxd/tests/test_pigeond.py"), + step("test manager", "pytest system/manager/test/test_manager.py"), ]) }, 'loopback': { deviceStage("loopback", "tici-loopback", ["UNSAFE=1"], [ - ["build openpilot", "cd system/manager && ./build.py"], - ["test pandad loopback", "pytest selfdrive/pandad/tests/test_pandad_loopback.py"], + step("build openpilot", "cd system/manager && ./build.py"), + step("test pandad loopback", "pytest selfdrive/pandad/tests/test_pandad_loopback.py"), ]) }, 'camerad': { deviceStage("AR0231", "tici-ar0231", ["UNSAFE=1"], [ - ["build", "cd system/manager && ./build.py"], - ["test camerad", "pytest system/camerad/test/test_camerad.py"], - ["test exposure", "pytest system/camerad/test/test_exposure.py"], + step("build", "cd system/manager && ./build.py"), + step("test camerad", "pytest system/camerad/test/test_camerad.py"), + step("test exposure", "pytest system/camerad/test/test_exposure.py"), ]) deviceStage("OX03C10", "tici-ox03c10", ["UNSAFE=1"], [ - ["build", "cd system/manager && ./build.py"], - ["test camerad", "pytest system/camerad/test/test_camerad.py"], - ["test exposure", "pytest system/camerad/test/test_exposure.py"], + step("build", "cd system/manager && ./build.py"), + step("test camerad", "pytest system/camerad/test/test_camerad.py"), + step("test exposure", "pytest system/camerad/test/test_exposure.py"), ]) }, 'sensord': { deviceStage("LSM + MMC", "tici-lsmc", ["UNSAFE=1"], [ - ["build", "cd system/manager && ./build.py"], - ["test sensord", "pytest system/sensord/tests/test_sensord.py"], + step("build", "cd system/manager && ./build.py"), + step("test sensord", "pytest system/sensord/tests/test_sensord.py"), ]) deviceStage("BMX + LSM", "tici-bmx-lsm", ["UNSAFE=1"], [ - ["build", "cd system/manager && ./build.py"], - ["test sensord", "pytest system/sensord/tests/test_sensord.py"], + step("build", "cd system/manager && ./build.py"), + step("test sensord", "pytest system/sensord/tests/test_sensord.py"), ]) }, 'replay': { deviceStage("model-replay", "tici-replay", ["UNSAFE=1"], [ - ["build", "cd system/manager && ./build.py", ["selfdrive/modeld/"]], - ["model replay", "selfdrive/test/process_replay/model_replay.py", ["selfdrive/modeld/"]], + step("build", "cd system/manager && ./build.py", [diffPaths: ["selfdrive/modeld/"]]), + step("model replay", "selfdrive/test/process_replay/model_replay.py", [diffPaths: ["selfdrive/modeld/"]]), ]) }, 'tizi': { deviceStage("tizi", "tizi", ["UNSAFE=1"], [ - ["build openpilot", "cd system/manager && ./build.py"], - ["test pandad loopback", "SINGLE_PANDA=1 pytest selfdrive/pandad/tests/test_pandad_loopback.py"], - ["test pandad spi", "pytest selfdrive/pandad/tests/test_pandad_spi.py"], - ["test pandad", "pytest selfdrive/pandad/tests/test_pandad.py", ["panda/", "selfdrive/pandad/"]], - ["test amp", "pytest system/hardware/tici/tests/test_amplifier.py"], - ["test qcomgpsd", "pytest system/qcomgpsd/tests/test_qcomgpsd.py"], + step("build openpilot", "cd system/manager && ./build.py"), + step("test pandad loopback", "SINGLE_PANDA=1 pytest selfdrive/pandad/tests/test_pandad_loopback.py"), + step("test pandad spi", "pytest selfdrive/pandad/tests/test_pandad_spi.py"), + step("test pandad", "pytest selfdrive/pandad/tests/test_pandad.py", [diffPaths: ["panda/", "selfdrive/pandad/"]]), + step("test amp", "pytest system/hardware/tici/tests/test_amplifier.py"), + step("test qcomgpsd", "pytest system/qcomgpsd/tests/test_qcomgpsd.py"), ]) }, diff --git a/launch_env.sh b/launch_env.sh index 1e5bc7b607..781f40fc7e 100755 --- a/launch_env.sh +++ b/launch_env.sh @@ -7,7 +7,7 @@ export OPENBLAS_NUM_THREADS=1 export VECLIB_MAXIMUM_THREADS=1 if [ -z "$AGNOS_VERSION" ]; then - export AGNOS_VERSION="10.1" + export AGNOS_VERSION="11.2" fi export STAGING_ROOT="/data/safe_staging" diff --git a/opendbc_repo b/opendbc_repo index c4114772ba..d632cc5bec 160000 --- a/opendbc_repo +++ b/opendbc_repo @@ -1 +1 @@ -Subproject commit c4114772ba9d77bf03b97972611591e0bf8e4a25 +Subproject commit d632cc5bec14d4e077fdf25e19b24b434c2653fd diff --git a/selfdrive/car/tests/test_models.py b/selfdrive/car/tests/test_models.py index 025c3ab660..2a62127749 100644 --- a/selfdrive/car/tests/test_models.py +++ b/selfdrive/car/tests/test_models.py @@ -22,7 +22,7 @@ from openpilot.selfdrive.selfdrived.selfdrived import SelfdriveD from openpilot.selfdrive.pandad import can_capnp_to_list from openpilot.selfdrive.test.helpers import read_segment_list from openpilot.system.hardware.hw import DEFAULT_DOWNLOAD_CACHE_ROOT -from openpilot.tools.lib.logreader import LogReader +from openpilot.tools.lib.logreader import LogReader, LogsUnavailable from openpilot.tools.lib.route import SegmentName from panda.tests.libpanda import libpanda_py @@ -113,10 +113,8 @@ class TestCarModelBase(unittest.TestCase): (SafetyModel.elm327, SafetyModel.noOutput): cls.car_safety_mode_frame = len(can_msgs) - if len(can_msgs) > int(50 / DT_CTRL): - return car_fw, can_msgs, experimental_long - - raise Exception("no can data found") + assert len(can_msgs) > int(50 / DT_CTRL), "no can data found" + return car_fw, can_msgs, experimental_long @classmethod def get_testing_data(cls): @@ -130,7 +128,7 @@ class TestCarModelBase(unittest.TestCase): try: lr = LogReader(segment_range) return cls.get_testing_data_from_logreader(lr) - except Exception: + except (LogsUnavailable, AssertionError): pass raise Exception(f"Route: {repr(cls.test_route.route)} with segments: {test_segs} not found or no CAN msgs found. Is it uploaded and public?") diff --git a/system/camerad/cameras/ife.h b/system/camerad/cameras/ife.h index 1616196a3f..a232000100 100644 --- a/system/camerad/cameras/ife.h +++ b/system/camerad/cameras/ife.h @@ -67,7 +67,7 @@ int build_update(uint8_t *dst, const SensorInfo *s, std::vector &patch // black level scale + offset dst += write_cont(dst, 0x6b0, { - ((uint32_t)(1 << 11) << 0xf) | (s->black_level << 0), + ((uint32_t)(1 << 11) << 0xf) | (s->black_level << (14 - s->bits_per_pixel)), 0x0, 0x0, }); diff --git a/system/hardware/tici/agnos.json b/system/hardware/tici/agnos.json index b1862bdef9..3aa712a6b0 100644 --- a/system/hardware/tici/agnos.json +++ b/system/hardware/tici/agnos.json @@ -1,39 +1,49 @@ [ { "name": "boot", - "url": "https://commadist.azureedge.net/agnosupdate/boot-5674ea6767e7198cf1e7def3de66a57061f001ed76d43dc4b4f84de545c53c6f.img.xz", - "hash": "5674ea6767e7198cf1e7def3de66a57061f001ed76d43dc4b4f84de545c53c6f", - "hash_raw": "5674ea6767e7198cf1e7def3de66a57061f001ed76d43dc4b4f84de545c53c6f", - "size": 16029696, + "url": "https://commadist.azureedge.net/agnosupdate-staging/boot-184b9edb429167dcc97110134cdeffaa9739a758b3069e3ea7700e6559b79a0a.img.xz", + "hash": "184b9edb429167dcc97110134cdeffaa9739a758b3069e3ea7700e6559b79a0a", + "hash_raw": "184b9edb429167dcc97110134cdeffaa9739a758b3069e3ea7700e6559b79a0a", + "size": 16414720, "sparse": false, "full_check": true, "has_ab": true }, { - "name": "abl", - "url": "https://commadist.azureedge.net/agnosupdate/abl-eeb89a74c968a5a2ffce96f23158b72e03e2814adf72ef59d1200ba8ea5d2f39.img.xz", - "hash": "eeb89a74c968a5a2ffce96f23158b72e03e2814adf72ef59d1200ba8ea5d2f39", - "hash_raw": "eeb89a74c968a5a2ffce96f23158b72e03e2814adf72ef59d1200ba8ea5d2f39", - "size": 274432, + "name": "system", + "url": "https://commadist.azureedge.net/agnosupdate-staging/system-93a86656670d6d8d99ea401bd5735cd1060c2355d65f2c14de522c77a80c57ea.img.xz", + "hash": "93a86656670d6d8d99ea401bd5735cd1060c2355d65f2c14de522c77a80c57ea", + "hash_raw": "93a86656670d6d8d99ea401bd5735cd1060c2355d65f2c14de522c77a80c57ea", + "size": 4404019200, "sparse": false, - "full_check": true, + "full_check": false, "has_ab": true }, { "name": "xbl", - "url": "https://commadist.azureedge.net/agnosupdate/xbl-bcef195b00a1ab685da601f4072722569773ab161e91c8753ad99ca4217a28f5.img.xz", - "hash": "bcef195b00a1ab685da601f4072722569773ab161e91c8753ad99ca4217a28f5", - "hash_raw": "bcef195b00a1ab685da601f4072722569773ab161e91c8753ad99ca4217a28f5", - "size": 3282672, + "url": "https://commadist.azureedge.net/agnosupdate/xbl-446e37054b4c2f08bac3ee9d98256cdb93e876fb3343acfc8881124900f11050.img.xz", + "hash": "446e37054b4c2f08bac3ee9d98256cdb93e876fb3343acfc8881124900f11050", + "hash_raw": "446e37054b4c2f08bac3ee9d98256cdb93e876fb3343acfc8881124900f11050", + "size": 3282256, + "sparse": false, + "full_check": true, + "has_ab": true + }, + { + "name": "abl", + "url": "https://commadist.azureedge.net/agnosupdate/abl-32a2174b5f764e95dfc54cf358ba01752943b1b3b90e626149c3da7d5f1830b6.img.xz", + "hash": "32a2174b5f764e95dfc54cf358ba01752943b1b3b90e626149c3da7d5f1830b6", + "hash_raw": "32a2174b5f764e95dfc54cf358ba01752943b1b3b90e626149c3da7d5f1830b6", + "size": 274432, "sparse": false, "full_check": true, "has_ab": true }, { "name": "xbl_config", - "url": "https://commadist.azureedge.net/agnosupdate/xbl_config-19791056558c16f8dae787531b5e30b3b3db2ded9d666688df45ce1b91a72bac.img.xz", - "hash": "19791056558c16f8dae787531b5e30b3b3db2ded9d666688df45ce1b91a72bac", - "hash_raw": "19791056558c16f8dae787531b5e30b3b3db2ded9d666688df45ce1b91a72bac", + "url": "https://commadist.azureedge.net/agnosupdate/xbl_config-80f3e644529d30e260bb9b8b6c765d76a4ccd0a2d3104cc07acf93b0eabb8995.img.xz", + "hash": "80f3e644529d30e260bb9b8b6c765d76a4ccd0a2d3104cc07acf93b0eabb8995", + "hash_raw": "80f3e644529d30e260bb9b8b6c765d76a4ccd0a2d3104cc07acf93b0eabb8995", "size": 98124, "sparse": false, "full_check": true, @@ -41,9 +51,9 @@ }, { "name": "devcfg", - "url": "https://commadist.azureedge.net/agnosupdate/devcfg-be44b73dda5be840b09d5347d536459e31098da3fea97596956c0bdad19bdf27.img.xz", - "hash": "be44b73dda5be840b09d5347d536459e31098da3fea97596956c0bdad19bdf27", - "hash_raw": "be44b73dda5be840b09d5347d536459e31098da3fea97596956c0bdad19bdf27", + "url": "https://commadist.azureedge.net/agnosupdate/devcfg-8ea8a9e779b0bd43af41ed367e3c781ba666012eebb4707ce58328b81219f9f8.img.xz", + "hash": "8ea8a9e779b0bd43af41ed367e3c781ba666012eebb4707ce58328b81219f9f8", + "hash_raw": "8ea8a9e779b0bd43af41ed367e3c781ba666012eebb4707ce58328b81219f9f8", "size": 40336, "sparse": false, "full_check": true, @@ -51,27 +61,12 @@ }, { "name": "aop", - "url": "https://commadist.azureedge.net/agnosupdate/aop-5d764611a683d6a738cf06a1dcf8a926d0f47b5117ad40d3054167de6dd8bd0f.img.xz", - "hash": "5d764611a683d6a738cf06a1dcf8a926d0f47b5117ad40d3054167de6dd8bd0f", - "hash_raw": "5d764611a683d6a738cf06a1dcf8a926d0f47b5117ad40d3054167de6dd8bd0f", + "url": "https://commadist.azureedge.net/agnosupdate/aop-c1dbeefa20e742dde97eac76aaa00d1e6c2e2b01cfbd4c1242bd4e26c7d2aed4.img.xz", + "hash": "c1dbeefa20e742dde97eac76aaa00d1e6c2e2b01cfbd4c1242bd4e26c7d2aed4", + "hash_raw": "c1dbeefa20e742dde97eac76aaa00d1e6c2e2b01cfbd4c1242bd4e26c7d2aed4", "size": 184364, "sparse": false, "full_check": true, "has_ab": true - }, - { - "name": "system", - "url": "https://commadist.azureedge.net/agnosupdate/system-1badfe72851628d6cf9200a53a6151bb4e797b49c717141409fc57138eae388a.img.xz", - "hash": "328e90c62068222dfd98f71dd3f6251fcb962f082b49c6be66ab2699f5db6f4f", - "hash_raw": "1badfe72851628d6cf9200a53a6151bb4e797b49c717141409fc57138eae388a", - "size": 10737418240, - "sparse": true, - "full_check": false, - "has_ab": true, - "alt": { - "hash": "bc11d2148f29862ee1326aca2af1cf6bbf5fed831e3f8f6b8f7a0f110dfe8d26", - "url": "https://commadist.azureedge.net/agnosupdate/system-skip-chunks-1badfe72851628d6cf9200a53a6151bb4e797b49c717141409fc57138eae388a.img.xz", - "size": 4548070000 - } } ] \ No newline at end of file diff --git a/tools/lib/logreader.py b/tools/lib/logreader.py index cf8748929c..5f7cdd3043 100755 --- a/tools/lib/logreader.py +++ b/tools/lib/logreader.py @@ -49,7 +49,7 @@ class _LogFileReader: _, ext = os.path.splitext(urllib.parse.urlparse(fn).path) if ext not in ('', '.bz2', '.zst'): # old rlogs weren't compressed - raise Exception(f"unknown extension {ext}") + raise ValueError(f"unknown extension {ext}") with FileReader(fn) as f: dat = f.read() @@ -99,6 +99,10 @@ Source = Callable[[SegmentRange, ReadMode], list[LogPath]] InternalUnavailableException = Exception("Internal source not available") +class LogsUnavailable(Exception): + pass + + @cache def default_valid_file(fn: LogPath) -> bool: return fn is not None and file_exists(fn) @@ -128,7 +132,7 @@ def apply_strategy(mode: ReadMode, rlog_paths: list[LogPath], qlog_paths: list[L return auto_strategy(rlog_paths, qlog_paths, False, valid_file) elif mode == ReadMode.AUTO_INTERACTIVE: return auto_strategy(rlog_paths, qlog_paths, True, valid_file) - raise Exception(f"invalid mode: {mode}") + raise ValueError(f"invalid mode: {mode}") def comma_api_source(sr: SegmentRange, mode: ReadMode) -> list[LogPath]: @@ -224,8 +228,8 @@ def auto_source(sr: SegmentRange, mode=ReadMode.RLOG, sources: list[Source] = No except Exception as e: exceptions[source.__name__] = e - raise Exception("auto_source could not find any valid source, exceptions for sources:\n - " + - "\n - ".join([f"{k}: {repr(v)}" for k, v in exceptions.items()])) + raise LogsUnavailable("auto_source could not find any valid source, exceptions for sources:\n - " + + "\n - ".join([f"{k}: {repr(v)}" for k, v in exceptions.items()])) def parse_indirect(identifier: str) -> str: diff --git a/tools/plotjuggler/layouts/longitudinal.xml b/tools/plotjuggler/layouts/longitudinal.xml index 33a24f76d6..460de97025 100644 --- a/tools/plotjuggler/layouts/longitudinal.xml +++ b/tools/plotjuggler/layouts/longitudinal.xml @@ -11,6 +11,7 @@ + diff --git a/tools/sim/bridge/metadrive/metadrive_world.py b/tools/sim/bridge/metadrive/metadrive_world.py index a34d270994..c5111289d0 100644 --- a/tools/sim/bridge/metadrive/metadrive_world.py +++ b/tools/sim/bridge/metadrive/metadrive_world.py @@ -105,7 +105,7 @@ class MetaDriveWorld(World): if x_dist >= dist_threshold or y_dist >= dist_threshold: # position not the same during staying still, > threshold is considered moving self.distance_moved += x_dist + y_dist - time_check_threshold = 15 + time_check_threshold = 29 current_time = time.monotonic() since_last_check = current_time - self.last_check_timestamp if since_last_check >= time_check_threshold: