4

我正在使用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 }) })

4

3 回答 3

3

发现一个答案听起来与SamuelPS 的答案相似,我使用了 LPF: Low Pass Filter for 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))
  }
于 2019-08-02T12:11:51.323 回答
1

我会提出两件事。

不要用磁力计的每个输出来更新你的状态。相反,对数据进行某种过滤。一个简单的例子是减少抽样。假设磁力计为您提供 1000 个样本/秒(我编造了数据)。每秒对视图进行 1000 次更新实在是太多了,而不是创建一个包含 200 个样本的缓冲区,并在每次满时设置这 200 个样本的平均值的状态。在这种情况下,您每秒只有 5 次更新,大大减少了振动感。在这里用不同的值做一些实验,直到找到所需的输出。如果您想要更平滑的东西,重叠缓冲区也可以工作:200 个样本缓冲区,但不是每次都重置缓冲区已满,您只需删除第一个 100 个。所以你的样本减少了1/10,

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

有了这两件事,它应该可以顺利工作。我希望这些信息有用,祝你的指南针好运!!

于 2019-08-01T12:33:01.453 回答
0

添加到 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));
};

有关详细信息,请参阅此 repo - react-native-compass

于 2020-04-09T22:46:33.680 回答