Sign in to follow this  
Madara

C/C++ tilt sensor for Android/iOS

Recommended Posts

I'm making a game for Android and iOS using OpenGL ES and SDL in C++ native code for cross-platformability and more efficient code. Though I am currently only testing on Android. (Inefficient code is a a BIG pet pevy of mine and a battery sucker.) OpenGL ES is for the graphics and SDL for the touch sensors, sound, OS events, timers, and to hold OpenGL ES. But there is a problem, how do I get tilt input with C/C++ code as I want to avoid the JNI as much as possible.

 

Can anyone help me out?

Share this post


Link to post
Share on other sites

Qt has recently added support for mobile platforms, and has a C++ sensor API.

 

If you aren't already using Qt, you almost certainly don't want to include the giant collection of libraries that is Qt, but luckily, Qt is opensource under LGPL and GPL, so you could look to see how they do it, separate out their sensor code, wrap it in its own separate LGPL'd library, and then use that - dynamically linking to it, so the rest of your closed-source commercial product isn't hampered by the licensing.

 

Or you could just examine it, to see what API function calls they use, and then write your own wrapper (or better yet, submit a patch for SDL so others can benefit) by reading the API documentation.

Share this post


Link to post
Share on other sites

You can get the accelerometer like this in C++:

ASensorManager *sensorManager = ASensorManager_getInstance();
const ASensor *accelSensor = ASensorManager_getDefaultSensor(sensorManager, ASENSOR_TYPE_ACCELEROMETER);

Then create an event queue for the sensors.

ASensorEventQueue *sensorEventQueue = ASensorManager_createEventQueue(sensorManager, looper, LOOPER_ID_USER, NULL, NULL);

If you use the android_native_app_glue "framework" the looper is in the struct android_app that is passed to your android_main.

 

Then when your main-loop poll (ALooper_pollAll?) returns LOOPER_ID_USER (I guess you can build your own messages by adding +1 +2 etc to LOOPER_ID_USER), handle the sensor-events:

ASensorEvent sensorEvent;
ssize_t sensorResult = ASensorEventQueue_getEvents(sensorEventQueue, &sensorEvent, 1);
while(sensorResult > 0) {
	codeToHandleSensorEvent(sensorEvent);
	
	sensorResult = ASensorEventQueue_getEvents(sensorEventQueue, &sensorEvent, 1);
}

And finally handle the ASensorEvent:

switch(sensorEvent.type) {
	case ASENSOR_TYPE_ACCELEROMETER:
		sensorEvent.acceleration.x;
		sensorEvent.acceleration.y;
		sensorEvent.acceleration.z;
	break;
}

I'm not really an expert at this stuff, but that's how I do it when using android_native_app_glue and run the main-loop from android_main.

 

EDIT: You also need to enable the sensor I think with ASensorEventQueue_enableSensor, and you can disable it when your app loses focus for example to avoid using it unnecessarily. And there's an ASensorEventQueue_setEventRate for setting how often you want data events from it.

 

Check <android/sensor.h>, it's the header with the functions and structures and has some comments in it.

Edited by Erik Rufelt

Share this post


Link to post
Share on other sites

Qt has recently added support for mobile platforms, and has a C++ sensor API.

 

If you aren't already using Qt, you almost certainly don't want to include the giant collection of libraries that is Qt, but luckily, Qt is opensource under LGPL and GPL, so you could look to see how they do it, separate out their sensor code, wrap it in its own separate LGPL'd library, and then use that - dynamically linking to it, so the rest of your closed-source commercial product isn't hampered by the licensing.

 

Or you could just examine it, to see what API function calls they use, and then write your own wrapper (or better yet, submit a patch for SDL so others can benefit) by reading the API documentation.

 

Thanks for the great ideas. I will make my own SDL patch for the tilt sensor.

 

 

You can get the accelerometer like this in C++:

ASensorManager *sensorManager = ASensorManager_getInstance();
const ASensor *accelSensor = ASensorManager_getDefaultSensor(sensorManager, ASENSOR_TYPE_ACCELEROMETER);

Then create an event queue for the sensors.

ASensorEventQueue *sensorEventQueue = ASensorManager_createEventQueue(sensorManager, looper, LOOPER_ID_USER, NULL, NULL);

If you use the android_native_app_glue "framework" the looper is in the struct android_app that is passed to your android_main.

 

Then when your main-loop poll (ALooper_pollAll?) returns LOOPER_ID_USER (I guess you can build your own messages by adding +1 +2 etc to LOOPER_ID_USER), handle the sensor-events:

ASensorEvent sensorEvent;
ssize_t sensorResult = ASensorEventQueue_getEvents(sensorEventQueue, &sensorEvent, 1);
while(sensorResult > 0) {
	codeToHandleSensorEvent(sensorEvent);
	
	sensorResult = ASensorEventQueue_getEvents(sensorEventQueue, &sensorEvent, 1);
}

And finally handle the ASensorEvent:

switch(sensorEvent.type) {
	case ASENSOR_TYPE_ACCELEROMETER:
		sensorEvent.acceleration.x;
		sensorEvent.acceleration.y;
		sensorEvent.acceleration.z;
	break;
}

I'm not really an expert at this stuff, but that's how I do it when using android_native_app_glue and run the main-loop from android_main.

 

EDIT: You also need to enable the sensor I think with ASensorEventQueue_enableSensor, and you can disable it when your app loses focus for example to avoid using it unnecessarily. And there's an ASensorEventQueue_setEventRate for setting how often you want data events from it.

 

Check <android/sensor.h>, it's the header with the functions and structures and has some comments in it.

 

Thanks, I googled #include <android/sensor.h> and found what I needed. Unfortunately I couldn't find the iOS equivalent.

Share this post


Link to post
Share on other sites

Google for "ios accelerometer". The easiest one is UIAccelerometer I think, just one line of code that registers for events and a selector that receives them if I remember correctly. I think it's deprecated though and we're supposed to move to CMMotionManager.

Share this post


Link to post
Share on other sites

Qt has recently added support for mobile platforms, and has a C++ sensor API.
 
If you aren't already using Qt, you almost certainly don't want to include the giant collection of libraries that is Qt, but luckily, Qt is opensource under LGPL and GPL, so you could look to see how they do it, separate out their sensor code, wrap it in its own separate LGPL'd library, and then use that - dynamically linking to it, so the rest of your closed-source commercial product isn't hampered by the licensing.
 
Or you could just examine it, to see what API function calls they use, and then write your own wrapper (or better yet, submit a patch for SDL so others can benefit) by reading the API documentation.


The LGPL is incompatible with Apples TOS (for the app store) and dynamic linking isn't much of an option on iOS(it is possible but apps using dynamic linking will be rejected by Apple). so using LGPL code in mobile cross platform applications is a pretty bad idea unless you intend to only support jailbroken iOS devices.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this