3D visionTroubleshooting

Depth camera not detected on Jetson: rebuild the SDK cleanly

A depth camera not detected on a Jetson is a backend and version clash: wipe old SDK builds, install 2.50.0 with the RSUSB backend, rebuild wrapper 2.3.2.

LumaSpec Vision10 min read Share on LinkedIn

On this page 9 sections
  1. 01Why does the SDK build succeed but the camera stays undetected?
  2. 02Is the fault in the USB link or in the SDK?
  3. 03What does the group_devices is empty warning mean?
  4. 04Which SDK and wrapper versions belong together?
  5. 05How do I wipe the old builds and install one clean version?
  6. 06Why does the wrapper report one version at build time and another at run time?
  7. 07When should I stop rebuilding and replace the camera?
  8. 08What should I check before the next build?
  9. 09Questions

The camera is plugged in, the SDK compiled without an error, and the viewer still tells you to connect a device — while the ROS wrapper refuses to stream. That is the most common bring-up failure when a stereo or ToF depth camera lands on a Jetson board, and it almost means anything but a dead camera. Two faults stack: several SDK versions installed over each other, and a default USB backend the Tegra kernel cannot serve without a patch. This guide walks the failure in the order you meet it — USB link, enumeration log, version pairing, clean rebuild — and ends with depth and color streaming in RViz. The worked case sits on Ubuntu 18 with the 4.9.140-tegra kernel; the method holds on any ARM board whose kernel the SDK patch will not take.

Why does the SDK build succeed but the camera stays undetected?

Because compiling and enumerating are different jobs: the default backend reaches the camera through the kernel's UVC driver, which the 4.9.140-tegra kernel only supports after a patch — and layered installs from earlier versions stop the loader from using the library you just built.

A from-source SDK build ends with an install step that copies libraries into the same system paths every time. Build 2.38.0, then 2.48.0, then 2.49.0, then 2.50.0, and the board carries fragments of all four. The viewer and the wrapper link whichever library the loader finds first, so a clean compile of 2.50.0 can still run against 2.49.0 leftovers. That is how one version out of four "works" in the viewer while the rest report no device: you were never testing the version you thought. The discipline is the same one behind pinning one library version across a whole build and behind fixing a wrong driver family for the camera — one SDK, everywhere.

The second fault is the backend. The default backend talks to the camera through the kernel's UVC driver and expects the SDK's kernel patch to be applied first. On Tegra kernels that patch is the step that fails or gets skipped, and without it the driver never claims the camera's video nodes — so no SDK version installed that way will enumerate the camera, however cleanly it compiled.

Check lsusb first: if the camera is listed while the SDK's enumeration tool answers "No device detected", the USB layer is healthy and the fault sits in the SDK backend — one command splits the problem in half.

Keep that dividing line strict. With the camera visible in lsusb, stop swapping cables and ports; the transport is up and the SDK simply cannot reach it, which is the case the RSUSB backend fixes. With nothing in lsusb at all, work the hardware first: another port, another cable, then the board. After a recovery reflash, board-level USB can stay down while everything else boots — USB devices missing after a JP6.0 recovery flash covers that path. A camera that appears and drops as you move between ports points at USB 3.2 signal integrity on the carrier board, not at software. The general Linux pattern — device present to the bus, invisible to the SDK — is laid out in a USB camera that lsusb sees but the vision SDK does not.

What does the group_devices is empty warning mean?

It is the signature of a default-backend build on an unpatched Tegra kernel: the SDK's device factory sees USB traffic but cannot group the camera's several USB nodes into one device, so it gives up and reports no camera.

A stereo depth camera is not one USB device to the host. It enumerates as several functions — depth, color and motion among them — and the SDK's factory must group those nodes into a single camera object before anything streams. When the backend cannot reach the nodes, the grouping set comes back empty: the log repeats a warning ending in group_devices is empty a few times, then the viewer asks you to plug in a camera. The enumeration tool answers "No device detected. Is it plugged in?" at the same moment. Paired with a camera that lsusb lists, the diagnosis is closed — the transport is fine, the driver link is missing. Do not chase cables at this point; rebuild the SDK with the RSUSB backend.

Which SDK and wrapper versions belong together?

On a Jetson, pin SDK 2.50.0 with ROS wrapper 2.3.2 — and know that SDK 2.49.0 has no published wrapper at all, so that version can run the viewer but can never drive the ROS stack.

Wrapper releases are built against specific SDK versions, and the launch log says so plainly when the pair is wrong: it reports the wrapper built with one version while the board now runs another. The pairs that matter:

