螺旋仪传感器控制手机转向修正版
程序员文章站
2022-05-06 20:09:15
经过测试观察,螺旋传感器,启动监听时的角度即为0度角度,那么我就想,可以在每次转向之后将角度值回复到这个零度角度,这就解决了上一篇,误差大的问题;angle[2] += sensorEvent.values[2] * dT;// 将弧度转化为角度anglez = (float) Math.toDegrees(angle[2]);data = anglez;灵敏度问题:1.设置灵敏度为SensorManager.SENSOR_DELAY_GAME 一般益智游戏水平2.直接设置两个临界....
经过测试观察,螺旋传感器,启动监听时的角度即为0度角度,那么我就想,可以在每次转向之后将角度值回复到这个零度角度,这就解决了上一篇,误差大的问题;
angle[2] += sensorEvent.values[2] * dT;
// 将弧度转化为角度
anglez = (float) Math.toDegrees(angle[2]);
data = anglez;
灵敏度问题:1.设置灵敏度为SensorManager.SENSOR_DELAY_GAME 一般益智游戏水平
2.直接设置两个临界值
data > 80 左转,angle[2] = 0;
data < -80 右转,angle[2] = 0;
在一定时间内连续两次左转为左调头,右为右调头
理论上不会存在因直接跳出角度判断区间的情况;
3.遗留问题:存在一种不合理情况:先左转75度,然后右转75度,实际上角度有150度的偏差,但是不会触发转向代码;
代码:
package com.zznode.sensor;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity implements SensorEventListener {
private TextView souce_z;
private TextView data_z;
private TextView orientation_z;
private SensorManager mSensorManager;
private Sensor gyroscopeSensor;
private float data;
private Button clear;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
souce_z = findViewById(R.id.souce_z);
data_z = findViewById(R.id.data_z);
clear = findViewById(R.id.clear);
clear.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
sb.setLength(0);
}
});
orientation_z = findViewById(R.id.orientation_z);
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
gyroscopeSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
/**
* 注册陀螺仪传感器,并设定传感器向应用中输出的时间间隔类型是SensorManager.SENSOR_DELAY_GAME(20000微秒)
* SensorManager.SENSOR_DELAY_FASTEST(0微秒):最快。最低延迟,一般不是特别敏感的处理不推荐使用,该模式可能在成手机电力大量消耗,由于传递的为原始数据,诉法不处理好会影响游戏逻辑和UI的性能
* SensorManager.SENSOR_DELAY_GAME(20000微秒):游戏。游戏延迟,一般绝大多数的实时性较高的游戏都是用该级别
* SensorManager.SENSOR_DELAY_NORMAL(200000微秒):普通。标准延时,对于一般的益智类或EASY级别的游戏可以使用,但过低的采样率可能对一些赛车类游戏有跳帧现象
* SensorManager.SENSOR_DELAY_UI(60000微秒):用户界面。一般对于屏幕方向自动旋转使用,相对节省电能和逻辑处理,一般游戏开发中不使用
*/
}
@Override
protected void onResume() {
super.onResume();
mSensorManager.registerListener(this, gyroscopeSensor,
SensorManager.SENSOR_DELAY_GAME);
}
@Override
protected void onPause() {
super.onPause();
mSensorManager.unregisterListener(this);
}
// 将纳秒转化为秒
private static final float NS2S = 1.0f / 1000000000.0f;
private float timestamp;
private float angle[] = new float[3];
StringBuilder sb = new StringBuilder();
private float oldTime; //记录上一次转向的时间
private int oldTurn;//记录上一次转向的方向,1右转,2左转,0初始值
@Override
public void onSensorChanged(SensorEvent sensorEvent) {
synchronized (this){
float anglex;
float angley;
float anglez;
if (timestamp != 0) {
// 得到两次检测到手机旋转的时间差(纳秒),并将其转化为秒
final float dT = (sensorEvent.timestamp - timestamp) * NS2S;
// 将手机在各个轴上的旋转角度相加,即可得到当前位置相对于初始位置的旋转弧度
angle[0] += sensorEvent.values[0] * dT;
angle[1] += sensorEvent.values[1] * dT;
angle[2] += sensorEvent.values[2] * dT;
// 将弧度转化为角度
anglex = (float) Math.toDegrees(angle[0]);
angley = (float) Math.toDegrees(angle[1]);
anglez = (float) Math.toDegrees(angle[2]);
data = anglez;
System.out.println("Z========="+ anglez);
if (data > 80 ) {
if ((sensorEvent.timestamp - oldTime) * NS2S < 1.5 && oldTurn == 2){
sb.append("左转调头了,");
oldTurn = 0;
}else {
sb.append("左转,");
oldTurn = 2;
}
angle[2] = 0;
oldTime = sensorEvent.timestamp;
} else if (data < -80 ) {
if ((sensorEvent.timestamp - oldTime) * NS2S < 1.5 && oldTurn ==1){
sb.append("右转调头了,");
oldTurn = 0;
}else {
sb.append("右转,");
oldTurn = 1;
}
angle[2] = 0;
oldTime = sensorEvent.timestamp;
}else if (data > 180 || data < -180){//容错,以防角度超过+-180度后转向无法触发
sb.append("方向异常,");
oldTurn = 0;
angle[2] = 0;
oldTime = sensorEvent.timestamp;
}
gyroscopeSensor.getMinDelay();
}
//将当前时间赋值给timestamp
timestamp = sensorEvent.timestamp;
souce_z.setText(angle[2]+"");
data_z.setText(data+"");
orientation_z.setText(sb.toString());
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int i) {
}
}
本文地址:https://blog.csdn.net/kailengchen/article/details/107379398
上一篇: I - A计划 HDU - 2102
下一篇: 门头沟京西十八潭
推荐阅读