Getting pitch and roll value - android

I am doing a project which is detecting the direction of moving by using accelerometer However, the 3 axis of accelerometer will not always follow the world xyz plane as we tilt or rotate our phone. I was trying to fix it by getting the pitch and roll from the phone and convert the axis of the phone to the world xyz axis. But now my pitch and roll always get 0. Can anyone help me ? or is there any other way to solve my problem? Thanks for the help!
package com.example.suntracking;
import android.app.Activity;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
public class AxisCheck extends Activity implements SensorEventListener{
Sensor accelerometer,magnetometer;
float[] lastAccelerometer = new float[3];
float[] lastMagnetometer = new float[3];
boolean lastAccelerometerSet = false;
boolean lastMagnetometerSet = false;
SensorManager sm;
float pval,rval;
float[] mR = new float[9];
float[] mhold= new float[3];
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
initialize();
accelerometer = sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
magnetometer = sm.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
finish();
}
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
sm.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_NORMAL);
sm.registerListener(this, magnetometer, SensorManager.SENSOR_DELAY_NORMAL);
}
protected void onPause() {
super.onPause();
sm.unregisterListener(this);
}
#Override
public void onAccuracyChanged(Sensor arg0, int arg1) {
// TODO Auto-generated method stub
}
private void initialize() {
// TODO Auto-generated method stub
sm =(SensorManager)getSystemService(SENSOR_SERVICE);
}
#Override
public void onSensorChanged(SensorEvent event) {
// TODO Auto-generated method stub
if (event.sensor == accelerometer) {
System.arraycopy(event.values, 0, lastAccelerometer, 0, event.values.length);
lastAccelerometerSet = true;
} else if (event.sensor == magnetometer) {
System.arraycopy(event.values, 0, lastMagnetometer, 0, event.values.length);
lastMagnetometerSet = true;
}
if (lastAccelerometerSet && lastMagnetometerSet) {
SensorManager.getRotationMatrix(mR, null, lastAccelerometer, lastMagnetometer);
SensorManager.getOrientation(mR,mhold);
pval = Math.round(mhold[1]);
rval = Math.round(mhold[2]);
savePreferences();
}
}
private void savePreferences() {
// TODO Auto-generated method stub
SharedPreferences savedata = getSharedPreferences("savealldata",0);
Editor editor=savedata.edit();
editor.putFloat("pval", pval);
editor.putFloat("rval", rval);
editor.commit();
}
}

Related

NullPointerException when closing app

