#!/usr/bin/env python3 import threading import os from collections import namedtuple from msgq.visionipc import VisionIpcServer, VisionStreamType from cereal import messaging from openpilot.tools.webcam.camera import Camera from openpilot.common.realtime import Ratekeeper DUAL_CAM = os.getenv("DUAL_CAMERA") CameraType = namedtuple("CameraType", ["msg_name", "stream_type", "cam_id"]) CAMERAS = [ CameraType("roadCameraState", VisionStreamType.VISION_STREAM_ROAD, os.getenv("CAMERA_ROAD_ID", "0")), CameraType("driverCameraState", VisionStreamType.VISION_STREAM_DRIVER, os.getenv("CAMERA_DRIVER_ID", "1")), ] if DUAL_CAM: CAMERAS.append(CameraType("wideRoadCameraState", VisionStreamType.VISION_STREAM_WIDE_ROAD, DUAL_CAM)) class Camerad: def __init__(self): self.pm = messaging.PubMaster([c.msg_name for c in CAMERAS]) self.vipc_server = VisionIpcServer("camerad") self.cameras = [] for c in CAMERAS: cam = Camera(c.msg_name, c.stream_type, c.cam_id) assert cam.cap.isOpened(), f"Can't find camera {c}" self.cameras.append(cam) self.vipc_server.create_buffers(c.stream_type, 20, False, cam.W, cam.H) self.vipc_server.start_listener() def _send_yuv(self, yuv, frame_id, pub_type, yuv_type): eof = int(frame_id * 0.05 * 1e9) self.vipc_server.send(yuv_type, yuv, frame_id, eof, eof) dat = messaging.new_message(pub_type, valid=True) msg = { "frameId": frame_id, "transform": [1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0] } setattr(dat, pub_type, msg) self.pm.send(pub_type, dat) def camera_runner(self, cam): rk = Ratekeeper(20, None) while cam.cap.isOpened(): for yuv in cam.read_frames(): self._send_yuv(yuv, cam.cur_frame_id, cam.cam_type_state, cam.stream_type) cam.cur_frame_id += 1 rk.keep_time() def run(self): threads = [] for cam in self.cameras: cam_thread = threading.Thread(target=self.camera_runner, args=(cam,)) cam_thread.start() threads.append(cam_thread) for t in threads: t.join() def main(): camerad = Camerad() camerad.run() if __name__ == "__main__": main()