当前位置: 移动技术网 > IT编程>开发语言>Java > 螺旋仪传感器控制手机转向修正版

螺旋仪传感器控制手机转向修正版

2020年07月17日  | 移动技术网IT编程  | 我要评论

经过测试观察,螺旋传感器,启动监听时的角度即为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

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网