camera names that make sense (#38585)

This commit is contained in:
Adeeb Shihadeh
2026-08-08 09:44:21 -07:00
committed by GitHub
parent 9738db0e39
commit fedea9fe8d
92 changed files with 502 additions and 496 deletions
@@ -234,11 +234,11 @@ void CameraState::sendState() {
framed.setSensor(camera.sensor->image_sensor);
// Log raw frames for road camera
if (env_log_raw_frames && camera.cc.stream_type == VISION_STREAM_ROAD && meta.frame_id % 100 == 5) { // no overlap with qlog decimation
if (env_log_raw_frames && camera.cc.stream_type == VISION_STREAM_NARROW_ROAD && meta.frame_id % 100 == 5) { // no overlap with qlog decimation
framed.setImage(get_raw_frame_image(&camera.buf));
}
set_camera_exposure(calculate_exposure_value(&camera.buf, ae_xywh, 2, camera.cc.stream_type != VISION_STREAM_DRIVER ? 2 : 4));
set_camera_exposure(calculate_exposure_value(&camera.buf, ae_xywh, 2, camera.cc.stream_type != VISION_STREAM_CABIN ? 2 : 4));
// Send the message
pm->send(camera.cc.publish_name, msg);
+9 -9
View File
@@ -44,12 +44,12 @@ const CameraConfig WIDE_ROAD_CAMERA_CONFIG = {
.staggered_sof = false,
};
const CameraConfig ROAD_CAMERA_CONFIG = {
const CameraConfig NARROW_ROAD_CAMERA_CONFIG = {
.camera_num = 1,
.stream_type = VISION_STREAM_ROAD,
.stream_type = VISION_STREAM_NARROW_ROAD,
.focal_len = 8.0,
.publish_name = "roadCameraState",
.init_camera_state = &cereal::Event::Builder::initRoadCameraState,
.publish_name = "narrowRoadCameraState",
.init_camera_state = &cereal::Event::Builder::initNarrowRoadCameraState,
.enabled = !getenv("DISABLE_ROAD"),
.phy = CAM_ISP_IFE_IN_RES_PHY_1,
.vignetting_correction = true,
@@ -57,12 +57,12 @@ const CameraConfig ROAD_CAMERA_CONFIG = {
.staggered_sof = false,
};
const CameraConfig DRIVER_CAMERA_CONFIG = {
const CameraConfig CABIN_CAMERA_CONFIG = {
.camera_num = 2,
.stream_type = VISION_STREAM_DRIVER,
.stream_type = VISION_STREAM_CABIN,
.focal_len = 1.71,
.publish_name = "driverCameraState",
.init_camera_state = &cereal::Event::Builder::initDriverCameraState,
.publish_name = "cabinCameraState",
.init_camera_state = &cereal::Event::Builder::initCabinCameraState,
.enabled = !getenv("DISABLE_DRIVER"),
.phy = CAM_ISP_IFE_IN_RES_PHY_2,
.vignetting_correction = false,
@@ -70,4 +70,4 @@ const CameraConfig DRIVER_CAMERA_CONFIG = {
.staggered_sof = true,
};
const CameraConfig ALL_CAMERA_CONFIGS[] = {WIDE_ROAD_CAMERA_CONFIG, ROAD_CAMERA_CONFIG, DRIVER_CAMERA_CONFIG};
const CameraConfig ALL_CAMERA_CONFIGS[] = {WIDE_ROAD_CAMERA_CONFIG, NARROW_ROAD_CAMERA_CONFIG, CABIN_CAMERA_CONFIG};
+3 -3
View File
@@ -9,8 +9,8 @@ from openpilot.common.realtime import DT_MDL
VISION_STREAMS = {
"roadCameraState": VisionStreamType.VISION_STREAM_ROAD,
"driverCameraState": VisionStreamType.VISION_STREAM_DRIVER,
"narrowRoadCameraState": VisionStreamType.VISION_STREAM_NARROW_ROAD,
"cabinCameraState": VisionStreamType.VISION_STREAM_CABIN,
"wideRoadCameraState": VisionStreamType.VISION_STREAM_WIDE_ROAD,
}
@@ -45,7 +45,7 @@ def extract_image(buf):
return yuv_to_rgb(y, u, v)
def get_snapshots(frame="roadCameraState", front_frame="driverCameraState"):
def get_snapshots(frame="narrowRoadCameraState", front_frame="cabinCameraState"):
sockets = [s for s in (frame, front_frame) if s is not None]
sm = messaging.SubMaster(sockets)
vipc_clients = {s: VisionIpcClient("camerad", VISION_STREAMS[s], True) for s in sockets}
@@ -13,7 +13,7 @@ from openpilot.system.camerad.snapshot import get_snapshots
from openpilot.selfdrive.test.helpers import collect_logs, log_collector, processes_context
TEST_TIMESPAN = 10
CAMERAS = ('roadCameraState', 'driverCameraState', 'wideRoadCameraState')
CAMERAS = ('narrowRoadCameraState', 'cabinCameraState', 'wideRoadCameraState')
EXPOSURE_STABLE_COUNT = 3
EXPOSURE_RANGE = (0.15, 0.35)
MAX_TEST_TIME = 25
@@ -49,7 +49,7 @@ def _camera_session():
exposure = {cam: [] for cam in CAMERAS}
start = time.monotonic()
while time.monotonic() - start < MAX_TEST_TIME:
rpic, dpic = get_snapshots(frame="roadCameraState", front_frame="driverCameraState")
rpic, dpic = get_snapshots(frame="narrowRoadCameraState", front_frame="cabinCameraState")
wpic, _ = get_snapshots(frame="wideRoadCameraState")
for cam, img in zip(CAMERAS, [rpic, dpic, wpic], strict=True):
exposure[cam].append(_exposure_stats(img))
@@ -106,8 +106,8 @@ class TestCamerad(OpenpilotTestCase):
assert set(np.diff(self.logs[c]['frameId'])) == {1, }, f"{c} has frame skips"
def test_frame_sync(self):
SYNCED_CAMS = ('roadCameraState', 'wideRoadCameraState')
n = range(len(self.logs['roadCameraState']['t'][:-10]))
SYNCED_CAMS = ('narrowRoadCameraState', 'wideRoadCameraState')
n = range(len(self.logs['narrowRoadCameraState']['t'][:-10]))
frame_ids = {i: [self.logs[cam]['frameId'][i] for cam in CAMERAS] for i in n}
assert all(len(set(v)) == 1 for v in frame_ids.values()), "frame IDs not aligned"
@@ -118,10 +118,10 @@ class TestCamerad(OpenpilotTestCase):
laggy_frames = {k: v for k, v in diffs.items() if v > 1.1}
assert len(laggy_frames) == 0, f"Frames not synced properly: {laggy_frames=}"
# driver camera should be staggered ~25ms from road camera
# cabin camera should be staggered ~25ms from road camera
for i in n:
offset_ms = abs(self.logs['driverCameraState']['timestampSof'][i] - self.logs['roadCameraState']['timestampSof'][i]) / 1e6
assert 20 < offset_ms < 30, f"driver camera stagger out of range at frame {i}: {offset_ms:.1f}ms (expected ~25ms)"
offset_ms = abs(self.logs['cabinCameraState']['timestampSof'][i] - self.logs['narrowRoadCameraState']['timestampSof'][i]) / 1e6
assert 20 < offset_ms < 30, f"cabin camera stagger out of range at frame {i}: {offset_ms:.1f}ms (expected ~25ms)"
def test_sanity_checks(self):
self._sanity_checks(self.logs)
+3 -3
View File
@@ -11,19 +11,19 @@ from openpilot.cereal import messaging
from openpilot.system.camerad.webcam.camera import Camera
from openpilot.common.realtime import Ratekeeper
ROAD_CAM = os.getenv("ROAD_CAM", "0")
NARROW_ROAD_CAM = os.getenv("NARROW_ROAD_CAM", os.getenv("ROAD_CAM", "0"))
WIDE_CAM = os.getenv("WIDE_CAM")
DRIVER_CAM = os.getenv("DRIVER_CAM")
CameraType = namedtuple("CameraType", ["msg_name", "stream_type", "cam_id"])
CAMERAS = [
CameraType("roadCameraState", VisionStreamType.VISION_STREAM_ROAD, ROAD_CAM)
CameraType("narrowRoadCameraState", VisionStreamType.VISION_STREAM_NARROW_ROAD, NARROW_ROAD_CAM)
]
if WIDE_CAM:
CAMERAS.append(CameraType("wideRoadCameraState", VisionStreamType.VISION_STREAM_WIDE_ROAD, WIDE_CAM))
if DRIVER_CAM:
CAMERAS.append(CameraType("driverCameraState", VisionStreamType.VISION_STREAM_DRIVER, DRIVER_CAM))
CAMERAS.append(CameraType("cabinCameraState", VisionStreamType.VISION_STREAM_CABIN, DRIVER_CAM))
class Camerad:
def __init__(self):
+2 -2
View File
@@ -29,11 +29,11 @@ constexpr int CLIP_FPS = 20;
constexpr double PARALLEL_CLIP_MIN_DURATION = 2 * SEGMENT_DURATION;
const EncoderInfo clip_encoder_info = {
.publish_name = "livestreamRoadEncodeData",
.publish_name = "livestreamNarrowRoadEncodeData",
.record = false,
.fps = CLIP_FPS,
.get_settings = [](int) { return EncoderSettings::StreamEncoderSettings(); },
INIT_ENCODE_FUNCTIONS(LivestreamRoadEncode),
INIT_ENCODE_FUNCTIONS(LivestreamNarrowRoadEncode),
};
bool open_input(const std::string &path, AVFormatContext **ctx, int *stream_index) {
+27 -27
View File
@@ -96,11 +96,11 @@ public:
};
const EncoderInfo main_road_encoder_info = {
.publish_name = "roadEncodeData",
.publish_name = "narrowRoadEncodeData",
.thumbnail_name = "thumbnail",
.filename = "fcamera.hevc",
.get_settings = [](int in_width){return EncoderSettings::MainEncoderSettings(in_width);},
INIT_ENCODE_FUNCTIONS(RoadEncode),
INIT_ENCODE_FUNCTIONS(NarrowRoadEncode),
};
const EncoderInfo main_wide_road_encoder_info = {
@@ -110,23 +110,23 @@ const EncoderInfo main_wide_road_encoder_info = {
INIT_ENCODE_FUNCTIONS(WideRoadEncode),
};
const EncoderInfo main_driver_encoder_info = {
.publish_name = "driverEncodeData",
const EncoderInfo main_cabin_encoder_info = {
.publish_name = "cabinEncodeData",
.filename = "dcamera.hevc",
.record = Params().getBool("RecordFront"),
.get_settings = [](int in_width){return EncoderSettings::MainEncoderSettings(in_width);},
INIT_ENCODE_FUNCTIONS(DriverEncode),
INIT_ENCODE_FUNCTIONS(CabinEncode),
};
const EncoderInfo stream_road_encoder_info = {
.publish_name = "livestreamRoadEncodeData",
.publish_name = "livestreamNarrowRoadEncodeData",
//.thumbnail_name = "thumbnail",
.record = false,
.is_live = true,
.frame_width = livestream_width(),
.frame_height = livestream_height(),
.get_settings = [](int){return EncoderSettings::StreamEncoderSettings();},
INIT_ENCODE_FUNCTIONS(LivestreamRoadEncode),
INIT_ENCODE_FUNCTIONS(LivestreamNarrowRoadEncode),
};
const EncoderInfo stream_wide_road_encoder_info = {
@@ -139,29 +139,29 @@ const EncoderInfo stream_wide_road_encoder_info = {
INIT_ENCODE_FUNCTIONS(LivestreamWideRoadEncode),
};
const EncoderInfo stream_driver_encoder_info = {
.publish_name = "livestreamDriverEncodeData",
const EncoderInfo stream_cabin_encoder_info = {
.publish_name = "livestreamCabinEncodeData",
.record = false,
.is_live = true,
.frame_width = livestream_width(),
.frame_height = livestream_height(),
.get_settings = [](int){return EncoderSettings::StreamEncoderSettings();},
INIT_ENCODE_FUNCTIONS(LivestreamDriverEncode),
INIT_ENCODE_FUNCTIONS(LivestreamCabinEncode),
};
const EncoderInfo qcam_encoder_info = {
.publish_name = "qRoadEncodeData",
.publish_name = "qNarrowRoadEncodeData",
.filename = "qcamera.ts",
.include_audio = Params().getBool("RecordAudio"),
.frame_width = 526,
.frame_height = 330,
.get_settings = [](int){return EncoderSettings::QcamEncoderSettings();},
INIT_ENCODE_FUNCTIONS(QRoadEncode),
INIT_ENCODE_FUNCTIONS(QNarrowRoadEncode),
};
const LogCameraInfo road_camera_info{
.thread_name = "road_cam_encoder",
.stream_type = VISION_STREAM_ROAD,
const LogCameraInfo narrow_road_camera_info{
.thread_name = "narrow_road_cam_encoder",
.stream_type = VISION_STREAM_NARROW_ROAD,
.encoder_infos = {main_road_encoder_info, qcam_encoder_info}
};
@@ -171,15 +171,15 @@ const LogCameraInfo wide_road_camera_info{
.encoder_infos = {main_wide_road_encoder_info}
};
const LogCameraInfo driver_camera_info{
.thread_name = "driver_cam_encoder",
.stream_type = VISION_STREAM_DRIVER,
.encoder_infos = {main_driver_encoder_info}
const LogCameraInfo cabin_camera_info{
.thread_name = "cabin_cam_encoder",
.stream_type = VISION_STREAM_CABIN,
.encoder_infos = {main_cabin_encoder_info}
};
const LogCameraInfo stream_road_camera_info{
.thread_name = "road_cam_encoder",
.stream_type = VISION_STREAM_ROAD,
.thread_name = "narrow_road_cam_encoder",
.stream_type = VISION_STREAM_NARROW_ROAD,
.encoder_infos = {stream_road_encoder_info},
};
@@ -189,11 +189,11 @@ const LogCameraInfo stream_wide_road_camera_info{
.encoder_infos = {stream_wide_road_encoder_info},
};
const LogCameraInfo stream_driver_camera_info{
.thread_name = "driver_cam_encoder",
.stream_type = VISION_STREAM_DRIVER,
.encoder_infos = {stream_driver_encoder_info},
const LogCameraInfo stream_cabin_camera_info{
.thread_name = "cabin_cam_encoder",
.stream_type = VISION_STREAM_CABIN,
.encoder_infos = {stream_cabin_encoder_info},
};
const LogCameraInfo cameras_logged[] = {road_camera_info, wide_road_camera_info, driver_camera_info};
const LogCameraInfo stream_cameras_logged[] = {stream_road_camera_info, stream_wide_road_camera_info, stream_driver_camera_info};
const LogCameraInfo cameras_logged[] = {narrow_road_camera_info, wide_road_camera_info, cabin_camera_info};
const LogCameraInfo stream_cameras_logged[] = {stream_road_camera_info, stream_wide_road_camera_info, stream_cabin_camera_info};
@@ -22,8 +22,8 @@ SEGMENT_LENGTH = 2
FULL_SIZE = 2507572
def hevc_size(w): return FULL_SIZE // 2 if w <= 1344 else FULL_SIZE
CAMERAS = [
("fcamera.hevc", 20, hevc_size, "roadEncodeIdx"),
("dcamera.hevc", 20, hevc_size, "driverEncodeIdx"),
("fcamera.hevc", 20, hevc_size, "narrowRoadEncodeIdx"),
("dcamera.hevc", 20, hevc_size, "cabinEncodeIdx"),
("ecamera.hevc", 20, hevc_size, "wideRoadEncodeIdx"),
("qcamera.ts", 20, lambda x: 130000, None),
]
@@ -112,12 +112,12 @@ class TestLoggerd(OpenpilotTestCase):
w, h = 320, 240
frame_spec = (w, h, w * h * 3 // 2, w, w * h)
streams = [
(VisionStreamType.VISION_STREAM_ROAD, frame_spec, "roadCameraState"),
(VisionStreamType.VISION_STREAM_DRIVER, frame_spec, "driverCameraState"),
(VisionStreamType.VISION_STREAM_NARROW_ROAD, frame_spec, "narrowRoadCameraState"),
(VisionStreamType.VISION_STREAM_CABIN, frame_spec, "cabinCameraState"),
(VisionStreamType.VISION_STREAM_WIDE_ROAD, frame_spec, "wideRoadCameraState"),
]
sm = messaging.SubMaster(["roadEncodeData"])
sm = messaging.SubMaster(["narrowRoadEncodeData"])
pm = messaging.PubMaster([s for _, _, s in streams] + ["rawAudioData"])
vipc_server = VisionIpcServer("camerad")
for stream_type, frame_spec, _ in streams:
@@ -128,7 +128,7 @@ class TestLoggerd(OpenpilotTestCase):
os.environ["LOGGERD_SEGMENT_LENGTH"] = str(segment_length)
managed_processes["loggerd"].start()
managed_processes["encoderd"].start()
assert pm.wait_for_readers_to_update("roadCameraState", timeout=5)
assert pm.wait_for_readers_to_update("narrowRoadCameraState", timeout=5)
fps = 20
for n in range(1, int(num_segs * segment_length * fps) + 1):
@@ -322,8 +322,8 @@ class TestLoggerd(OpenpilotTestCase):
self._publish_camera_and_audio_messages()
dcamera_hevc_exists = os.path.exists(os.path.join(self._get_latest_log_dir(), 'dcamera.hevc'))
assert dcamera_hevc_exists == record_front
cabin_hevc_exists = os.path.exists(os.path.join(self._get_latest_log_dir(), 'dcamera.hevc'))
assert cabin_hevc_exists == record_front
@parameterized.expand([True, False])
def test_record_audio(self, record_audio):
+2 -2
View File
@@ -32,9 +32,9 @@ class EncodedVideoFrame:
class LiveStreamVideoStreamTrack(TiciVideoStreamTrack):
camera_to_sock_mapping = {
"driver": "livestreamDriverEncodeData",
"driver": "livestreamCabinEncodeData",
"wideRoad": "livestreamWideRoadEncodeData",
"road": "livestreamRoadEncodeData",
"road": "livestreamNarrowRoadEncodeData",
}
def __init__(self, camera_type: str, video_enabled: bool = True):
@@ -65,7 +65,7 @@ class TestStreamSession(OpenpilotTestCase):
mocked_pubmaster.reset_mock()
def test_livestream_track(self, mocker):
fake_msg = messaging.new_message("livestreamDriverEncodeData")
fake_msg = messaging.new_message("livestreamCabinEncodeData")
config = {"receive.return_value": fake_msg.to_bytes()}
mocker.patch("msgq.SubSocket", spec=True, **config)