欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 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