I have a bubble level app that I am trying to incorporate into another app I wrote. The app works as it should, except when you push the android back button, it force closes the app with the following exception:
Logcat:
04-08 08:10:15.056: I/SensorManager(21015): Set normal delay = true
04-08 08:10:15.287: W/dalvikvm(21015): threadid=11: thread exiting with uncaught exception (group=0x41ca7ac8)
04-08 08:10:15.287: E/AndroidRuntime(21015): FATAL EXCEPTION: Thread-89255
04-08 08:10:15.287: E/AndroidRuntime(21015): java.lang.NullPointerException
04-08 08:10:15.287: E/AndroidRuntime(21015): at com.golfstuff.ecolevel.MoveSkater$DrawSkater.run(MoveSkater.java:121)
04-08 08:10:15.287: E/AndroidRuntime(21015): at java.lang.Thread.run(Thread.java:856)
Movescater:
package com.golfstuff.ecolevel;
// STAND-ALONE
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnTouchListener;
public class MoveSkater extends Activity implements SensorEventListener, OnTouchListener {
Bitmap level, logo, ball, lines,background, exit;
SensorManager sm;
DrawSkater ourView;
MediaPlayer beepl,beepr;
//private Camera cameraObj;
float x,y,sensorX, sensorY,mid,exitx,exity;
boolean isRunning;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
// Check for Accelerometer
beepl = MediaPlayer.create(this, R.raw.beepleft);
beepr = MediaPlayer.create(this, R.raw.beepright);
ourView = new DrawSkater(this);
ourView.resume();
ourView.setOnTouchListener(this);
sm = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
if(sm.getSensorList(Sensor.TYPE_ACCELEROMETER).size() !=0) {
Sensor s=sm.getSensorList(Sensor.TYPE_ACCELEROMETER).get(0);
sm.registerListener(this, s, SensorManager.SENSOR_DELAY_NORMAL);
}
lines=BitmapFactory.decodeResource(getResources(), R.drawable.lines);
level=BitmapFactory.decodeResource(getResources(), R.drawable.newlevel);
logo=BitmapFactory.decodeResource(getResources(), R.drawable.ecolevel);
ball = BitmapFactory.decodeResource(getResources(), R.drawable.newball);
background = BitmapFactory.decodeResource(getResources(), R.drawable.levelback);
exit = BitmapFactory.decodeResource(getResources(), R.drawable.btn_exit);
x = y = sensorX = sensorY = 0;
setContentView(ourView);
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// TODO Auto-generated method stub
}
#Override
public void onSensorChanged(SensorEvent event) {
// TODO Auto-generated method stub
try {
Thread.sleep(30);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
sensorX=event.values[1];
sensorY=event.values[0];
}
public class DrawSkater extends SurfaceView implements Runnable {
SurfaceHolder ourHolder;
Thread ourThread = null;
boolean isRunning = true;
public DrawSkater(Context context) {
super(context);
ourHolder = getHolder();
}
public void pause() {
isRunning = false;
while(true) {
try {
ourThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
finish();
}
break;
}
ourThread = null;
}
public void resume() {
isRunning = true;
ourThread = new Thread(this);
ourThread.start();
}
#Override
public void run() {
// TODO Auto-generated method stub
while(isRunning) {
if(!ourHolder.getSurface().isValid())
continue;
Canvas canvas = ourHolder.lockCanvas();
canvas.drawColor(Color.WHITE); *** JAVA ERROR POINT ***
canvas.drawBitmap(background, canvas.getWidth()/2-640,canvas.getHeight()/2-200,null);
canvas.drawBitmap(logo, canvas.getWidth()/2-230,0,null);
canvas.drawBitmap(level, canvas.getWidth()/2-605,canvas.getHeight()-130,null);
canvas.drawBitmap(exit, 20,140,null);
mid = ((sensorX*(-100))+600);
// Right Side Max
if (mid > 757) {
mid = 757;
} //Left Side Max
else if (mid <422) {
mid = 422;
}
canvas.drawBitmap(ball, mid,494,null);
canvas.drawBitmap(lines,575,497,null);
canvas.drawBitmap(lines,653,497,null);
ourHolder.unlockCanvasAndPost(canvas);
// Left Center Tone
if ((mid > 570 && mid<580)) {
//beepl.start();
}
// Right Center Tone
else if (mid >600 && mid<610) {
//beepr.start();
}
}
}
}
I've tried in the onPause method: stop(); interupt(); finish();
Also tried: onDestroy method
Thanks in advance for your help.

Getting 0 as return values from accelrometer

I am having problem with this accelerometer coding. I keep getting 0 as my return value from the accelerometer. Just ignore the cal_displace part first because now i cant get any value form the accelerometer. your help is much appreciated.
package com.example.suntracking;
import android.app.Activity;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.widget.TextView;
public class Accelerometer extends Activity implements SensorEventListener{
Sensor accelerometer;
SensorManager sm;
int samintval;
float ax,ay,axtemp ,aytemp ,sx,sy;
TextView showax,showay,showaxtemp,showaytemp;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.accelerometer);
loadsavedPref();
initialize();
cal_displace();
display();
savePreferences();
}
private void display() {
// TODO Auto-generated method stub
showax.setText(""+ax);
showay.setText(""+ay);
showaxtemp.setText(""+axtemp);
showaytemp.setText(""+aytemp);
}
#Override
protected void onResume()
{
super.onResume();
sm.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_NORMAL);
}
#Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
sm.unregisterListener(this);
}
private void initialize() {
// TODO Auto-generated method stub
showax=(TextView)findViewById(R.id.tvax);
showay=(TextView)findViewById(R.id.tvay);
showaxtemp=(TextView)findViewById(R.id.tvaxtemp);
showaytemp=(TextView)findViewById(R.id.tvaytemp);
sm=(SensorManager)getSystemService(SENSOR_SERVICE);
accelerometer=sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
sm.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_NORMAL);
}
private void loadsavedPref() {
// TODO Auto-generated method stub
SharedPreferences savedata= getSharedPreferences("savealldata",0);
samintval = savedata.getInt("samintval", 1000);
}
private void cal_displace() {
// TODO Auto-generated method stub
sx = (float) (0.5 * ((ax - axtemp)/(samintval/1000)) * (samintval / 1000)*(samintval / 1000));
sy = (float) (0.5 * ((ay - aytemp)/(samintval/1000)) * (samintval / 1000)*(samintval / 1000));
//axtemp = ax;
//aytemp = ay;
}
#Override
public void onAccuracyChanged(Sensor arg0, int arg1) {
// TODO Auto-generated method stub
}
#Override
public void onSensorChanged(SensorEvent event) {
// TODO Auto-generated method stub
if (event.sensor.getType() != Sensor.TYPE_ACCELEROMETER)
return;
ax = event.values[0];
ay = event.values[1];
}
private void savePreferences() {
// TODO Auto-generated method stub
SharedPreferences savedata = getSharedPreferences("savealldata",0);
Editor editor=savedata.edit();
editor.putFloat("ax", ax);
editor.putFloat("ay", ay);
editor.putFloat("axtemp", axtemp);
editor.putFloat("aytemp", aytemp);
editor.commit();
}
}
You're registering sensor listener twice, in initialize() and in onResume() - do it in onResume() only.
You're getting the values, but not updating your TextViews. Modify your onSensorChanged():
#Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() != Sensor.TYPE_ACCELEROMETER)
return;
ax = event.values[0];
ay = event.values[1];
//update TextViews
display();
}

