Astra Mini - Depth frame lost

Hi there,

I am facing a strange behavior with depth-only data acquisition on raspberry pi 3B+ when properly working on Pi 4 with exact same code and configuration. Both configuration are USB 2.0 Moreover, when unplung-replug the Astra Mini, sometimes, it works properly back.

I am using the latest SDK release: OpenNI_2.3.0.63/Linux/OpenNI-Linux-Arm-2.3.0.63
I used the install.sh script as sudo and source the dedicated OpenNIDevEnvironment file.

I use this python code: here
It waits for a device, starts a stream and measure per-second on-frame-ready events.

Activating the logging in the OpenNI.ini, I posted two log files here. One is the proper behavior with 30fps, the other is when the problem occures.

It seems data-stream is corrupted:
when in the ok log we got

 13400348 VERBOSE    [FPS] Depth: 31.64

in the ko log we got:

1668059 WARNING    Depth: Expected e81, got e79
1668075 WARNING    Depth frame is corrupt!
1668087 WARNING    Read: Depth buffer is corrupt. Size is 4448 (!= 512000)

It seems to be the only difference between both logs.
I already saw this kind of message here on the forum but i could’nt find the proper solution for it.

To be noted that:

  • this same exact code with same exact ini files is properly working on Raspberry PI4 USB 2.0
  • the same problem occures when started as Root (no more Thread Priority Warning Message)

For more information, I tested all available VideoModes.
Could it be a USB low bandwidth problem ???
Here is the result:

     320x240@30_1_MM: 29.2
     320x240@30_1_MM: 29.2
     320x240@60_1_MM: 29.2
     320x240@60_1_MM: 29.2
     640x480@30_1_MM: 3.8
     640x480@30_1_MM: 2.8
     640x400@30_1_MM: 5.2
     640x400@30_1_MM: 5.8
     1280x800@5_1_MM: 0.0
     1280x800@5_1_MM: 0.0
    1280x800@30_1_MM: 0.0
    1280x800@30_1_MM: 0.0
     320x200@30_1_MM: 0.0
     320x200@30_1_MM: 0.0
     800x1280@5_1_MM: 0.0
     800x1280@5_1_MM: 0.0
     400x640@30_1_MM: 0.0
     400x640@30_1_MM: 0.0
   1280x1024@30_1_MM: 0.0
   1280x1024@30_1_MM: 0.0
     1280x960@5_1_MM: 0.0
     1280x960@5_1_MM: 0.0
     160x120@30_1_MM: 0.0
     160x120@30_1_MM: 0.0

Here is the test code:

from openni import openni2
from threading import Lock
from time import sleep

openni2.initialize()
device = openni2.Device.open_any()
stream = device.create_depth_stream()
sinfo  = stream.get_sensor_info()
dmodes = sinfo.videoModes

class EventCounter:
    def __init__(self):
        self._cnt = 0
        self._lock = Lock()
    
    def clear(self):
        with self._lock:
            self._cnt = 0
    
    def increase(self, *_):
        with self._lock:
            self._cnt += 1
    
    @property
    def value(self):
        with self._lock:
            return self._cnt

def test(stream, dmode):
    label = '%dx%d@%d_%s' % (dmode.resolutionX, dmode.resolutionY, dmode.fps,
        '_'.join(str(dmodes[0].pixelFormat).split('_')[-2:]))
    print('#' * 100)
    print(label)
    stream.set_video_mode(dmode)
    ecounter = EventCounter()
    stream.register_new_frame_listener(ecounter.increase)
    stream.start()
    sleep(5.0)
    stream.stop()
    stream.unregister_all_new_frame_listeners()
    return label, ecounter.value/5.0

info = list(map(lambda dmode: test(stream, dmode), dmodes))

stream.close()
device.close()
openni2.unload()

for label, fps in info:
    print('%20s: %.1f' % (label, fps))