discover a camera when none is configured
validate / validate (push) Successful in 59m14s

CAPTURE_PATH defaulted to index 0, which is a coin flip on a machine with one
camera. A UVC camera exposes a second device node for its metadata stream --
/dev/video1 beside /dev/video0 -- and that node opens happily and never yields
an image, so the lowest device number is wrong about as often as it is right.

With neither CAMERA_ID nor CAPTURE_PATH set, the node now opens each
/dev/video* in numeric order and keeps the first that actually delivers a
frame. Reading one is the test, because opening is not evidence.

Discovery finding nothing falls back to index 0 rather than raising, which
keeps the failure in one place: the first read, where CI publishes a
placeholder and a normal run raises with a message naming the device.

CAMERA_ID is still worth preferring on a robot. Neither an index nor discovery
order is stable across reboots or across which port a camera is in; a by-id
name is.
This commit is contained in:
2026-09-15 06:16:14 -03:00
parent dc700106c5
commit 7628a8515b
5 changed files with 117 additions and 12 deletions
+9 -3
View File
@@ -74,7 +74,7 @@ compressed encoding, `width` and `height` are the image's dimensions, not the le
| Variable | Default | Meaning |
|---|---|---|
| `CAMERA_ID` | unset | Substring of a `/dev/v4l/by-id/` entry. Wins over `CAPTURE_PATH`. |
| `CAPTURE_PATH` | `0` | Device path (`/dev/video1`) or index. A numeric string is an index. |
| `CAPTURE_PATH` | auto | Device path (`/dev/video1`) or index. A numeric string is an index. |
| `IMAGE_WIDTH` | native | Requested capture width; frames are also resized to it. |
| `IMAGE_HEIGHT` | native | Requested capture height; frames are also resized to it. |
| `ENCODING` | `bgr8` | One of `bgr8`, `rgb8`, `yuv420`, `jpeg`/`jpg`/`jpe`, `png`, `bmp`, `webp`. |
@@ -85,8 +85,14 @@ compressed encoding, `width` and `height` are the image's dimensions, not the le
Resizing only happens when both `IMAGE_WIDTH` and `IMAGE_HEIGHT` are set.
`CAMERA_ID` is worth preferring on a robot: a by-id name is stable across reboots and
across which USB port the camera is in, and an index is not.
With neither `CAMERA_ID` nor `CAPTURE_PATH` set, the node opens the first `/dev/video*`
that actually delivers a frame. Merely opening is not enough to go on: a UVC camera
exposes a second node for its metadata stream — `/dev/video1` beside `/dev/video0` on a
one-camera machine — which opens happily and never yields an image, so the lowest device
number is wrong about as often as it is right.
`CAMERA_ID` is worth preferring on a robot anyway: a by-id name is stable across reboots
and across which USB port the camera is in, and neither an index nor discovery order is.
`CI=true` makes a failed read publish a labelled black frame instead of raising, which
is what lets the dataflow run on a machine with no camera. It is not a configuration