SDK on the board Wrapper to build Result
2.50.0 2.3.2 The pair to install; enumerates once the RSUSB backend is in
2.49.0 none published Viewer may detect the camera; no wrapper release exists
2.48.0 2.3.1 The fallback pair, one generation back

Versions older than these — 2.38.0 among them — belong to stacks a further generation back; reach for them only when an existing machine demands exactly that build.

Worked example — the board whose launch log reads built with 2.49.0, running with 2.50.0.

  • Installed: SDK 2.49.0, the only version the viewer detects; wrapper 2.3.2, compiled earlier against 2.49.0.
  • Rule: wrapper 2.3.2 pairs with SDK 2.50.0. Wrapper releases for 2.49.0: zero. The installed pair is invalid by one SDK step.
  • Option A: move the SDK up one step, 2.49.0 → 2.50.0, keep wrapper 2.3.2, rebuild the wrapper once.
  • Option B: move the SDK down one step, 2.49.0 → 2.48.0, and the wrapper down one step, 2.3.2 → 2.3.1 — two version changes, two rebuilds.
  • Decision: Option A. One rebuild fewer, the newer SDK, and 2.50.0 is the version that enumerates once the RSUSB backend is enabled.

The same one-version rule runs between camera firmware and SDK headers — read 3D camera header and firmware alignment before you upgrade either end.

How do I wipe the old builds and install one clean version?

Uninstall every earlier SDK copy, then build 2.50.0 from source once with the RSUSB backend and run the SDK's libuvc backend installation script — a board carrying one SDK version beats any number of layered reinstalls.

  1. Uninstall each old version from its own build tree, newest first; where a tree is gone, delete the libraries and headers it left in the system paths by hand.
  2. Refresh the linker cache and confirm exactly one copy of the SDK library remains on the board.
  3. Confirm lsusb still lists the camera, so hardware stays ruled out while you change software.
  4. Configure the 2.50.0 source build with the RSUSB backend option — the libuvc route, no kernel patch — then build and install.
  5. Run the SDK's libuvc backend installation script from the source tree so user-space USB access and device permissions are set.
  6. Prove enumeration before ROS: the SDK's enumeration tool prints the camera with its serial number, and the viewer opens depth and color streams.

On Tegra kernels this is the road that works when the kernel-patch route fails; when a depth camera kernel patch fails, and how to avoid it covers the other road and its failure modes.

Why does the wrapper report one version at build time and another at run time?

Because the wrapper was compiled against the headers of the previous SDK but links, at launch, the library now on the board — after any SDK change the wrapper must be rebuilt in the catkin workspace, not just relaunched.

That mismatch line in the launch log is not advisory; it names the fault. Clean the wrapper's build products out of the catkin workspace, run catkin_make again so the wrapper compiles against the new headers, then relaunch. Two checks close it out: the launch log no longer prints a built-with/running-with pair, and the depth and color topics publish — open RViz and confirm both render. The launch may still print control_transfer lines once the streams are live; with topics publishing they are noise, safe to leave.

When should I stop rebuilding and replace the camera?

Stop when the SDK, not the camera, is the dead end — when no version both enumerates on your kernel and has a matching wrapper, or the stack is too old to build on current boards — and move to a depth sensor with a maintained stack.

If the only SDK that talks to your camera is a 2.38.0-era release, you are maintaining an abandoned stack; testing a legacy depth camera against modern Linux shows how to make that call once, honestly. For the replacement, the decision splits by job: a robot cell or inline station takes a purpose-built 3D sensor, while an embedded product you integrate yourself takes a board-level module you can design in.

For the station, three sensor families cover most jobs — a laser-galvanometer stereo camera such as the MV-DLS300P-04, projected structured light like the MV-DPS200P-02, or a ToF unit such as the MV-DT01WMU — all in 3D sensors. For the embedded build, the LS-BCM-0043 is a binocular USB3 board module at 1.3 MP (1280 x 1024 @ 123FPS) with an M12 mount, from board-level cameras.

3D sensorsHikrobot MV-DLS300P-04 Laser galvanometer stereo cameraMV-DLS300P-04
Type
Stereo / structured light
$16,579.00 · quotedView and quote
Board-level camerasBinocular camera / module, 1.3 MP, USB3, Colour/Mono, 1280 x 1024 @ 123FPS resolution (LS-BCM-0043)LS-BCM-0043
Sensor format
1/2"
Lens mount
M12
$179.00View part

Set the three sensor types side by side before you shortlist one:

