使用反应原生传感器磁力计的平滑方向指南针



我正在使用react-native-sensors磁力计开发指南针应用程序。我得到了正确的值,指南针正常工作,主要问题是指南针的快速更新,方向不断变化,更改为 -5度。我想做一个平稳的方向指南针。

_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)
  }

//Inside ComponentDidMount
magnetometer.subscribe(({ x, y, z, timestamp }) =>
      this.setState({ sensorValue: this._angle({ x, y, z }) })

找到一个答案听起来与塞缪尔普斯的答案相似,我使用了lpf:javaScript的低通滤波器,它更加优化和平滑。

constructor(props) {
    super(props)
    LPF.init([])
  }
_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(LPF.next(angle))
  }

我会提出2件事。

不要使用磁力计的每个输出来更新您的状态。相反,使用数据进行某种过滤器。一个简单的例子可能是减少采样。假设磁力计为您提供1000个样本/s(我构成了数据(。每秒对视图的更新太多,而不是创建200个样本的缓冲区,并设置该200个样本的平均值的状态。在这种情况下,您每秒只会只有5个更新,从而大大降低了振动的感觉。在此处进行一些不同的实验,直到找到所需的输出为止。如果您想要更顺畅的东西,那么重叠的缓冲区也可以工作:200个样本缓冲区,但是您只需删除100个第一个,而不是每次都已重置缓冲区。因此,您的样本中有1/10个,但是每个输出都是100个新样本和已经影响输出的100个样本之间的平均值。

第二件事是不要将指南针直接设置在磁力计值的位置,否则,看起来像针头跳动(零平滑(。创建一个过渡动画以在更改位置时产生平稳运动。

在这两件事上,它应该顺利进行。希望此信息有用,祝您好运!

添加到Abdullah Yahya的答案,安装和导入LPF模块中。设置LPF平滑值并检查是否仍然存在波动。

import LPF from "lpf";
constructor() {
  super();
  LPF.init([]);
  LPF.smoothing = 0.2;
}
_angle = magnetometer => {
let angle = 0;
if (magnetometer) {
  let {x, y} = 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(LPF.next(angle));
};

有关详细信息,请参见此仓库 - react-native-compass。

最新更新