Errors occuring when using accelerometer in android

I am getting some errors when using the accelerometer sensor.
These errors don't affect the functioning of the class, but when I press the back button , my application is "force closed."
09-22 21:33:17.119: E/SensorManager(1397): registerListener :: handle = 0
name= BMA220 delay= 20000 Listener= com.ic.edata.GameActivity#4053b4e8
09-22 21:33:17.119: E/SensorManager(1397): =======>>>Sensor Thread RUNNING <<<========
09-22 21:33:17.129: E/SensorManager(1397): reg :: handle = 0
09-22 21:33:17.139: E/SensorManager(1397): registerListener :: handle = 0
name= BMA220 delay= 20000 Listener= com.ic.edata.GameActivity#4053b4e8
09-22 21:33:17.149: E/SensorManager(1397): reg :: handle = 0
09-22 21:33:36.029: E/SensorManager(1397): unregisterListener:: handle = 0
Listener= com.ic.edata.GameActivity#4053b4e8 name = BMA220
09-22 21:33:36.029: E/SensorManager(1397): unregisterListener:: handle = 0
Listener= com.ic.edata.GameActivity#4053b4e8 name = BMA220
09-22 21:33:36.179: E/SensorManager(1397): unregisterListener:: handle = 0
Listener= com.ic.edata.GameActivity#4053b4e8 name = BMA220
`
My code for this activity is
package com.ic.edata;
import java.util.Random;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class GameActivity extends Activity implements SensorEventListener {
float x,y,sensorX,sensorY,a,b;
Bitmap ball,end1;
SensorManager sm;
MySurfaceView ourSurfaceView;
Thread ourThread = null;
int count=0;
Sensor s;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
sm = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
if(sm.getSensorList(Sensor.TYPE_ACCELEROMETER).size()!=0)
{
s = sm.getSensorList(Sensor.TYPE_ACCELEROMETER).get(0);
sm.registerListener(this, s, SensorManager.SENSOR_DELAY_GAME);
}
ball = BitmapFactory.decodeResource(getResources(), R.drawable.blueball2);
end1 = BitmapFactory.decodeResource(getResources(), R.drawable.end1);
x=y=sensorX=sensorY=0;
a=150;
b=170;
ourSurfaceView = new MySurfaceView(this);
ourSurfaceView.resume();
setContentView(ourSurfaceView);
}
#Override
public void onDestroy() //main thread stopped
{
sm.unregisterListener(this,s);
super.onDestroy();
}
#Override
protected void onPause() {
sm.unregisterListener(this, s);
super.onPause();
}
#Override
protected void onResume() {
sm.registerListener(this, s, SensorManager.SENSOR_DELAY_GAME);
super.onResume();
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// TODO Auto-generated method stub
}
#Override
public void onSensorChanged(SensorEvent event) {
// TODO Auto-generated method stub
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
sensorX=-event.values[0];
sensorY=event.values[1];
x=x+sensorX;
y=y+sensorY;
}
public class MySurfaceView extends SurfaceView implements Runnable {
SurfaceHolder ourHolder;
boolean isRunning = false;
public MySurfaceView(Context context) {
super(context);
ourHolder = getHolder();
}
public void pause()
{
isRunning=false;
while(true)
{
try {
ourThread.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
break;
}
ourThread=null;
}
public void resume()
{
isRunning=true;
ourThread = new Thread(this);
ourThread.start();
}
#Override
public void run() {
// TODO Auto-generated method stub
while(isRunning)
{
if(!ourHolder.getSurface().isValid())
continue;
Random r = new Random();
Canvas canvas = ourHolder.lockCanvas();
canvas.drawColor(Color.rgb(230, 223, 223));
Paint p1 = new Paint(Color.BLACK);
p1.setTextSize(25);
float endx=a;
float endy=b;
if(x>canvas.getWidth())
x=0-ball.getWidth();
if(y>canvas.getHeight())
y=0-ball.getHeight();
if(x<0-ball.getWidth())
x=canvas.getWidth();
if(y<0-ball.getHeight())
y=canvas.getHeight();
canvas.drawBitmap(end1, endx, endy, null);
if((x>endx-16)&&(x<endx+24)&&(y>endy)&&(y<endy+24))
{
a=r.nextInt(canvas.getWidth()-40);
b=r.nextInt(canvas.getHeight()-40);
x=r.nextInt(canvas.getWidth());
y=r.nextInt(canvas.getHeight());
count++;
}
canvas.drawBitmap(ball, x, y, null);
canvas.drawText("Score : "+count,
canvas.getWidth()/2-45, 20, p1);
ourHolder.unlockCanvasAndPost(canvas);
}
}
}
#Override
public void onBackPressed() {
onDestroy();
super.onBackPressed();
}
}
put unregistering in a try catch block, its unregistering in onPause and then getting exception in ondestroy because theres nothing to unregister
First stop calling ondestroy() in onbackpress. ondestroy calls when it has to be call ucant forcfully call it
second for ur error... remove the code "sm.unregisterListener(this,s);"from destroy

accelerometer in android

The following example is taken from internet. In all the example the code is explained using a seprate thread for sensor manager. Could you please let me know why all the accelerometer is explained with a seperate thread for SensorManager
package com.example.myapp1;
import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.TextView;
import android.widget.Toast;
public class Accelerate extends Activity implements SensorEventListener {
float x, y, sensorX, sensorY;
Bitmap ball;
SensorManager sm;
Sensor s;
MyBringBackSurface ourSurfaceView;
public class MyBringBackSurface extends SurfaceView implements Runnable {
SurfaceHolder ourHolder;
Thread ourThread = null;
boolean isRunning = false;
public MyBringBackSurface(Context context) {
super(context);
Log.i("Notice","In constructor of mybringbacksurface");
ourHolder = getHolder();
}
public void pause() {
isRunning = false;
Log.i("Notice","In pause of mybringbacksurface");
while (true) {
try {
ourThread.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
break;
}
ourThread = null;
}
public void resume() {
Log.i("Notice","In resume of mybringbacksurface");
isRunning = true;
ourThread = new Thread(this);
ourThread.start();
}
public void run() {
// TODO Auto-generated method stub
Log.i("Notice","In run of mybringbacksurface");
while (isRunning) {
if (!ourHolder.getSurface().isValid())
continue;
Canvas canvas = ourHolder.lockCanvas();
canvas.drawRGB(02, 02, 150);
float centerX = canvas.getWidth() / 2;
float centerY = canvas.getHeight() / 2;
canvas.drawBitmap(ball, centerX - sensorX * 18, centerY
+ sensorY * 18, null);
ourHolder.unlockCanvasAndPost(canvas);
}
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
Log.i("Notice","In oncreate of of Accelerator");
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
sm = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
if (sm.getSensorList(Sensor.TYPE_ACCELEROMETER).size() != 0) {
s = sm.getSensorList(Sensor.TYPE_ACCELEROMETER).get(0);
sm.registerListener(this, s, SensorManager.SENSOR_DELAY_NORMAL);
}
ball = BitmapFactory.decodeResource(getResources(), R.drawable.greenball);
x = y = sensorX = sensorY = 0;
ourSurfaceView = new MyBringBackSurface(this);
ourSurfaceView.resume();
setContentView(ourSurfaceView);
}
#Override
protected void onPause() {
// TODO Auto-generated method stub
Log.i("Notice","In pause of Accelerator");
sm.unregisterListener(this, s);
super.onPause();
ourSurfaceView.pause();
}
public void onAccuracyChanged(Sensor arg0, int arg1) {
// TODO Auto-generated method stub
}
public void onSensorChanged(SensorEvent e) {
// TODO Auto-generated method stub
Log.i("Notice","In sensorchanged of of Accelerator");
try {
Thread.sleep(32);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
sensorX = e.values[0];
sensorY = e.values[1];
}
}
Because the continuous while loop in the run() method would block the main thread and cause your app to be shut down with an "Application Not Responding" or ANR.
Anytime you have a long running loop like that, it must happen in a separate thread.

Accelerometer code

I am working with accelerometer for android, I do not understand why the three axis for them which I have assigned to mSensorX, mSensorY and mSensorZ are labelled as unused when I have used them in the onSensorChange, could someone please help me understand this.
package com.example.imageaccel;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.widget.TextView;
public class ImageAccelActivity extends Activity implements SensorEventListener {
/** Called when the activity is first created. */
TextView x, y, z;
private float mSensorX;
private float mSensorY;
private float mSensorZ;
private Bitmap car;
private SensorManager sm = null;
// Bitmap car1;
// float x1, y1, z1, sensorX, sensorY, sensorZ;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
x = (TextView)findViewById(R.id.x_axis);
y = (TextView)findViewById(R.id.y_axis);
z = (TextView)findViewById(R.id.z_axis);
SensorManager sm = (SensorManager)getSystemService(Context.SENSOR_SERVICE);
if (sm.getSensorList(Sensor.TYPE_ACCELEROMETER).size() !=0){
Sensor s = sm.getSensorList(Sensor.TYPE_ACCELEROMETER).get(0);
sm.registerListener(this, s, SensorManager.SENSOR_DELAY_NORMAL);
}
}
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
sm.registerListener(this, sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),SensorManager.SENSOR_DELAY_NORMAL);
}
#Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
sm.unregisterListener(this);
super.onPause();
}
#Override
public void onAccuracyChanged(Sensor arg0, int arg1) {
// TODO Auto-generated method stub
}
#Override
public void onSensorChanged(SensorEvent ev) {
// TODO Auto-generated method stub
if(ev.sensor.getType()==Sensor.TYPE_ACCELEROMETER){
mSensorX = ev.values[0];
mSensorY = ev.values[1];
mSensorZ = ev.values[2];
}
}
protected void onDraw(Canvas canvas) {
/*
* draw the background
*/
canvas.drawBitmap(car, 0, 0, null);
}
}
You're setting them to a value but that's only half the story. The complaint is most likely that you're never using them after that. It's similar to the C code:
int main (void) {
int a = 1;
return 0;
}
While that compiles and runs fine, you do get a warning (using gcc -Wall) that:
warning: unused variable 'a'
Quick way to check this theory, put a:
System.out.println (mSensorX + "," + mSensorY + "," + mSensorZ);
(or some other sort of use) following the setting and see if the warning disappears.
I think there is a warning because of the if statement there..In some cases they won't be used and hence the warning..That's my opinion:)

Categories

Resources