Myo Scol plugin
scolplugin.cpp
1 /*
2 -----------------------------------------------------------------------------
3 This source file is part of OpenSpace3D
4 For the latest info, see http://www.openspace3d.com
5 
6 Copyright (c) 2012 I-maginer
7 
8 This program is free software; you can redistribute it and/or modify it under
9 the terms of the GNU Lesser General Public License as published by the Free Software
10 Foundation; either version 2 of the License, or (at your option) any later
11 version.
12 
13 This program is distributed in the hope that it will be useful, but WITHOUT
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
16 
17 You should have received a copy of the GNU Lesser General Public License along with
18 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
19 Place - Suite 330, Boston, MA 02111-1307, USA, or go to
20 http://www.gnu.org/copyleft/lesser.txt
21 
22 -----------------------------------------------------------------------------
23 */
24 
25 /*
26  MYO by ThalmicLabs interface for Scol
27  First version : May 2014
28  Author : Bastien BOURINEAU - I-Maginer
29 */
30 
31 #include "SMyo.h"
32 #include <scolPlugin.h>
33 #include <scolMemoryHelper.hpp>
34 
36 #ifdef SCOL_STATIC
37 extern cbmachine ww;
38 extern mmachine mm;
39 #else
40 cbmachine ww;
41 mmachine mm;
42 #endif
43 
44 int OBJ_MYO_SCOL;
45 
46 int MYO_CONNECTED_CB;
47 int SCOL_MYO_CONNECTED_CB = 0;
48 
49 int MYO_DISCONNECTED_CB;
50 int SCOL_MYO_DISCONNECTED_CB = 1;
51 
52 int MYO_ORIENTATION_CB;
53 int SCOL_MYO_ORIENTATION_CB = 2;
54 
55 int MYO_ACCEL_CB;
56 int SCOL_MYO_ACCEL_CB = 3;
57 
58 int MYO_POSE_CB;
59 int SCOL_MYO_POSE_CB = 4;
60 
61 int MYO_ARMRECOGNIZED_CB;
62 int SCOL_MYO_ARMRECOGNIZED_CB = 5;
63 
64 int MYO_ARMLOST_CB;
65 int SCOL_MYO_ARMLOST_CB = 6;
66 
88 int destroyMyoObj(mmachine m, SCOL_PTR_TYPE handsys, int handscol)
89 {
90  // Read the first element of a TAB element (table of object)
91  SMyo* myoInstance = MMgetPointer<SMyo*>(m, MTOP(handscol));
92 
93  // Safely dispose of "myoInstance" pointer
94  if (myoInstance)
95  SMyoManager::GetInstance()->RemoveMyoInstance(myoInstance);
96 
97  MMsetPointer(m, MTOP(handscol), NULL);
98 
99  // Display debug message
100  MMechostr(MSKDEBUG, "ObjMyo destroyed.\n");
101  return 0;
102 }
103 
104 
117 int _CRmyoDevice(mmachine m)
118 {
119 #ifdef _SCOL_DEBUG_
120  MMechostr(0,"_CRmyoDevice\n");
121 #endif
122  // Declare local variables
123  int k = 0;
124 
125  int pUserd = MMpull(m);
126  int pCbkd = MMpull(m);
127  int pUserc = MMpull(m);
128  int pCbkc = MMpull(m);
129 
130  // Get the channel without pulling it (first element in the stack)
131  int channel = MMget(m, 0);
132 
133  // Test the channel
134  if (channel == NIL)
135  {
136  MMechostr(MSKDEBUG, "_CRmyoDevice : Channel NIL\n");
137  return 0;
138  }
139 
140  SMyo* myoInstance = SMyoManager::GetInstance()->AddMyoInstance();
141  if (myoInstance == NULL)
142  {
143  MMechostr(MSKDEBUG, "_CRmyoDevice : myoInstance failed\n");
144  MMset(m, 0, NIL);
145  return 0;
146  }
147 
148  // Allocate a space in the stack for a table of joypad object
149  if ((MMpushPointer(m, myoInstance) != 0))
150  {
151  SMyoManager::GetInstance()->RemoveMyoInstance(myoInstance);
152  MMset(m, 0, NIL);
153  return MERRMEM;
154  }
155 
156  // Create a new scol myo object
157  k = OBJcreate(m, OBJ_MYO_SCOL, SCOL_PTR myoInstance, NULL, NULL);
158 
159  if ((k = MMpush(m, pCbkc))) return k; /* reading callback */
160  if ((k = MMpush(m, pUserc))) return k; /* user param */
161  if ((k = OBJaddreflex(m, OBJ_MYO_SCOL, SCOL_MYO_CONNECTED_CB))) return k;
162 
163  if ((k = MMpush(m, pCbkd))) return k; /* reading callback */
164  if ((k = MMpush(m, pUserd))) return k; /* user param */
165  if ((k = OBJaddreflex(m, OBJ_MYO_SCOL, SCOL_MYO_DISCONNECTED_CB))) return k;
166 
167 #ifdef _SCOL_DEBUG_
168  MMechostr(0,"ok\n");
169 #endif
170 
171  return k;
172 }
173 
181 int _DSmyoDevice(mmachine m)
182 {
183 #ifdef _SCOL_DEBUG_
184  MMechostr(MSKDEBUG,"_DSmyoDevice\n");
185 #endif
186 
187  int myoTab = MMget(m, 0);
188  if (myoTab == NIL)
189  {
190  MMset(m, 0, NIL);
191  return 0;
192  }
193 
194  OBJdelTM(m, OBJ_MYO_SCOL, myoTab);
195  MMset(m, 0, ITOM(0));
196 
197 #ifdef _SCOL_DEBUG_
198  MMechostr(MSKDEBUG,"ok\n");
199 #endif
200  return 0;
201 }
202 
211 int _VibrateMyoDevice(mmachine m)
212 {
213 #ifdef _SCOL_DEBUG_
214  MMechostr(MSKDEBUG,"_VibrateMyoDevice\n");
215 #endif
216 
217  int period = MTOI(MMpull(m));
218  int myoTab = MMget(m, 0);
219  if (myoTab == NIL)
220  {
221  MMset(m, 0, NIL);
222  return 0;
223  }
224 
225  SMyo* myoInstance = MMgetPointer<SMyo*>(m, MTOP(myoTab));
226  myo::Myo::VibrationType vtype = myo::Myo::vibrationShort;
227 
228  if (period == 1)
229  vtype = myo::Myo::vibrationMedium;
230  else if (period == 2)
231  vtype = myo::Myo::vibrationLong;
232 
233  myoInstance->Vibrate(vtype);
234 
235  MMset(m, 0, ITOM(0));
236 
237 #ifdef _SCOL_DEBUG_
238  MMechostr(MSKDEBUG,"ok\n");
239 #endif
240  return 0;
241 }
242 
250 int _IsMyoDeviceTrained(mmachine m)
251 {
252 #ifdef _SCOL_DEBUG_
253  MMechostr(MSKDEBUG,"_IsMyoDeviceTrained\n");
254 #endif
255 
256  int myoTab = MMget(m, 0);
257  if (myoTab == NIL)
258  {
259  MMset(m, 0, NIL);
260  return 0;
261  }
262 
263  //SMyo* myoInstance = MMgetPointer<SMyo*>(m, MTOP(myoTab));
264  MMset(m, 0, ITOM(1));
265 
266 #ifdef _SCOL_DEBUG_
267  MMechostr(MSKDEBUG,"ok\n");
268 #endif
269  return 0;
270 }
271 
279 int _GetMyoArmDirection(mmachine m)
280 {
281 #ifdef _SCOL_DEBUG_
282  MMechostr(MSKDEBUG,"_GetMyoArmDirection\n");
283 #endif
284 
285  int myoTab = MMget(m, 0);
286  if (myoTab == NIL)
287  {
288  MMset(m, 0, NIL);
289  return 0;
290  }
291 
292  SMyo* myoInstance = MMgetPointer<SMyo*>(m, MTOP(myoTab));
293  if (!myoInstance)
294  {
295  MMset(m, 0, NIL);
296  return 0;
297  }
298 
299  int dir = (myoInstance->GetDirection() == xDirectionTowardWrist) ? 1 : -1;
300 
301  MMset(m, 0, ITOM(dir));
302 
303 #ifdef _SCOL_DEBUG_
304  MMechostr(MSKDEBUG,"ok\n");
305 #endif
306  return 0;
307 }
308 
309 /* Callbacks */
310 
321 int _CBMyoOrientation(mmachine m)
322 {
323  return OBJaddreflex(m, OBJ_MYO_SCOL, SCOL_MYO_ORIENTATION_CB);
324 }
325 
326 int getMyoOrientationCb(mmachine m, SCOL_PTR_TYPE id, LONG param)
327 {
328  int k = 0;
329  SMyo* myoInstance = (SMyo*)id;
330 
331  SCbData* data = (SCbData*)param;
332 
333  if (!myoInstance)
334  {
335  delete data;
336  return 0;
337  }
338 
339  // OBJbeginreflex(mmachine, objecttype, objectptr, cbtype)
340  if (OBJbeginreflex(m, OBJ_MYO_SCOL, SCOL_PTR myoInstance, SCOL_MYO_ORIENTATION_CB))
341  {
342  delete data;
343  return 0;
344  }
345 
346  int tuple = MMmalloc(m, 4, TYPETAB);
347  if(tuple==NIL)
348  {
349  return MERRMEM;
350  }
351  MMstore(m, tuple, 0, FTOM(data->quat.x()));
352  MMstore(m, tuple, 1, FTOM(data->quat.y()));
353  MMstore(m, tuple, 2, FTOM(data->quat.z()));
354  MMstore(m, tuple, 3, FTOM(data->quat.w()));
355  MMpush(m, PTOM(tuple));
356 
357  k=OBJcallreflex(m, 1);
358 
359  delete data;
360  return k;
361 }
362 
373 int _CBMyoAccel(mmachine m)
374 {
375  return OBJaddreflex(m, OBJ_MYO_SCOL, SCOL_MYO_ACCEL_CB);
376 }
377 
378 int getMyoAccelCb(mmachine m, SCOL_PTR_TYPE id, LONG param)
379 {
380  int k = 0;
381  SMyo* myoInstance = (SMyo*)id;
382 
383  SCbData* data = (SCbData*)param;
384 
385  if (!myoInstance)
386  {
387  delete data;
388  return 0;
389  }
390 
391  // OBJbeginreflex(mmachine, objecttype, objectptr, cbtype)
392  if (OBJbeginreflex(m, OBJ_MYO_SCOL, SCOL_PTR myoInstance, SCOL_MYO_ACCEL_CB))
393  {
394  delete data;
395  return 0;
396  }
397 
398  int ftuple = MMmalloc(m, 3, TYPETAB);
399  if(ftuple==NIL)
400  {
401  return MERRMEM;
402  }
403  MMstore(m, ftuple, 0, FTOM(data->svec.x()));
404  MMstore(m, ftuple, 1, FTOM(data->svec.y()));
405  MMstore(m, ftuple, 2, FTOM(data->svec.z()));
406  MMpush(m, PTOM(ftuple));
407 
408  k=OBJcallreflex(m, 1);
409 
410  delete data;
411  return k;
412 }
413 
424 int _CBMyoPose(mmachine m)
425 {
426  return OBJaddreflex(m, OBJ_MYO_SCOL, SCOL_MYO_POSE_CB);
427 }
428 
429 int getMyoPoseCb(mmachine m, SCOL_PTR_TYPE id, LONG param)
430 {
431  int k = 0;
432  SMyo* myoInstance = (SMyo*)id;
433 
434  SCbData* data = (SCbData*)param;
435 
436  if (!myoInstance)
437  {
438  delete data;
439  return 0;
440  }
441 
442  // OBJbeginreflex(mmachine, objecttype, objectptr, cbtype)
443  if (OBJbeginreflex(m, OBJ_MYO_SCOL, SCOL_PTR myoInstance, SCOL_MYO_POSE_CB))
444  {
445  delete data;
446  return 0;
447  }
448 
449  int pose = (int)data->pose.type();
450  //hack for Alpha compatibilty replace twist gesture by pinky
451  if (pose == 6)
452  pose = 5;
453 
454  MMpush(m, ITOM(pose));
455 
456  k=OBJcallreflex(m, 1);
457 
458  delete data;
459  return k;
460 }
461 
462 int getMyoConnectedCb(mmachine m, SCOL_PTR_TYPE id, LONG param)
463 {
464  int k = 0;
465  SMyo* myoInstance = (SMyo*)id;
466 
467  if (!myoInstance)
468  return 0;
469 
470  // OBJbeginreflex(mmachine, objecttype, objectptr, cbtype)
471  if (OBJbeginreflex(m, OBJ_MYO_SCOL, SCOL_PTR myoInstance, SCOL_MYO_CONNECTED_CB))
472  return 0;
473 
474  k=OBJcallreflex(m, 0);
475  return k;
476 }
477 
478 int getMyoDisconnectedCb(mmachine m, SCOL_PTR_TYPE id, LONG param)
479 {
480  int k = 0;
481  SMyo* myoInstance = (SMyo*)id;
482 
483  if (!myoInstance)
484  return 0;
485 
486  // OBJbeginreflex(mmachine, objecttype, objectptr, cbtype)
487  if (OBJbeginreflex(m, OBJ_MYO_SCOL, SCOL_PTR myoInstance, SCOL_MYO_DISCONNECTED_CB))
488  return 0;
489 
490  k=OBJcallreflex(m, 0);
491  return k;
492 }
493 
504 int _CBMyoArmRecognized(mmachine m)
505 {
506  return OBJaddreflex(m, OBJ_MYO_SCOL, SCOL_MYO_ARMRECOGNIZED_CB);
507 }
508 
509 int getMyoArmRecognizedCb(mmachine m, SCOL_PTR_TYPE id, LONG param)
510 {
511  int k = 0;
512  SMyo* myoInstance = (SMyo*)id;
513 
514  if (!myoInstance)
515  return 0;
516 
517  // OBJbeginreflex(mmachine, objecttype, objectptr, cbtype)
518  if (OBJbeginreflex(m, OBJ_MYO_SCOL, SCOL_PTR myoInstance, SCOL_MYO_ARMRECOGNIZED_CB))
519  return 0;
520 
521  MMpush(m, ITOM(param));
522 
523  k=OBJcallreflex(m, 1);
524  return k;
525 }
526 
536 int _CBMyoArmLost(mmachine m)
537 {
538  return OBJaddreflex(m, OBJ_MYO_SCOL, SCOL_MYO_ARMLOST_CB);
539 }
540 
541 int getMyoArmLostCb(mmachine m, SCOL_PTR_TYPE id, LONG param)
542 {
543  int k = 0;
544  SMyo* myoInstance = (SMyo*)id;
545 
546  if (!myoInstance)
547  return 0;
548 
549  // OBJbeginreflex(mmachine, objecttype, objectptr, cbtype)
550  if (OBJbeginreflex(m, OBJ_MYO_SCOL, SCOL_PTR myoInstance, SCOL_MYO_ARMLOST_CB))
551  return 0;
552 
553  k=OBJcallreflex(m, 0);
554  return k;
555 }
556 
560 char* mMYOname[]=
561 {
562  "ObjMyo",
563 
564  "_CRmyoDevice",
565  "_DSmyoDevice",
566  "_VibrateMyoDevice",
567  "_GetMyoArmDirection",
568  "_IsMyoDeviceTrained",
569  "_CBMyoOrientation",
570  "_CBMyoAccel",
571  "_CBMyoPose",
572  "_CBMyoArmRecognized",
573  "_CBMyoArmLost"
574 };
575 
579 #define NMYOPKG (sizeof(mMYOname)/sizeof(char*))
580 
584 int (*mMYOfun[NMYOPKG])(mmachine m)=
585 {
586  NULL, //ObjMyo
587 
588  _CRmyoDevice,
589  _DSmyoDevice,
594  _CBMyoAccel,
595  _CBMyoPose,
598 };
599 
603 int mMYOnarg[NMYOPKG]=
604 {
605  TYPTYPE, //ObjMyo
606 
607  5, //_CRmyoDevice
608  1, //_DSmyoDevice
609  2, //_VibrateMyoDevice
610  1, //_GetMyoArmDirection
611  1, //_IsMyoDeviceTrained
612  3, //_CBMyoOrientation
613  3, //_CBMyoAccel
614  3, //_CBMyoPose
615  3, //_CBMyoArmRecognized
616  3 //_CBMyoArmLost
617 };
618 
622 char* mMYOtype[NMYOPKG]=
623 {
624  NULL, //ObjMyo
625 
626  "fun [Chn fun [ObjMyo u0] u1 u0 fun [ObjMyo u0] u1 u0] ObjMyo", //_CRmyoDevice
627  "fun [ObjMyo] I", //_DSmyoDevice
628  "fun [ObjMyo I] I", //_VibrateMyoDevice
629  "fun [ObjMyo] I", //_GetMyoArmDirection
630  "fun [ObjMyo] I", //_IsMyoDeviceTrained
631  "fun [ObjMyo fun [ObjMyo u0 [F F F F]] u1 u0] ObjMyo", //_CBMyoOrientation
632  "fun [ObjMyo fun [ObjMyo u0 [F F F]] u1 u0] ObjMyo", //_CBMyoAccel
633  "fun [ObjMyo fun [ObjMyo u0 I] u1 u0] ObjMyo", //_CBMyoPose
634  "fun [ObjMyo fun [ObjMyo u0 I] u1 u0] ObjMyo", //_CBMyoArmRecognized
635  "fun [ObjMyo fun [ObjMyo u0] u1 u0] ObjMyo" //_CBMyoArmLost
636 };
637 
638 
639 // Everything inside _cond and _endcond is ignored by doxygen
641 
646 int LoadMyo(mmachine m)
647 {
648  int k = 0;
649 
650  MMechostr(MSKDEBUG,"\n" );
651  MMechostr(MSKDEBUG," > Loading MYO Support\n");
652 
653  // initialize myo manager singleton
654  SMyoManager::GetInstance();
655 
656  // Declare a new type of object ("ObjMyo")
657  OBJ_MYO_SCOL = OBJregister(7 /*nb of callback*/, 0, destroyMyoObj, "OBJ_MYO_SCOL");
658  k = PKhardpak(m, "mMYO.pkg-1.0", NMYOPKG, mMYOname, mMYOfun, mMYOnarg, mMYOtype);
659 
660  MYO_CONNECTED_CB = OBJgetUserEvent();
661  OBJdefEvent(MYO_CONNECTED_CB, (int (__cdecl *)(struct Mmachine*, SCOL_PTR_TYPE, LONG))getMyoConnectedCb);
662 
663  MYO_DISCONNECTED_CB = OBJgetUserEvent();
664  OBJdefEvent(MYO_DISCONNECTED_CB, (int (__cdecl *)(struct Mmachine*, SCOL_PTR_TYPE, LONG))getMyoDisconnectedCb);
665 
666  MYO_ORIENTATION_CB = OBJgetUserEvent();
667  OBJdefEvent(MYO_ORIENTATION_CB, (int (__cdecl *)(struct Mmachine*, SCOL_PTR_TYPE, LONG))getMyoOrientationCb);
668 
669  MYO_ACCEL_CB = OBJgetUserEvent();
670  OBJdefEvent(MYO_ACCEL_CB, (int (__cdecl *)(struct Mmachine*, SCOL_PTR_TYPE, LONG))getMyoAccelCb);
671 
672  MYO_POSE_CB = OBJgetUserEvent();
673  OBJdefEvent(MYO_POSE_CB, (int (__cdecl *)(struct Mmachine*, SCOL_PTR_TYPE, LONG))getMyoPoseCb);
674 
675  MYO_ARMRECOGNIZED_CB = OBJgetUserEvent();
676  OBJdefEvent(MYO_ARMRECOGNIZED_CB, (int (__cdecl *)(struct Mmachine*, SCOL_PTR_TYPE, LONG))getMyoArmRecognizedCb);
677 
678  MYO_ARMLOST_CB = OBJgetUserEvent();
679  OBJdefEvent(MYO_ARMLOST_CB, (int (__cdecl *)(struct Mmachine*, SCOL_PTR_TYPE, LONG))getMyoArmLostCb);
680 
681  MMechostr(MSKDEBUG," > Successfully Loaded\n\n");
682  return k;
683 }
684 
685 int CloseMyo()
686 {
687  MMechostr(MSKDEBUG,"\n" );
688  MMechostr(MSKDEBUG," > Unloading MYO Support\n");
689 
690  // kill myo manager singleton
691  SMyoManager::GetInstance()->Kill();
692 
693  MMechostr(MSKDEBUG," > Successfully unloaded\n\n");
694  return 0;
695 }
696 
698 
699 #ifndef SCOL_STATIC
700 
704 extern "C" SCOL_EXPORT int ScolLoadPlugin(mmachine m, cbmachine w)
705 {
706  SCOLinitplugin(w);
707  mm = m;
708 
709  return LoadMyo(m);
710 }
711 
716 extern "C" SCOL_EXPORT int ScolUnloadPlugin()
717 {
718  return CloseMyo();
719 }
720 #else
721 
725 extern "C" SCOL_EXPORT int ScolMyoLoadPlugin(mmachine m, cbmachine w)
726 {
727  SCOLinitplugin(w);
728  mm = m;
729 
730  return LoadMyo(m);
731 }
732 
737 extern "C" SCOL_EXPORT int ScolMyoUnloadPlugin()
738 {
739  return CloseMyo();
740 }
741 #endif
int _CBMyoPose(mmachine m)
_CBMyoPose : Called on a pose gesture
Definition: scolplugin.cpp:424
Definition: sMyo.h:63
int _CRmyoDevice(mmachine m)
_CRmyoDevice : This function create a MYO object
Definition: scolplugin.cpp:117
int _CBMyoOrientation(mmachine m)
_CBMyoOrientation : Called on a Orientation data
Definition: scolplugin.cpp:321
int _VibrateMyoDevice(mmachine m)
_VibrateMyoDevice : Set a vibration period on MYO object
Definition: scolplugin.cpp:211
int _CBMyoArmRecognized(mmachine m)
_CBMyoArmRecognized : Called on when the myo is positionned on the arm
Definition: scolplugin.cpp:504
int _IsMyoDeviceTrained(mmachine m)
_IsMyoDeviceTrained : Get the trained state of the MYO object (Deprecated) always return 1 ...
Definition: scolplugin.cpp:250
int _DSmyoDevice(mmachine m)
_DSmyoDevice : Destroy MYO object
Definition: scolplugin.cpp:181
int _CBMyoArmLost(mmachine m)
_CBMyoArmLost : Called on when the myo is removed from the arm
Definition: scolplugin.cpp:536
int _GetMyoArmDirection(mmachine m)
_GetMyoArmDirection : Get the myo direction on the arm
Definition: scolplugin.cpp:279
Definition: sMyo.h:40
int _CBMyoAccel(mmachine m)
_CBMyoAccel : Called on Acceleration data
Definition: scolplugin.cpp:373