# car_usb_cam YAML Adaptation Implementation Plan

> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.

**Goal:** Make the bird's-eye node accept its image topic and expected input size from YAML, consume the already-rectified output of the current `car_usb_cam`, and document the complete workflow.

**Architecture:** `car_usb_cam` remains an independent upstream package and is included through its public `camera_config` launch argument without modification. `origincar_birdseye` loads all of its own parameters from `birdseye_defaults.yaml`, validates every received frame against the configured calibration size, and optionally skips local undistortion when the upstream image is already rectified.

**Tech Stack:** ROS 2 Humble, C++17, OpenCV, ROS 2 Python launch, YAML, ament/GoogleTest.

---

### Task 1: Testable input-size validation

**Files:**
- Create: `include/origincar_birdseye/image_validation.hpp`
- Modify: `test/test_ground_projection.cpp`

- [ ] Add tests showing that an exact configured size succeeds and a mismatched frame returns a diagnostic containing both sizes.
- [ ] Run `colcon test --packages-select origincar_birdseye` and verify the new test fails before implementation.
- [ ] Add the minimal pure validation helper.
- [ ] Rebuild and verify the unit test passes.

### Task 2: YAML-controlled runtime input

**Files:**
- Modify: `src/birdseye_node.cpp`
- Modify: `config/birdseye_defaults.yaml`

- [ ] Declare `input_width`, `input_height`, and `input_is_rectified` as node parameters.
- [ ] Reject non-positive configured dimensions during construction.
- [ ] Store the configured dimensions in `CameraIntrinsics` and reject mismatching frames with a throttled error before projection.
- [ ] Skip `cv::undistort` when `input_is_rectified: true`; retain the optional path for a raw camera source.
- [ ] Configure the current `car_usb_cam` defaults as `/image`, `1280`, `720`, and already rectified.

### Task 3: Current car_usb_cam launch compatibility

**Files:**
- Modify: `launch/car_usb_birdseye.launch.py`
- Modify: `launch/birdseye_runtime.launch.py`

- [ ] Replace obsolete `usb_*` launch arguments with the current single `camera_config` argument.
- [ ] Add `camera_config` and `birdseye_config` launch arguments with package defaults.
- [ ] Include `car_usb_cam/launch/hobot_usb_cam.launch.py` unchanged and pass only `camera_config`.
- [ ] Start the bird's-eye node using `birdseye_config`; do not modify or remap the camera package internally.
- [ ] Verify both launch files are importable and expose the documented arguments.

### Task 4: Package tutorial

**Files:**
- Create: `README.md`

- [ ] Document architecture, current car configuration, prerequisites, build commands, offline validation, bird's-eye-only launch, joint real-camera launch, and YAML overrides.
- [ ] Document every input/output topic and parameter, vehicle/world coordinate behavior, upstream rectification, calibration-size constraints, checkerboard-to-runtime workflow, and troubleshooting.
- [ ] State explicitly that `car_usb_cam` is not modified and its camera YAML/calibration remain authoritative for capture and upstream rectification.

### Task 5: Local and robot verification

**Files:**
- Verify only; no planned source additions.

- [ ] Build the package in `/home/hikos/Yiliao2026` and run all package tests with full failure output.
- [ ] Run the synthetic offline pipeline and verify `/birdseye/vehicle/image` is published at the configured output size.
- [ ] Copy only `origincar_birdseye` to `/home/sunrise/yiliao_ws/src/`, preserving `car_usb_cam`.
- [ ] Build and test on RDKx5.
- [ ] Start the existing real camera through the joint launch, verify the current MJPEG `/image` is `sensor_msgs/msg/CompressedImage` decoded as `1280x720`, verify bird's-eye output, then stop the launch and confirm `/dev/video0` is released.

### Task 6: MJPEG message compatibility discovered on the vehicle

**Files:**
- Modify: `include/origincar_birdseye/image_validation.hpp`
- Modify: `src/birdseye_node.cpp`
- Modify: `config/birdseye_defaults.yaml`
- Create: `config/offline_birdseye_overrides.yaml`
- Modify: `README.md`

- [ ] Test and validate the YAML value `image_message_type` as `raw` or `compressed`.
- [ ] Subscribe to `sensor_msgs/msg/CompressedImage` for the current MJPEG camera configuration and decode it before the common processing path.
- [ ] Retain configurable `sensor_msgs/msg/Image` support for raw publishers.
- [ ] Verify the decoded frame is `1280x720` and the vehicle output is published on the robot.
