How to implement gyroscope sensor in android? -
i'm trying write simplest implementation of gyroscope (only log orientation of screen when it's changed). provide simple example of this?
this i'm trying right now:
public class lessonfiveglsurfaceview extends glsurfaceview implements sensoreventlistener { private lessonfiverenderer mrenderer; public lessonfiveglsurfaceview(context context) { super(context); system.out.println("test"); } @override public void onsensorchanged(sensorevent event) { //output roll, pitch , yawn values system.out.println("orientation x (roll) :"+ float.tostring(event.values[2]) +"\n"+ "orientation y (pitch) :"+ float.tostring(event.values[1]) +"\n"+ "orientation z (yaw) :"+ float.tostring(event.values[0])); }
however i'm getting error: "the type lessonfiveglsurfaceview must implement inherited abstract method sensoreventlistener.onaccuracychanged(sensor, int)".
here class came absract use gyroscope sensor in android smooth input data little, correct orientation output tablet , phone doesn't have same natural orientation (phone in portrait while tablet in landscape):
/** * uses sensor api determine phones orientation. * registering events accelerator , magnetometer (compass) * rotation matrix computed. matrix can used rotate * opengl scene. */ public class phonegyroscope implements sensoreventlistener{ private static final string tag = phonegyroscope.class.getsimplename(); private sensormanager msensormanager; private windowmanager mwindowmanager; private float[] maccelgravitydata = new float[3]; private float[] mgeomagneticdata = new float[3]; private float[] mrotationmatrix = new float[16]; private float[] bufferedaccelgdata = new float[3]; private float[] bufferedmagnetdata = new float[3]; public phonegyroscope(context context) { msensormanager = (sensormanager) context.getsystemservice(context.sensor_service); mwindowmanager = (windowmanager) context.getsystemservice(context.window_service); } public void start() { msensormanager.registerlistener(this, msensormanager.getdefaultsensor(sensor.type_accelerometer), sensormanager.sensor_delay_game ); msensormanager.registerlistener(this, msensormanager.getdefaultsensor(sensor.type_magnetic_field), sensormanager.sensor_delay_game ); } public void stop() { msensormanager.unregisterlistener(this); } private void loadnewsensordata(sensorevent event) { final int type = event.sensor.gettype(); if (type == sensor.type_accelerometer) { //smoothing sensor data bit maccelgravitydata[0]=(maccelgravitydata[0]*2+event.values[0])*0.33334f; maccelgravitydata[1]=(maccelgravitydata[1]*2+event.values[1])*0.33334f; maccelgravitydata[2]=(maccelgravitydata[2]*2+event.values[2])*0.33334f; } if (type == sensor.type_magnetic_field) { //smoothing sensor data bit mgeomagneticdata[0]=(mgeomagneticdata[0]*1+event.values[0])*0.5f; mgeomagneticdata[1]=(mgeomagneticdata[1]*1+event.values[1])*0.5f; mgeomagneticdata[2]=(mgeomagneticdata[2]*1+event.values[2])*0.5f; float x = mgeomagneticdata[0]; float y = mgeomagneticdata[1]; float z = mgeomagneticdata[2]; double field = math.sqrt(x*x+y*y+z*z); if (field>25 && field<65){ log.e(tag, "loadnewsensordata : wrong magnetic data, need recalibration field = " + field); } } } private void rootmeansquarebuffer(float[] target, float[] values) { final float amplification = 200.0f; float buffer = 20.0f; target[0] += amplification; target[1] += amplification; target[2] += amplification; values[0] += amplification; values[1] += amplification; values[2] += amplification; target[0] = (float) (math .sqrt((target[0] * target[0] * buffer + values[0] * values[0]) / (1 + buffer))); target[1] = (float) (math .sqrt((target[1] * target[1] * buffer + values[1] * values[1]) / (1 + buffer))); target[2] = (float) (math .sqrt((target[2] * target[2] * buffer + values[2] * values[2]) / (1 + buffer))); target[0] -= amplification; target[1] -= amplification; target[2] -= amplification; values[0] -= amplification; values[1] -= amplification; values[2] -= amplification; } /* * tablets have landscape default orientation, screen rotation 0 or 180 when orientation landscape, , smartphones have portrait. * use next code difference between tablets , smartphones: */ public static int getscreenorientation(display display){ int orientation; if(display.getwidth()==display.getheight()){ orientation = configuration.orientation_square; }else{ //if width less height portrait if(display.getwidth() < display.getheight()){ orientation = configuration.orientation_portrait; }else{ // if not of above definitly landscape orientation = configuration.orientation_landscape; } } return orientation; } private void debugsensordata(sensorevent event) { stringbuilder builder = new stringbuilder(); builder.append("--- sensor ---"); builder.append("\nname: "); sensor sensor = event.sensor; builder.append(sensor.getname()); builder.append("\ntype: "); builder.append(sensor.gettype()); builder.append("\nvendor: "); builder.append(sensor.getvendor()); builder.append("\nversion: "); builder.append(sensor.getversion()); builder.append("\nmaximum range: "); builder.append(sensor.getmaximumrange()); builder.append("\npower: "); builder.append(sensor.getpower()); builder.append("\nresolution: "); builder.append(sensor.getresolution()); builder.append("\n\n--- event ---"); builder.append("\naccuracy: "); builder.append(event.accuracy); builder.append("\ntimestamp: "); builder.append(event.timestamp); builder.append("\nvalues:\n"); (int = 0; < event.values.length; i++) { // ... builder.append(" ["); builder.append(i); builder.append("] = "); builder.append(event.values[i]); builder.append("\n"); } log.d(tag, builder.tostring()); } @override public void onaccuracychanged(sensor sensor, int accuracy) { // todo auto-generated method stub } /* sensor processing/rotation matrix * each time sensor update happens onsensorchanged method called. * receive raw sensor data. * first of want take sensor data accelerometer , magnetometer , smooth out reduce jitters. * there can call getrotationmatrix function our smoothed accelerometer , magnetometer data. * rotation matrix outputs mapped have y axis pointing out top of phone, when phone flat on table facing north, read {0,0,0}. * need read {0,0,0} when pointing north, sitting vertical. achieve remap co-ordinates system x axis negative. * following code example shows how acheived. */ @override public void onsensorchanged(sensorevent event) { if (event.accuracy == sensormanager.sensor_status_unreliable) { return; } loadnewsensordata(event); int type=event.sensor.gettype(); if (maccelgravitydata != null && mgeomagneticdata != null) { if ((type==sensor.type_magnetic_field) || (type==sensor.type_accelerometer)) { rootmeansquarebuffer(bufferedaccelgdata, maccelgravitydata); rootmeansquarebuffer(bufferedmagnetdata, mgeomagneticdata); if (sensormanager.getrotationmatrix(mrotationmatrix, null, bufferedaccelgdata, bufferedmagnetdata)){ display display = mwindowmanager.getdefaultdisplay(); int orientation = getscreenorientation(display); int rotation = display.getrotation(); boolean dontremapcoordinates = (orientation == configuration.orientation_landscape && rotation == surface.rotation_0) || (orientation == configuration.orientation_landscape && rotation == surface.rotation_180) || (orientation == configuration.orientation_portrait && rotation == surface.rotation_90) || (orientation == configuration.orientation_portrait && rotation == surface.rotation_270); if( !dontremapcoordinates){ sensormanager.remapcoordinatesystem( mrotationmatrix, sensormanager.axis_y, sensormanager.axis_minus_x, mrotationmatrix); } debugsensordata(event); } } } } }
Comments
Post a Comment