Use gyroscope to rotate the camera

HI!,

I´m starting to test differents helloWorlds so I can create an augmented reallity game.



For now im tryng to use the giroscope from android.



I´m able to recieve an x, y, and z values (they turn arround the bouds [0, 250] , [-50, 50], [-50,50]. But i’ve dont have too much idea about how i could parse them so i can turn the android gyroscope values into cam.rotate values…



¿Any idea?.



Here are the codes…



[java]package com.mycompany.mygame;



import android.content.Context;

import mygame.Main;



import android.hardware.Sensor;

import android.hardware.SensorEvent;

import android.hardware.SensorEventListener;

import android.hardware.SensorListener;

import android.hardware.SensorManager;

import android.os.Bundle;

import android.util.Log;

import java.math.*;





import java.lang.Math;



import com.jme3.app.AndroidHarness;

import com.jme3.system.android.AndroidConfigChooser.ConfigType;



import mygame.Main;



public class MainActivity extends AndroidHarness implements SensorListener {



SensorManager sm = null;

Main juego;



@Override

public void onCreate(Bundle savedInstanceState) {

sm = (SensorManager) getSystemService(SENSOR_SERVICE);

super.onCreate(savedInstanceState);

}



public MainActivity() {





// Set the application class to run

appClass = “mygame.Main”; // clickable hud navigation buttons & accelarometer



eglConfigType = ConfigType.BEST;



exitDialogTitle = “Exit?”;

exitDialogMessage = “Press Yes”;

eglConfigVerboseLogging = false;



}



private static final float NS2S = 1.0f / 1000000000.0f;

private final float[] deltaRotationVector = new float[4];

private float timestamp;



public void onSensorChanged(int sensor, float[] values) {

synchronized (this) {

if (sensor == SensorManager.SENSOR_ORIENTATION) {



System.out.println("Orientation X: " + values[0]);

System.out.println("Orientation Y: " + values[1]);

System.out.println("Orientation Z: " + values[2]);

juego.rotateCamera(values[0], values[1], values[2]);

}

}

}



public void onAccuracyChanged(int sensor, int accuracy) {

//Log.d(“Hola Mundo”, "onAccuracyChanged: " + sensor + ", accuracy: " + accuracy);

}



@Override

protected void onResume() {

super.onResume();

sm.registerListener(this, SensorManager.SENSOR_ORIENTATION,

SensorManager.SENSOR_DELAY_NORMAL);

}



@Override

protected void onStop() {

sm.unregisterListener(this);

super.onStop();

}

}[/java]



[java]package mygame;



import com.jme3.app.SimpleApplication;

import com.jme3.material.Material;

import com.jme3.math.ColorRGBA;

import com.jme3.math.Quaternion;

import com.jme3.math.Vector3f;

import com.jme3.renderer.RenderManager;

import com.jme3.scene.Geometry;

import com.jme3.scene.shape.Box;



/**

  • test
  • @author normenhansen

    /

    public class Main extends SimpleApplication {



    public static void main(String[] args) {

    Main app = new Main();

    app.start();

    }



    @Override

    public void simpleInitApp() {

    Box b = new Box(Vector3f.ZERO, 1, 1, 1);

    Geometry geom = new Geometry(“Box”, b);



    Material mat = new Material(assetManager, “Common/MatDefs/Misc/Unshaded.j3md”);

    mat.setColor(“Color”, ColorRGBA.Blue);

    geom.setMaterial(mat);



    rootNode.attachChild(geom);

    }



    @Override

    public void simpleUpdate(float tpf) {

    //TODO: add update code

    }



    @Override

    public void simpleRender(RenderManager rm) {

    //TODO: add render code

    }



    public void rotateCamera(float x, float y, float z) {

    cam.setRotation(new Quaternion (0.1f, x, y, z));

    }

    }[/java]



    Also in android develop site i found this code, i think its for make the transformation from degrees to radians…



    [java]private static final float NS2S = 1.0f / 1000000000.0f;

    private final float[] deltaRotationVector = new float4;

    private float timestamp;



    public void onSensorChanged(SensorEvent event) {

    // This timestep’s delta rotation to be multiplied by the current rotation

    // after computing it from the gyro sample data.

    if (timestamp != 0) {

    final float dT = (event.timestamp - timestamp) * NS2S;

    // Axis of the rotation sample, not normalized yet.

    float axisX = event.values[0];

    float axisY = event.values[1];

    float axisZ = event.values[2];



    // Calculate the angular speed of the sample

    float omegaMagnitude = sqrt(axisX
    axisX + axisYaxisY + axisZaxisZ);



    // Normalize the rotation vector if it’s big enough to get the axis

    if (omegaMagnitude > EPSILON) {

    axisX /= omegaMagnitude;

    axisY /= omegaMagnitude;

    axisZ /= omegaMagnitude;

    }



    // Integrate around this axis with the angular speed by the timestep

    // in order to get a delta rotation from this sample over the timestep

    // We will convert this axis-angle representation of the delta rotation

    // into a quaternion before turning it into the rotation matrix.

    float thetaOverTwo = omegaMagnitude * dT / 2.0f;

    float sinThetaOverTwo = sin(thetaOverTwo);

    float cosThetaOverTwo = cos(thetaOverTwo);

    deltaRotationVector[0] = sinThetaOverTwo * axisX;

    deltaRotationVector[1] = sinThetaOverTwo * axisY;

    deltaRotationVector[2] = sinThetaOverTwo * axisZ;

    deltaRotationVector[3] = cosThetaOverTwo;

    }

    timestamp = event.timestamp;

    float[] deltaRotationMatrix = new float[9];

    SensorManager.getRotationMatrixFromVector(deltaRotationMatrix, deltaRotationVector);

    // User code should concatenate the delta rotation we computed with the current rotation

    // in order to get the updated rotation.

    // rotationCurrent = rotationCurrent * deltaRotationMatrix;

    }

    [/java]
1 Like

Check out this: https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:math_for_dummies



Heres some code I did for the ARDrone, maybe it can help you:

[java]

public void update(float tpf) {

//always poll data

NavData data = queue.poll();

while (data != null) {

float pitch = (float) Math.toRadians(data.getPitch());

float yaw = (float) Math.toRadians(data.getYaw());

float roll = (float) Math.toRadians(data.getRoll());

rot.fromAngles(-pitch, -yaw, roll);

loc.setY(data.getAltitude() * mult);

loc.addLocal(data.getVx() * mult, 0, data.getVz() * mult);

if (spatial != null && enabled) {

spatial.setLocalTranslation(loc);

spatial.setLocalRotation(rot);

}

data = queue.poll();

}

super.update(tpf);

}[/java]

3 Likes

Humm, i dont know, ARDrone is a plane sistem right?? :PPP



I´ve been reading the dummies tutorial and try this code:



[java]

public void onSensorChanged(int sensor, float[] values) {

synchronized (this) {

if (sensor == SensorManager.SENSOR_ORIENTATION) {

System.out.println("Orientation X: " + values[0]);

System.out.println("Orientation Y: " + values[1]);

System.out.println("Orientation Z: " + values[2]);

juego.rotateCamera(values[0], values[1], values[2]);

}

}

}[/java]



and



[java] public void rotateCamera(float x, float y, float z) {

float angles[];

angles = new float[]{x, y, z};

Quaternion quatC = new Quaternion();

quatC.fromAngles(angles);

}[/java]



But still having an error on the android mobile “The application cannot be oppenned”. There I cant find any documentation in the forums about how to use the giroscope in jmonkey… Nobody has try it before?.



Thx.

1 Like

Moving the camera is a well documented jme feature and getting gyro info should be a well documented android feature, you just need to put the two together. Heres a link to the android docs and an example app that accesses the camera. Your synchronized{} statement doesn’t make what you do thread safe, in fact its completely unsafe.

https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:android#using_android_specific_functions

http://hub.jmonkeyengine.org/AndroidCamera.zip

Okkk, I know what was givving me error, I have to includes this code.



[java]

public void onSensorChanged(int sensor, float[] values) {

if (juego == null) {

juego = (Main) getJmeApplication();

return;

}

[/java]



So i´ve check that i´ve inizialize the jmonkey application before access its methods…



Know i rotate really fast!!!, i need to find the way to calibrate the values. I´ll make some research in the android develop site. Thx.

1 Like