读取csv文件中的IMU数据并以sensor_msgs/Imu格式发送

读取csv文件中的IMU数据并以sensor_msgs/Imu格式发送 20210724

项目需要将所给的csv表格中IMU数据读取并转化为sensor_msgs/Imu格式,以便于后续使用数据跑定位算法。

csv表格:

请添加图片描述

读取csv文件
code:
ifstream inFile("(csv文件绝对路径)", ios::in);    //
vector<string> stamp,Yaw,Pitch,Roll,Ve,Vn,Vu;

if (!inFile)
{
    cout << "打开CSV文件失败!" << endl;
    exit(1);
}
string line;
while (getline(inFile, line)){
	string field;
    istringstream sin(line);

    getline(sin, field, ',');
    stamp.push_back(field.c_str()); 

    getline(sin, field, ',');
    Yaw.push_back(field.c_str()); 

    getline(sin, field, ',');
    Pitch.push_back(field.c_str()); 

    getline(sin, field, ',');
    Roll.push_back(field.c_str()); 

    getline(sin, field, ',');
    Ve.push_back(field.c_str()); 

    getline(sin, field, ',');
    Vn.push_back(field.c_str()); 

    getline(sin, field); 
    Vu.push_back(field.c_str()); 
}
IMU数据转换

由于csv中所给的数据并不是标准IMU格式,而是通过解算得到的处理过后的数据,所以需要通过逆变换反推出IMU的标准数据,得到gyro,accel,四元数等数据。

四元数
公式

q B = [ cos ⁡ ( ψ / 2 ) 0 0 sin ⁡ ( ψ / 2 ) ] [ cos ⁡ ( θ / 2 ) 0 sin ⁡ ( θ / 2 ) 0 ] [ cos ⁡ ( ϕ / 2 ) sin ⁡ ( ϕ / 2 ) 0 0 ] = [ cos ⁡ ( ϕ / 2 ) cos ⁡ ( θ / 2 ) cos ⁡ ( ψ / 2 ) + sin ⁡ ( ϕ / 2 ) sin ⁡ ( θ / 2 ) sin ⁡ ( ψ / 2 ) sin ⁡ ( ϕ / 2 ) cos ⁡ ( θ / 2 ) cos ⁡ ( ψ / 2 ) − cos ⁡ ( ϕ / 2 ) sin ⁡ ( θ / 2 ) sin ⁡ ( ψ / 2 ) cos ⁡ ( ϕ / 2 ) sin ⁡ ( θ / 2 ) cos ⁡ ( ψ / 2 ) + sin ⁡ ( ϕ / 2 ) cos ⁡ ( θ / 2 ) sin ⁡ ( ψ / 2 ) cos ⁡ ( ϕ / 2 ) cos ⁡ ( θ / 2 ) sin ⁡ ( ψ / 2 ) − sin ⁡ ( ϕ / 2 ) sin ⁡ ( θ / 2 ) cos ⁡ ( ψ / 2 ) ] \begin{aligned} \mathbf{q}_{\mathrm{B}} &=\left[\begin{array}{c} \cos (\psi / 2) \\ 0 \\ 0 \\ \sin (\psi / 2) \end{array}\right]\left[\begin{array}{c} \cos (\theta / 2) \\ 0 \\ \sin (\theta / 2) \\ 0 \end{array}\right]\left[\begin{array}{c} \cos (\phi / 2) \\ \sin (\phi / 2) \\ 0 \\ 0 \end{array}\right] \\ &=\left[\begin{array}{l} \cos (\phi / 2) \cos (\theta / 2) \cos (\psi / 2)+\sin (\phi / 2) \sin (\theta / 2) \sin (\psi / 2) \\ \sin (\phi / 2) \cos (\theta / 2) \cos (\psi / 2)-\cos (\phi / 2) \sin (\theta / 2) \sin (\psi / 2) \\ \cos (\phi / 2) \sin (\theta / 2) \cos (\psi / 2)+\sin (\phi / 2) \cos (\theta / 2) \sin (\psi / 2) \\ \cos (\phi / 2) \cos (\theta / 2) \sin (\psi / 2)-\sin (\phi / 2) \sin (\theta / 2) \cos (\psi / 2) \end{array}\right] \end{aligned} qB=cos(ψ/2)00sin(ψ/2)cos(θ/2)0sin(θ/2)0cos(ϕ/2)sin(ϕ/2)00=cos(ϕ/2)cos(θ/2)cos(ψ/2)+sin(ϕ/2)sin(θ/2)sin(ψ/2)sin(ϕ/2)cos(θ/2)cos(ψ/2)cos(ϕ/2)sin(θ/2)sin(ψ/2)cos(ϕ/2)sin(θ/2)cos(ψ/2)+sin(ϕ/2)cos(θ/2)sin(ψ/2)cos(ϕ/2)cos(θ/2)sin(ψ/2)sin(ϕ/2)sin(θ/2)cos(ψ/2)

