Commit d04c6ed0 authored by August Bjalemark's avatar August Bjalemark
Browse files

to Anders

parent 7fa05bda
.gradle
/local.properties
/.idea/workspace.xml
.idea
*.iml
.DS_Store
apply plugin: 'android'
android {
compileSdkVersion 19
buildToolsVersion "19.0.3"
defaultConfig {
minSdkVersion 13
targetSdkVersion 19
versionCode 1
versionName "1.0"
}
buildTypes {
release {
runProguard false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
}
}
dependencies {
compile 'com.android.support:appcompat-v7:19.+'
compile 'com.android.support:support-v4:19.+'
compile fileTree(dir: 'libs', include: ['*.jar'])
compile files('libs/androidplot-core-0.6.0 .jar')
}
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /Applications/Android Studio.app/sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the ProGuard
# include property in project.properties.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="imu3.imu5.app" >
<uses-feature android:name="android.hardware.sensor.accelerometer" android:required="true" />
<uses-feature android:name="android.hardware.sensor.gyroscope" android:required="true" />
<uses-feature android:name="android.hardware.sensor.magnetometer" android:required="true" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE"/>
<application
android:allowBackup="true"
android:icon="@drawable/lth_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="imu3.imu5.app.MainActivity"
android:label="@string/app_name"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
package imu3.imu5.app;
import android.util.Log;
import java.lang.Number;
/**
* Created by H on 08/05/14.
*/
public class AccAngleFilter implements Filter {
private long tid;
public AccAngleFilter(){
}
public void filt(){
MainActivity.accXBuffer.addValue((float) Math.atan2(MainActivity.accRXBuffer.getFirst().doubleValue(), MainActivity.accRZBuffer.getFirst().doubleValue()),MainActivity.accRXBuffer.getTime().longValue());
MainActivity.accYBuffer.addValue((float) Math.atan2(MainActivity.accRYBuffer.getFirst().doubleValue(), MainActivity.accRZBuffer.getFirst().doubleValue()),MainActivity.accRYBuffer.getTime().longValue());
Log.e("t1", "AccAngle"+((System.nanoTime() - tid) / 1000000) ); // measure frequency
tid = System.nanoTime();
}
}
package imu3.imu5.app;
import android.util.Log;
/**
* Created by H on 26/05/14.
*/
public class AccAngleLowpassFilter implements Filter {
private double accXAngle;
private double accYAngle;
private long tid;
public AccAngleLowpassFilter(){
}
@Override
public void filt() {
accXAngle = (float) Math.atan2(MainActivity.accRXBuffer.getFirst().doubleValue(), MainActivity.accRZBuffer.getFirst().doubleValue());
MainActivity.accFXBuffer.addValue((float) (MainActivity.alpha*MainActivity.accFXBuffer.getFirst().doubleValue()+(1-MainActivity.alpha)*accXAngle), MainActivity.accRXBuffer.getTime().longValue());
accYAngle = (float) Math.atan2(MainActivity.accRYBuffer.getFirst().doubleValue(), MainActivity.accRZBuffer.getFirst().doubleValue());
MainActivity.accFYBuffer.addValue((float) (MainActivity.alpha*MainActivity.accFYBuffer.getFirst().doubleValue()+(1-MainActivity.alpha)*accYAngle), MainActivity.accRYBuffer.getTime().longValue());
Log.e("t1", "AccAngleLowpass" + ((System.nanoTime() - tid) / 1000000)); // measure frequency
tid = System.nanoTime();
}
}
package imu3.imu5.app;
import android.util.Log;
/**
* Created by H on 28/05/14.
*/
public class AccGyroCompFilter implements Filter{
private double oldTimeStamp;
private double velOffsetX;
private double velOffsetY;
public AccGyroCompFilter(){
}
public void filt(){
if(MainActivity.calibrate){
Log.e("t1","calibrate accGyro1"+ Boolean.toString(MainActivity.calibrate));
velOffsetX = MainActivity.gyroRXBuffer.getFirst().doubleValue();
velOffsetY = MainActivity.gyroRYBuffer.getFirst().doubleValue();
//MainActivity.calibrate=false;
//Log.e("t1","calibrate accGyro2"+ velOffsetX);
//Log.e("t1","calibrate accGyro2"+ Boolean.toString(MainActivity.calibrate));
}
//Log.e("t1","accgyro");
MainActivity.accGyroXBuffer.addValue( (float) (MainActivity.alpha* (MainActivity.accGyroXBuffer.getFirst().doubleValue() + (MainActivity.gyroRXBuffer.getFirst().doubleValue()-velOffsetX)* (MainActivity.gyroTimestamp - oldTimeStamp)*0.000000001f) + (1-MainActivity.alpha)* (Math.atan2(MainActivity.accRXBuffer.getFirst().doubleValue(), MainActivity.accRXBuffer.getFirst().doubleValue()))),MainActivity.gyroTimestamp);
MainActivity.accGyroYBuffer.addValue( (float) (MainActivity.alpha* (MainActivity.accGyroYBuffer.getFirst().doubleValue() + (MainActivity.gyroRYBuffer.getFirst().doubleValue()-velOffsetY)* (MainActivity.gyroTimestamp - oldTimeStamp)*0.000000001f) + (1-MainActivity.alpha)* (Math.atan2(MainActivity.accRYBuffer.getFirst().doubleValue(), MainActivity.accRYBuffer.getFirst().doubleValue()))),MainActivity.gyroTimestamp);
oldTimeStamp = MainActivity.gyroTimestamp;
}
}
package imu3.imu5.app;
/**
* Created by H on 03/05/14.
*/
import android.os.AsyncTask;
import android.util.Log;
public class AlgorithmThread extends AsyncTask<Object, Object, Object>{
private AccAngleFilter accAngleFilter;
private AccAngleLowpassFilter accAngleLowpassFilter;
private AccGyroCompFilter accGyroCompFilter;
private long tid;
public AlgorithmThread(){
accAngleFilter = new AccAngleFilter();
accAngleLowpassFilter = new AccAngleLowpassFilter();
accGyroCompFilter = new AccGyroCompFilter();
}
protected Object doInBackground(Object... params) {
while (true){
try {
Thread.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.e("t1", "AlgorithmThread"+((System.nanoTime() - tid) / 1000000) ); // measure frequency
tid = System.nanoTime();
accAngleFilter.filt();
accAngleLowpassFilter.filt();
accGyroCompFilter.filt();
//return null;
}
}
}
\ No newline at end of file
package imu3.imu5.app;
import com.androidplot.xy.SimpleXYSeries;
import com.androidplot.xy.XYSeries;
import org.w3c.dom.Element;
import java.util.LinkedList;
import java.lang.Number;
import java.lang.Double;
/**
* Created by H on 03/05/14.
*/
public class DataBuffer{
public int color;
public String title;
public SimpleXYSeries series;
public DataBuffer(String title, int color){
this.color = color;
this.title = title;
this.series = new SimpleXYSeries(title);
series.addFirst(0,0);
}
public void addValue(float value, long timestamp){
series.addFirst(timestamp, value);
if(series.size() > 500 ){
series.removeLast();
}
}
public int size() { return series.size(); }
public Number getFirst() {
int s = series.size();
if(s < 0){
return null;
}else {
return series.getY(0);
}
}
public Number getTime() {
int s = series.size();
if(s < 0){
return null;
}else {
return series.getX(0);
}
}
public void useImplicitXVals() { series.useImplicitXVals(); }
}
package imu3.imu5.app;
/**
* Created by H on 03/05/14.
*/
public interface Filter {
public void filt(); // calculations
}
This diff is collapsed.
This diff is collapsed.
package imu3.imu5.app;
import android.util.Log;
/**
* Created by H on 28/05/14.
*/
public class GyroAngleFilter {
private double velOffsetX;
private double velOffsetY;
private double calibX;
private double calibY;
private long oldTimeStamp;
public GyroAngleFilter(){
MainActivity.calibrate = true;
}
public void filt(long timeStamp){
if(MainActivity.calibrate){
//Log.e("t1","calibrate gyro1"+ Boolean.toString(MainActivity.calibrate));
velOffsetX = MainActivity.gyroRXBuffer.getFirst().doubleValue();
velOffsetY = MainActivity.gyroRYBuffer.getFirst().doubleValue();
calibX = MainActivity.gyroXBuffer.getFirst().doubleValue();
calibY = MainActivity.gyroXBuffer.getFirst().doubleValue();
MainActivity.calibrate=false;
//Log.e("t1","calibrate gyro"+ velOffsetX+""+ velOffsetY);
//Log.e("t1","calibrate gyro2"+ Boolean.toString(MainActivity.calibrate));
}
MainActivity.gyroXBuffer.addValue((float) ( (MainActivity.gyroXBuffer.getFirst().doubleValue() - calibX - (MainActivity.gyroRXBuffer.getFirst().doubleValue()-velOffsetX) * (timeStamp - oldTimeStamp)*0.000000001f)),timeStamp);
MainActivity.gyroYBuffer.addValue((float) ( (MainActivity.gyroYBuffer.getFirst().doubleValue() - calibY - (MainActivity.gyroRYBuffer.getFirst().doubleValue()-velOffsetY) * (timeStamp - oldTimeStamp)*0.000000001f)),timeStamp);
oldTimeStamp = timeStamp;
//Log.e("t1", "angle X: " + MainActivity.gyroXBuffer.getFirst());
//Log.e("t1", "angle Y: " + MainActivity.gyroYBuffer.getFirst());
//Log.e("t1", "timestamp: "+timeStamp+"");
}
}
package imu3.imu5.app;
import android.util.Log;
/**
* Created by H on 28/05/14.
*/
public class GyroAngleHighpassFilter {
private double velOffset;
private long oldTimeStamp;
public GyroAngleHighpassFilter(){}
public void filt(long timeStamp){
// if(MainActivity.calibrate){
// MainActivity.calibrate=false;
// velOffset = MainActivity.gyroRXBuffer.getFirst().doubleValue();
// return;
// }
MainActivity.gyroFXBuffer.addValue((float) ((1 - MainActivity.beta)* (MainActivity.gyroFXBuffer.getFirst().doubleValue() - (MainActivity.gyroRXBuffer.getFirst().doubleValue()-velOffset) * (timeStamp - oldTimeStamp)*0.000000001f)),timeStamp);
oldTimeStamp = timeStamp;
//Log.d("t1", "angleFilter: " + MainActivity.gyroFXBuffer.getFirst());
//Log.d("t1", "timestampFilter: "+timeStamp+"");
}
}
\ No newline at end of file
package imu3.imu5.app;
/**
* Created by H on 28/05/14.
*/
public class GyroMagCompFilter {
private double velOffsetZ;
private double oldTimeStamp;
private double nbrTurnsZ;
private double actualMagAngleZ;
private double magAngleZ;
public GyroMagCompFilter(){}
public void filt( long timeStamp){
// if(MainActivity.calibrate){
// MainActivity.calibrate=false;
// velOffsetZ = MainActivity.gyroRZBuffer.getFirst().doubleValue();
// return;
// }
if((float) - Math.atan2(MainActivity.magRYBuffer.getFirst().doubleValue(), MainActivity.magRXBuffer.getFirst().doubleValue()) - actualMagAngleZ>6){
nbrTurnsZ--;
}
if((float)- Math.atan2(MainActivity.magRYBuffer.getFirst().doubleValue(), MainActivity.magRXBuffer.getFirst().doubleValue())-actualMagAngleZ<-6){
nbrTurnsZ++;
}
actualMagAngleZ=((float)- Math.atan2(MainActivity.magRYBuffer.getFirst().doubleValue(), MainActivity.magRXBuffer.getFirst().doubleValue()));
magAngleZ = (float) (actualMagAngleZ +nbrTurnsZ*Math.PI*2);
MainActivity.gyroMagZBuffer.addValue( (float) (MainActivity.alpha* (MainActivity.gyroMagZBuffer.getFirst().doubleValue() + (MainActivity.gyroRZBuffer.getFirst().doubleValue()-velOffsetZ)* (timeStamp - oldTimeStamp)*0.000000001f) + (1-MainActivity.alpha)* (magAngleZ)), timeStamp);
oldTimeStamp = timeStamp;
}
}
\ No newline at end of file
package imu3.imu5.app;
/**
* Created by H on 28/05/14.
*/
public class MagAngleFilter implements Filter {
private double actualMagAngleZ;
private double nbrTurnsZ;
public MagAngleFilter(){}
public void filt(){
if((float) - Math.atan2(MainActivity.magRYBuffer.getFirst().doubleValue(), MainActivity.magRXBuffer.getFirst().doubleValue()) - actualMagAngleZ>6){
nbrTurnsZ--;
}
if((float)- Math.atan2(MainActivity.magRYBuffer.getFirst().doubleValue(), MainActivity.magRXBuffer.getFirst().doubleValue())-actualMagAngleZ<-6){
nbrTurnsZ++;
}
actualMagAngleZ=((float)- Math.atan2(MainActivity.magRYBuffer.getFirst().doubleValue(), MainActivity.magRXBuffer.getFirst().doubleValue()));
MainActivity.magZBuffer.addValue((float) (actualMagAngleZ +nbrTurnsZ*Math.PI*2), MainActivity.magRZBuffer.getTime().longValue());
}
}
package imu3.imu5.app;
/**
* Created by H on 28/05/14.
*/
public class MagAngleLowpassFilter implements Filter {
private double actualMagAngleZ;
private double nbrTurnsZ;
private double magAngle;
public MagAngleLowpassFilter(){}
public void filt(){
if((float) - Math.atan2(MainActivity.magRYBuffer.getFirst().doubleValue(), MainActivity.magRXBuffer.getFirst().doubleValue()) - actualMagAngleZ>6){
nbrTurnsZ--;
}
if((float)- Math.atan2(MainActivity.magRYBuffer.getFirst().doubleValue(), MainActivity.magRXBuffer.getFirst().doubleValue())-actualMagAngleZ<-6){
nbrTurnsZ++;
}
actualMagAngleZ=((float)- Math.atan2(MainActivity.magRYBuffer.getFirst().doubleValue(), MainActivity.magRXBuffer.getFirst().doubleValue()));
magAngle = (float) (actualMagAngleZ +nbrTurnsZ*Math.PI*2);
MainActivity.magFZBuffer.addValue( (float) (MainActivity.alpha*MainActivity.magFZBuffer.getFirst().doubleValue()+(1-MainActivity.alpha)*magAngle),MainActivity.magRZBuffer.getTime().longValue());
}
}
\ No newline at end of file
package imu3.imu5.app;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Color;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.AsyncTask;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import com.androidplot.xy.LineAndPointFormatter;
import com.androidplot.xy.SimpleXYSeries;
import com.androidplot.xy.XYPlot;
import java.util.Arrays;
public class MainActivity extends ActionBarActivity implements SensorEventListener{
ActionBar.Tab tab1, tab2;
FragmentTab1 fragmentTab1 = new FragmentTab1();
FragmentTab2 fragmentTab2 = new FragmentTab2();
private AlgorithmThread algorithmThread;
private long aTime; // to measure frequency
private long gTime;
private long mTime;
public static volatile long accTimestamp;
public static volatile long gyroTimestamp;
public static volatile long magTimestamp;
public static double alpha;
public static double beta;
public static boolean calibrate;
public static boolean freeze;
private Sensor acc = null;
private Sensor gyro = null;
private Sensor mag = null;
private SensorManager sensorMgr = null;
public static DataBuffer accRXBuffer;
public static DataBuffer accRYBuffer;
public static DataBuffer accRZBuffer;
public static DataBuffer accXBuffer;
public static DataBuffer accFXBuffer;
public static DataBuffer accYBuffer;
public static DataBuffer accFYBuffer;
public static DataBuffer accZBuffer;
public static DataBuffer accFZBuffer;
public static DataBuffer gyroRXBuffer;
public static DataBuffer gyroRYBuffer;
public static DataBuffer gyroRZBuffer;
public static DataBuffer gyroXBuffer;
public static DataBuffer gyroFXBuffer;
public static DataBuffer gyroYBuffer;
public static DataBuffer gyroFYBuffer;
public static DataBuffer gyroZBuffer;
public static DataBuffer gyroFZBuffer;
public static DataBuffer magRXBuffer;
public static DataBuffer magRYBuffer;
public static DataBuffer magRZBuffer;
public static DataBuffer magXBuffer;
public static DataBuffer magFXBuffer;
public static DataBuffer magYBuffer;
public static DataBuffer magFYBuffer;
public static DataBuffer magZBuffer;
public static DataBuffer magFZBuffer;
public static DataBuffer accGyroXBuffer;
public static DataBuffer accGyroYBuffer;
public static DataBuffer gyroMagZBuffer;
//private AccAngleFilter accAngleFilter;
private AccAngleLowpassFilter accAngleLowpassFilter;
private AccGyroCompFilter accGyroCompFilter;
private GyroAngleFilter gyroAngleFilter;
private GyroAngleHighpassFilter gyroAngleHighpassFilter;
private MagAngleFilter magAngleFilter;
private MagAngleLowpassFilter magAngleLowpassFilter;
private GyroMagCompFilter gyroMagCompFilter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//setup the actionbar and tabs
ActionBar actionBar = getSupportActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
tab1 = actionBar.newTab().setText("Plot data");
tab2 = actionBar.newTab().setText("Send data");
tab1.setTabListener(new TabListener(fragmentTab1));
tab2.setTabListener(new TabListener(fragmentTab2));
actionBar.addTab(tab1);
actionBar.addTab(tab2);
alpha = 0.97;
beta = 0.03;
calibrate = false;
freeze = false;
// register for sensor events:
sensorMgr = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
acc = sensorMgr.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
sensorMgr.registerListener(this, acc, SensorManager.SENSOR_DELAY_FASTEST);
gyro = sensorMgr.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
sensorMgr.registerListener(this, gyro, SensorManager.SENSOR_DELAY_FASTEST);
mag = sensorMgr.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);