0

Androidでカメラの方向を取得しようとしています。ポートレートでは完全に機能するコードがあります (ゆっくりと円を描いて 1 秒間隔で更新を確認してテストします) が、ランドスケープではまったく機能しません。数字がランダムに変化するようです。また、ポートレートからランドスケープに切り替えた後も、まったくおかしくなりません。これが私のコードです

public void onSensorChanged(SensorEvent event) {

    switch (event.sensor.getType()) {
    case Sensor.TYPE_ACCELEROMETER:
        accelerometerValues = event.values.clone();

        break;
    case Sensor.TYPE_MAGNETIC_FIELD:
        geomagneticMatrix = event.values.clone();
        break;
    default:
        break;
    }   

    if (geomagneticMatrix != null && accelerometerValues != null) {

        float[] R = new float[16];
        float[] I = new float[16];
        float[] outR = new float[16];

        //Get the rotation matrix, then remap it from camera surface to world coordinates
        SensorManager.getRotationMatrix(R, I, accelerometerValues, geomagneticMatrix);
        SensorManager.remapCoordinateSystem(R, SensorManager.AXIS_X, SensorManager.AXIS_Z, outR);
        float values[] = new float[4];
        SensorManager.getOrientation(outR,values);
        float direction = normalizeDegrees((float) Math.toDegrees(values[0]));
        float pitch = normalizeDegrees((float) Math.toDegrees(values[1]));
        float roll = normalizeDegrees((float) Math.toDegrees(values[2]));

        if((int)direction != (int)lastDirection){
            lastDirection = direction;
            for(CompassListener listener: listeners){
                listener.onDirectionChanged(lastDirection, pitch, roll);
            }
        }
    }
}

私が間違っていることはありますか?私はこれを 100% 理解しているわけではないことを率直に認めます。また、Google が方向センサーを非推奨にした理由もわかりません。それは十分に一般的な欲求のようです。

4

2 に答える 2

1

縦から横に変更すると、加速度計の軸が変わることを考慮しましたか? Y軸がZ軸になるように。これは、奇妙な動作の 1 つの原因である可能性があります。

于 2012-09-04T08:46:46.407 に答える
0

私はそれを解決したか、少なくとも何が問題なのかがわかるまで改善したようです。単一のセンサー読み取り値を提供する代わりに、最後の読み取り値を記憶し、それにデルタを適用するようにフィルターを入れました。新しいセンサー ポイントごとに、最大 5 度を追加できます。これにより、奇妙なホップが完全に除外され、強制的に値に収束します。ときどき奇妙なジャンプが見られますが、必要なのはもっと洗練されたフィルターだと思います。新しいコード:

public void onSensorChanged(SensorEvent event) {
    if (event.accuracy == SensorManager.SENSOR_STATUS_UNRELIABLE)
        return;

    switch (event.sensor.getType()) {
    case Sensor.TYPE_ACCELEROMETER:
        accelerometerValues = event.values.clone();

        break;
    case Sensor.TYPE_MAGNETIC_FIELD:
        geomagneticMatrix = event.values.clone();
        break;
    }   

    if (geomagneticMatrix != null && accelerometerValues != null) {

        float[] R = new float[16];
        float[] I = new float[16];
        float[] outR = new float[16];

        //Get the rotation matrix, then remap it from camera surface to world coordinates
        SensorManager.getRotationMatrix(R, I, accelerometerValues, geomagneticMatrix);
        SensorManager.remapCoordinateSystem(R, SensorManager.AXIS_X, SensorManager.AXIS_Z, outR);
        float values[] = new float[4];
        SensorManager.getOrientation(outR,values);

        int direction = filterChange(normalizeDegrees(Math.toDegrees(values[0])));
        int pitch = normalizeDegrees(Math.toDegrees(values[1]));
        int roll = normalizeDegrees(Math.toDegrees(values[2]));
        if((int)direction != (int)lastDirection){
            lastDirection = (int)direction;
            lastPitch = (int)pitch;
            lastRoll = (int)roll;
            for(CompassListener listener: listeners){
                listener.onDirectionChanged(lastDirection, pitch, roll);
            }
        }
    }
}

//Normalize a degree from 0 to 360 instead of -180 to 180
private int normalizeDegrees(double rads){
    return (int)((rads+360)%360);
}

//We want to ignore large bumps in individual readings.  So we're going to cap the number of degrees we can change per report
private int filterChange(int newDir){
    int change = newDir - lastDirection;
    int circularChange = newDir-(lastDirection+360);
    int smallestChange;
    if(Math.abs(change) < Math.abs(circularChange)){
        smallestChange = change;
    }
    else{
        smallestChange = circularChange;
    }
    smallestChange = Math.max(Math.min(change,5),-5);
    return lastDirection+smallestChange;
}
于 2012-09-05T00:25:22.077 に答える