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

ROS订阅节点中IMU角速度积分出现大幅偏移问题求助

问题根因

你遇到的偏移问题核心是时间变量初始化逻辑缺失:

  • 全局变量last_time_启动后未赋值,默认是Unix纪元0时间戳(1970-01-01 00:00:00)
  • 第一次触发回调时,计算得到的dt等于当前时间减去0时间,数值量级刚好是百万级,乘以角速度后直接得到了几百万的错误初始偏移,后续所有积分都是在这个错误值基础上累加,所以结果完全异常。

修复方案

修改代码补充首次回调的时间初始化逻辑,同时增加异常校验,修改后代码如下:

#include "ros/ros.h"
#include <sensor_msgs/Imu.h>
#include <cmath>

ros::Time current_time_;
ros::Time last_time_;
double rotation = 0;
double dt = 0;
// 新增首次回调标记
bool is_first_callback = true;

void chatterCallback(const sensor_msgs::Imu::ConstPtr& scout_imu){
  current_time_ = scout_imu->header.stamp;
  // 首次回调仅初始化时间,不执行积分
  if(is_first_callback){
    last_time_ = current_time_;
    is_first_callback = false;
    return;
  }
  
  dt = (current_time_ - last_time_).toSec();
  // 异常dt校验:50Hz频率下正常dt约为0.02s,超过0.1s或为负数时跳过当前帧避免错误
  if(dt > 0.1 || dt < 0){
    ROS_WARN("异常时间差: %f,跳过当前帧", dt);
    last_time_ = current_time_;
    return;
  }

  rotation += scout_imu->angular_velocity.z * dt;
  ROS_INFO("转角: [%f], 时间差: [%f], 角速度z: [%f]", rotation, dt, scout_imu->angular_velocity.z);
  last_time_ = current_time_;
}

int main(int argc, char **argv){
  ros::init(argc, argv, "scout_subs");
  ros::NodeHandle nh;
  ros::Subscriber sub = nh.subscribe("/mavros/imu/data_raw", 1000, chatterCallback);
  ros::spin();
  return 0;
}

优化说明

  • 直接通过指针读取传入的IMU数据,不需要额外赋值给新的sensor_msgs/Imu变量,减少不必要的内存拷贝
  • 若需要转角单位为角度,可将积分结果乘以 180/M_PI 做单位转换
  • 时间差校验可以避免时间回退、数据丢帧导致的积分异常

内容的提问来源于stack exchange,提问作者A.mir

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 16:24:03