Problem with using multiple device

1,672 views
Skip to first unread message

Heresy

unread,
Dec 7, 2011, 4:23:22 AM12/7/11
to openn...@googlegroups.com
I am trying to use multiple Kinect on single computer, but I have some problems.
 
  1. Is there any example for using multiple device at the same time?
     
  2. I had try to read the sample NiViewer (the function openDeviceFromXmlWithChoice() in Device.cpp) to know how to control which device to use.But I am still not sure.
    In the sample program, it call CreateProductionTree() with specified NodeInfo and Device Node, and then run RunXmlScriptFromFile() to create other nodes.
    Is this mean after I call CreateProductionTree() with specified NodeInfo, OpenNI will create other nodes which is depend on the device node?
     
  3. Should I use only one context for all device? Or I should use many context for each device? 
Thanks for reading this.

Bernie

unread,
Dec 7, 2011, 11:20:04 AM12/7/11
to OpenNI
Hi, Heresy,

I have not tried using multiple Kinects on a PC. But I did try to
connect 2 Xtions and read the depth data from both of them from my
laptop.

Here is a sample code that you can refer to for enumerating multiple
sensors and reading depth map out of them. It used only one context
for all the devices.

int main()
{
XnStatus nRetVal = XN_STATUS_OK;

// Getting Sensors information and configure all sensors
DepthRgbSensors sensors[NUM_OF_SENSORS];
nRetVal = g_Context.Init();

NodeInfoList devicesList;
int devicesListCount = 0;
nRetVal = g_Context.EnumerateProductionTrees(XN_NODE_TYPE_DEVICE,
NULL, devicesList);
for (NodeInfoList::Iterator it = devicesList.Begin(); it !=
devicesList.End(); ++it)
{
devicesListCount++;
}
CHECK_RC(nRetVal, "Enumerate");
int i=0;
for (NodeInfoList::Iterator it = devicesList.Begin(); it !=
devicesList.End(); ++it, ++i)
{
// Create the device node
NodeInfo deviceInfo = *it;
nRetVal = g_Context.CreateProductionTree(deviceInfo);
CHECK_RC(nRetVal, "Create Device");

// create a query to depend on this node
Query query;
query.AddNeededNode(deviceInfo.GetInstanceName());

// Copy the device name
xnOSMemCopy(sensors[i].name,deviceInfo.GetInstanceName(),
xnOSStrLen(deviceInfo.GetInstanceName()));
// now create a depth generator over this device
nRetVal = g_Context.CreateAnyProductionTree(XN_NODE_TYPE_DEPTH,
&query, sensors[i].depth);
CHECK_RC(nRetVal, "Create Depth");
}

g_Context.StartGeneratingAll();

XnFPSData xnFPS;
nRetVal = xnFPSInit(&xnFPS, 180);
CHECK_RC(nRetVal, "FPS Init");

while (!xnOSWasKeyboardHit())
{
for(i = 0 ; i < NUM_OF_SENSORS ; ++i)
{
printf("Sensor [%d] output:\n",i);
UpdateCommon(sensors[i]);
xnFPSMarkFrame(&xnFPS);
// Print Depth central pixel
const DepthMetaData *dmd = &sensors[i].depthMD;
const XnDepthPixel* pDepthMap = sensors[i].depthMD.Data();
printf("Depth frame [%d] Middle point is: %u. FPS: %f\n", dmd-
>FrameID(), sensors[i].depthMD(dmd->XRes() / 2, dmd->YRes() / 2),
xnFPSCalc(&xnFPS));
}
}

closeDevice();

return 0;
}


Hope this is helpful. : )

Bernie

On Dec 7, 5:23 pm, Heresy <kher...@gmail.com> wrote:
> I am trying to use multiple Kinect on single computer, but I have some
> problems.
>

>    1. Is there any example for using multiple device at the same time?
>
>    2. I had try to read the sample NiViewer (the function


>    openDeviceFromXmlWithChoice() in Device.cpp) to know how to control which
>    device to use.But I am still not sure.
>    In the sample program, it call CreateProductionTree() with specified
>    NodeInfo and Device Node, and then run RunXmlScriptFromFile() to create
>    other nodes.
>    Is this mean after I call CreateProductionTree() with specified
>    NodeInfo, OpenNI will create other nodes which is depend on the device node?
>

>    3. Should I use only one context for all device? Or I should use many

Heresy

unread,
Dec 8, 2011, 7:14:37 AM12/8/11
to openn...@googlegroups.com
Thanks for your sample code, I will try it.

Lior Cohen

unread,
Dec 11, 2011, 10:18:11 AM12/11/11
to openn...@googlegroups.com
Hi Guys,