code:
q0 = sin(roll/360.0f*M_PI) * cos(pitch/360.0f*M_PI) * cos(yaw/360.0f*M_PI) - cos(roll/360.0f*M_PI) * 			sin(pitch/360.0f*M_PI) * sin(yaw/360.0f*M_PI);
q1 = cos(roll/360.0f*M_PI) * sin(pitch/360.0f*M_PI) * cos(yaw/360.0f*M_PI) + sin(roll/360.0f*M_PI) * 			cos(pitch/360.0f*M_PI) * sin(yaw/360.0f*M_PI);
q2 = cos(roll/360.0f*M_PI) * cos(pitch/360.0f*M_PI) * sin(yaw/360.0f*M_PI) - sin(roll/360.0f*M_PI) * 			sin(pitch/360.0f*M_PI) * cos(yaw/360.0f*M_PI);
q3 = cos(roll/360.0f*M_PI) * cos(pitch/360.0f*M_PI) * cos(yaw/360.0f*M_PI) + sin(roll/360.0f*M_PI) * 			sin(pitch/360.0f*M_PI) * sin(yaw/360.0f*M_PI);
GYRO
公式

[ g x g y g z ] = M x ⋅ M y ⋅ [ 0 0 d y d t ] + M x ⋅ [ 0 d p d t 0 ] + [ d r d t 0 0 ] \left[\begin{array}{l} g_{x} \\ g_{y} \\ g_{z} \end{array}\right]=\mathrm{M}_{x} \cdot \mathrm{M}_{y} \cdot\left[\begin{array}{c} 0 \\ 0 \\ \frac{d y}{d t} \end{array}\right]+\mathrm{M}_{x} \cdot\left[\begin{array}{c} 0 \\ \frac{d p}{d t} \\ 0 \end{array}\right]+\left[\begin{array}{c} \frac{d r}{d t} \\ 0 \\ 0 \end{array}\right] gxgygz=MxMy00dtdy+Mx0dtdp0+dtdr00

= [ 1 0 0 0 cos ⁡ r sin ⁡ r 0 − sin ⁡ r cos ⁡ r ] ⋅ [ cos ⁡ p 0 − sin ⁡ p 0 1 0 sin ⁡ p 0 cos ⁡ p ] ⋅ [ 0 0 d y d t ] + [ 1 0 0 0 cos ⁡ r sin ⁡ r 0 − sin ⁡ r cos ⁡ r ] ⋅ [ 0 d p d t 0 ] + [ d r d t 0 0 ] =\left[\begin{array}{ccc} 1 & 0 & 0 \\ 0 & \cos r & \sin r \\ 0 & -\sin r & \cos r \end{array}\right] \cdot\left[\begin{array}{ccc} \cos p & 0 & -\sin p \\ 0 & 1 & 0 \\ \sin p & 0 & \cos p \end{array}\right] \cdot\left[\begin{array}{c} 0 \\ 0 \\ \frac{d y}{d t} \end{array}\right]+\left[\begin{array}{ccc} 1 & 0 & 0 \\ 0 & \cos r & \sin r \\ 0 & -\sin r & \cos r \end{array}\right] \cdot\left[\begin{array}{c} 0 \\ \frac{d p}{d t} \\ 0 \end{array}\right]+\left[\begin{array}{c} \frac{d r}{d t} \\ 0 \\ 0 \end{array}\right] =1000cosrsinr0sinrcosrcosp0sinp010sinp0cosp00dtdy+1000cosrsinr0sinrcosr0dtdp0+dtdr00

