Problem knowing which RGB cameras map to which Astra Pro devices

I have two astra pro devices connected to my linux laptop. Given that the OpenNI driver for the Astra pro does not yet stream RGB with the depth data, I have to capture the RGB separately through opencv. Unfortunately, this leads me to a predicament. I can connect to “device/sensor0” or “device/sensor1” using the astra sdk, but is there any way I can get the usb ID (or something) that can give me hints about mapping my RGB cameras to my depth cameras? Especially on my laptop, I have 3 total RGB cams, only 2 of which come with the astra pro sensors.

Anything helps!

I think I have a workaround. If openni is used directly, the Uris can be listed using the below.

openni::Arrayopenni::DeviceInfo deviceList;
openni::OpenNI::enumerateDevices(&deviceList);

for(int i = 0; i != deviceList.getSize(); ++i) {
const openni::DeviceInfo& info = deviceList[i];
std::string uri = info.getUri();
cout << "Device " << i << ": " << uri << “\n”;
}

This give me output like:
Device 0: 2bc5/0403@1/40
Device 1: 2bc5/0403@1/37

My relevant lsusb gives me:

Bus 001 Device 040: ID 2bc5:0403
Bus 001 Device 039: ID 2bc5:0501
Bus 001 Device 037: ID 2bc5:0403
Bus 001 Device 036: ID 2bc5:0501

I’m assuming that the webcams have vendor/product ids 2bc5:0501.

I’m assuming that the webcams have vendor/product ids 2bc5:0501.

Yeah, I got that too.

But…you still only got two depth devices and two RGB devices. There is still no way to know for sure which belongs to which, is there? Or is the ordering it guaranteed (the RGB device always has a smaller lsusb device number than the corresponding depth device)?

Well, if you run lsusb -t, you get a hierarchy. The astra pro devices appear to be under an internal usb hub:

/: Bus 02.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/4p, 5000M
/: Bus 01.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/11p, 480M
|__ Port 1: Dev 35, If 0, Class=Hub, Driver=hub/4p, 480M
–>Port 1: Dev 36, If 0, Class=Video, Driver=uvcvideo, 480M
→ Port 1: Dev 36, If 1, Class=Video, Driver=uvcvideo, 480M
→ Port 2: Dev 37, If 0, Class=Vendor Specific Class, Driver=, 480M
→ Port 2: Dev 37, If 1, Class=Audio, Driver=snd-usb-audio, 480M
→ Port 2: Dev 37, If 2, Class=Audio, Driver=snd-usb-audio, 480M
|__ Port 3: Dev 2, If 0, Class=Video, Driver=uvcvideo, 480M
|__ Port 3: Dev 2, If 1, Class=Video, Driver=uvcvideo, 480M
|__ Port 4: Dev 3, If 0, Class=Human Interface Device, Driver=usbhid, 12M
|__ Port 5: Dev 4, If 0, Class=Human Interface Device, Driver=usbhid, 12M
|__ Port 6: Dev 41, If 0, Class=Hub, Driver=hub/4p, 480M
→ Port 1: Dev 42, If 0, Class=Video, Driver=uvcvideo, 480M
→ Port 1: Dev 42, If 1, Class=Video, Driver=uvcvideo, 480M
→ Port 2: Dev 43, If 0, Class=Vendor Specific Class, Driver=, 480M
→ Port 2: Dev 43, If 1, Class=Audio, Driver=snd-usb-audio, 480M
→ Port 2: Dev 43, If 2, Class=Audio, Driver=snd-usb-audio, 480M
|__ Port 7: Dev 15, If 0, Class=Wireless, Driver=btusb, 12M
|__ Port 7: Dev 15, If 1, Class=Wireless, Driver=btusb, 12M

Again, here is my lsusb output:

Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 015: ID 8087:0a2a Intel Corp.
Bus 001 Device 043: ID 2bc5:0403
Bus 001 Device 042: ID 2bc5:0501
Bus 001 Device 041: ID 05e3:0608 Genesys Logic, Inc. Hub
Bus 001 Device 004: ID 048d:8350 Integrated Technology Express, Inc.
Bus 001 Device 003: ID 04f3:2070 Elan Microelectronics Corp.
Bus 001 Device 002: ID 1bcf:2c7d Sunplus Innovation Technology Inc.
Bus 001 Device 037: ID 2bc5:0403
Bus 001 Device 036: ID 2bc5:0501
Bus 001 Device 035: ID 05e3:0608 Genesys Logic, Inc. Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

