센서 주제(3) - 가속도/자이로 센서


이 섹션 소개:

이 섹션에서는 Android의 센서에 대해 계속 설명합니다. 이 섹션에서는 가속도 센서(가속도계 센서)와 이전 섹션의 방향 센서와 마찬가지로 자이로스코프 센서에는 x, y, z의 세 축이 있습니다. 한 가지 더 말씀드릴 점은 x, y축 좌표가 도면의 x, y축 좌표와 구별되어야 한다는 것입니다! 센서는 왼쪽 하단에 있습니다. 원산지를 위해! x는 오른쪽으로 가고, y는 위로 갑니다! 좋아요, 이번 섹션의 센서를 루틴을 통해 배워봅시다!

그리고 제가 말씀드리고 싶은 것은 저희는 전문적이지 않고 그냥 재미로 글을 쓰고 경험을 쌓는다는 것, 여러가지가 있다는 것입니다. 너무 심각해지지 마세요! 1.jpg

PS: 방향 센서는 실제로 방향을 얻기 위해 가속도 센서와 자기장 센서를 사용합니다. 2.2~


1) 가속도 센서(Accelerometer sensor)

1) 명사 개념입니다. :

  • 가속도 센서의 단위 : 가속도(m/s^2)
  • 방향 센서로 구한 가속도는 휴대폰의 움직임 가속도와 가속도의 합 중력의 (9.81m/s^2) 가속도
  • 게다가 중력에 의한 가속도는 수직 하향입니다!

다양한 방향의 총 가속도 계산은 상당히 복잡해 보이므로 여기서는 걱정하지 않겠습니다! 먼저 가속도 값 배열의 세 숫자 값을 살펴보겠습니다~ 여전히 이전 섹션의 코드입니다. 센서만 변경하면 됩니다~

가로로 배치하세요: 2.png 세로로 배치하고 가로로 배치하세요 : 3.png 세로와 가로로 배치하세요 :4.png

위에서 우리는 값 배열의 세 가지 값이 각각 X, Y, Z축의 가속도에 해당한다는 것을 알 수 있습니다! 좋아, 일반적인 아이디어는 알고 있으니, 사용법에 익숙해지기 위해 간단한 만보계를 작성해 봅시다!

2) 간단한 보수계 구현

렌더링 실행 :

5.gif

코드 구현 :

레이아웃 코드: activity_main.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="5dp">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:layout_marginTop="30dp"
        android:text="简易计步器"
        android:textSize="25sp" />

    <TextView
        android:id="@+id/tv_step"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:layout_marginTop="5dp"
        android:text="0"
        android:textColor="#DE5347"
        android:textSize="100sp"
        android:textStyle="bold" />

    <Button
        android:id="@+id/btn_start"
        android:layout_width="match_parent"
        android:layout_height="64dp"
        android:text="开始"
        android:textSize="25sp" /></LinearLayout>

MainActivity .java :

public class MainActivity extends AppCompatActivity implements View.OnClickListener, SensorEventListener {

    private SensorManager sManager;
    private Sensor mSensorAccelerometer;
    private TextView tv_step;
    private Button btn_start;
    private int step = 0;   //步数
    private double oriValue = 0;  //原始值
    private double lstValue = 0;  //上次的值
    private double curValue = 0;  //当前值
    private boolean motiveState = true;   //是否处于运动状态
    private boolean processState = false;   //标记当前是否已经在计步


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        sManager = (SensorManager) getSystemService(SENSOR_SERVICE);
        mSensorAccelerometer = sManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
        sManager.registerListener(this, mSensorAccelerometer, SensorManager.SENSOR_DELAY_UI);
        bindViews();
    }

    private void bindViews() {

        tv_step = (TextView) findViewById(R.id.tv_step);
        btn_start = (Button) findViewById(R.id.btn_start);
        btn_start.setOnClickListener(this);
    }


    @Override
    public void onSensorChanged(SensorEvent event) {
        double range = 1;   //设定一个精度范围
        float[] value = event.values;
        curValue = magnitude(value[0], value[1], value[2]);   //计算当前的模
        //向上加速的状态
        if (motiveState == true) {
            if (curValue >= lstValue) lstValue = curValue;
            else {
                //检测到一次峰值
                if (Math.abs(curValue - lstValue) > range) {
                    oriValue = curValue;
                    motiveState = false;
                }
            }
        }
        //向下加速的状态
        if (motiveState == false) {
            if (curValue  range) {
                    //检测到一次峰值
                    oriValue = curValue;
                    if (processState == true) {
                        step++;  //步数 + 1
                        if (processState == true) {
                            tv_step.setText(step + "");    //读数更新
                        }
                    }
                    motiveState = true;
                }
            }
        }
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {}

    @Override
    public void onClick(View v) {
        step = 0;
        tv_step.setText("0");
        if (processState == true) {
            btn_start.setText("开始");
            processState = false;
        } else {
            btn_start.setText("停止");
            processState = true;
        }
    }

    //向量求模
    public double magnitude(float x, float y, float z) {
        double magnitude = 0;
        magnitude = Math.sqrt(x * x + y * y + z * z);
        return magnitude;
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        sManager.unregisterListener(this);
    }
}

아 정말 간단한 만보계네요... 제가 앉아서 찍은 걸음 수...6.gif 결국 재미삼아~


2. 자이로 센서

1) 명사 개념:

자이로는 각속도 센서라고도 합니다. 일반적으로 휴대폰의 자이로 센서는 3개가 있는 것 같습니다. -축. 동작 감지 게임은 휴대폰 카메라 안정화, GPS 관성 내비게이션 및 앱에 일부 동작 감지 추가(예: 전화기를 부드럽게 흔들기)에 가장 일반적으로 사용됩니다. 전화 수신 벨소리 끄기) 등 자세한 내용은 바이두에 직접 가보시면 됩니다~

  • 자이로 센서의 단위: 각속도(라디안/초) 라디안/초
  • 센서를 얻으려면 : Sensor.TYPE_GYROSCOPE

세 가지 값은 X축, Y축, Z축을 따른 회전 각속도입니다. 휴대폰이 시계 반대 방향으로 회전할 때 각속도 값은 양수이고 시계 방향입니다. 그것은 부정적이다! 전화기가 회전한 각도를 계산하는 데 자주 사용됩니다! 인터넷상의 코드입니다~

private static final float NS2S = 1.0f / 1000000000.0f;
private float timestamp;

public void onSensorChanged(SensorEvent event)
{
    if (timestamp != 0)
    {
        // event.timesamp表示当前的时间,单位是纳秒(1百万分之一毫秒)
        final float dT = (event.timestamp - timestamp) * NS2S;
        angle[0] += event.values[0] * dT;
        angle[1] += event.values[1] * dT;
        angle[2] += event.values[2] * dT;
    }
    timestamp = event.timestamp;
}

자이로스코프 센서에 의해 획득된 인접한 두 데이터 간의 시간차(dT)를 이용하여 이 기간 동안 휴대폰이 X, Y, Z 축을 따라 회전한 각도 시간이 계산되고 값이 각도 배열의 다양한 요소에 각각 누적됩니다. 좋습니다. 이번 섹션에서는 가속도 센서와 자이로스코프에 대해 간략하게 소개하겠습니다. 간단한 보수계를 작성했습니다. 센서를 많이 다루지 않은 것 같아서 쓸 내용이 없습니다. 다음 섹션에서 나머지 센서를 간략하게 소개하겠습니다. 잊어버리세요, 그냥 대중과학으로 다루세요. 나중에 꼭 활용해야 한다면 심도있게 공부하시면 됩니다~