= [ 1 0 − sin ⁡ p 0 cos ⁡ r cos ⁡ p ⋅ sin ⁡ r 0 − sin ⁡ r cos ⁡ p ⋅ cos ⁡ r ] ⋅ [ d r d t d p d t d y d t ] =\left[\begin{array}{ccc} 1 & 0 & -\sin p \\ 0 & \cos r & \cos p \cdot \sin r \\ 0 & -\sin r & \cos p \cdot \cos r \end{array}\right] \cdot\left[\begin{array}{l} \frac{d r}{d t} \\ \frac{d p}{d t} \\ \frac{d y}{d t} \end{array}\right] =1000cosrsinrsinpcospsinrcospcosrdtdrdtdpdtdy

code
Eigen::Vector3f deltaAngle;
Eigen::Vector3f gyro;
Eigen::Matrix3f tfmatrix;
yaw   = atof(Yaw[i].c_str());
pitch = atof(Pitch[i].c_str());
roll  = atof(Roll[i].c_str());
tfmatrix<<1,0,-sin(pitch/180.0f*M_PI),0,cos(roll/180.0f*M_PI),
			cos(pitch/180.0f*M_PI)*sin(roll/180.0f*M_PI),0,-sin(roll/180.0f*M_PI),
			cos(pitch/180.0f*M_PI)*cos(roll/180.0f*M_PI);
deltaAngle<<(roll-last_roll)/0.01f,(pitch-last_pitch)/0.01f,(yaw-last_yaw)/0.01f;
gyro=tfmatrix*deltaAngle;
Accel
公式:

[ a x a y a z ] = M x ⋅ M y ⋅ M z ⋅ [ d v n d v e g + d v u / d t ] \left[\begin{array}{l} a_{x} \\ a_{y} \\ a_{z} \end{array}\right]=\mathrm{M}_{x} \cdot \mathrm{M}_{y} \cdot \mathrm{M}_{z} \cdot\left[\begin{array}{l} d vn \\ d ve \\ g+dvu/dt \end{array}\right] axayaz=MxMyMzdvndveg+dvu/dt

= [ 1 0 0 0 cos ⁡ r sin ⁡ r 0 − sin ⁡ r cos ⁡ r ] ⋅ [ cos ⁡ p 0 − sin ⁡ p 0 1 0 sin ⁡ p 0 cos ⁡ p ] ⋅ [ cos ⁡ y sin ⁡ y 0 − sin ⁡ y cos ⁡ y 0 0 0 1 ] ⋅ [ d v n d v e g + d v u / d t ] =\left[\begin{array}{ccc} 1 & 0 & 0 \\ 0 & \cos r & \sin r \\ 0 & -\sin r & \cos r \end{array}\right] \cdot\left[\begin{array}{ccc} \cos p & 0 & -\sin p \\ 0 & 1 & 0 \\ \sin p & 0 & \cos p \end{array}\right] \cdot\left[\begin{array}{ccc} \cos y & \sin y & 0 \\ -\sin y & \cos y & 0 \\ 0 & 0 & 1 \end{array}\right] \cdot\left[\begin{array}{l} d vn \\ d ve \\ g+dvu/dt \end{array}\right] =1000cosrsinr0sinrcosrcosp0sinp010sinp0cospcosysiny0sinycosy0001dvndveg+dvu/dt

= [ cos ⁡ p ⋅ cos ⁡ y cos ⁡ p ⋅ sin ⁡ y − sin ⁡ p cos ⁡ y ⋅ sin ⁡ p ⋅ sin ⁡ r − cos ⁡ r ⋅ sin ⁡ y cos ⁡ r ⋅ cos ⁡ y + sin ⁡ p ⋅ sin ⁡ r ⋅ sin ⁡ y cos ⁡ p ⋅ sin ⁡ r sin ⁡ r ⋅ sin ⁡ y + cos ⁡ r ⋅ cos ⁡ y ⋅ sin ⁡ p cos ⁡ r ⋅ sin ⁡ p ⋅ sin ⁡ y − cos ⁡ y ⋅ sin ⁡ r cos ⁡ p ⋅ cos ⁡ r ] ⋅ [ d v n d v e g + d v u / d t ] =\left[\begin{array}{ccc} \cos p \cdot \cos y & \cos p \cdot \sin y & -\sin p \\ \cos y \cdot \sin p \cdot \sin r-\cos r \cdot \sin y & \cos r \cdot \cos y+\sin p \cdot \sin r \cdot \sin y & \cos p \cdot \sin r \\ \sin r \cdot \sin y+\cos r \cdot \cos y \cdot \sin p & \cos r \cdot \sin p \cdot \sin y-\cos y \cdot \sin r & \cos p \cdot \cos r \end{array}\right] \cdot\left[\begin{array}{l} dvn \\ dve \\ g+dvu/dt \end{array}\right] =cospcosycosysinpsinrcosrsinysinrsiny+cosrcosysinpcospsinycosrcosy+sinpsinrsinycosrsinpsinycosysinrsinpcospsinrcospcosrdvndveg+dvu/dt

