首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何计算给定(x,y,z)磁强计和加速度计数据的航向(N/W/S/E)?

如何计算给定(x,y,z)磁强计和加速度计数据的航向(N/W/S/E)?
EN

Stack Overflow用户
提问于 2019-03-07 00:10:18
回答 2查看 7.4K关注 0票数 6

我正在使用反应-本机传感器从这些传感器获取原始数据。

代码语言:javascript
复制
import {magnetometer, acclerometer} from 'react-native-sensors';
const subscription = accelerometer.subscribe(({ x, y, z, timestamp }) =>
    console.log({ x, y, z, timestamp })
    this.setState({ accelerometer: { x, y, z, timestamp } })
);
const subscription = magnetometer.subscribe(({ x, y, z, timestamp }) => 
    console.log({ x, y, z })
    this.setState({ magnetometer: { x, y, z, timestamp } })
);

鉴于这6个数据点,我如何才能得到程度和方向?什么是合适的算法?

我不理解这个回答中的算法。这个答案使用与"x,y,z“相同的α,β,gamma...is?为什么只使用3个数据点而不使用6个数据点?为什么其他一些答案说加速度计数据是必需的(倾斜调整?)为什么没有一个利用所有6个数据点的答案?

(注:文件中有“磁强计”的拼写错误)

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-03-10 13:55:02

背景

磁强计测量地球的磁场。这个信息与手机内部的加速器结合在一起。加速器获取关于手机在太空中位置的信息。它能够从手机内部的固态传感器中精确定位手机的位置,这些传感器可以测量手机的倾斜和移动。根据算法软件开发公司Sensor的说法,这些设备提供的信息意味着指南针应用程序可以显示基本方向,不管手机在哪个方向。

一个类似的项目:罗盘-反应-本地-非博览会MIT许可证下使用设备内置的磁强计传感器,使用包反应本机传感器识别方向和计算角度,使用磁强计中的3个数据点:

代码语言:javascript
复制
subscribe = async () => {
    new Magnetometer({
      updateInterval: 100
    })
    .then(magnetometerObservable => {
      this._subscription = magnetometerObservable;
      this._subscription.subscribe(sensorData => {
        console.log(sensorData);
        this.setState({magnetometer: this._angle(sensorData)});
      });
    })
    .catch(error => {
      console.log("The sensor is not available");
    });
  };

  _unsubscribe = () => {
    this._subscription && this._subscription.stop();
    this._subscription = null;
  };

  _angle = (magnetometer) => {
    if (magnetometer) {
      let {x, y, z} = magnetometer;

      if (Math.atan2(y, x) >= 0) {
        angle = Math.atan2(y, x) * (180 / Math.PI);
      }
      else {
        angle = (Math.atan2(y, x) + 2 * Math.PI) * (180 / Math.PI);
      }
    }

    return Math.round(angle);
  };

  _direction = (degree) => {
    if (degree >= 22.5 && degree < 67.5) {
      return 'NE';
    }
    else if (degree >= 67.5 && degree < 112.5) {
      return 'E';
    }
    else if (degree >= 112.5 && degree < 157.5) {
      return 'SE';
    }
    else if (degree >= 157.5 && degree < 202.5) {
      return 'S';
    }
    else if (degree >= 202.5 && degree < 247.5) {
      return 'SW';
    }
    else if (degree >= 247.5 && degree < 292.5) {
      return 'W';
    }
    else if (degree >= 292.5 && degree < 337.5) {
      return 'NW';
    }
    else {
      return 'N';
    }
  };

  // Match the device top with pointer 0° degree. (By default 0° starts from the right of the device.)
  _degree = (magnetometer) => {
    return magnetometer - 90 >= 0 ? magnetometer - 90 : magnetometer + 271;
};

另一个项目:反应型本机传感器经理使用来自的6数据点--磁强计和加速度计--计算方位:

代码语言:javascript
复制
 float[] mGravity;
float[] mGeomagnetic;

@Override
public void onSensorChanged(SensorEvent sensorEvent) {
  Sensor mySensor = sensorEvent.sensor;
  WritableMap map = mArguments.createMap();

  if (mySensor.getType() == Sensor.TYPE_ACCELEROMETER)
    mGravity = sensorEvent.values;
  if (mySensor.getType() == Sensor.TYPE_MAGNETIC_FIELD)
    mGeomagnetic = sensorEvent.values;
  if (mGravity != null && mGeomagnetic != null) {
    float R[] = new float[9];
    float I[] = new float[9];
    boolean success = mSensorManager.getRotationMatrix(R, I, mGravity, mGeomagnetic);
    if (success) {
      long curTime = System.currentTimeMillis();
      float orientation[] = new float[3];
      mSensorManager.getOrientation(R, orientation);

      float heading = (float)((Math.toDegrees(orientation[0])) % 360.0f);
      float pitch = (float)((Math.toDegrees(orientation[1])) % 360.0f);
      float roll = (float)((Math.toDegrees(orientation[2])) % 360.0f);

      if (heading < 0) {
        heading = 360 - (0 - heading);
      }

      if (pitch < 0) {
        pitch = 360 - (0 - pitch);
      }

      if (roll < 0) {
        roll = 360 - (0 - roll);
      }

      map.putDouble("azimuth", heading);
      map.putDouble("pitch", pitch);
      map.putDouble("roll", roll);
      sendEvent("Orientation", map);
      lastUpdate = curTime;
    }
  }
}

其他 也是

票数 10
EN

Stack Overflow用户

发布于 2019-08-08 04:55:50

这就是我在android系统中所做的工作:

代码语言:javascript
复制
let angle = Math.atan2(y, x);
angle = angle * (180 / Math.PI)
angle = angle + 90
angle = (angle +360) % 360

来自磁强计的数据在android和ios中并不一致。最后我自己做了一个包裹:

https://github.com/firofame/react-native-compass-heading

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55034145

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档