Thread-Safe Communication

78 views
Skip to first unread message

Morad Behandish

unread,
Oct 29, 2013, 2:05:05 PM10/29/13
to unofficial-hapti...@googlegroups.com
Hi All,

I have a question about communication between the application and the 1kHz haptics thread: 

Although there are functions in the API to get a thread-safe copy of the device parameters (e.g., the forces or positions) in the application, I could not find a mechanism in the documentation for custom communication with the servo-loop in a thread-safe fashion. For example, let's say you have some additional variables that are modified constantly in your simulation function that is registered to virtSetPeriodicFunction() and asynchronously run in a separate thread after calling virtStartLoop(). Now you want to query that variable for some graphics rendering from your graphics thread, but it has to first interrupt the haptic servo-loop for mutual exclusion.

Now in the OpenHaptics HDAPI with Phantom haptic devices, the standard way of doing this is to use synchronous callbacks via HDAPI scheduler. When using the Virtuose device, I use OpenMP mutex to make a thread-safe copy of the variables into a shared data structure, which is updated at the beginning of every haptic frame, and use another mutex to query this into my other threads in the application. This way neither of the threads has to wait for another, and it works fine. But is there some sort of standard mechanism in the Virtuose API to do this?

Thanks in advance,
Morad

Ryan Pavlik

unread,
Oct 31, 2013, 12:19:46 PM10/31/13
to unofficial-hapti...@googlegroups.com
As far as I know, there's no built-in system.  I use a similar "roll-your-own" system to communicate, though in my case I actually made the setPeriodicFunction call essentially a "job scheduler" to simulate what the HDAPI does and allow a "synchronous" call into the loop.  It lets me unify the programming models a bit and moves where the mutex is, but there's nothing fundamentally wrong with what you've described.

Ryan

Jerome Perret

unread,
Oct 31, 2013, 12:27:34 PM10/31/13
to unofficial-hapti...@googlegroups.com
Hi Morad and Ryan,

There is really no need for mutex protection of the code called by setPeriodicFunction.
The only way you can interact with the haptic service is by calling functions of the VirtuoseAPI, and all have an internal mutex.
The setPeriodicFunction is a service provided to the developer for practical reasons, but it does not actually put your code inside the haptic update loop of the control software.
It is safe to call functions of the VirtuoseAPI from any number of different threads, whether they are called by setPeriodicFunction of not.
If you experience a different behaviour, then please tell us quickly, because that would be a bug.

Jerome

Morad Behandish

unread,
Nov 1, 2013, 3:12:19 PM11/1/13
to unofficial-hapti...@googlegroups.com
Thanks Ryan, I think I understand how you make use of the virtSetPeriodicFunction() to simulate the job scheduler. I might try doing that too, but so far using the mutex seems to work properly.

Thanks,
Morad

Morad Behandish

unread,
Nov 1, 2013, 3:34:55 PM11/1/13
to unofficial-hapti...@googlegroups.com
Thanks Jerome, I understand that calling the VirtuoseAPI functions are thread-safe from either the application code or inside the periodic function. My question is about querying variables that are not owned and protected by the haptic service. Let me give an example: Let's say we have two objects in a scene, one is the master attached to the device end-effector, and the other one is a slave that is connected with some user-defined coupling mechanism to the master. The dynamic simulation callback will then look something like this:

void PeriodicCB(VirtContext VC, void* pUserData)
{
float MasterPos[7], SlavePos[7], MutualForce[6];
 
virtGetPosition(VC, MasterPos);

//Perform dynamic simulation between master & slave:
MyDynamicsFunc(MasterPos, SlavePos, MutualForce);

virtSetForce(VC, MutualForce);
}

The function MyDynamicsFunc() takes the master position as input, and computes and returns the slave position and mutual force as output. Now after calling virtSetPeriodicFunction(VC, PeriodicCB, 0.001f, NULL) and virtStartLoop(), the master position and mutual force can be queried outside the periodic function (e.g., inside the graphics rendering loop) using VirtuoseAPI functions, but how would you query the most recent slave position?

Thanks,
Morad
Reply all
Reply to author
Forward
0 new messages