Android项目之利用手机传感器做惯性导航

利用手机的传感器做手机的姿态解算,利用扩展卡尔曼滤波算法获得手机的航向角、偏航角和滚转角。再进一步做人步行的惯性导航。

需要程序的源码请联系~~~

整体规划:

1.获得手机传感器的数据,实时发送到电脑。

加上时间戳——日期加精确的ms数。

2.在电脑端接收数据,并保存为指定格式

3.运用扩展卡尔曼滤波算法进行手机的姿态解算

4.做惯性导航的计算

1.Android使用到的技术

1.1 Android开发中保留两位小数

我用的是方法三。。。。

参考链接:https://blog.csdn.net/qq_36487432/article/details/81904207

方法一:

BigDecimal bg = new BigDecimal(xx);

double f1 = bg.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();

方法二:

DecimalFormat df = new DecimalFormat("#.00");

df.format(xx)

方法三:

String.format("%.2f", xx);

方法四:

NumberFormat nf = NumberFormat.getNumberInstance();

nf.setMaximumFractionDigits(2);

nf.format(xx);

1.2 Android传感器的使用

传感器的采样率 a) SENSOR_DELAY_NOMAL (200000微秒) 200ms b) SENSOR_DELAY_UI (60000微秒) 60ms c) SENSOR_DELAY_GAME (20000微秒) 20ms d) SENSOR_DELAY_FASTEST (0微秒) 0ms

设置采样率方法:以下每个传感器函数的最后都有一个设置采样率的参数,如下面代码中的SensorManager.SENSOR_DELAY_NORMAL

传感器的属性

//传感器的名字

String sensorName=event.sensor.getName();

//传感器制造商的名字

String sensorVendor=event.sensor.getVendor();

//传感器的分辨率,传感器所能识别的最小的精度是多少

float sensorRevolution=event.sensor.getResolution();

//传感器的功率

float sensorPower=event.sensor.getPower();

//传感器取得数据的时间是多少

double timeStamp=event.timestamp;

第一、加速度传感器

SensorManager sm = (SensorManager) this.getSystemService(Context.SENSOR_SERVICE);//创建一个SensorManager对象,用来管理或者获取传感器

//加速度传感器

Sensor acc = sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);

//为该传感器注册一个事件,直接使用内部类

sm.registerListener(new SensorEventListener() {

@Override

public void onSensorChanged(SensorEvent event) {

txtx.setText("x方向的加速度为:" + String.format("%.2f", event.values[0]) + "m/s2");

txty.setText("y方向的加速度为:" + String.format("%.2f", event.values[1]) + "m/s2");

txtz.setText("z方向的加速度为:" + String.format("%.2f", event.values[2]) + "m/s2");

}

@Override

public void onAccuracyChanged(Sensor sensor, int accuracy) {

}

}, acc, SensorManager.SENSOR_DELAY_NORMAL);

第二、方向传感器

//方向传感器

Sensor direc = sm.getDefaultSensor(Sensor.TYPE_ORIENTATION);

//为该传感器注册一个事件,直接使用内部类

sm.registerListener(new SensorEventListener() {

@Override

public void onSensorChanged(SensorEvent event) {

txtxx.setText("x方向为:" + String.format("%.2f", event.values[0])+ "度");

txtyy.setText("y方向为:" + String.format("%.2f", event.values[1])+ "度");

txtzz.setText("z方向为:" + String.format("%.2f", event.values[2])+ "度");

}

@Override

public void onAccuracyChanged(Sensor sensor, int accuracy) {

}

}, direc, SensorManager.SENSOR_DELAY_NORMAL);

第三、陀螺仪传感器

//陀螺仪传感器

Sensor tuoluo = sm.getDefaultSensor(Sensor.TYPE_GYROSCOPE);

//为该传感器注册一个事件,直接使用内部类

sm.registerListener(new SensorEventListener() {

@Override

public void onSensorChanged(SensorEvent event) {

txtxxx.setText("x方向的陀螺仪为:" + String.format("%.2f", event.values[0])+ "rad/s");

txtyyy.setText("y方向的陀螺仪为:" + String.format("%.2f", event.values[1])+ "rad/s");

txtzzz.setText("z方向的陀螺仪为:" + String.format("%.2f", event.values[2])+ "rad/s");

}

@Override

public void onAccuracyChanged(Sensor sensor, int accuracy) {

}

}, tuoluo, SensorManager.SENSOR_DELAY_NORMAL);

