从BNO055传感器获取IMU数据-1

最近学习惯导相关知识,BNO055是博世的绝对方向传感器,它结合了传感器数据和微处理器来过滤和组合数据,为用户提供空间中的绝对方向。

关于BNO055传感器

BNO055使用三个三轴传感器同时测量切向加速度(通过加速度计),旋转加速度(通过陀螺仪)和局部磁场强度(通过磁力计)。然后,可以将数据发送到外部微处理器,或使用运行专有融合算法的M0+微处理器在传感器内部进行分析。然后,用户可以选择以各种格式从传感器请求数据。

该芯片还具有中断功能,可以在发生某些运动(方向变化、突然加速等)时通知主机微控制器。

框图

传感器必须在使用前进行校准,读寄存器保存当前的校准状态。校准后,校准偏移可以写入传感器,然后传感器在下次通电时立即可以使用。

观看下面的视频,了解如何校准传感器。

Bosch Sensortec Tutorials:校准absolute orientation sensor BNO055

主机微控制器可以在非融合模式下从传感器(加速度计、陀螺仪和/或磁力计)请求任何或所有数据,并且可以在融合模式下请求绝对和相对方向(角度或四元数)。

传感器可以返回以 m / s 2 m/s^2 m/s2 或 mg ( 1 m g = 9.81 × 1 0 − 3 m / s 2 1mg = 9.81 \times 10^{-3} m/s^2 1mg=9.81×103m/s2); 磁场强度(mT);陀螺仪数据以度或弧度每秒为单位(分别为 DPS 和 RPS),以度或弧度为单位的欧拉角或四元数; 和以°C或°F为单位的温度。所有选项均在unit_selection寄存器中设置(数据表中的表 3-11,PDF 第 30 页)。

欧拉角 vs 四元数

如果要为运动范围有限的系统设计传感器解决方案,则可以使用欧拉角。但是,如果您正在设计一种可以在空间中定位任何地方的传感器,则应使用四元数。

欧拉角

欧拉角允许围绕垂直轴旋转三次的对象(x-y-x、x-z-x、y-x-y、y-z-y、z-x-z、z-y-z、x-y-z、x-z-y、y-x-z、y-z-x、y-z-x、z-x-y、z-y-x)的物体的简单可视化。

欧拉角示例

只要轴至少部分垂直,它们就足够了。但是,当轴旋转时,存在一个角度,其中两个轴可以描述相同的旋转 - 产生称为万向节锁定的条件。当万向节锁定发生时,如果没有外部参考,就不可能重新定向。

此动画有三个万向节(显示为红色、绿色和蓝色实心圆柱段)以及可用的旋转(显示为红色、绿色和蓝色透明球面月亮)。当内部绿色云台平面与红色云台平面对齐时,红蓝云台旋转轴重叠,云台锁定发生(浅黄色背景表示)。

使用四元数时不存在云台锁定的问题。

四元数

四元数是由威廉·汉密尔顿于1843年发明的,作为乘除三个数字的一种方式。几十年来,它们慢慢失宠,并在核时代看到了复兴,并再次通过现代计算机图形编程进行了振兴。四元数由四个数字组成:一个标量和一个三分量向量。

四元数

其中 w、x、y 和 z 都是实数,i、j 和 k 是四元数单位。

通常,w、x、y 和 z 保持在 -1 和 1 之间的范围内,并且 w 2 + x 2 + y 2 + z 2 = 1 \sqrt{w^2+x^2+y^2+z^2}=1 w2+x2+y2+z2 =1

这四个数字在一次旋转中简洁地重新定向矢量,无论长度是否发生变化。

蓝色和红色矢量的单位长度。橙色是将蓝色矢量旋转为红色矢量所需的旋转。

正态变换矩阵由九个数字组成,涉及三角函数的应用。四元数由四个数字组成,全部小于或等于 1。可以将四元数转换为正交变换矩阵,但由于与万向锁相关的数学性质,从旋转矩阵转换为四元数稍微困难一些。

将四元数转换为 3x3 正交旋转矩阵的方法。

下面的代码片段演示了如何创建 3×3 变换矩阵以及四元数的横滚角、俯仰角和偏航角。

/* Create Rotation Matrix rm from Quaternion */
double rm[3][3];

rm[1][1] = quat.w()*quat.w() + quat.x()*quat.x() - quat.y()*quat.y() - quat.z()*quat.z();   
rm[1][2] = 2*quat.x()*quat.y() - 2*quat.w()*quat.z();            
rm[1][3] = 2*quat.x()*quat.z() + 2*quat.w()*quat.y();
rm[2][1] = 2*quat.x()*quat.y() + 2*quat.w()*quat.z();       
rm[2][2] = quat.w()*quat.w() - quat.x()*quat.x() + quat.y()*quat.y() - quat.z()*quat.z();          
rm[2][3] = 2*quat.y()*quat.z() - 2*quat.w()*quat.x();     
rm[3][1] = 2*quat.x()*quat.z() - 2*quat.w()*quat.y();       
rm[3][2] = 2*quat.y()*quat.z() + 2*quat.w()*quat.x();            
rm[3][3] = quat.w()*quat.w() - quat.x()*quat.x() - quat.y()*quat.y() + quat.z()*quat.z();

/* Display Rotation Matrix */
Serial.print(rm[1][1],5);Serial.print("  \t");
Serial.print(rm[1][2],5);Serial.print("  \t");
Serial.println(rm[1][3],5);
Serial.print(rm[2][1],5);Serial.print("  \t");
Serial.print(rm[2][2],5);Serial.print("  \t");
Serial.println(rm[2][3],5);
Serial.print(rm[3][1],5);Serial.print("  \t");
Serial.print(rm[3][2],5);Serial.print("  \t");
Serial.println(rm[3][3],5);

/* Create Roll Pitch Yaw Angles from Quaternions */
double yy = quat.y() * quat.y(); // 2 Uses below

double roll = atan2(2 * (quat.w() * quat.x() + quat.y() * quat.z()), 1 - 2*(quat.x() * quat.x() + yy));
double pitch = asin(2 * quat.w() * quat.y() - quat.x() * quat.z());
double yaw = atan2(2 * (quat.w() * quat.z() + quat.x() * quat.y()), 1 - 2*(yy+quat.z() * quat.z()));

/*  Convert Radians to Degrees */
float rollDeg  = 57.2958 * roll;
float pitchDeg = 57.2958 * pitch;
float yawDeg   = 57.2958 * yaw;

/*  Display Roll, Pitch, and Yaw in Radians and Degrees*/
Serial.print("Roll:");  Serial.print(roll,5);  Serial.print(" Radians \t"); Serial.print(rollDeg,2);  Serial.println(" Degrees");
Serial.print("Pitch:"); Serial.print(pitch,5); Serial.print(" Radians \t"); Serial.print(pitchDeg,2); Serial.println(" Degrees");
Serial.print("Yaw:");   Serial.print(yaw,5);   Serial.print(" Radians \t"); Serial.print(yawDeg,2);   Serial.println(" Degrees");

今天有些困了,明天继续。。。

公众号 | FunIO
微信搜一搜 “funio”,发现更多精彩内容。
个人博客 | blog.boringhex.top

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值