= [ − sin ⁡ p cos ⁡ p ⋅ sin ⁡ r cos ⁡ p ⋅ cos ⁡ r ] ⋅ [ d v n d v e g + d v u / d t ] =\left[\begin{array}{c} -\sin p \\ \cos p \cdot \sin r \\ \cos p \cdot \cos r \end{array}\right] \cdot\left[\begin{array}{l} d vn \\ d ve \\ g+dvu/dt \end{array}\right] =sinpcospsinrcospcosrdvndveg+dvu/dt

code:
Eigen::Vector3f deltaV;
Eigen::Vector3f accel;
Eigen::Matrix3f tfmatrix2;
vx = atof(Vn[i].c_str());
vy = atof(Ve[i].c_str());
vz = atof(Vu[i].c_str());

tfmatrix2<<cos(pitch/180.0f*M_PI)*cos(yaw/180.0f*M_PI),cos(pitch/180.0f*M_PI)*sin(yaw/180.0f*M_PI),
		   -sin(pitch/180.0f*M_PI),
            cos(yaw/180.0f*M_PI)*sin(pitch/180.0f*M_PI)*sin(roll/180.0f*M_PI)-											cos(roll/180.0f*M_PI)*sin(yaw/180.0f*M_PI),
			cos(roll/180.0f*M_PI)*cos(yaw/180.0f*M_PI)
 		   +sin(pitch/180.0f*M_PI)*sin(roll/180.0f*M_PI)*sin(yaw/180.0f*M_PI),
			cos(pitch/180.0f*M_PI)*sin(roll/180.0f*M_PI),
            sin(roll/180.0f*M_PI)*sin(yaw/180.0f*M_PI)
           +cos(roll/180.0f*M_PI)*cos(yaw/180.0f*M_PI)*sin(pitch/180.0f*M_PI),
			cos(roll/180.0f*M_PI)*sin(pitch/180.0f*M_PI)*sin(yaw/180.0f*M_PI)
   		   -cos(yaw/180.0f*M_PI)*sin(roll/180.0f*M_PI),
			cos(pitch/180.0f*M_PI)*cos(roll/180.0f*M_PI);
deltaV<<(vx-last_vx)/0.01f,(vy-last_vy)/0.01f,(vz-last_vz)/0.01f+9.8f;
accel=tfmatrix2*deltaV;
节点发布
ros::init(argc, argv, "imu2rosbag");
ros::NodeHandle nh;
ros::Publisher IMU_pub = nh.advertise<sensor_msgs::Imu>("IMU_data", 20);
ros::Rate loop_rate(10);
sensor_msgs::Imu imu_data;
imu_data.header.frame_id = "base_link";
imu_data.header.stamp = ros::Time(atoi(stamp[i].c_str()));

imu_data.orientation.x = q0;
imu_data.orientation.y = q1;
imu_data.orientation.z = q2;
imu_data.orientation.w = q3;

imu_data.linear_acceleration.x = accel(0);
imu_data.linear_acceleration.y = accel(1);
imu_data.linear_acceleration.z = accel(2);

imu_data.angular_velocity.x = gyro(0);
imu_data.angular_velocity.y = gyro(1);
imu_data.angular_velocity.z = gyro(2);

ref: https://blog.csdn.net/weixin_39719127/article/details/110299079 (姿态解算)

https://blog.csdn.net/chenlin41204050/article/details/78429437 (C++读CSV文件)

  • 3
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sdhdwyx

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值