Specification MV-DLS300P-04 MV-DPS200P-02 MV-DT01WMU
Near field of view 280 mm × 220 mm @ 400 mm 180 mm × 160 mm @ 250 mm –
Typical field of view 480 mm × 320 mm @ 600 mm – 800 mm × 500 mm @ 0.5 m
Far field of view 620 mm × 440 mm @ 800 mm 420 mm × 320 mm @ 500 mm –
Clearance distance (CD) 400 mm 250 mm –
Measurement range (MR) 400 mm 250 mm –
Repeatability (Z-axis) 0.03 mm @ 600 mm 0.02 mm @ 300 mm ±(10+0.5%depth1)mm
VDI/VDE accuracy 0.05 mm @ 600 mm 0.03 mm @ 300 mm –
Resolution 3200 × 1944 @ RGB image; 1632 × 1080 @ depth map 3200 × 1944 @ RGB image; 1632 × 1264 @ depth map Depth map: 640 × 480 @ 30 fps; RGB image: 1280 × 1024 @ 30 fps
Acquisition time 0.4~0.9 s 0.2 ~ 0.7 s –
Image output latency 0.8~1.5 s 0.5 ~ 1.2 s 133 ms
Data type Raw image (mono + color), Depth map, RGB-D image Raw image (mono + color), Depth map, RGB-D image Intensity image, Color image, Depth map
Data interface Gigabit Ethernet (1000 Mbit/s) Gigabit Ethernet (1000 Mbit/s) USB3.0
Price $16,579.00 · quoted $8,829.00 · quoted Price on request

Values as printed in each product's data sheet; open a part for its drawing and full specifications.

Once enumeration is solved, the next fight on an embedded board is usually throughput — frame drops on embedded boards and how to isolate them is the next read. Start the replacement in the camera finder or the system configurator, and if a clean single-version RSUSB build still fights you, send the launch log to our applications team through the contact page.

What should I check before the next build?

Run this list before you compile anything: it catches the two real causes — mixed SDK versions and the wrong backend — while they still cost you minutes instead of a day.

  • One SDK version on the board: 2.50.0, with nothing left from 2.38.0, 2.48.0 or 2.49.0.
  • Backend chosen for the kernel: RSUSB on Tegra; the kernel patch only when the default backend is mandatory.
  • Wrapper pair matches the table: 2.3.2 with 2.50.0, or 2.3.1 with 2.48.0.
  • lsusb lists the camera before you open any viewer.
  • The enumeration tool prints a serial number before you launch ROS.
  • The wrapper is rebuilt in the catkin workspace after every SDK change.
  • Depth and color topics confirmed in RViz; only then are control_transfer lines ignorable.

Questions

Can I leave an older SDK installed and build the new one over it?

No. Every version installs libraries into the same paths, and the loader will link the viewer or wrapper against whichever copy it finds first. That is exactly what produces a launch log that says built with one version and running with another. Uninstall each earlier version from its own build tree before you compile 2.50.0, then refresh the linker cache so only one library remains on the board.

What does it mean when lsusb lists the camera but the SDK finds nothing?

The USB transport is healthy and the fault sits in the SDK's device access layer — the precise case the RSUSB backend fixes. Treat lsusb visibility as the dividing line: with the camera listed, stop swapping cables and ports and rebuild the SDK with the RSUSB backend instead. If lsusb shows nothing at all, work the hardware first: port, cable, then the board's own USB state.

Which wrapper version pairs with which SDK version?

Wrapper 2.3.2 pairs with SDK 2.50.0, and wrapper 2.3.1 pairs with SDK 2.48.0. No wrapper release exists for SDK 2.49.0, so that version can run the viewer but can never drive the ROS stack. If something pins you below 2.50.0, step the whole pair down together to 2.48.0 with wrapper 2.3.1 rather than mixing generations.

Are the control_transfer warnings after launch a fault I must fix?

Not if the streams are alive. Once the wrapper publishes its depth and color topics and RViz renders both, the control_transfer lines in the launch output are noise from control queries the backend answers in user space. Confirm the topics publish, then leave the warnings alone. If the topics never appear, treat the launch as failed and go back to the enumeration checks.

Do I need to patch the kernel at all with the RSUSB build?

No — avoiding that patch is the point of the route. The RSUSB build reaches the camera through libuvc in user space, and the SDK's libuvc backend installation script sets up the access permissions during install. Patch the kernel's UVC driver only if you must run the default backend, and on Tegra kernels that patch is exactly the step that tends to fail.