第四、线性加速度传感器

//线性加速度传感器

Sensor lineacc = sm.getDefaultSensor(Sensor.TYPE_LINEAR_ACCELERATION);

//为该传感器注册一个事件,直接使用内部类

sm.registerListener(new SensorEventListener() {

@Override

public void onSensorChanged(SensorEvent event) {

txtxxxx.setText("x方向的线性加速度为:" + String.format("%.2f", event.values[0]) + "m/s2");

txtyyyy.setText("y方向的线性加速度为:" + String.format("%.2f", event.values[1]) + "m/s2");

txtzzzz.setText("z方向的线性加速度为:" + String.format("%.2f", event.values[2]) + "m/s2");

}

@Override

public void onAccuracyChanged(Sensor sensor, int accuracy) {

}

}, lineacc, SensorManager.SENSOR_DELAY_NORMAL);

第五、重力传感器

//重力传感器

Sensor sr = sm.getDefaultSensor(Sensor.TYPE_GRAVITY);//根据Sensor下枚举获得对应的传感器对象

//为该传感器注册一个事件,直接使用内部类

sm.registerListener(new SensorEventListener() {

@Override

public void onSensorChanged(SensorEvent event) {

txtxxxxx.setText("x方向的重力加速度为:" + String.format("%.2f", event.values[0]) + "m/s2");

txtyyyyy.setText("y方向的重力加速度为:" + String.format("%.2f", event.values[1]) + "m/s2");

txtzzzzz.setText("z方向的重力加速度为:" + String.format("%.2f", event.values[2]) + "m/s2");

}

@Override

public void onAccuracyChanged(Sensor sensor, int accuracy) {

}

}, sr, SensorManager.SENSOR_DELAY_NORMAL);

1.3 手机利用socket作为TCP客户端发送数据给电脑

参考链接:https://www.cnblogs.com/zhangqie/p/8876059.html

步骤1:添加权限,在AndroidManife.xml中

步骤2:开启新线程,现在要求TCP通信必须在非UI线程中开启

在最开始定义socket

Socket socket_my;

在onCreate中定义新线程,线程在syncRunnable函数中运行

//开网络通信线程

SyncRunnable syncRunnable = new SyncRunnable();//定义Runnable接口

Thread thread = new Thread(syncRunnable, "syncRunnable");//定义新线程

thread.start();//开启新线程

在新线程执行函数中开启网络通信

public class SyncRunnable implements Runnable {

@Override

public void run() {

synchronized (this) {

//建立连接

try {

socket_my = new Socket("192.168.1.5", 8086);

} catch (IOException e) {

e.printStackTrace();

}

// try {

// socket = new DatagramSocket(4534);//本机的接收端口号

// serverAddress = InetAddress.getByName("192.168.1.5");//发送到的IP

// } catch (Exception e) {

// e.printStackTrace();

// }

while (true) {

String sendData = "12345";//发送的数据

}

}

}

}

发送数据给服务端

try {

// socket.getInputStream()

DataOutputStream writer = new DataOutputStream(socket_my.getOutputStream());

writer.writeUTF("嘿嘿,你好啊,服务器.."); // 写一个UTF-8的信息

System.out.println("发送消息");

} catch (IOException e) {

e.printStackTrace();

}

接收服务端发送的数据

//接收数据

byte[] buffer = new byte[10000];

InputStream inputStream = null;

try {

inputStream = socket_my.getInputStream();

} catch (IOException e) {

e.printStackTrace();

}

DataInputStream input = new DataInputStream(inputStream);

int length = 0;

try {

length = input.read(buffer);

} catch (IOException e) {

e.printStackTrace();

}

String Msg = null;

try {

Msg = new String(buffer, 0, length, "gb2312");

} catch (UnsupportedEncodingException e) {

e.printStackTrace();

}

Log.e("data:", Msg);

System.out.println("***Msg***"+Msg);

未完待续~~~~