# Unified USB Camera Launch Design ## Goal Make the camera behavior of `hobot_usb_cam.launch.py` and `hobot_usb_cam_websocket.launch.py` identical. The WebSocket variant must add only the WebSocket service. ## Configuration Add `config/usb_camera.yaml` as the single source of runtime camera parameters: - `video_device`: `/dev/video0` - `image_width`: `1280` - `image_height`: `720` - `framerate`: `30` - `pixel_format`: `mjpeg` - `io_method`: `mmap` - `zero_copy`: `false` - `frame_id`: `default_usb_cam` - `camera_calibration_file_path`: the existing `config/usb_camera_calibration.yaml` The calibration data remains in `usb_camera_calibration.yaml`; it is not mixed with ROS runtime parameters. ## Launch Structure `hobot_usb_cam.launch.py` will: 1. Declare one `camera_config` launch argument whose default is the installed `config/usb_camera.yaml` path. 2. Start the shared-memory environment once. 3. Start one `hobot_usb_cam` node with the YAML file as its parameter source. `hobot_usb_cam_websocket.launch.py` will: 1. Include `hobot_usb_cam.launch.py` without overriding camera parameters. 2. Include the WebSocket launch configured for `/image`, MJPEG input, image-only display, and a 30 FPS output limit. It will not start `hobot_codec`, duplicate the shared-memory launch, or carry camera parameter literals. ## Data Flow Without WebSocket: `/dev/video0 -> hobot_usb_cam -> /image (CompressedImage)` With WebSocket: `/dev/video0 -> hobot_usb_cam -> /image (CompressedImage) -> WebSocket` No RGB conversion or second JPEG encode is performed. ## Validation An automated structural check will verify that: - the YAML contains the required 1280x720, 30 FPS, native MJPEG parameters; - the base launch loads that YAML; - the WebSocket launch includes the base launch; - the WebSocket launch does not define a camera node, codec node, or camera parameter overrides. After building, each launch will be started separately. Both must publish one `sensor_msgs/msg/CompressedImage` topic at approximately 30 FPS with decoded dimensions of 1280x720. Only the WebSocket launch may create the WebSocket node and port 8080 service. ## Operational Notes The two launch files cannot run concurrently because they both own `/dev/video0`. Runtime validation is sequential and stops the first launch before starting the second. Any separately started `usb_cam_node_exe` must also be stopped before validation because V4L2 permits only one active capture owner for this camera.