mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-08-21 08:14:00 +08:00
The Saturday Threshold
This commit is contained in:
@@ -101,6 +101,7 @@ class Request:
|
||||
@dataclass
|
||||
class FwQueryConfig:
|
||||
requests: list[Request]
|
||||
non_tester_present_ecus: list[Ecu] = field(default_factory=list)
|
||||
# TODO: make this automatic and remove hardcoded lists, or do fingerprinting with ecus
|
||||
# Overrides and removes from essential ecus for specific models and ecus (exact matching)
|
||||
non_essential_ecus: dict[Ecu, list[str]] = field(default_factory=dict)
|
||||
|
||||
@@ -181,6 +181,9 @@ def get_present_ecus(can_recv: CanRecvCallable, can_send: CanSendCallable, set_o
|
||||
continue
|
||||
|
||||
for ecu_type, addr, sub_addr in config.get_all_ecus(VERSIONS[brand]):
|
||||
if ecu_type in config.non_tester_present_ecus:
|
||||
continue
|
||||
|
||||
# Only query ecus in whitelist if whitelist is not empty
|
||||
if len(r.whitelist_ecus) == 0 or ecu_type in r.whitelist_ecus:
|
||||
a = (addr, sub_addr, r.bus)
|
||||
@@ -216,6 +219,9 @@ def get_brand_ecu_matches(ecu_rx_addrs: set[EcuAddrBusType]) -> dict[str, list[b
|
||||
# Since we can't know what request an ecu responded to, add matches for all possible rx offsets
|
||||
for brand, config, r in REQUESTS:
|
||||
for ecu in config.get_all_ecus(VERSIONS[brand]):
|
||||
if ecu[0] in config.non_tester_present_ecus:
|
||||
continue
|
||||
|
||||
if len(r.whitelist_ecus) == 0 or ecu[0] in r.whitelist_ecus:
|
||||
brand_rx_addrs[brand].add((uds.get_rx_addr_for_tx_addr(ecu[1], r.rx_offset), ecu[2]))
|
||||
|
||||
|
||||
@@ -5,14 +5,16 @@ from types import SimpleNamespace
|
||||
import pytest
|
||||
|
||||
from opendbc.can import CANPacker, CANParser
|
||||
from opendbc.car import Bus, structs
|
||||
from opendbc.car import Bus, fw_versions, structs
|
||||
from opendbc.car.fw_query_definitions import StdQueries
|
||||
from opendbc.car.subaru import subarucan
|
||||
from opendbc.car.subaru.carcontroller import CarController
|
||||
from opendbc.car.subaru.carstate import CarState
|
||||
from opendbc.car.subaru.fingerprints import FW_VERSIONS
|
||||
from opendbc.car.fw_versions import match_fw_to_car
|
||||
from opendbc.car.subaru.interface import CarInterface
|
||||
from opendbc.car.subaru.values import CAR, DBC, CanBus, SubaruFlags, SubaruSafetyFlags
|
||||
from opendbc.car.subaru.values import CAR, DBC, FW_QUERY_CONFIG, SUBARU_ALT_VERSION_REQUEST, SUBARU_VERSION_REQUEST, CanBus, \
|
||||
SubaruFlags, SubaruSafetyFlags
|
||||
from opendbc.car.structs import CarParams
|
||||
|
||||
|
||||
@@ -66,6 +68,32 @@ def test_preglobal_sng_does_not_send_standstill_keepalive_without_manual_toggle(
|
||||
|
||||
|
||||
class TestSubaruFingerprint:
|
||||
def test_eyesight_queries_do_not_change_diagnostic_state(self, monkeypatch):
|
||||
camera_requests = [request for request in FW_QUERY_CONFIG.requests if CarParams.Ecu.fwdCamera in request.whitelist_ecus]
|
||||
|
||||
assert CarParams.Ecu.fwdCamera in FW_QUERY_CONFIG.non_tester_present_ecus
|
||||
assert {tuple(request.request) for request in camera_requests} == {
|
||||
(SUBARU_VERSION_REQUEST,),
|
||||
(SUBARU_ALT_VERSION_REQUEST,),
|
||||
}
|
||||
for request in camera_requests:
|
||||
assert StdQueries.TESTER_PRESENT_REQUEST not in request.request
|
||||
assert StdQueries.DEFAULT_DIAGNOSTIC_REQUEST not in request.request
|
||||
|
||||
queried_ecus = set()
|
||||
|
||||
def collect_queries(_can_recv, _can_send, queries, _responses, timeout):
|
||||
queried_ecus.update(queries)
|
||||
return set()
|
||||
|
||||
monkeypatch.setattr(fw_versions, "REQUESTS", [("subaru", FW_QUERY_CONFIG, request) for request in FW_QUERY_CONFIG.requests])
|
||||
monkeypatch.setattr(fw_versions, "VERSIONS", {"subaru": FW_VERSIONS})
|
||||
monkeypatch.setattr(fw_versions, "get_ecu_addrs", collect_queries)
|
||||
fw_versions.get_present_ecus(lambda **_kwargs: [], lambda _msgs: None, lambda _enabled: None)
|
||||
|
||||
assert queried_ecus
|
||||
assert all(address != 0x787 for address, _subaddress, _bus in queried_ecus)
|
||||
|
||||
def test_fw_version_format(self):
|
||||
for platform, fws_per_ecu in FW_VERSIONS.items():
|
||||
for (ecu, _, _), fws in fws_per_ecu.items():
|
||||
|
||||
@@ -281,12 +281,10 @@ FW_QUERY_CONFIG = FwQueryConfig(
|
||||
Request(
|
||||
[StdQueries.TESTER_PRESENT_REQUEST, SUBARU_VERSION_REQUEST],
|
||||
[StdQueries.TESTER_PRESENT_RESPONSE, SUBARU_VERSION_RESPONSE],
|
||||
whitelist_ecus=[Ecu.abs, Ecu.eps, Ecu.fwdCamera, Ecu.engine, Ecu.transmission],
|
||||
whitelist_ecus=[Ecu.abs, Ecu.eps, Ecu.engine, Ecu.transmission],
|
||||
logging=True,
|
||||
),
|
||||
# Non-OBD requests
|
||||
# Some Eyesight modules fail on TESTER_PRESENT_REQUEST
|
||||
# TODO: check if this resolves the fingerprinting issue for the 2023 Ascent and other new Subaru cars
|
||||
Request(
|
||||
[SUBARU_VERSION_REQUEST],
|
||||
[SUBARU_VERSION_RESPONSE],
|
||||
@@ -300,28 +298,22 @@ FW_QUERY_CONFIG = FwQueryConfig(
|
||||
bus=0,
|
||||
logging=True,
|
||||
),
|
||||
Request(
|
||||
[StdQueries.DEFAULT_DIAGNOSTIC_REQUEST, StdQueries.TESTER_PRESENT_REQUEST, SUBARU_VERSION_REQUEST],
|
||||
[StdQueries.DEFAULT_DIAGNOSTIC_RESPONSE, StdQueries.TESTER_PRESENT_RESPONSE, SUBARU_VERSION_RESPONSE],
|
||||
whitelist_ecus=[Ecu.fwdCamera],
|
||||
bus=0,
|
||||
logging=True,
|
||||
),
|
||||
Request(
|
||||
[StdQueries.TESTER_PRESENT_REQUEST, SUBARU_VERSION_REQUEST],
|
||||
[StdQueries.TESTER_PRESENT_RESPONSE, SUBARU_VERSION_RESPONSE],
|
||||
whitelist_ecus=[Ecu.abs, Ecu.eps, Ecu.fwdCamera, Ecu.engine, Ecu.transmission],
|
||||
whitelist_ecus=[Ecu.abs, Ecu.eps, Ecu.engine, Ecu.transmission],
|
||||
bus=0,
|
||||
),
|
||||
# GEN2 powertrain bus query
|
||||
Request(
|
||||
[StdQueries.TESTER_PRESENT_REQUEST, SUBARU_VERSION_REQUEST],
|
||||
[StdQueries.TESTER_PRESENT_RESPONSE, SUBARU_VERSION_RESPONSE],
|
||||
whitelist_ecus=[Ecu.abs, Ecu.eps, Ecu.fwdCamera, Ecu.engine, Ecu.transmission],
|
||||
whitelist_ecus=[Ecu.abs, Ecu.eps, Ecu.engine, Ecu.transmission],
|
||||
bus=1,
|
||||
obd_multiplexing=False,
|
||||
),
|
||||
],
|
||||
non_tester_present_ecus=[Ecu.fwdCamera],
|
||||
# We don't get the EPS from non-OBD queries on GEN2 cars. Note that we still attempt to match when it exists
|
||||
non_essential_ecus={
|
||||
Ecu.eps: list(CAR.with_flags(SubaruFlags.GLOBAL_GEN2)),
|
||||
|
||||
@@ -265,7 +265,7 @@ class TestFwFingerprintTiming:
|
||||
print(f'get_vin {name} case, query time={self.total_time / self.N} seconds')
|
||||
|
||||
def test_fw_query_timing(self, subtests, mocker):
|
||||
total_ref_time = {1: 7.4, 2: 8.0}
|
||||
total_ref_time = {1: 7.3, 2: 7.9}
|
||||
brand_ref_times = {
|
||||
1: {
|
||||
'gm': 1.0,
|
||||
@@ -276,7 +276,7 @@ class TestFwFingerprintTiming:
|
||||
'hyundai': 0.65,
|
||||
'mazda': 0.1,
|
||||
'nissan': 0.8,
|
||||
'subaru': 0.65,
|
||||
'subaru': 0.55,
|
||||
'tesla': 0.1,
|
||||
'toyota': 0.7,
|
||||
'volkswagen': 0.65,
|
||||
|
||||
@@ -21,6 +21,7 @@ from openpilot.selfdrive.controls.lib.lead_follow_policy import is_nonurgent_dup
|
||||
from openpilot.selfdrive.controls.lib.longitudinal_vehicle_tunes import (
|
||||
get_far_follow_output_slew_rates,
|
||||
get_follow_prebrake_min_headway,
|
||||
get_force_stop_handoff_distance,
|
||||
is_gm_silverado_early_follow_lead,
|
||||
is_toyota_rav4_tss2_post_departure_tune,
|
||||
get_toyota_sienna_post_departure_restop_cap,
|
||||
@@ -2177,7 +2178,8 @@ class LongitudinalPlanner:
|
||||
# the line parks us short. Below that the existing v_cruise=0 path finishes the stop,
|
||||
# since forcingStopLength is decaying to zero and the obstacle would land behind us.
|
||||
force_stop_x = None
|
||||
if sm['starpilotPlan'].forcingStop and sm['starpilotPlan'].forcingStopLength > STOP_DISTANCE:
|
||||
force_stop_handoff_m = get_force_stop_handoff_distance(self.CP.carFingerprint)
|
||||
if sm['starpilotPlan'].forcingStop and sm['starpilotPlan'].forcingStopLength > force_stop_handoff_m:
|
||||
force_stop_x = float(sm['starpilotPlan'].forcingStopLength) + STOP_DISTANCE
|
||||
|
||||
self.mpc.update(sm['radarState'], v_cruise, x, v, a, j,
|
||||
|
||||
@@ -18,6 +18,8 @@ TOYOTA_SIENNA_POST_DEPARTURE_RESTOP_MIN_MODEL_PROB = 0.95
|
||||
TOYOTA_SIENNA_POST_DEPARTURE_RESTOP_MAX_LATERAL_OFFSET = 1.75
|
||||
TOYOTA_SIENNA_POST_DEPARTURE_RESTOP_MIN_BRAKE = 0.18
|
||||
TOYOTA_SIENNA_POST_DEPARTURE_RESTOP_MAX_BRAKE = 0.32
|
||||
TOYOTA_CAMRY_TSS2_FORCE_STOP_HANDOFF_M = 4.5
|
||||
DEFAULT_FORCE_STOP_HANDOFF_M = 6.0
|
||||
|
||||
|
||||
def is_toyota_rav4_tss2_post_departure_tune(CP):
|
||||
@@ -109,3 +111,10 @@ def get_toyota_sienna_post_departure_restop_cap(CP, lead, v_ego, accel_min,
|
||||
TOYOTA_SIENNA_POST_DEPARTURE_RESTOP_MAX_BRAKE,
|
||||
))
|
||||
return brake_floor if accel_min >= 0.0 else max(float(accel_min), brake_floor)
|
||||
|
||||
|
||||
def get_force_stop_handoff_distance(car_fingerprint):
|
||||
"""Return the distance at which force-stop control hands off to MPC."""
|
||||
if str(car_fingerprint) == "TOYOTA_CAMRY_TSS2":
|
||||
return TOYOTA_CAMRY_TSS2_FORCE_STOP_HANDOFF_M
|
||||
return DEFAULT_FORCE_STOP_HANDOFF_M
|
||||
|
||||
@@ -13,6 +13,7 @@ from openpilot.starpilot.controls.lib.starpilot_vcruise import (
|
||||
get_lead_veto_distance,
|
||||
get_slc_lead_drop_relaxed_target,
|
||||
)
|
||||
from openpilot.selfdrive.controls.lib.longitudinal_vehicle_tunes import get_force_stop_handoff_distance
|
||||
from types import SimpleNamespace
|
||||
|
||||
|
||||
@@ -116,6 +117,11 @@ def test_elantra_gets_lead_veto_margin_before_force_stop():
|
||||
assert get_lead_veto_distance(SimpleNamespace(carFingerprint="OTHER_CAR")) == pytest.approx(75.0)
|
||||
|
||||
|
||||
def test_camry_tss2_uses_closer_force_stop_handoff():
|
||||
assert get_force_stop_handoff_distance("TOYOTA_CAMRY_TSS2") == pytest.approx(4.5)
|
||||
assert get_force_stop_handoff_distance("TOYOTA_RAV4_TSS2") == pytest.approx(6.0)
|
||||
|
||||
|
||||
def test_curve_speed_controller_holds_target_through_brief_detector_dropout():
|
||||
planner, vcruise = make_vcruise()
|
||||
sm = make_sm(standstill=False)
|
||||
@@ -478,6 +484,24 @@ def test_force_stop_stays_committed_while_moving_even_if_scene_opens():
|
||||
assert vcruise.forcing_stop
|
||||
|
||||
|
||||
def test_force_stop_releases_after_cem_light_clears_while_moving():
|
||||
planner, vcruise = make_vcruise(red_light=True, raw_model_stopped=False, forcing_stop=True)
|
||||
sm = make_sm(standstill=False)
|
||||
toggles = make_toggles()
|
||||
|
||||
update_vcruise(vcruise, sm, toggles, now=0.0, v_ego=3.0)
|
||||
assert vcruise.force_stop_from_light
|
||||
|
||||
planner.starpilot_cem.stop_light_detected = False
|
||||
update_vcruise(vcruise, sm, toggles, now=0.25, v_ego=3.0)
|
||||
assert vcruise.forcing_stop
|
||||
|
||||
result = update_vcruise(vcruise, sm, toggles, now=0.75, v_ego=3.0)
|
||||
assert result == pytest.approx(20.0)
|
||||
assert not vcruise.forcing_stop
|
||||
assert not vcruise.force_stop_from_light
|
||||
|
||||
|
||||
def test_force_stop_turn_scene_veto_blocks_new_activation():
|
||||
_, vcruise = make_vcruise(red_light=False, raw_model_stopped=False, forcing_stop=False)
|
||||
sm = make_sm(standstill=False)
|
||||
|
||||
@@ -6,7 +6,7 @@ import pyray as rl
|
||||
|
||||
from msgq.visionipc import VisionIpcClient, VisionStreamType, VisionBuf
|
||||
from openpilot.common.swaglog import cloudlog
|
||||
from openpilot.system.hardware import PC, TICI
|
||||
from openpilot.system.hardware import HARDWARE, PC, TICI
|
||||
from openpilot.system.ui.lib.application import gui_app
|
||||
from openpilot.system.ui.lib.egl import (
|
||||
init_egl, is_egl_initialized, finish_gl, create_egl_image, destroy_egl_image,
|
||||
@@ -17,7 +17,17 @@ from openpilot.selfdrive.ui.ui_state import ui_state
|
||||
|
||||
CONNECTION_RETRY_INTERVAL = 0.2 # seconds between connection attempts
|
||||
STREAM_DISCOVERY_REFRESH_INTERVAL = 0.5 # seconds between nonblocking stream advertisements
|
||||
MICI_FORCE_TEXTURE_CAMERA = os.getenv("MICI_FORCE_TEXTURE_CAMERA", "0") == "1"
|
||||
|
||||
|
||||
def _default_force_texture_camera(device_type: str) -> bool:
|
||||
return device_type == "mici"
|
||||
|
||||
|
||||
DEVICE_TYPE = HARDWARE.get_device_type()
|
||||
MICI_FORCE_TEXTURE_CAMERA = os.getenv(
|
||||
"MICI_FORCE_TEXTURE_CAMERA",
|
||||
"1" if _default_force_texture_camera(DEVICE_TYPE) else "0",
|
||||
) == "1"
|
||||
# One stale frame can be normal ring-buffer reuse; repeated consecutive regressions demote EGL.
|
||||
EGL_REGRESSIVE_FRAME_FALLBACK_THRESHOLD = 3
|
||||
|
||||
|
||||
@@ -30,6 +30,12 @@ def test_mici_uses_shared_camera_view():
|
||||
assert not big_cameraview.CameraView._use_upstream_engaged_color
|
||||
|
||||
|
||||
def test_c4_defaults_to_ui_owned_camera_textures():
|
||||
assert big_cameraview._default_force_texture_camera("mici")
|
||||
assert not big_cameraview._default_force_texture_camera("tici")
|
||||
assert not big_cameraview._default_force_texture_camera("tizi")
|
||||
|
||||
|
||||
def test_pending_switch_is_cancelled_when_requested_stream_is_current():
|
||||
view = _camera_view()
|
||||
view._stream_type = big_cameraview.VisionStreamType.VISION_STREAM_ROAD
|
||||
|
||||
@@ -8,12 +8,14 @@ from openpilot.common.realtime import DT_MDL
|
||||
from openpilot.starpilot.common.starpilot_variables import CITY_SPEED_LIMIT, CRUISING_SPEED
|
||||
from openpilot.starpilot.controls.lib.curve_speed_controller import CurveSpeedController, is_manual_speed_control
|
||||
from openpilot.starpilot.controls.lib.speed_limit_controller import SpeedLimitController
|
||||
from openpilot.selfdrive.controls.lib.longitudinal_vehicle_tunes import get_force_stop_handoff_distance
|
||||
|
||||
CSC_MIN_SPEED = CITY_SPEED_LIMIT * CV.MPH_TO_MS
|
||||
CSC_CURVE_RELEASE_HOLD_TIME = 0.75
|
||||
OVERRIDE_FORCE_STOP_TIMER = 10
|
||||
STANDSTILL_FORCE_STOP_CLEAR_TIME = 0.75
|
||||
STANDSTILL_FORCE_STOP_LIGHT_HOLD_TIME = 5.0
|
||||
FORCE_STOP_LIGHT_CLEAR_TIME = 0.5
|
||||
SLC_LEAD_DROP_RELAXATION_MIN_SPEED = 20.0 * CV.MPH_TO_MS
|
||||
SLC_LEAD_DROP_RELAXATION_MIN_DISTANCE = 30.0
|
||||
SLC_LEAD_DROP_RELAXATION_MIN_HEADWAY = 1.2
|
||||
@@ -48,7 +50,6 @@ LEAD_VETO_M = 75.0 # m — lead proximity that vetoes Force Stop (kept of
|
||||
LEAD_VETO_M_OVERRIDES = {
|
||||
"HYUNDAI_ELANTRA_2021": 90.0,
|
||||
}
|
||||
MPC_HANDOFF_M = 6.0 # m — below this, command 0 and let MPC finish the stop
|
||||
FORCE_STOP_APPROACH_DECEL = 0.65 # m/s^2 — speed ceiling before commit. LOWER = more early
|
||||
# braking; don't go under FORCE_STOP_MODEL_APPROACH_DECEL
|
||||
ADAS_MAX_MS = 17.88 # 40 mph — cross-street ADAS guard
|
||||
@@ -166,6 +167,8 @@ class StarPilotVCruise:
|
||||
self.standstill_force_stop_clear_since = 0.0
|
||||
self.standstill_force_stop_started_at = None
|
||||
self.standstill_force_stop_reason = None
|
||||
self.force_stop_from_light = False
|
||||
self.force_stop_light_clear_since = None
|
||||
self.controls_enabled_previously = False
|
||||
# Kinematic distance estimator. Same attribute also published as
|
||||
# starpilotPlan.forcingStopLength, so the existing reader keeps working.
|
||||
@@ -314,6 +317,9 @@ class StarPilotVCruise:
|
||||
self._applied_slc_control_target = 0.0
|
||||
|
||||
long_control_active = sm["carControl"].longActive
|
||||
force_stop_handoff_m = get_force_stop_handoff_distance(
|
||||
getattr(starpilot_toggles, "car_model", "")
|
||||
)
|
||||
|
||||
raw_stop_seen = bool(
|
||||
self.starpilot_planner.starpilot_cem.stop_light_detected
|
||||
@@ -393,6 +399,13 @@ class StarPilotVCruise:
|
||||
|
||||
force_stop_active = cem_path or dash_path
|
||||
|
||||
if cem_path:
|
||||
self.force_stop_from_light = True
|
||||
self.force_stop_light_clear_since = None
|
||||
elif not self.forcing_stop:
|
||||
self.force_stop_from_light = False
|
||||
self.force_stop_light_clear_since = None
|
||||
|
||||
# Latch on first dash frame so the CEM pin can fire and we don't release on
|
||||
# transient dashboard dropouts. Cleared in the no-force-stop branch below.
|
||||
if dash_path:
|
||||
@@ -463,6 +476,26 @@ class StarPilotVCruise:
|
||||
force_stop_enabled |= self.forcing_stop and not sm["carState"].standstill
|
||||
force_stop_enabled |= self.standstill_force_stop_hold
|
||||
|
||||
light_stop_cleared = (
|
||||
self.forcing_stop and
|
||||
self.force_stop_from_light and
|
||||
not sm["carState"].standstill and
|
||||
not stop_light_detected and
|
||||
not raw_model_stopped and
|
||||
not dash_active
|
||||
)
|
||||
if light_stop_cleared:
|
||||
if self.force_stop_light_clear_since is None:
|
||||
self.force_stop_light_clear_since = now
|
||||
elif self._elapsed_seconds(now, self.force_stop_light_clear_since) >= FORCE_STOP_LIGHT_CLEAR_TIME:
|
||||
self.forcing_stop = False
|
||||
self.force_stop_from_light = False
|
||||
self.force_stop_light_clear_since = None
|
||||
self.force_stop_timer = 0.0
|
||||
force_stop_enabled = False
|
||||
else:
|
||||
self.force_stop_light_clear_since = None
|
||||
|
||||
if self.forcing_stop and standstill and not force_stop_enabled and self.standstill_force_stop_reason != "sign":
|
||||
self.override_force_stop_timer = OVERRIDE_FORCE_STOP_TIMER
|
||||
|
||||
@@ -583,11 +616,11 @@ class StarPilotVCruise:
|
||||
# Kinematic profile with user offset. Positive offset shifts the perceived
|
||||
# line further down the road -> car rolls further before commanding 0.
|
||||
effective_d = self.tracked_model_length + offset_m
|
||||
if effective_d <= MPC_HANDOFF_M:
|
||||
if effective_d <= force_stop_handoff_m:
|
||||
v_target = 0.0
|
||||
else:
|
||||
approach_decel = FORCE_STOP_DASH_APPROACH_DECEL if dash_active else FORCE_STOP_MODEL_APPROACH_DECEL
|
||||
v_target = math.sqrt(2.0 * approach_decel * (effective_d - MPC_HANDOFF_M))
|
||||
v_target = math.sqrt(2.0 * approach_decel * (effective_d - force_stop_handoff_m))
|
||||
|
||||
v_cruise = min(v_target, v_cruise)
|
||||
|
||||
@@ -644,8 +677,8 @@ class StarPilotVCruise:
|
||||
if adjacent_stop_d is not None:
|
||||
approach_d = min(approach_d, adjacent_stop_d)
|
||||
approach_d += offset_m
|
||||
if approach_d > MPC_HANDOFF_M:
|
||||
targets.append(math.sqrt(2.0 * FORCE_STOP_APPROACH_DECEL * (approach_d - MPC_HANDOFF_M)))
|
||||
if approach_d > force_stop_handoff_m:
|
||||
targets.append(math.sqrt(2.0 * FORCE_STOP_APPROACH_DECEL * (approach_d - force_stop_handoff_m)))
|
||||
|
||||
v_cruise = min(targets)
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ Quick start:
|
||||
Set `BURN_IN_PREVENTION=0` to disable it or tune it with `BURN_IN_SHIFT_PIXELS`, `BURN_IN_SHIFT_INTERVAL`, and
|
||||
`BURN_IN_SHIFT_TRANSITION_SECONDS`. TICI/TIZI shift the completed frame through the offscreen presentation path;
|
||||
MICI uses direct shifting by default. Setting `WHITE_LUMINANCE_CAP` below `1.0` also enables the offscreen presentation path.
|
||||
* the C4 UI uses copied camera textures by default to avoid sampling camerad's reusable EGL buffers; set `MICI_FORCE_TEXTURE_CAMERA=0` to re-enable EGL for diagnostics
|
||||
* set `MICI_FORCE_RENDER_TEXTURE=1` to force the C4 UI through the offscreen presentation path for diagnostics
|
||||
* set `GRID=50` to show a 50-pixel alignment grid overlay
|
||||
* set `MAGIC_DEBUG=1` to show every dropped frames (only on device)
|
||||
|
||||
Reference in New Issue
Block a user