diff --git a/.github/workflows/selfdrive_tests.yaml b/.github/workflows/selfdrive_tests.yaml index 9456914371..6e17f5a480 100644 --- a/.github/workflows/selfdrive_tests.yaml +++ b/.github/workflows/selfdrive_tests.yaml @@ -48,7 +48,7 @@ jobs: - uses: ./.github/workflows/setup-with-retry - name: Check submodules if: github.ref == 'refs/heads/master' && github.repository == 'commaai/openpilot' - timeout-minutes: 1 + timeout-minutes: 3 run: release/check-submodules.sh - name: Build openpilot and run checks timeout-minutes: ${{ ((steps.restore-scons-cache.outputs.cache-hit == 'true') && 10 || 30) }} # allow more time when we missed the scons cache @@ -56,7 +56,7 @@ jobs: cd $STRIPPED_DIR ${{ env.RUN }} "python3 system/manager/build.py" - name: Run tests - timeout-minutes: 3 + timeout-minutes: 1 run: | cd $STRIPPED_DIR ${{ env.RUN }} "release/check-dirty.sh && \ @@ -76,7 +76,9 @@ jobs: ((github.repository == 'commaai/openpilot') && ((github.event_name != 'pull_request') || (github.event.pull_request.head.repo.full_name == 'commaai/openpilot'))) && '["x86_64", "aarch64"]' || '["x86_64"]' ) }} - runs-on: ${{ (matrix.arch == 'aarch64') && 'namespace-profile-arm64-2x8' || 'ubuntu-latest' }} + runs-on: ${{ ((matrix.arch == 'aarch64') && 'namespace-profile-arm64-2x8') || + ((matrix.arch == 'x86_64') && ((github.repository == 'commaai/openpilot') && ((github.event_name != 'pull_request') || (github.event.pull_request.head.repo.full_name == 'commaai/openpilot'))) && 'namespace-profile-amd64-8x16') || + 'ubuntu-latest'}} steps: - uses: actions/checkout@v4 with: @@ -144,11 +146,12 @@ jobs: PYTHONWARNINGS: default steps: - uses: actions/checkout@v4 - - name: Setup - run: tools/op.sh setup + with: + submodules: true + - uses: ./.github/workflows/setup-with-retry - name: Static analysis timeout-minutes: 1 - run: tools/op.sh lint + run: ${{ env.RUN }} "scripts/lint/lint.sh" unit_tests: name: unit tests @@ -327,24 +330,54 @@ jobs: comment_id: ${{ steps.fc.outputs.comment-id }} }) + simulator_driving: + name: simulator driving + runs-on: ${{ ((github.repository == 'commaai/openpilot') && + ((github.event_name != 'pull_request') || + (github.event.pull_request.head.repo.full_name == 'commaai/openpilot'))) && 'namespace-profile-amd64-8x16' || 'ubuntu-24.04' }} + steps: + - uses: actions/checkout@v4 + with: + submodules: true + - uses: ./.github/workflows/setup-with-retry + - name: Build openpilot + run: | + ${{ env.RUN }} "scons -j$(nproc)" + - name: Driving test + timeout-minutes: 1 + run: | + ${{ env.RUN }} "source selfdrive/test/setup_xvfb.sh && \ + source selfdrive/test/setup_vsound.sh && \ + CI=1 pytest tools/sim/tests/test_metadrive_bridge.py" + create_ui_report: # This job name needs to be the same as UI_JOB_NAME in ui_preview.yaml name: Create UI Report - runs-on: ubuntu-latest + runs-on: ${{ ((github.repository == 'commaai/openpilot') && + ((github.event_name != 'pull_request') || + (github.event.pull_request.head.repo.full_name == 'commaai/openpilot'))) && 'namespace-profile-amd64-8x16' || 'ubuntu-24.04' }} steps: - uses: actions/checkout@v4 with: submodules: true - uses: ./.github/workflows/setup-with-retry + - name: caching frames + id: frames-cache + uses: actions/cache@v4 + with: + path: .ci_cache/comma_download_cache + key: ui_screenshots_test_${{ hashFiles('selfdrive/ui/tests/test_ui/run.py') }} - name: Build openpilot run: ${{ env.RUN }} "scons -j$(nproc)" - name: Create Test Report + timeout-minutes: ${{ ((steps.frames-cache.outputs.cache-hit == 'true') && 1 || 3) }} run: > ${{ env.RUN }} "PYTHONWARNINGS=ignore && source selfdrive/test/setup_xvfb.sh && - python3 selfdrive/ui/tests/test_ui/run.py" + CACHE_ROOT=/tmp/comma_download_cache python3 selfdrive/ui/tests/test_ui/run.py && + chmod -R 777 /tmp/comma_download_cache" - name: Upload Test Report uses: actions/upload-artifact@v4 with: - name: report-${{ github.event_name == 'push' && github.ref == 'refs/heads/master' && 'master' || github.event.number }} + name: report-${{ inputs.run_number || '1' }}-${{ github.event_name == 'push' && github.ref == 'refs/heads/master' && 'master' || github.event.number }} path: selfdrive/ui/tests/test_ui/report_1/screenshots diff --git a/.github/workflows/tools_tests.yaml b/.github/workflows/tools_tests.yaml index c1c3552472..493671051f 100644 --- a/.github/workflows/tools_tests.yaml +++ b/.github/workflows/tools_tests.yaml @@ -25,24 +25,6 @@ env: jobs: - simulator_driving: - name: simulator driving - runs-on: ubuntu-latest - timeout-minutes: 20 - steps: - - uses: actions/checkout@v4 - with: - submodules: true - - uses: ./.github/workflows/setup-with-retry - - name: Build openpilot - run: | - ${{ env.RUN }} "scons -j$(nproc)" - - name: Run bridge test - run: | - ${{ env.RUN }} "source selfdrive/test/setup_xvfb.sh && \ - source selfdrive/test/setup_vsound.sh && \ - CI=1 pytest tools/sim/tests/test_metadrive_bridge.py" - devcontainer: name: devcontainer runs-on: ubuntu-latest diff --git a/.github/workflows/ui_preview.yaml b/.github/workflows/ui_preview.yaml index 4f25a71452..1842ef21e9 100644 --- a/.github/workflows/ui_preview.yaml +++ b/.github/workflows/ui_preview.yaml @@ -52,7 +52,7 @@ jobs: github_token: ${{ secrets.GITHUB_TOKEN }} run_id: ${{ steps.get_run_id.outputs.run_id }} search_artifacts: true - name: report-${{ env.REPORT_NAME }} + name: report-1-${{ env.REPORT_NAME }} path: ${{ github.workspace }}/pr_ui - name: Getting master ui diff --git a/docs/CARS.md b/docs/CARS.md index 84efe3c041..44c9327378 100644 --- a/docs/CARS.md +++ b/docs/CARS.md @@ -30,7 +30,7 @@ A supported vehicle is one that just works when you install a comma device. All |comma|body|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|None|| |CUPRA|Ateca 2018-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 USB-C coupler
- 1 VW J533 connector
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Dodge|Durango 2020-21|Adaptive Cruise Control (ACC)|Stock|0 mph|39 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 FCA connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| -|Ford|Bronco Sport 2021-23|Co-Pilot360 Assist+|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Ford Q3 connector
- 1 RJ45 cable (7 ft)
- 1 angled mount (8 degrees)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| +|Ford|Bronco Sport 2021-24|Co-Pilot360 Assist+|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Ford Q3 connector
- 1 RJ45 cable (7 ft)
- 1 angled mount (8 degrees)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Ford|Escape 2020-22|Co-Pilot360 Assist+|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Ford Q3 connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Ford|Escape Hybrid 2020-22|Co-Pilot360 Assist+|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Ford Q3 connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Ford|Escape Plug-in Hybrid 2020-22|Co-Pilot360 Assist+|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Ford Q3 connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| @@ -184,8 +184,8 @@ A supported vehicle is one that just works when you install a comma device. All |Lexus|RX Hybrid 2017-19|All|openpilot available[2](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|
Parts- 1 RJ45 cable (7 ft)
- 1 Toyota A connector
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Lexus|RX Hybrid 2020-22|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 RJ45 cable (7 ft)
- 1 Toyota A connector
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Lexus|UX Hybrid 2019-23|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 RJ45 cable (7 ft)
- 1 Toyota A connector
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| -|Lincoln|Aviator 2020-23|Co-Pilot360 Plus|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Ford Q3 connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| -|Lincoln|Aviator Plug-in Hybrid 2020-23|Co-Pilot360 Plus|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Ford Q3 connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| +|Lincoln|Aviator 2020-24|Co-Pilot360 Plus|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Ford Q3 connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| +|Lincoln|Aviator Plug-in Hybrid 2020-24|Co-Pilot360 Plus|openpilot available[1](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Ford Q3 connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |MAN|eTGE 2020-24|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|31 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 USB-C coupler
- 1 VW J533 connector
- 1 angled mount (8 degrees)
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |MAN|TGE 2017-24|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,12](#footnotes)|0 mph|31 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 USB-C coupler
- 1 VW J533 connector
- 1 angled mount (8 degrees)
- 1 comma 3X
- 1 harness box
- 1 long OBD-C cable
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| |Mazda|CX-5 2022-24|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Mazda connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here
|| diff --git a/opendbc_repo b/opendbc_repo index 4aae6d02be..c4114772ba 160000 --- a/opendbc_repo +++ b/opendbc_repo @@ -1 +1 @@ -Subproject commit 4aae6d02bece759b6f25666db6b9428ae5011161 +Subproject commit c4114772ba9d77bf03b97972611591e0bf8e4a25 diff --git a/panda b/panda index 3066f93d8a..0b364ece1e 160000 --- a/panda +++ b/panda @@ -1 +1 @@ -Subproject commit 3066f93d8a1db92ac900e6ccc64ff68c154deafb +Subproject commit 0b364ece1eafa2e66b71be7cade3fdfb56a3014e diff --git a/selfdrive/controls/lib/longitudinal_mpc_lib/long_mpc.py b/selfdrive/controls/lib/longitudinal_mpc_lib/long_mpc.py index fa6d5542bd..65e1421d77 100755 --- a/selfdrive/controls/lib/longitudinal_mpc_lib/long_mpc.py +++ b/selfdrive/controls/lib/longitudinal_mpc_lib/long_mpc.py @@ -347,7 +347,8 @@ class LongitudinalMpc: lead_1_obstacle = lead_xv_1[:,0] + get_stopped_equivalence_factor(lead_xv_1[:,1]) self.params[:,0] = ACCEL_MIN - self.params[:,1] = self.max_a + # negative accel constraint causes problems because negative speed is not allowed + self.params[:,1] = max(0.0, self.max_a) # Update in ACC mode or ACC/e2e blend if self.mode == 'acc': @@ -356,6 +357,7 @@ class LongitudinalMpc: # Fake an obstacle for cruise, this ensures smooth acceleration to set speed # when the leads are no factor. v_lower = v_ego + (T_IDXS * self.cruise_min_a * 1.05) + # TODO does this make sense when max_a is negative? v_upper = v_ego + (T_IDXS * self.max_a * 1.05) v_cruise_clipped = np.clip(v_cruise * np.ones(N+1), v_lower, diff --git a/selfdrive/controls/lib/longitudinal_planner.py b/selfdrive/controls/lib/longitudinal_planner.py index 5f47cebb1f..f1637d960c 100755 --- a/selfdrive/controls/lib/longitudinal_planner.py +++ b/selfdrive/controls/lib/longitudinal_planner.py @@ -22,7 +22,7 @@ A_CRUISE_MAX_VALS = [1.6, 1.2, 0.8, 0.6] A_CRUISE_MAX_BP = [0., 10.0, 25., 40.] CONTROL_N_T_IDX = ModelConstants.T_IDXS[:CONTROL_N] ALLOW_THROTTLE_THRESHOLD = 0.5 -ACCEL_LIMIT_MARGIN = 0.05 +MIN_ALLOW_THROTTLE_SPEED = 2.5 # Lookup table for turns _A_TOTAL_MAX_V = [1.7, 3.2] @@ -151,12 +151,12 @@ class LongitudinalPlanner: self.v_model_error = get_speed_error(sm['modelV2'], v_ego) x, v, a, j, throttle_prob = self.parse_model(sm['modelV2'], self.v_model_error) # Don't clip at low speeds since throttle_prob doesn't account for creep - self.allow_throttle = throttle_prob > ALLOW_THROTTLE_THRESHOLD or v_ego <= 5.0 + self.allow_throttle = throttle_prob > ALLOW_THROTTLE_THRESHOLD or v_ego <= MIN_ALLOW_THROTTLE_SPEED if not self.allow_throttle: - # MPC breaks when accel limits would cause negative velocity within the MPC horizon, so we clip the max accel limit at vEgo/T_MAX plus a bit of margin - clipped_accel_coast = max(accel_coast, accel_limits_turns[0], -v_ego / T_IDXS_MPC[-1] + ACCEL_LIMIT_MARGIN) - accel_limits_turns[1] = min(accel_limits_turns[1], clipped_accel_coast) + clipped_accel_coast = max(accel_coast, accel_limits_turns[0]) + clipped_accel_coast_interp = interp(v_ego, [MIN_ALLOW_THROTTLE_SPEED, MIN_ALLOW_THROTTLE_SPEED*2], [accel_limits_turns[1], clipped_accel_coast]) + accel_limits_turns[1] = min(accel_limits_turns[1], clipped_accel_coast_interp) if force_slow_decel: v_cruise = 0.0 diff --git a/selfdrive/test/longitudinal_maneuvers/test_longitudinal.py b/selfdrive/test/longitudinal_maneuvers/test_longitudinal.py index 7eea44aae6..4bc1ebba8f 100644 --- a/selfdrive/test/longitudinal_maneuvers/test_longitudinal.py +++ b/selfdrive/test/longitudinal_maneuvers/test_longitudinal.py @@ -108,18 +108,6 @@ def create_maneuvers(kwargs): breakpoints=[0.0, 2., 2.01], **kwargs, ), - Maneuver( - "slow to 5m/s with allow_throttle = False and pitch = +0.1", - duration=25., - initial_speed=20., - lead_relevancy=False, - prob_throttle_values=[1., 0., 0.], - cruise_values=[20., 20., 20.], - pitch_values=[0., 0.1, 0.1], - breakpoints=[0.0, 2., 2.01], - ensure_slowdown=True, - **kwargs, - ), Maneuver( "approach slower cut-in car at 20m/s", duration=20., @@ -163,6 +151,20 @@ def create_maneuvers(kwargs): **kwargs, ), ] + if not kwargs['e2e']: + # allow_throttle won't trigger with e2e + maneuvers.append(Maneuver( + "slow to 5m/s with allow_throttle = False and pitch = +0.1", + duration=30., + initial_speed=20., + lead_relevancy=False, + prob_throttle_values=[1., 0., 0.], + cruise_values=[20., 20., 20.], + pitch_values=[0., 0.1, 0.1], + breakpoints=[0.0, 2., 2.01], + ensure_slowdown=True, + **kwargs, + )) if not kwargs['force_decel']: # controls relies on planner commanding to move for stock-ACC resume spamming maneuvers.append(Maneuver( diff --git a/selfdrive/test/process_replay/ref_commit b/selfdrive/test/process_replay/ref_commit index 6842530946..2f565836fd 100644 --- a/selfdrive/test/process_replay/ref_commit +++ b/selfdrive/test/process_replay/ref_commit @@ -1 +1 @@ -8f9dba78b0a2a4fbf8122f61d49e9529dba9b3b4 \ No newline at end of file +992ac80ef848afb85562ca24b1c5a3d410aacd05 \ No newline at end of file diff --git a/selfdrive/ui/tests/test_ui/run.py b/selfdrive/ui/tests/test_ui/run.py index e6fd9a016a..8cd5f1930d 100644 --- a/selfdrive/ui/tests/test_ui/run.py +++ b/selfdrive/ui/tests/test_ui/run.py @@ -3,11 +3,10 @@ import capnp import pathlib import shutil import sys -import jinja2 -import matplotlib.pyplot as plt -import numpy as np import os import pywinctl +import pyautogui +import pickle import time from cereal import log @@ -23,8 +22,9 @@ from openpilot.selfdrive.test.process_replay.migration import migrate, migrate_c from openpilot.tools.lib.logreader import LogReader from openpilot.tools.lib.framereader import FrameReader from openpilot.tools.lib.route import Route +from openpilot.tools.lib.cache import DEFAULT_CACHE_DIR -UI_DELAY = 0.5 # may be slower on CI? +UI_DELAY = 0.1 # may be slower on CI? TEST_ROUTE = "a2a0ccea32023010|2023-07-27--13-01-19" STREAMS: list[tuple[VisionStreamType, CameraConfig, bytes]] = [] @@ -222,41 +222,20 @@ class TestUI: print(f"failed to find ui window, assuming that it's in the top left (for Xvfb) {e}") self.ui = namedtuple("bb", ["left", "top", "width", "height"])(0,0,2160,1080) - def screenshot(self): - import pyautogui - im = pyautogui.screenshot(region=(self.ui.left, self.ui.top, self.ui.width, self.ui.height)) + def screenshot(self, name): + im = pyautogui.screenshot(SCREENSHOTS_DIR / f"{name}.png", region=(self.ui.left, self.ui.top, self.ui.width, self.ui.height)) assert im.width == 2160 assert im.height == 1080 - img = np.array(im) - im.close() - return img def click(self, x, y, *args, **kwargs): - import pyautogui pyautogui.click(self.ui.left + x, self.ui.top + y, *args, **kwargs) time.sleep(UI_DELAY) # give enough time for the UI to react @with_processes(["ui"]) def test_ui(self, name, setup_case): self.setup() - setup_case(self.click, self.pm) - - im = self.screenshot() - plt.imsave(SCREENSHOTS_DIR / f"{name}.png", im) - - -def create_html_report(): - OUTPUT_FILE = TEST_OUTPUT_DIR / "index.html" - - with open(TEST_DIR / "template.html") as f: - template = jinja2.Template(f.read()) - - cases = {f.stem: (str(f.relative_to(TEST_OUTPUT_DIR)), "reference.png") for f in SCREENSHOTS_DIR.glob("*.png")} - cases = dict(sorted(cases.items())) - - with open(OUTPUT_FILE, "w") as f: - f.write(template.render(cases=cases)) + self.screenshot(name) def create_screenshots(): if TEST_OUTPUT_DIR.exists(): @@ -277,13 +256,23 @@ def create_screenshots(): break cam = DEVICE_CAMERAS[("tici", "ar0231")] - road_img = FrameReader(route.camera_paths()[segnum]).get(0, pix_fmt="nv12")[0] - STREAMS.append((VisionStreamType.VISION_STREAM_ROAD, cam.fcam, road_img.flatten().tobytes())) - wide_road_img = FrameReader(route.ecamera_paths()[segnum]).get(0, pix_fmt="nv12")[0] - STREAMS.append((VisionStreamType.VISION_STREAM_WIDE_ROAD, cam.ecam, wide_road_img.flatten().tobytes())) + frames_cache = f'{DEFAULT_CACHE_DIR}/ui_frames' + if os.path.isfile(frames_cache): + with open(frames_cache, 'rb') as f: + frames = pickle.load(f) + road_img = frames[0] + wide_road_img = frames[1] + driver_img = frames[2] + else: + with open(frames_cache, 'wb') as f: + road_img = FrameReader(route.camera_paths()[segnum]).get(0, pix_fmt="nv12")[0] + wide_road_img = FrameReader(route.ecamera_paths()[segnum]).get(0, pix_fmt="nv12")[0] + driver_img = FrameReader(route.dcamera_paths()[segnum]).get(0, pix_fmt="nv12")[0] + pickle.dump([road_img, wide_road_img, driver_img], f) - driver_img = FrameReader(route.dcamera_paths()[segnum]).get(0, pix_fmt="nv12")[0] + STREAMS.append((VisionStreamType.VISION_STREAM_ROAD, cam.fcam, road_img.flatten().tobytes())) + STREAMS.append((VisionStreamType.VISION_STREAM_WIDE_ROAD, cam.ecam, wide_road_img.flatten().tobytes())) STREAMS.append((VisionStreamType.VISION_STREAM_DRIVER, cam.dcam, driver_img.flatten().tobytes())) t = TestUI() @@ -302,6 +291,3 @@ def create_screenshots(): if __name__ == "__main__": print("creating test screenshots") create_screenshots() - - print("creating html report") - create_html_report() diff --git a/system/camerad/cameras/ife.h b/system/camerad/cameras/ife.h index 70a448dd1f..1616196a3f 100644 --- a/system/camerad/cameras/ife.h +++ b/system/camerad/cameras/ife.h @@ -167,16 +167,16 @@ int build_initial_config(uint8_t *dst, const SensorInfo *s, std::vector color_correct_matrix; // 3x3 std::vector gamma_lut_rgb; // gamma LUTs are length 64 * sizeof(uint32_t); same for r/g/b here + void prepare_gamma_lut() { + for (int i = 0; i < 64; i++) { + gamma_lut_rgb[i] |= ((uint32_t)(gamma_lut_rgb[i+1] - gamma_lut_rgb[i]) << 10); + } + gamma_lut_rgb.pop_back(); + } std::vector linearization_lut; // length 288 std::vector linearization_pts; // length 4 std::vector vignetting_lut; // 2x length 884 diff --git a/system/hardware/tici/amplifier.py b/system/hardware/tici/amplifier.py index af82067467..f6b29ec0ce 100755 --- a/system/hardware/tici/amplifier.py +++ b/system/hardware/tici/amplifier.py @@ -125,13 +125,15 @@ class Amplifier: def set_configs(self, configs: list[AmpConfig]) -> bool: # retry in case panda is using the amp tries = 15 - for i in range(15): + backoff = 0. + for i in range(tries): try: self._set_configs(configs) return True except OSError: + backoff += 0.1 + time.sleep(backoff) print(f"Failed to set amp config, {tries - i - 1} retries left") - time.sleep(0.02) return False def set_global_shutdown(self, amp_disabled: bool) -> bool: diff --git a/tools/sim/bridge/metadrive/metadrive_world.py b/tools/sim/bridge/metadrive/metadrive_world.py index 5bb4555dc1..a34d270994 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 = 30 + time_check_threshold = 15 current_time = time.monotonic() since_last_check = current_time - self.last_check_timestamp if since_last_check >= time_check_threshold: diff --git a/tools/sim/tests/test_metadrive_bridge.py b/tools/sim/tests/test_metadrive_bridge.py index 8849e901cb..04ce5d584f 100644 --- a/tools/sim/tests/test_metadrive_bridge.py +++ b/tools/sim/tests/test_metadrive_bridge.py @@ -12,10 +12,7 @@ from openpilot.tools.sim.tests.test_sim_bridge import TestSimBridgeBase class TestMetaDriveBridge(TestSimBridgeBase): @pytest.fixture(autouse=True) def setup_create_bridge(self, test_duration): - # run bridge test for at least 60s, since not-moving check runs every 30s - if test_duration < 60: - test_duration = 60 - self.test_duration = test_duration + self.test_duration = 30 def create_bridge(self): return MetaDriveBridge(False, False, self.test_duration, True) diff --git a/tools/sim/tests/test_sim_bridge.py b/tools/sim/tests/test_sim_bridge.py index 12f38b86c3..d58cddff7f 100644 --- a/tools/sim/tests/test_sim_bridge.py +++ b/tools/sim/tests/test_sim_bridge.py @@ -89,7 +89,4 @@ class TestSimBridgeBase: p.terminate() for p in reversed(self.processes): - if isinstance(p, subprocess.Popen): - p.wait(15) - else: - p.join(15) + p.kill()