forums.naturalpoint.com

Discussion and Support for the OptiTrack, SmartNav and TrackIR brands by NaturalPoint

GetObjectData

by leith » Wed Jun 18, 2008 10:50 am

Just a question/thought.

When using the optitrack SDK with a .net language (c# for example), the tlb importer ends up turning the GetObjectData method call into something like:

Code: Select all
int ret = camFrame.GetObjectData(ref byteBuffer[0], buffSize);


point being, it asks for a ref to a byte rather than a ref to a byte array. When it comes to pure C code, I understand there's really no difference, but at a COM level, there really is. I'm wondering if it might be worth revising the COM interface so that it asks for the right object type, a byte array, rather than the first member. That way, the auto-magical type marshalling of COM and the appropriate client languages will take care of the issue directly.

In the meantime, I'm going to push through with c# "unsafe" code and some marshalling attributes and hopefully I'll figure out how to get this to work without the change. If anyone has any useful info on how to hack c# to use this method in its current state, info would be much appreciated.
leith
 
Posts: 192
Joined: Tue Jan 02, 2007 2:17 pm

by beckdo » Wed Jun 18, 2008 12:41 pm

Thanks for the heads-up, Brad. We will look into this.
beckdo
NaturalPoint Employee
NaturalPoint Employee
 
Posts: 519
Joined: Tue Jan 02, 2007 2:02 pm

by leith » Fri Jul 04, 2008 4:28 pm

okay, this one is officially driving me nuts.

I've tried allocating a byte array and passing it through that ref a number of ways and none of them appear to be working.

my latest:

Code: Select all
 public static int DoFrameDump(INPCameraFrame camFrame)
        {           
            int ret = 0;
            unsafe
            {
                byte* secbuff = stackalloc byte[4096];
               
                ret = camFrame.GetObjectData(ref secbuff[0], 4096);
                for (int c = 0; c < ret; c++)
                {
                    System.Console.WriteLine(ret);
                }
               
            }
            return ret;
        }


I figure this one should be foolproof. But none the less, the byte array remains filled with nothing but 0s (I'm in a debugger so the fact that its initialized to 0 doesn't phase me). I've been checking by putting a breakpoint on the WriteLine statement and then looking through the byte array with the debugger.

I've also tried an alternate method that used this struct:

Code: Select all
        public unsafe struct buffStruct
        {
            public fixed byte buff[buffSize];
        }
        public const int buffSize = 4096;


anyhow, the fixed keyword in combination with an unsafe keyword should allow me to pass the first byte into the ref parameter. And it does. Both of these solutions compile and run. But neither returns me any data in the byte arrays other than 0s.

So... do you guys have any .net code (any .net language will do) that uses this method?
leith
 
Posts: 192
Joined: Tue Jan 02, 2007 2:17 pm

by leith » Sun Jul 19, 2009 7:11 pm

Been a LONG time. My day job has gotten in the way.

Anyhow, resurrected my codebase, gave this another go, and its working fine in the latest SDK.

Great news :)

However, I've noticed a behavior change.

Now that I'm getting my frames this way, the frame ID numbers don't match anymore. Any frame I get from any camera, comes in with a frame ID number different from the prior frame. So you can't use the IDs to automatically group sync'd frames anymore.

This leaves me with the timestamp as the best sync option. However, this wont work across computers the way the frame ID used to (or at least as I remember it working). As I understand it, the timestamp is based on a high resolution timer on the computer, rather than in the camera system.

So, a general query: In this mode, what is the best way to sync cameras that are connected to different machines? My understanding was that you could have cameras on different computers, but as long as you looped the sync through all the cameras, you'd be able to sync.
leith
 
Posts: 192
Joined: Tue Jan 02, 2007 2:17 pm

by Birch » Mon Jul 20, 2009 1:58 pm

Brad,

Are you using 1.3.037 Beta 1?

Is your app seeing the new 24 bit Frame ID?

Whats your test setup for checking the Frame IDs? How many cameras? All V100s?

If the new 24 bit Frame ID's aren't coming out right we will need to take a closer look.
Birch
 
Posts: 1139
Joined: Thu Jan 30, 2003 5:00 am
Location: Corvallis, Oregon

by brunoleos » Thu Jul 01, 2010 7:57 am

Hi people,

I'm also trying to use NPCameraFrame.GetObjectData() with .NET language (C#). With Brad example I could get the array of bytes from the objects captured by the camera, but I don't know how to deserialize it to NPObject objects.

I tryed using System.Runtime.Serialization, as in the code below, but I got an error that says the bynary stream isn't in a correct binary format:

Code: Select all
NPObject[] t_oObj = new NPObject[t_oFrame.Count];             
BinaryFormatter b = new BinaryFormatter();
int ret = 0;
int size = 4096;
byte[] bbuffer = new byte[size];

ret = t_oFrame.GetObjectData(ref bbuffer[0], size);

Stream s = new MemoryStream(bbuffer);

if (ret != 0)
{
    t_oObj = (NPObject[])b.Deserialize(s);
    System.Diagnostics.Trace.WriteLine(t_oObj[0].X);
}


Any sugestion?

Thanks!
brunoleos
 
Posts: 1
Joined: Thu Jul 01, 2010 7:45 am

by beckdo » Thu Jul 01, 2010 1:55 pm

I'm not sure why you're not able to inspect the binary data you're receiving, but once you overcome that, the GetObjectData basically returns the following structure one after the next:

struct sCameraObject
{
float X;
float Y;
int Width;
int Height;
int Area;
int Rank;
int Score;
};

Good luck
beckdo
NaturalPoint Employee
NaturalPoint Employee
 
Posts: 519
Joined: Tue Jan 02, 2007 2:02 pm


Return to OptiTrack SDK