So, in a clunky way, I could get the available devices by vendor id, then look at the lsusb tree view to pair camera device numbers with the sensor device numbers.

Also, I have a feeling that the Uri I get from OpenNI is not the same as the Uri expected by astra. I tried running the following:

astra::StreamSet streamSet(“2bc5/0403@1/40”)

…but it didn’t seem to work. There must be a couple things I’m missing.

So in my opinion, the below should work, but it actually doesn’t on the develop branch.

I figured out a fix that works for me. In astra/src/plugins/openni_sensor/oni_adapter_plugin.cpp, there is what looks like a bug in the “add_or_get_device” function. I changed

    streamset_ptr streamSet = std::make_unique<device_streamset>(sstream.str(),
                                                                 pluginService(),
                                                                 oniUri);

to

    streamset_ptr streamSet = std::make_unique<device_streamset>(std::string(oniUri),
                                                                 pluginService(),
                                                                 oniUri);

so that the streamSet and OpenNI versions of URIs agree. I’m still trying to figure out how to map RGB cameras to the sensors. For now, I will pursue the lsusb -t method I devised above.

This isn’t a bug. We intentionally use the constructed stream like device/sensor0 as the name of the streamset to be more user-friendly. However, the device discovery API (which should help with the RGB camera mapping problem) isn’t completed yet.

In the meantime, you could use the change you suggest for your own code so you can request a specific OpenNI-style URI, if it helps.

For matching the two, you have the right idea about using information about the USB hierarchy. When you plug in an Astra Pro, it will enumerate as a USB hub with internal devices connected, including the depth camera module and the UVC color camera.

Thank you! Based on hierarchy, I got this working like a charm :slight_smile:

I can now switch between two devices on-the-fly.

1 Like

Hi,

I’m reviving this topic because it is really close to an issue that I’m having, so before starting a new one, I thought it would be better to start from here.

I’m working with two astra_s that need to work simultaneously and due to the specific application their usb cables need to be plugged in and out often. Thus, having to go to the lsusb and changing the launch file every time makes things a bit hard.

I’m using the ros_astra_camera pkg in a linux machine, and in the launch file for the driver there is the parameter device_id that allows to specify the device, however, it is not possible to distinguish between two equal models of cameras. Usually, if you do:
lsusb -v
One of the fields that it is shown is iSerial, which could be used to identify the device. However, this field returns a 0, which means that there is no internal serial number.
So, is there any way or workaround I can set the driver to pick the right camera with its parameters automatically in the lauch file?

Thanks.

Leave a single camera plugged and run rosrun openni2_camera list_devices. Then copy/paste the serial number of found devices in the device_id field

I’ve tried this instruction with one and also with both cameras plugged in, but I only get:
Found 0 devices:

Any other idea?

Thank again

that is very weird, if there is 0 devices found, you should not be able to connect with them at all.
can you try different port and several times?

Hi, I’m having a very similar problem. I’m trying to reliably connect multiple orbbec cameras on a single computer but the device/sensor# style of addressing does not guarantee that I get the same sensor number every time. I am trying to get this setup on windows using openframeworks and I’m unsure how to use the USB bus addressing technique outlined earlier here. What’s the syntax of an openNI URI on windows ?

Has anyone been able to get a solution working? I have been running a separate driver to get the color camera stream but this doesn’t work with multiple cameras connected to the same host pc.

I’ve been able to use the getConnectedDeviceInfos() function from the camera manager to find the device uri’s for the depth cameras and was intending to just assume the color camera is the previous device number on the usb bus. Unfortunately I’m using libuvc for the color camera driver which only supports addressing devices by vendor/product/serial not usb device number.

Does anyone know of an alternative?

Thanks

@josh , is the device discovery API included in the latest (2.0.8) Astra SDK?

In my application, I won’t know the number of connected Astras until runtime, so I need to dynamically discover the devices and setup the corresponding streams; otherwise, I will have to stick to a single device implementation.

@ryanw No, the device discovery API has not been released yet. It is still on the roadmap though. Sorry for the inconvenience.

Thanks for the quick reply. Much appreciated.
Looks like I’ll implement a single device interface to start.
The latest sdk is great.