32#include <scolPlugin.h>
35#include "tools/Vector3d.h"
36#include "tools/Quaternion.h"
47#include <scolMemoryHelper.hpp>
49#if !defined (ANDROID) && !defined(_WIN32)
50extern int(*CallMainThread)(
void*, mmachine m);
55int SCOL_SENSOR_DATA_CB = 0;
57#define GD_semiMajorAxis 6378137.000000
58#define GD_TranMercB 6356752.314245
59#define GD_geocentF 0.003352810664
61void geodeticOffsetInv(
double refLat,
double refLon,
double lat,
double lon,
double& xOffset,
double& yOffset)
63 double a = GD_semiMajorAxis;
64 double b = GD_TranMercB;
65 double f = GD_geocentF;
67 double L = lon - refLon;
68 double U1 = atan((1 - f) * tan(refLat));
69 double U2 = atan((1 - f) * tan(lat));
70 double sinU1 = sin(U1);
71 double cosU1 = cos(U1);
72 double sinU2 = sin(U2);
73 double cosU2 = cos(U2);
87 sinLambda = sin(lambda);
88 cosLambda = cos(lambda);
89 sinSigma = sqrt((cosU2*sinLambda) * (cosU2*sinLambda) +
90 (cosU1*sinU2 - sinU1*cosU2*cosLambda) *
91 (cosU1*sinU2 - sinU1*cosU2*cosLambda));
98 cosSigma = sinU1*sinU2 + cosU1*cosU2*cosLambda;
99 sigma = atan2(sinSigma, cosSigma);
100 sinAlpha = cosU1 * cosU2 * sinLambda / sinSigma;
101 cosSqAlpha = 1 - sinAlpha*sinAlpha;
102 cos2SigmaM = cosSigma - 2 * sinU1*sinU2 / cosSqAlpha;
103 if (cos2SigmaM != cos2SigmaM)
107 double C = f / 16 * cosSqAlpha*(4 + f*(4 - 3 * cosSqAlpha));
109 lambda = L + (1 - C) * f * sinAlpha *
110 (sigma + C*sinSigma*(cos2SigmaM + C*cosSigma*(-1 + 2 * cos2SigmaM*cos2SigmaM)));
111 }
while (fabs(lambda - lambdaP) > 1e-12 && --iterLimit > 0);
120 double uSq = cosSqAlpha * (a*a - b*b) / (b*b);
121 double A = 1 + uSq / 16384 * (4096 + uSq*(-768 + uSq*(320 - 175 * uSq)));
122 double B = uSq / 1024 * (256 + uSq*(-128 + uSq*(74 - 47 * uSq)));
123 double deltaSigma = B*sinSigma*(cos2SigmaM + B / 4 * (cosSigma*(-1 + 2 * cos2SigmaM*cos2SigmaM) -
124 B / 6 * cos2SigmaM*(-3 + 4 * sinSigma*sinSigma)*(-3 + 4 * cos2SigmaM*cos2SigmaM)));
125 double s = b*A*(sigma - deltaSigma);
127 double bearing = atan2(cosU2*sinLambda, cosU1*sinU2 - sinU1*cosU2*cosLambda);
128 xOffset = sin(bearing)*s;
129 yOffset = cos(bearing)*s;
157 MMechostr(MSKDEBUG,
"_IsSensorAvailable\n");
160 int itype = MMget(m, 0);
163 MMechostr(MSKRUNTIME,
"_IsSensorAvailable : No Sensor Type Given\n");
168 if (!SSensorManager::GetInstance())
170 MMechostr(MSKRUNTIME,
"_IsSensorAvailable : No Sensor Manager Initialized\n");
175 SSensorType type = (SSensorType)MTOI(itype);
177 bool isAvailable = SSensorManager::GetInstance()->IsAvailable(type);
178 MMset(m, 0, ITOM(isAvailable ? 1 : 0));
181 MMechostr(MSKDEBUG,
"ok\n");
198 MMechostr(MSKDEBUG,
"_IsSensorEnabled\n");
201 int itype = MMget(m, 0);
204 MMechostr(MSKRUNTIME,
"_IsSensorEnabled : No Sensor Type Given\n");
209 if (!SSensorManager::GetInstance())
211 MMechostr(MSKRUNTIME,
"_IsSensorEnabled : No Sensor Manager Initialized\n");
216 SSensorType type = (SSensorType)MTOI(itype);
217 if (!SSensorManager::GetInstance()->IsAvailable(type))
219 MMechostr(MSKDEBUG,
"_SetSensorEnable : invalid sensor\n");
224 bool isEnabled = SSensorManager::GetInstance()->IsEnabled(type);
225 MMset(m, 0, ITOM(isEnabled ? 1 : 0));
228 MMechostr(MSKDEBUG,
"ok\n");
244#if defined(ANDROID) || defined(_WIN32)
245int _SetSensorEnable(mmachine m)
251 MMechostr(MSKDEBUG,
"_SetSensorEnable\n");
254 int istate = MMpull(m);
255 int itype = MMget(m, 0);
258 MMechostr(MSKRUNTIME,
"_SetSensorEnable : No Sensor Type Given\n");
263 if (!SSensorManager::GetInstance())
265 MMechostr(MSKRUNTIME,
"_SetSensorEnable : No Sensor Manager Initialized\n");
270 SSensorType type = (SSensorType)MTOI(itype);
271 if (!SSensorManager::GetInstance()->IsAvailable(type))
273 MMechostr(MSKDEBUG,
"_SetSensorEnable : invalid sensor\n");
279 if (istate != NIL && MTOI(istate) > 0)
282 int success = SSensorManager::GetInstance()->SetSensorEnable(type, state);
284 MMset(m, 0, ITOM((success == 1) ? 1 : NIL));
287 MMechostr(MSKDEBUG,
"ok\n");
293#if !defined(ANDROID) && !defined(_WIN32)
294int _SetSensorEnable(mmachine m)
313 MMechostr(MSKDEBUG,
"_GetVectorData\n");
316 int itype = MMget(m, 0);
319 MMechostr(MSKRUNTIME,
"_GetVectorData : No Sensor Type Given\n");
324 if (!SSensorManager::GetInstance())
326 MMechostr(MSKDEBUG,
"_GetVectorData : No Sensor Manager Initialized\n");
331 SSensorType type = (SSensorType)MTOI(itype);
332 if (!SSensorManager::GetInstance()->IsAvailable(type))
334 MMechostr(MSKDEBUG,
"_SetSensorEnable : invalid sensor\n");
339 SSensor* sensor = SSensorManager::GetInstance()->GetSensorByType(type);
342 MMechostr(MSKDEBUG,
"_GetVectorData : invalid sensor\n");
349 int vectorData = MMmalloc(m, 3, TYPETAB);
350 if (vectorData == NIL)
356 MMstore(m, vectorData, 0, FTOM((
float)sensorData.vec3.x));
357 MMstore(m, vectorData, 1, FTOM((
float)sensorData.vec3.y));
358 MMstore(m, vectorData, 2, FTOM((
float)sensorData.vec3.z));
359 MMset(m, 0, PTOM(vectorData));
362 MMechostr(MSKDEBUG,
"ok\n");
380 MMechostr(MSKDEBUG,
"_GetDeviceQuaternionOrientation\n");
383 double delayInSecond = 0;
384 int idelay = MMget(m, 0);
386 delayInSecond = (double)(MTOI(idelay)) / 1000.0;
388 if (!SSensorManager::GetInstance())
390 MMechostr(MSKDEBUG,
"_GetDeviceQuaternionOrientation : No Sensor Manager Initialized\n");
395 if (!SSensorManager::GetInstance()->IsAvailable(SSENSOR_TYPE_ORIENTATION))
397 MMechostr(MSKDEBUG,
"_GetDeviceQuaternionOrientation : sensor not available\n");
402 Quaternion orientation = SSensorManager::GetInstance()->GetDeviceOrientation(delayInSecond);
404 int quatData = MMmalloc(m, 4, TYPETAB);
407 MMechostr(MSKDEBUG,
"_GetDeviceQuaternionOrientation : memory allocation error\n");
412 MMstore(m, quatData, 0, FTOM(orientation.x));
413 MMstore(m, quatData, 1, FTOM(orientation.y));
414 MMstore(m, quatData, 2, FTOM(orientation.z));
415 MMstore(m, quatData, 3, FTOM(orientation.w));
416 MMset(m, 0, PTOM(quatData));
419 MMechostr(MSKDEBUG,
"ok\n");
490 MMechostr(MSKDEBUG,
"_GetFloatData\n");
493 if (!SSensorManager::GetInstance())
495 MMechostr(MSKDEBUG,
"_GetFloatData : No Sensor Manager Initialized\n");
500 int itype = MMget(m, 0);
503 MMechostr(MSKRUNTIME,
"_GetFloatData : No Sensor Type Given\n");
508 SSensorType type = (SSensorType)MTOI(itype);
509 if (!SSensorManager::GetInstance()->IsAvailable(type))
511 MMechostr(MSKDEBUG,
"_SetSensorEnable : invalid sensor\n");
516 SSensor* sensor = SSensorManager::GetInstance()->GetSensorByType(type);
519 MMechostr(MSKDEBUG,
"_GetFloatData : invalid sensor\n");
526 MMset(m, 0, FTOM(sensorData.fval));
529 MMechostr(MSKDEBUG,
"ok\n");
547 MMechostr(MSKDEBUG,
"_SetDeviceVibration\n");
550 int itime = MMget(m, 0);
553 MMechostr(MSKRUNTIME,
"_SetDeviceVibration : Define a time duration\n");
558 if (MTOI(itime) <= 0)
560 MMechostr(MSKRUNTIME,
"_SetDeviceVibration : Define a correct time duration\n");
565 if (!SSensorManager::GetInstance())
567 MMechostr(MSKRUNTIME,
"_SetDeviceVibration : No Sensor Manager Initialized\n");
572 SSensorManager::GetInstance()->Vibrate(MTOI(itime));
574 MMset(m, 0, ITOM(1));
577 MMechostr(MSKDEBUG,
"ok\n");
595 MMechostr(MSKDEBUG,
"_SetDeviceVibrationPattern\n");
598 int iloop = MMpull(m);
599 int ipattern = MMget(m, 0);
602 MMechostr(MSKRUNTIME,
"_SetDeviceVibrationPattern : Define a pattern\n");
607 if (!SSensorManager::GetInstance())
609 MMechostr(MSKRUNTIME,
"_SetDeviceVibrationPattern : No Sensor Manager Initialized\n");
614 bool loop = (MTOI(iloop) > 0) ?
true :
false;
615 ipattern = MTOP(ipattern);
616 std::vector<int> pattern;
619 while (ipattern != NIL)
621 curptr = MTOI(MMfetch(m, ipattern, 0));
624 pattern.push_back(curptr);
626 ipattern = MTOP(MMfetch(m, ipattern, 1));
630 SSensorManager::GetInstance()->VibratePattern(pattern, loop);
632 MMset(m, 0, ITOM(1));
635 MMechostr(MSKDEBUG,
"ok\n");
650 MMechostr(MSKDEBUG,
"_StartDeviceVibration\n");
653 if (!SSensorManager::GetInstance())
655 MMechostr(MSKRUNTIME,
"_StartDeviceVibration : No Sensor Manager Initialized\n");
660 SSensorManager::GetInstance()->StartVibration();
665 MMechostr(MSKDEBUG,
"ok\n");
681 MMechostr(MSKDEBUG,
"_StopDeviceVibration\n");
684 if (!SSensorManager::GetInstance())
686 MMechostr(MSKRUNTIME,
"_StopDeviceVibration : No Sensor Manager Initialized\n");
691 SSensorManager::GetInstance()->StopVibration();
696 MMechostr(MSKDEBUG,
"ok\n");
712 MMechostr(MSKDEBUG,
"_StartDeviceLocation\n");
716 struct android_app* androidApp = (
struct android_app*)SCgetExtra(
"this_inst");
720 ANativeActivity* nativeActivity = androidApp->activity;
721 if (nativeActivity->vm->GetEnv((
void**)&env, JNI_VERSION_1_6) != JNI_OK)
722 nativeActivity->vm->AttachCurrentThread(&env, NULL);
725 jobject oActivity = nativeActivity->clazz;
726 jclass cActivity = env->GetObjectClass(oActivity);
728 bool authPassed =
false;
731 jfieldID reqBoolean = env->GetFieldID(cActivity,
"mMinAuthPassed",
"Z");
732 authPassed = (bool)env->GetBooleanField(oActivity, reqBoolean);
734 boost::this_thread::sleep_for(boost::chrono::milliseconds(100));
738 jmethodID location_permission = env->GetMethodID(cActivity,
"RequestLocationPermission",
"()V");
739 if (location_permission)
740 env->CallVoidMethod(oActivity, location_permission);
742 if (env->ExceptionCheck())
744 env->ExceptionClear();
745 MMechostr(MSKRUNTIME,
"Android location exception : Check android.permission.FINE_LOCATION\n");
751 jfieldID reqBoolean = env->GetFieldID(cActivity,
"mLocationAuthPassed",
"Z");
752 authPassed = (bool)env->GetBooleanField(oActivity, reqBoolean);
754 boost::this_thread::sleep_for(boost::chrono::milliseconds(100));
756 env->DeleteLocalRef(cActivity);
757 nativeActivity->vm->DetachCurrentThread();
761 if (!SSensorManager::GetInstance())
763 MMechostr(MSKRUNTIME,
"_StartDeviceLocation : No Sensor Manager Initialized\n");
768 SSensorManager::GetInstance()->StartLocationService();
773 MMechostr(MSKDEBUG,
"ok\n");
789 MMechostr(MSKDEBUG,
"_StopDeviceLocation\n");
792 if (!SSensorManager::GetInstance())
794 MMechostr(MSKRUNTIME,
"_StopDeviceLocation : No Sensor Manager Initialized\n");
799 SSensorManager::GetInstance()->StopLocationService();
804 MMechostr(MSKDEBUG,
"ok\n");
820 MMechostr(MSKDEBUG,
"_StopDeviceLocation\n");
823 if (!SSensorManager::GetInstance())
825 MMechostr(MSKRUNTIME,
"_GetDeviceLocation : No Sensor Manager Initialized\n");
830 float lat, lon, alt = 0.0f;
831 if (!SSensorManager::GetInstance()->GetLocation(lon, lat, alt))
837 int tuple = MMmalloc(m, 3, TYPETAB);
843 MMstore(m, tuple, 0, FTOM(lon));
844 MMstore(m, tuple, 1, FTOM(lat));
845 MMstore(m, tuple, 2, FTOM(alt));
846 MMpush(m, PTOM(tuple));
849 MMechostr(MSKDEBUG,
"ok\n");
870 MMechostr(MSKDEBUG,
"_StopDeviceLocation\n");
874 int rlat = MMpull(m);
875 int rlon = MMget(m, 0);
877 if ((lat == NIL) || (lon == NIL) || (rlat == NIL) || (rlon == NIL))
883 double rolong = MTOF(rlon);
884 double rolat = MTOF(rlat);
885 double dlong = MTOF(lon);
886 double dlat = MTOF(lat);
887 double xoffset = 0.0;
888 double yoffset = 0.0;
889 geodeticOffsetInv(rolat, rolong, dlat, dlong, xoffset, yoffset);
891 int tuple = MMmalloc(m, 2, TYPETAB);
897 MMstore(m, tuple, 0, FTOM((
float)xoffset));
898 MMstore(m, tuple, 1, FTOM((
float)yoffset));
899 MMset(m, 0, PTOM(tuple));
902 MMechostr(MSKDEBUG,
"ok\n");
923int _CrSensorCallBack(mmachine m)
926 MMechostr(0,
"_CrSensorCallBack\n");
932 int pUser = MMget(m, 0);
933 int cbfun = MMget(m, 1);
934 int itype = MMget(m, 2);
935 int channel = MMget(m, 3);
938 if (channel == NIL || cbfun == NIL)
940 MMechostr(MSKDEBUG,
"Channel NIL\n");
941 SEDROP(m, 3); MMset(m, 0, NIL);
945 SSensorType type = (SSensorType)MTOI(itype);
946 SSensorCb* sensorCb = SSensorManager::GetInstance()->AddSensorCallBack(type);
947 if (sensorCb == NULL)
949 MMechostr(MSKDEBUG,
"Axis sensor failed\n");
950 SAFE_DELETE(sensorCb);
951 SEDROP(m, 3); MMset(m, 0, NIL);
956 if ((k = MMpush(m, MMget(m, 3))))
960 if ((MMpushPointer(m, sensorCb) != 0))
962 SAFE_DELETE(sensorCb);
968 k = OBJcreate(m, OBJSENSORSCOL, SCOL_PTR sensorCb, NIL, 0);
971 if ((k = MMpush(m, MMget(m, 2))))
973 if ((k = MMpush(m, MMget(m, 2))))
975 if ((k = OBJaddreflex(m, OBJSENSORSCOL, SCOL_SENSOR_DATA_CB)))
999 MMechostr(MSKDEBUG,
"_DsSensorCallBack\n");
1002 int sensorCb = MMget(m, 0);
1003 if (sensorCb == NIL)
1009 OBJdelTM(m, OBJSENSORSCOL, sensorCb);
1010 MMset(m, 0, ITOM(0));
1013 MMechostr(MSKDEBUG,
"ok\n");
1023static NativeDefinition sSensorDef[] =
1025 {
"ObjSensorCB", TYPTYPE, NULL, NULL},
1026 {
"SENSOR_TYPE_UNKNOWN", TYPVAR,
"I", SCOL_TYPTYPE(SSENSOR_TYPE_UNKNOWN) },
1027 {
"SENSOR_TYPE_ACCELEROMETER", TYPVAR,
"I", SCOL_TYPTYPE(SSENSOR_TYPE_ACCELEROMETER) },
1028 {
"SENSOR_TYPE_MAGNETIC_FIELD", TYPVAR,
"I", SCOL_TYPTYPE(SSENSOR_TYPE_MAGNETIC_FIELD) },
1029 {
"SENSOR_TYPE_GYROSCOPE", TYPVAR,
"I", SCOL_TYPTYPE(SSENSOR_TYPE_GYROSCOPE) },
1030 {
"SENSOR_TYPE_LIGHT", TYPVAR,
"I", SCOL_TYPTYPE(SSENSOR_TYPE_LIGHT) },
1031 {
"SENSOR_TYPE_PROXIMITY", TYPVAR,
"I", SCOL_TYPTYPE(SSENSOR_TYPE_PROXIMITY) },
1032 {
"SENSOR_TYPE_ORIENTATION", TYPVAR,
"I", SCOL_TYPTYPE(SSENSOR_TYPE_ORIENTATION) },
1035 {
"_SetSensorEnable", 2,
"fun [I I] I", _SetSensorEnable },
1047 {
"_CrSensorCallBack", 4,
"fun [Chn I fun [ObjSensorCB u0 [F F F] F F] u1 u0] ObjSensorCB", _CrSensorCallBack },
1061int destroySensorObj(mmachine m, SCOL_PTR_TYPE handsys,
int handscol)
1063 SSensorCb* sensorCb = MMgetPointer<SSensorCb*>(m, MTOP(handscol));
1064 SSensorManager::GetInstance()->RemoveSensorCallBack(sensorCb);
1065 MMsetPointer<SSensorCb*>(m, MTOP(handscol), 0);
1068 MMechostr(MSKDEBUG,
"Sensor object destroyed.\n");
1078int getSensorData(mmachine m, SCOL_PTR_TYPE
id, SCOL_PTR_TYPE param)
1087 if (OBJbeginreflex(m, OBJSENSORSCOL, SCOL_PTR sensor, SCOL_SENSOR_DATA_CB))
1089 MMechostr(MSKDEBUG,
"Sensor not found\n");
1093 int tuple = MMmalloc(m, 3, TYPETAB);
1100 MMstore(m, tuple, 0, FTOM(ndata->vec3.x));
1101 MMstore(m, tuple, 1, FTOM(ndata->vec3.y));
1102 MMstore(m, tuple, 2, FTOM(ndata->vec3.z));
1104 MMpush(m, PTOM(tuple));
1105 MMpush(m, FTOM(ndata->fval));
1106 MMpush(m, FTOM(ndata->delta));
1109 k = OBJcallreflex(m, 3 );
1114#if !defined(ANDROID) && !defined(_WIN32)
1116int _InitSensors(mmachine m)
1118 SSensorManager::GetInstance();
1127int LoadSensor(mmachine m)
1129 int k = PKhardpak2(m,
"SensorsEngine.pkg-1.0",
sizeof(sSensorDef) /
sizeof(sSensorDef[0]), sSensorDef);
1131#if defined(ANDROID) || defined (_WIN32)
1132 SSensorManager::GetInstance();
1134 CallMainThread = (int(__cdecl *)(
void*, mmachine))SCgetExtra(
"callMainThread");
1135 CallMainThread((
void*)_InitSensors, m);
1143 SSensorManager::GetInstance()->Kill();
1153extern "C" SCOL_EXPORT
void ScolPauseWindowPlugin(mmachine m)
1155extern "C" SCOL_EXPORT
void ScolSensorPauseWindowPlugin(mmachine m)
1159 SSensorManager::GetInstance()->PauseSensorManager();
1167extern "C" SCOL_EXPORT
void ScolResumeWindowPlugin(mmachine m)
1169extern "C" SCOL_EXPORT
void ScolSensorResumeWindowPlugin(mmachine m)
1173 SSensorManager::GetInstance()->ResumeSensorManager();
1182extern "C" SCOL_EXPORT
int ScolLoadPlugin(mmachine m, cbmachine w)
1184extern "C" SCOL_EXPORT
int ScolSensorLoadPlugin(mmachine m, cbmachine w)
1189 OBJSENSORSCOL = OBJregister(1 , 1, destroySensorObj,
"OBJSENSORSCOL");
1193 SENSOR_DATA_CB = OBJgetUserEvent();
1195 OBJdefEvent(SENSOR_DATA_CB, getSensorData);
1197 return LoadSensor(m);
1205extern "C" SCOL_EXPORT
int ScolUnloadPlugin()
1207extern "C" SCOL_EXPORT
int ScolSensorUnloadPlugin()
1210 return CloseSensor();
int _GetVectorData(mmachine m)
_GetVectorData : get data from a sensor : get a 3D vector with float value
int _IsSensorAvailable(mmachine m)
_IsSensorAvailable : indicates if whether or not a sensor of the given type is available on the curre...
int _GetFloatData(mmachine m)
_GetDeviceEulerOrientation : get device orientation as euler angles
int _SetDeviceVibrationPattern(mmachine m)
_SetDeviceVibrationPattern : Set a vibration pattern from a time / pause list
int _GetDeviceLocation(mmachine m)
_GetDeviceLocation : Get the device location
int _StopDeviceLocation(mmachine m)
_StopDeviceLocation : Stop the device location service
int _StartDeviceLocation(mmachine m)
_StartDeviceLocation : Start the device location service
int _SetSensorEnableSync(mmachine m)
_SetSensorEnable : enable or disable a sensor of a given type.
int _DsSensorCallBack(mmachine m)
_DsSensorCallBack : Destroy sensor callback object
int _StopDeviceVibration(mmachine m)
_StopDeviceVibration : Stop the device vibration
int _StartDeviceVibration(mmachine m)
_StartDeviceVibration : Start the device vibration
int _GetLocationOffset(mmachine m)
_GetLocationOffset : Get the offset from a longitude / latitude reference in meters
int _GetDeviceQuaternionOrientation(mmachine m)
_GetDeviceQuaternionOrientation : get device orientation in x seconds (quaternion)
int _IsSensorEnabled(mmachine m)
_IsSensorEnabled : indicates if whether or not the sensor of the given type is enabled.
int _SetDeviceVibration(mmachine m)
_SetDeviceVibration : Set a vibration time duration on the device