In questo articolo prenderemo in esame come sia possibile enumerare i device RealSense presenti su un PC.
Il post si riferisce alla versione 6.0.x dell’SDK di Intel® RealSense™ attualmente scaricabile all’indirizzo https://software.intel.com/en-us/intel-realsense-sdk/download
Alla ricerca di moduli con la PXCMSession
Per poter ricavare l’elenco dei device connessi al PC, abbiamo la necessità di utilizzare la classe PXCMSession e, in particolare, le sue funzionalità di ricerca di moduli in base a filtri relativi alle varie implementazioni.
In particolare Il metodo che ci viene in aiuto per questo è il metodo QueryImpl della PXCMSession la cui firma è la seguente:
Il metodo permette di ottenere l’idx-esima istanza di ImplDesc (parametro desc) che verifica un determinato insieme di filtri, definiti all’interno dell’argomento templat di tipo ImplDesc.
La struttura della classe ImplDesc è la seguente:
Questa classe (innestata in PXCMSession) viene utilizzata sia per definire un template di ricerca, sia per contenere le informazioni del modulo trovato.
Il meccanismo di ricerca prevede, quindi, che si definisca un template impostando le opportune proprietà di una istanza della suddetta ImplDesc e si iteri la chiamata al metodo QueryImpl della PXCMSession fino a che non si ottenga un risultato diverso da pxcmStatus.PXCM_STATUS_NO_ERROR incrementando l’indice idx ad ogni giro.
Il primo step prevede che si definisca il template di ricerca e, nel nostro caso, stiamo ricercando i moduli che permettono di accedere a dei sensori per la cattura di video:
Dim implDescTemplate = New PXCMSession.ImplDesc() implDescTemplate.group = PXCMSession.ImplGroup.IMPL_GROUP_SENSOR implDescTemplate.subgroup = PXCMSession.ImplSubgroup.IMPL_SUBGROUP_VIDEO_CAPTURE
Il secondo step prevede l’iterazione sui risultati della query ottenuta dalla singola chiamata al QueryImpl della PXCMSession:
Dim implIndex = 0 Dim implDesc As PXCMSession.ImplDesc = Nothing' eseguo una query per recuperare l'i-esima implDesc che soddisfa il template While session.QueryImpl(implDescTemplate, implIndex, implDesc).IsSuccessful()' Recupero le info del device di cattura video descritto da implDesc implIndex += 1 End While
Ad ogni ciclo, se il metodo QueryImpl non ritorna errore, la variabile implDesc contiene l’istanza di un modulo che verifica le condizioni del template utilizzato.
Quello che serve, in questo caso, è effettivamente recuperare le informazioni complete di tale metodo.
La classe PXCMCapture
Per recuperare le informazioni del modulo di cattura recuperato all’interno del ciclo visto in precedenza, dobbiamo utilizzare un’istanza della classe PXCMCapture.
La classe PXCMCapture è la classe che ci consente di accedere alle informazioni relative ad un determinato sensore di cattura video o, addirittura, poterne creare un’istanza.
La sua struttura è la seguente:
Nel nostro caso, se avessimo in mano l’istanza della PXCMCapture identificata dal risultato della precedente query ottenuto tramite la QueryImpl della PXCMSession, potremmo utilizzare il metodo QueryDeviceInfo per ottenere le informazioni che ci interessano sulla camera.
Per prima cosa, dunque, abbiamo la necessità di creare l’istanza di PXCMCapture a partire dall’istanza di PXCMSession.ImplDesc del passo precedente.
Anche in questo caso ci viene in aiuto la PXCMSession:
Dim capture As PXCMCapture = Nothing' recupero le info del device la cui implDesc ho recuperato If session.CreateImpl(implDesc, capture).IsSuccessful() Then' Recupero le info relative ai device gestiti da capture End If
A questo punto abbiamo in mano l’istanza di PXCMCapture e possiamo andare alla ricerca delle info relative alle camere fisiche effettivamente gestite dalla stessa.
Per fare questo utilizziamo il già citato metodo QueryDeviceInfo che ha la firma:
Anche questo metodo va iterato incrementando il parametro didx fino a che non si ottiene un risultato di errore. Questo perché’ una singola istanza di PXCMCapture può, potenzialmente, gestire più sensori fisici.
Il risultato della QueryDeviceInfo è un’istanza della DeviceInfo, classe innestata nella PXCMCapture, che contiene le informazioni del singolo device.
La struttura della DeviceInfo è la seguente:
Le informazioni esposte dalla classe sono:
- name: contiene il nome user-friendly del device (ad esempio “Intel(R) RealSense(TM) 3D Camera”);
- model: contiene il modello di device (ad esempio DEVICE_MODEL_F200 per la F200). E’ uno dei valori contenuti nell’enumerazione PXCMCapture.DeviceModel:
- serial: contiene il serial number del device;
- did: contiene il device id, cioè un identificativo univoco che contraddistingue il device
- firmware: versione del firmware del device. E’ un array di 4 interi;
- location: contiene una coppi di single il cui valore dovrebbe rappresentare la posizione della camera rispetto alla posizione in basso a sinistra del display panel;
- orientation: orientamento del device in termini di front o rear (ad esempio DEVICE_ORIENTATION_FRONT_FACING per la F200). E’ uno dei valori contenuti nell’enumerazione PXCMCapture.DeviceOrientation:
- rotation: contiene quali possibili rotazioni può subire l’immagine ripresa dal device (ad esempio ROTATION_ANY per la F200). E’ uno dei valori dell’enumerazione PXCMImage.Rotation:
- streams: contiene la maschera di bit indicante il tipo di stream supportato dalla camera (ad esempio STREAM_TYPE_COLOR Or STREAM_TYPE_DEPTH Or STREAM_TYPE_IR per la F200). E’ una maschera di bit formata dai valori, in OR, contenuti nell’enumeration PXCMCapture.StreamType:
- didx: contiene l’indice (a base zero) del device nel caso in cui il sistema abbia più device collegati;
- duid: contiene lo unique identifier del device. L’SDK crea tale identificativo in maniera casuale per ogni sessione dell’SDK. E’ uno dei modi per identificare il device.
Nella seguente figura è riportato un esempio di DeviceInfo:
Per recuperare le informazioni di tutti i device gestiti da una istanza di PXCMCapture, è necessario richiamare il metodo QueryDeviceInfo iterando sull’indice del device fino a che non si ottiene un errore:
Dim deviceInfoIndex = 0 Dim deviceInfo As PXCMCapture.DeviceInfo = Nothing'eseguo la query per recuperare l'i-esima device info legata alla captture (ce ne dovrebbe essere una sola) While capture.QueryDeviceInfo(deviceInfoIndex, deviceInfo).IsSuccessful()' deviceInfo contiene le info del device deviceInfoIndex += 1 End While
L’esempio completo
L’esempio completo del codice mostrato fino ad ora è il seguente:
Private Function GetAllDevices(session As PXCMSession) As IEnumerable(Of CameraInfo) Dim deviceList = New List(Of CameraInfo)' Preparo il filtro con cui ricercare i sensori di tipo device Dim implDescTemplate = New PXCMSession.ImplDesc() implDescTemplate.group = PXCMSession.ImplGroup.IMPL_GROUP_SENSOR implDescTemplate.subgroup = PXCMSession.ImplSubgroup.IMPL_SUBGROUP_VIDEO_CAPTURE Dim implIndex = 0 Dim implDesc As PXCMSession.ImplDesc = Nothing ' eseguo una query per recuperare l'i-esima implDesc che soddisfa il template While session.QueryImpl(implDescTemplate, implIndex, implDesc).IsSuccessful() Dim capture As PXCMCapture = Nothing ' recupero le info del device la cui implDesc ho recuperato If session.CreateImpl(implDesc, capture).IsSuccessful() Then Dim deviceInfoIndex = 0 Dim deviceInfo As PXCMCapture.DeviceInfo = Nothing'eseguo la query per recuperare l'i-esima device info legata alla captture (ce ne dovrebbe essere una sola) While capture.QueryDeviceInfo(deviceInfoIndex, deviceInfo).IsSuccessful() deviceList.Add(New CameraInfo(deviceInfo)) deviceInfoIndex += 1 End While End If implIndex += 1 End While Return deviceList End Function
La classe CameraInfo è una classe che espone gli stessi valori dei campi esposti dalla classe DeviceInfo come proprietà ed è stata realizzata solo ed esclusivamente per permettere il binding all’interno della finestra WPF che, come ben noto, supporta il binding solo ed esclusivamente su proprietà.
Public Class CameraInfo Public Sub New(deviceInfo As PXCMCapture.DeviceInfo) If deviceInfo Is Nothing Then Throw New ArgumentNullException("deviceInfo") UID = deviceInfo.duid Firmware = New Version(deviceInfo.firmware(0), deviceInfo.firmware(1), deviceInfo.firmware(2), deviceInfo.firmware(3)) Model = deviceInfo.model Name = deviceInfo.name Orientation = deviceInfo.orientation SerialNumber = deviceInfo.serial Streams = deviceInfo.streams End Sub Public Property UID As Integer Public Property Firmware As Version Public Property Model As PXCMCapture.DeviceModel Public Property Name As String Public Property Orientation As PXCMCapture.DeviceOrientation Public Property SerialNumber As String Public Property Streams As PXCMCapture.StreamType End Class
Il risultato dell’esecuzione del progetto allegato è il seguente: