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

在Flutter中基于CC2650 STK的MPU-9250传感器检测移动方向与距离

在Dart中基于MPU-9250传感器BLE数据检测设备移动方向与距离

原始传感器数据

初始值

[138,255,185,0,164,0,84,2,160,0,108,64,50,2,101,253,28,252]

最终值

[120,255,122,0,203,0,152,2,216,0,112,64,27,29,253,44,247]

数据格式定义

陀螺仪数据(前6个字节)

  • GXLSB: X轴陀螺仪读数最低有效字节
  • GXMSB: X轴陀螺仪读数最高有效字节
  • GYLSB: Y轴陀螺仪读数最低有效字节
  • GYMSB: Y轴陀螺仪读数最高有效字节
  • GZLSB: Z轴陀螺仪读数最低有效字节
  • GZMSB: Z轴陀螺仪读数最高有效字节

加速度计数据(接下来6个字节,索引6-11)

  • AXLSB: X轴加速度计读数最低有效字节
  • AXMSB: X轴加速度计读数最高有效字节
  • AYLSB: Y轴加速度计读数最低有效字节
  • AYMSB: Y轴加速度计读数最高有效字节
  • AZLSB: Z轴加速度计读数最低有效字节
  • AZMSB: Z轴加速度计读数最高有效字节

Dart实现步骤

1. 字节转物理单位数值

首先将LSB和MSB拼接为16位有符号整数,再根据MPU-9250默认量程转换为物理单位:

  • 陀螺仪:±250°/s,灵敏度131 LSB/(°/s)
  • 加速度计:±2g,灵敏度16384 LSB/g(1g≈9.81m/s²)
// 拼接LSB和MSB为16位有符号整数
int combineBytes(int lsb, int msb) {
  int value = (msb << 8) | lsb;
  return value >= 0x8000 ? value - 0x10000 : value;
}

// 陀螺仪原始值转°/s
double gyroRawToDps(int rawValue) {
  const sensitivity = 131.0;
  return rawValue / sensitivity;
}

// 加速度计原始值转m/s²
double accelRawToMs2(int rawValue) {
  const sensitivity = 16384.0;
  return (rawValue / sensitivity) * 9.81;
}

// 解析传感器数据列表
Map<String, double> parseSensorData(List<int> data) {
  // 解析陀螺仪数据
  final gxRaw = combineBytes(data[0], data[1]);
  final gyRaw = combineBytes(data[2], data[3]);
  final gzRaw = combineBytes(data[4], data[5]);
  
  // 解析加速度计数据
  final axRaw = combineBytes(data[6], data[7]);
  final ayRaw = combineBytes(data[8], data[9]);
  final azRaw = combineBytes(data[10], data[11]);
  
  return {
    'gx': gyroRawToDps(gxRaw),
    'gy': gyroRawToDps(gyRaw),
    'gz': gyroRawToDps(gzRaw),
    'ax': accelRawToMs2(axRaw),
    'ay': accelRawToMs2(ayRaw),
    'az': accelRawToMs2(azRaw),
  };
}

2. 检测移动方向

通过校准加速度计去除重力影响,再根据三轴加速度值判断移动方向:

// 校准加速度计,移除初始静止时的重力分量
Map<String, double> calibrateAccel(Map<String, double> initial, Map<String, double> current) {
  final gravityX = initial['ax']!;
  final gravityY = initial['ay']!;
  final gravityZ = initial['az']!;
  
  return {
    'ax': current['ax']! - gravityX,
    'ay': current['ay']! - gravityY,
    'az': current['az']! - gravityZ,
  };
}

// 判断移动方向
String detectMovementDirection(Map<String, double> calibratedAccel) {
  final ax = calibratedAccel['ax']!;
  final ay = calibratedAccel['ay']!;
  final az = calibratedAccel['az']!;
  
  // 噪声过滤阈值
  const threshold = 0.5;
  
  List<String> directions = [];
  if (ax > threshold) directions.add('X轴正方向');
  else if (ax < -threshold) directions.add('X轴负方向');
  
  if (ay > threshold) directions.add('Y轴正方向');
  else if (ay < -threshold) directions.add('Y轴负方向');
  
  if (az > threshold) directions.add('Z轴正方向');
  else if (az < -threshold) directions.add('Z轴负方向');
  
  return directions.isEmpty ? '无明显移动' : directions.join('、');
}

3. 估算移动距离

通过加速度积分计算位移(基础实现,实际需结合陀螺仪或滤波算法优化误差):

import 'dart:math';

// 估算移动距离(dt为初始到最终数据的时间差,单位秒)
double estimateDistance(Map<String, double> initialAccel, Map<String, double> finalAccel, double dt) {
  final calibratedInitial = calibrateAccel(initialAccel, initialAccel);
  final calibratedFinal = calibrateAccel(initialAccel, finalAccel);
  
  // 计算三轴平均加速度
  final avgAx = (calibratedInitial['ax']! + calibratedFinal['ax']!) / 2;
  final avgAy = (calibratedInitial['ay']! + calibratedFinal['ay']!) / 2;
  final avgAz = (calibratedInitial['az']! + calibratedFinal['az']!) / 2;
  
  // 积分计算位移(假设初始速度为0)
  final dx = 0.5 * avgAx * dt * dt;
  final dy = 0.5 * avgAy * dt * dt;
  final dz = 0.5 * avgAz * dt * dt;
  
  return sqrt(dx*dx + dy*dy + dz*dz);
}

4. 完整使用示例

void main() {
  final initialData = [138,255,185,0,164,0,84,2,160,0,108,64,50,2,101,253,28,252];
  final finalData = [120,255,122,0,203,0,152,2,216,0,112,64,27,29,253,44,247];
  
  // 解析数据
  final initialParsed = parseSensorData(initialData);
  final finalParsed = parseSensorData(finalData);
  
  // 检测移动方向
  final calibratedFinal = calibrateAccel(initialParsed, finalParsed);
  final direction = detectMovementDirection(calibratedFinal);
  print('移动方向:$direction');
  
  // 估算距离(假设时间差为1秒,实际需按BLE采样频率设置)
  final distance = estimateDistance(initialParsed, finalParsed, 1.0);
  print('估算移动距离:${distance.toStringAsFixed(2)}米');
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 00:23:22