Below You will find the additional code that is missing and that you probably need.
The RGB Image might not work for all of you due to bandwidth limitations, so it is disabled by default :-(.
Enjoy,


//---------------------------------------------------------------------------
// Includes
//---------------------------------------------------------------------------
#include <XnOpenNI.h>
#include <XnLog.h>
#include <XnCppWrapper.h>
#include <XnFPSCalculator.h>

using namespace xn;

//---------------------------------------------------------------------------
// Defines
//---------------------------------------------------------------------------
#define NUM_OF_SENSORS 2
//#define USE_RGB_IMAGE_STREAMS
//---------------------------------------------------------------------------
// Macros
//---------------------------------------------------------------------------
#define CHECK_RC(rc, what) \
if (rc != XN_STATUS_OK) \
{ \
printf("%s failed: %s\n", what, xnGetStatusString(rc)); \
return rc; \
}

#define CHECK_RC_CONTINUE(rc, what) \
if (rc != XN_STATUS_OK) \
{ \
printf("%s failed: %s\n", what, xnGetStatusString(rc)); \
}
//---------------------------------------------------------------------------
// Code
//---------------------------------------------------------------------------

xn::Context g_Context;

struct DepthRgbSensors
{
char name[80];
ProductionNode device;
DepthGenerator depth;
DepthMetaData depthMD;
#if defined(USE_RGB_IMAGE_STREAMS)
ImageGenerator image;
ImageMetaData imageMD;
#endif
};

void CloseDevice()
{
//Do additional cleanup if needed
g_Context.Release();
}

void UpdateCommon(DepthRgbSensors &sensor)
{
XnStatus rc = XN_STATUS_OK;
rc = g_Context.WaitAnyUpdateAll();
//This function will wait until all nodes will have new data:
//rc = g_Context.WaitAndUpdateAll();
CHECK_RC_CONTINUE(rc, "WaitAnyUpdateAll() failed");

if (sensor.depth.IsValid())
{
sensor.depth.GetMetaData(sensor.depthMD);
}
#if defined(USE_RGB_IMAGE_STREAMS)
if (sensor.image.IsValid())
{
sensor.image.GetMetaData(sensor.imageMD);
}
#endif
}

int main()
{
XnStatus nRetVal = XN_STATUS_OK;

// Getting Sensors information and configure all sensors
DepthRgbSensors sensors[NUM_OF_SENSORS];
nRetVal = g_Context.Init();

NodeInfoList devicesList;
int devicesListCount = 0;
nRetVal = g_Context.EnumerateProductionTrees(XN_NODE_TYPE_DEVICE, NULL, devicesList);
for (NodeInfoList::Iterator it = devicesList.Begin(); it != devicesList.End(); ++it)
{
devicesListCount++;
}
CHECK_RC(nRetVal, "Enumerate");
int i=0;
for (NodeInfoList::Iterator it = devicesList.Begin(); it != devicesList.End(); ++it, ++i)
{
// Create the device node
NodeInfo deviceInfo = *it;

nRetVal = g_Context.CreateProductionTree(deviceInfo, sensors[i].device);
CHECK_RC(nRetVal, "Create Device");

// Create a query to depend on this node
Query query;
query.AddNeededNode(deviceInfo.GetInstanceName());

// Copy the device name
xnOSMemCopy(sensors[i].name,deviceInfo.GetInstanceName(),
xnOSStrLen(deviceInfo.GetInstanceName()));

// Now create a depth generator over this device


nRetVal = g_Context.CreateAnyProductionTree(XN_NODE_TYPE_DEPTH, &query, sensors[i].depth);
CHECK_RC(nRetVal, "Create Depth");

#if defined(USE_RGB_IMAGE_STREAMS)
// now create a image generator over this device
nRetVal = g_Context.CreateAnyProductionTree(XN_NODE_TYPE_IMAGE, &query, sensors[i].image);
CHECK_RC(nRetVal, "Create Image");
#endif
}

g_Context.StartGeneratingAll();

XnFPSData xnFPS;
nRetVal = xnFPSInit(&xnFPS, 180);
CHECK_RC(nRetVal, "FPS Init");

while (!xnOSWasKeyboardHit())
{
for(i = 0 ; i < NUM_OF_SENSORS ; ++i)
{
printf("Sensor [%d] output:\n",i);
UpdateCommon(sensors[i]);
xnFPSMarkFrame(&xnFPS);
// Print Depth central pixel
const DepthMetaData *dmd = &sensors[i].depthMD;
const XnDepthPixel* pDepthMap = sensors[i].depthMD.Data();
printf("Depth frame [%d] Middle point is: %u. FPS: %f\n",
dmd->FrameID(), sensors[i].depthMD(dmd->XRes() / 2, dmd->YRes() / 2),
xnFPSCalc(&xnFPS));

#if defined(USE_RGB_IMAGE_STREAMS)
// Print Image first pixel
const ImageMetaData *imd = &sensors[i].imageMD;
const XnUInt8 *imageMap = sensors[i].imageMD.Data();
printf("Image frame [%d] first pixel is: R[%u],G[%u],B[%u]. FPS: %f\n",
imd->FrameID(), imageMap[0], imageMap[1], imageMap[2], xnFPSCalc(&xnFPS));
#endif
}
}

CloseDevice();

return 0;
}

Best Regards,
Lior Cohen

Hi, Heresy,

g_Context.StartGeneratingAll();

closeDevice();

return 0;
}

Bernie

--
You received this message because you are subscribed to the Google Groups "OpenNI" group.
To post to this group, send email to openn...@googlegroups.com.
To unsubscribe from this group, send email to openni-dev+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/openni-dev?hl=en.

Bernie Wu

unread,
Dec 11, 2011, 10:34:47 AM12/11/11
to openn...@googlegroups.com
Right, Lior. Thanks a lot. : )

Bernie

Message has been deleted

stageWorks

unread,
Mar 28, 2012, 8:59:42 PM3/28/12
to openn...@googlegroups.com
Hi lc,

This is the first ever sample that I found really works even on Linux. I have four sensors on my computer and they all works great.

Thanks lc, you are my hero of the day!

To unsubscribe from this group, send email to openni-dev+unsubscribe@googlegroups.com.

Reply all
Reply to author
Forward
0 new messages