You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Capacitor.js的PWA设备升降速率检测技术问询

基于Capacitor.js实现设备全局垂直轴升降速率计算

一、精准计算升降速率的核心逻辑

要得到不受设备朝向影响的升降速率,核心是将设备坐标系的加速度转换为全局坐标系(垂直轴固定指向地心反方向)的加速度,再通过积分得到速度,具体流程和公式如下:

  1. 坐标系转换:利用设备姿态(欧拉角:俯仰、滚转、偏航)构建旋转矩阵,把设备加速度映射到全局坐标系。
  2. 净加速度计算:全局Z轴的加速度值减去重力加速度(9.81m/s²),得到设备实际的运动加速度(加速度计原始数据包含重力影响)。
  3. 速率积分:对净加速度按时间积分,采用梯形积分法降低误差,同时加入滤波处理噪声。
  4. 漂移修正:纯加速度积分会产生累计漂移,可结合气压计(通过海拔变化求导)定期校准速率。

二、陀螺仪与加速度计数据处理流程

步骤拆解

    1. 获取传感器数据:通过Capacitor Motion插件监听deviceMotion事件,一次性获取加速度(含重力)、姿态欧拉角和时间戳。
    1. 姿态转换:将欧拉角(角度)转为弧度,用于构建旋转矩阵。
    1. 坐标系映射:用旋转矩阵把设备坐标系的加速度转换为全局坐标系下的加速度。
    1. 噪声过滤:用一阶低通滤波处理净加速度,减少高频噪声干扰。
    1. 速率计算:通过时间差积分净加速度,得到实时升降速率。
    1. 校准优化:若设备支持气压计,可定期用海拔变化修正速率,抵消积分漂移。

Capacitor.js代码实现

# 先安装Motion插件
npm install @capacitor/motion
npx cap sync
import { Motion } from '@capacitor/motion';

// 全局状态变量
let lastTimestamp = null;
let verticalVelocity = 0;
const GRAVITY = 9.81;
let filteredAccelZ = 0;

// 监听设备运动数据
Motion.addListener('deviceMotion', event => {
  const { accelerationIncludingGravity, orientation, timestamp } = event;
  
  if (!lastTimestamp) {
    lastTimestamp = timestamp;
    filteredAccelZ = accelerationIncludingGravity.z;
    return;
  }

  // 计算时间差(转秒)
  const deltaT = (timestamp - lastTimestamp) / 1000;
  lastTimestamp = timestamp;

  // 欧拉角转弧度
  const pitchRad = orientation.pitch * Math.PI / 180;
  const rollRad = orientation.roll * Math.PI / 180;
  const yawRad = orientation.yaw * Math.PI / 180;

  // 构建Z-Y-X顺序的旋转矩阵(设备→全局坐标系)
  const cosY = Math.cos(yawRad);
  const sinY = Math.sin(yawRad);
  const cosP = Math.cos(pitchRad);
  const sinP = Math.sin(pitchRad);
  const cosR = Math.cos(rollRad);
  const sinR = Math.sin(rollRad);

  const R00 = cosY * cosP;
  const R01 = cosY * sinP * sinR - sinY * cosR;
  const R02 = cosY * sinP * cosR + sinY * sinR;
  const R10 = sinY * cosP;
  const R11 = sinY * sinP * sinR + cosY * cosR;
  const R12 = sinY * sinP * cosR - cosY * sinR;
  const R20 = -sinP;
  const R21 = cosP * sinR;
  const R22 = cosP * cosR;

  // 设备坐标系加速度向量
  const accelDevice = [
    accelerationIncludingGravity.x,
    accelerationIncludingGravity.y,
    accelerationIncludingGravity.z
  ];

  // 转换为全局坐标系加速度
  const accelGlobalZ = R20 * accelDevice[0] + R21 * accelDevice[1] + R22 * accelDevice[2];

  // 计算净加速度(去除重力)
  const netAccelZ = accelGlobalZ - GRAVITY;

  // 一阶低通滤波(alpha值0.1-0.3,越小滤波越强)
  const alpha = 0.2;
  filteredAccelZ = alpha * netAccelZ + (1 - alpha) * filteredAccelZ;

  // 梯形积分计算升降速率
  verticalVelocity += filteredAccelZ * deltaT;

  // 输出结果(正为上升,负为下降)
  console.log(`当前升降速率: ${verticalVelocity.toFixed(2)} m/s`);
});

// 启动传感器采样
async function startMotionDetection() {
  await Motion.start({
    interval: 100 // 采样间隔(毫秒),按需调整
  });
}

// 停止传感器采样
async function stopMotionDetection() {
  await Motion.stop();
}

关键注意事项

  • 坐标系校准:不同设备的加速度计坐标系定义可能有差异,需实际测试调整旋转矩阵的符号或欧拉角顺序。
  • 噪声处理:加速度计噪声较大,低通滤波是必要步骤,也可引入卡尔曼滤波进一步优化姿态和加速度数据。
  • 权限配置:iOS需在Info.plist添加NSMotionUsageDescription,Android需在AndroidManifest.xml添加android.permission.ACTIVITY_RECOGNITION权限。

内容的提问来源于stack exchange,提问作者Mez

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 20:40:33