Reachy Robot Camera Not Detected: Diagnosing USB Enumeration, Kernel Drivers, and ROS

Start with what lsusb is actually telling you

The cameras in Reachy 1 connect to the onboard computer over internal USB. That detail matters because it means the same diagnostic tools used for any Linux webcam apply here — but the order you work through them changes everything.

Blank output from lsusb is not a driver problem. It means the USB bus never enumerated the device. No modprobe command, no udev rule, and no ROS service restart will help at this stage because all of those operate above the physical layer. The fault is upstream of all software.

Compare this to a different failure mode: lsusb shows the camera, but /dev/video* is empty. That is a driver problem — the kernel saw the device but never attached the right module to it. The two situations look similar on the surface and need completely different fixes. Knowing which one you’re in is the whole game.

Layer 1: catch USB enumeration in real time

Open a terminal and run:

dmesg -w

Leave it running and power-cycle the robot’s head — or just the USB hub inside the head if you can reach it. Watch the output. A working camera produces a burst of lines like this when it enumerates:

usb 1-1.2: new high-speed USB device number 4 using xhci_hcd
usb 1-1.2: New USB device found, idVendor=XXXX, idProduct=XXXX
uvcvideo: Found UVC 1.00 device ...

Dead silence across a full power cycle means the physical layer has failed — the USB controller got no signal. An enumeration attempt that immediately errors out with unable to enumerate USB device points to a power or signal integrity problem on the internal cable, often from a partial connection rather than a complete break.

Also pull the boot-time log to catch anything that happened before you connected the monitor:

journalctl -b | grep -iE 'video|uvc|camera'

Layer 2: the uvcvideo kernel module

This layer only matters if dmesg showed the device appearing on USB but no /dev/video* node was created. Check whether the driver is loaded:

lsmod | grep uvcvideo

Nothing returned? Load it manually:

sudo modprobe uvcvideo
dmesg | tail -20

On Ubuntu-based systems, the module lives in the linux-modules-extra package. If modprobe fails with a not-found error, that package may be missing or mismatched to the running kernel version. One more thing to check:

grep -r uvcvideo /etc/modprobe.d/

A blacklist line in any of those files will silently block the driver from loading even when the hardware is detected. This catches a surprising number of stubborn cases.

Layer 3: v4l2-ctl for a cleaner device view

Install v4l-utils if it isn’t present, then run:

v4l2-ctl --list-devices

This maps /dev/videoX nodes to human-readable device names, which is much more useful than ls /dev/video* alone. Reachy 1 has two cameras, so a healthy system shows two separate entries. One missing means one camera has a connection problem. Both missing alongside a silent lsusb sends you straight back to the physical layer.

You can also probe a specific node directly:

v4l2-ctl --device=/dev/video0 --all

This prints format capabilities and confirms the device actually responds on open — useful when a node exists but throws errors when any application tries to use it.

Layer 4: the ROS camera controller

Reachy 1 runs its cameras through a ROS controller that sits on top of the V4L2 layer. If the USB devices appear correctly but the cameras are still unreachable through the Reachy SDK, the service may not have started cleanly. Stop it first so you can launch the camera stack in isolation:

systemctl --user stop reachy_sdk_server.service

Then launch the camera controller directly and watch for errors:

ros2 launch camera_controllers camera_controllers.launch.py

If that completes without errors, confirm the topics are publishing:

ros2 topic list | grep image

You should see /left_image/image_raw/compressed and /right_image/image_raw/compressed with active publishers. Both topics live means the camera stack is healthy and the original failure was a startup race in the main service. A simple restart usually clears it.

When everything points to hardware

Silent dmesg across a clean power cycle almost always means a physical fault. Three most common culprits on Reachy 1:

  • A loose USB connector on the camera module or internal USB hub. The connectors inside the head can work themselves loose over time from repeated neck movement — no impact required.
  • A kinked or damaged cable near a flex point in the neck assembly. Look for tight bends or areas where the cable was pinched during a previous movement.
  • A failed camera module. Less common than a loose connector, but possible after physical impact or over time.

Before opening the head, check which revision of Reachy 1 you have. The internal layout changed across units produced in different years, and the path to the USB hub varies. Pollen Robotics support can run a remote diagnostic session and confirm whether the unit needs a module replacement — worth a quick email before disassembling anything if the internal routing is unfamiliar.

Diagnostic commands, in order

# 1. Watch USB enumeration in real time (power-cycle the head while this runs)
dmesg -w

# 2. Check boot log for camera activity
journalctl -b | grep -iE 'video|uvc|camera'

# 3. Confirm USB presence
lsusb

# 4. Check for /dev nodes
ls /dev/video*

# 5. Get full device names
v4l2-ctl --list-devices

# 6. Load UVC driver if missing
lsmod | grep uvcvideo
sudo modprobe uvcvideo

# 7. Test ROS camera layer (after stopping main service)
systemctl --user stop reachy_sdk_server.service
ros2 launch camera_controllers camera_controllers.launch.py
ros2 topic list | grep image

Sources

Similar Posts