陀螺仪LSM6DSV16X与AI集成(2)----姿态解算

2023-12-05 07:45

本文主要是介绍陀螺仪LSM6DSV16X与AI集成(2)----姿态解算,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

陀螺仪LSM6DSV16X与AI集成.2--姿态解算

  • 概述
  • 视频教学
  • 样品申请
  • 完整代码下载
  • 欧拉角
  • 万向节死锁
  • 四元数法
  • 姿态解算
  • 双环PI控制器
  • 偏航角
  • 陀螺仪解析代码
  • 上位机通讯
  • 加速度演示
  • 陀螺仪工作方式
  • 主程序
  • 演示

概述

LSM6DSV16X包含三轴陀螺仪与三轴加速度计。
姿态有多种数学表示方式,常见的是四元数,欧拉角,矩阵和轴角。他们各自有其自身的优点,在不同的领域使用不同的表示方式。在四轴飞行器中使用到了四元数和欧拉角。
姿态解算选用的旋转顺序为ZYX,即IMU坐标系初始时刻与大地坐标系重合,然后依次绕自己的Z、Y、X轴进行旋转:
绕IMU的Z轴旋转:航向角yaw
绕IMU的Y轴旋转:俯仰角pitch
绕IMU的X轴旋转:横滚角row

最近在弄ST和瑞萨RA的课程,需要样片的可以加群申请:615061293 。

在这里插入图片描述

横滚roll,俯仰pitch,偏航yaw的实际含义如下图:

在这里插入图片描述
由于需要解析姿态角,故将陀螺仪速度修改快一点。

在这里插入图片描述

视频教学

样品申请

https://www.wjx.top/vm/OhcKxJk.aspx#

完整代码下载

欧拉角

横滚角φ:机体绕OBXB转动,轴Y’B与平面OBXBYB构成的夹角。
俯仰角θ:机体绕OBYB转动,轴Z’B与平面OBYBZB构成的夹角。
偏航角ψ:机体绕OBZB转动,轴X’B与平面OBXBZB构成的夹角。

在这里插入图片描述
将姿态角从机体坐标系转换到惯性坐标系中是为了便于分析无人机状态,反映无人机在惯性坐标系下的姿态运动状态,利用齐次线性变换可实现坐标系的转换,旋转矩阵就是在线性变化中产生的,用REB表示惯性坐标系{E}到机体坐标系{B}的变换。
例如,绕OBXB旋转必角,此时两个坐标系存在必的角度差,不再重合。点(x, y, z)的转换方程为:
在这里插入图片描述
可提取转换矩阵:
在这里插入图片描述

同理,绕口OBYB旋转θ角得:
在这里插入图片描述

而绕OBZB旋转ψ角得:
在这里插入图片描述

不同旋转顺序有不同的旋转矩阵,按照偏航,俯仰,横滚的顺序,即分别绕X-Y-Z旋转,就可计算出旋转矩阵REB,REB等于依次旋转所得的矩阵连乘,且顺序为从右向左排列。

在这里插入图片描述

万向节死锁

当俯仰角θ=±Π/2时,横滚运动与偏航运动的旋转轴重合,出现万向节死锁现象,在空间失去了一个自由度。如式所示,φ或ψ的变化具有相同的效果,因此不再具有唯一性啊。

在这里插入图片描述

四元数法

本文选择的是四元数法进行姿态解算。无人机姿态解算方法主要有四种,它们各自的优缺点如下图所示。欧拉角法不能用于计算飞行器的全姿态角,且难以实时计算而不易于工程应用。方向余弦法不会出现“奇点”现象,但计算量大,效率低。四元数法避免了复杂的三角函数运算,变为求解线性微分方程,算法简单易操作,且不存在角度奇异性问题,可以更好的线性化系统,是一种更实用的工程方法。

在这里插入图片描述

四元数的概念诞生在1843年的爱尔兰,是数学家哈密顿研究空间几何时提出。在如今的导航技术领域,四元数的优势逐渐被发现,得到了研究者们的广泛关注,并逐渐应用在姿态解算领域。

四元数是由四个元构成的数Q(q0,q1,q2,q3) = q0 + q1i + q2j + q3k;其中,q0,q1,q2,q3是实数,i,j,k既是互相正交的单位向量,又是虚单位根号-1。四元数即可看作四维空间中的一个向量,又可以看做一个超复数。对于后续有一个重要的变化需要记住:
Q=q0 + q1i + q2j + q3k
可视为一个超复数,Q 的共轭复数记为
Q’=q0 - q1i - q2j - q3k
Q°称为Q的共轭四元数。
同时,有
ij=k,jk=i,ki=j,ji=-k,kj=-i,ik=-j
i2 = j2 = k2 =ijk=-1
在这里插入图片描述
其中,i、j、k是相互正交的单位向量,其几何意义可理解为分别绕三个坐标轴的旋转,q0、q1、q2、q3为常数,有
在这里插入图片描述

通过四元数进行欧拉角求解,可以减少芯片运算负担,提高运算速度。
在这里插入图片描述

一个矢量V相对于坐标系OXYZ固定:V = xi + yj + zk;坐标系OXYZ转动了Q得到一个新坐标系OX’Y’Z’:V = x’i’ + y’j‘ + z’k’;设四元数Ve、Ve‘
Ve = xi + yj + zk;
Ve’ = x’i + y’j + z’k;
则Ve’ = Q* Ve * Q’;
设Q = q0 + q1i + q2j + q3k;则Q’ = q0 - q1i - q2j - q3k;
则Ve’ = Q* Ve * Q’=(q0 + q1i + q2j + q3k) * (0+xi + yj + zk) + (q0 - q1i - q2j - q3k)
可以算出
x’=(q0 ^2+q1 ^2-q2 ^2-q3 ^2)x+2(q1q2+ q1q3)y+2(q1q3-q0q2)z
y’ = 2(q1q2-q0q3)x+(q0 ^2-q1 ^2+q2 ^2-q3 ^2)y+2(q2q3+q0q1)z
z’ = 2(q1q3+q0q2)x+2(q2q3-q0q1)y+(q0 ^2-q1 ^2-q2 ^2+q3 ^2)z

在这里插入图片描述

结合
在这里插入图片描述
可以反推
在这里插入图片描述

        Pitch  = asin(2 * q2 * q3 + 2 * q0* q1)* 57.3; // pitch ,转换为度数Roll = atan2(-2 * q1 * q3 + 2 * q0 * q2, q0*q0-q1*q1-q2*q2+q3*q3)* 57.3; // rollvYaw = atan2(2*(q1*q2 - q0*q3),q0*q0-q1*q1+q2*q2-q3*q3) * 57.3;   //偏移太大,

将加速度的三维向量转为单位向量

        // 测量正常化norm = sqrt(ax*ax + ay*ay + az*az);      ax = ax / norm;                   //单位化ay = ay / norm;az = az / norm;    

世界坐标系重力分向量是通过方向旋转矩阵的最后一列的三个元素乘上加速度就可以算出机体坐标系中的重力向量。

        // 估计方向的重力vx = 2*(q1*q3 - q0*q2);//由下向上方向的加速度在加速度计X分量 vy = 2*(q0*q1 + q2*q3);//由下向上方向的加速度在加速度计X分量 vz = q0*q0 - q1*q1 - q2*q2 + q3*q3;//由下向上方向的加速度在加速度计Z分量

姿态解算

在这里插入图片描述

双环PI控制器

陀螺仪能够迅速响应设备的旋转,在短时间内误差较小且可靠。然而,因为温度漂移、零漂移和积分误差会随时间累积,陀螺仪的长时间精度受到影响。在静止状态下,加速度计的漂移很小,其倾角求解过程中不存在积分误差,但在飞行过程中,加速度计受到发动机和机架振动以及转动和运动加速度的干扰。磁罗盘测量的地磁向量在特定地理范围内可视为不变,但磁罗盘易受硬磁场和软磁场干扰。
因此,若系统外环采用九轴姿态传感器(包括三轴加速度计、三轴磁罗盘和三轴陀螺仪)进行数据融合,磁罗盘易受干扰可能导致融合后的数据仍有较大误差。为此,在内环使用六轴姿态传感器(包括三轴加速度计和三轴陀螺仪)进行数据融合,对融合后的传感器姿态偏差进行二次修正,以提高整体精度。
外环九轴姿态传感器数据融合,记在飞行器机体坐标系下an=[ax ay az]T和mn=[mx my mz]T分别为加速度计和磁罗盘实际测量得到的重力向量和地磁向量。
记vn=[vx vy vz]T和wn=[mx my mz]T是将地理坐标系下重力向量kb=[0 0 1g]T和地磁向量nb=[nx 0 nz]T(不考虑地理磁偏角因素,将机头固定向北)通过四元数坐标换算成机体坐标系下的重力向量和地磁向量。向量之间的误差为坐标轴的旋转误差,可以用向量的叉积en=[ex ey ez]T表示,如下所示。
在这里插入图片描述

由于我的LSM6DS3TR-C为六轴,不带三轴陀螺仪,故代码如下。

//这个叉积向量仍旧是位于机体坐标系上的,而陀螺积分误差也是在机体坐标系,而且叉积的大小与陀螺积分误差成正比,正好拿来纠正陀螺。
//(你可以自己拿东西想象一下)由于陀螺是对机体直接积分,所以对陀螺的纠正量会直接体现在对机体坐标系的纠正。ex = (ay*vz - az*vy);ey = (az*vx - ax*vz);ez = (ax*vy - ay*vx);

由于陀螺仪是对机体直接积分,所以,陀螺仪的误差可以体现为机体坐标的误差。因此修正坐标轴的误差可以达到修正陀螺仪误差的目的,从而将加速度计和磁罗盘进行修正陀螺仪,实现了九轴的数据融合。即如果陀螺仪按照叉积误差的轴,转动叉积误差的角度,就可以消除机体坐标上实际测量的重力向量和地磁向量和坐标换算后的重力向量和地磁向量之间的误差。
PI调节器的比例部分用于迅速纠正陀螺仪误差,积分部分用于消除稳态偏差。PI调节器的比例系数和积分系数自己去修正。陀螺仪经过外环PI控制器修正姿态误差后输出值为了gn =[gx gy gz]T
在这里插入图片描述

        // 积分误差比例积分增益,计算陀螺仪测量的重力向量与估计方向的重力向量之间的误差。exInt = exInt + ex*Ki;eyInt = eyInt + ey*Ki;ezInt = ezInt + ez*Ki;// 调整后的陀螺仪测量,使用叉积误差来进行比例-积分(PI)修正陀螺仪的零偏。将修正量乘以比例增益Kp,并加上之前计算的积分误差exInt、eyInt和ezInt。gx = gx + Kp*ex + exInt;gy = gy + Kp*ey + eyInt;gz = gz + Kp*ez + ezInt;
内环的六轴姿态传感器数据融合是将地理坐标系下的重力场向量与加速度计在机体坐标系下采集到的重力向量进行叉乘,求出两者向量误差。并通过PI控制器修正向量误差,从而达到修正外环九轴数据融合后的陀螺仪的偏差的目的。在每个姿态解算周期读取出机体坐标系下双环PI控制后的陀螺仪的角速率

在这里插入图片描述

整合四元数率和正常化,根据陀螺仪的测量值和比例-积分修正值,对四元数进行更新。
在这里插入图片描述

        // 整合四元数率和正常化,根据陀螺仪的测量值和比例-积分修正值,对四元数进行更新。根据微分方程的离散化形式,将四元数的每个分量加上相应的微分项乘以采样周期的一半(halfT)。q0 = q0 + (-q1*gx - q2*gy - q3*gz)*halfT;q1 = q1 + (q0*gx + q2*gz - q3*gy)*halfT;q2 = q2 + (q0*gy - q1*gz + q3*gx)*halfT;q3 = q3 + (q0*gz + q1*gy - q2*gx)*halfT;  // 正常化四元数norm = sqrt(q0*q0 + q1*q1 + q2*q2 + q3*q3);q0 = q0 / norm;q1 = q1 / norm;q2 = q2 / norm;q3 = q3 / norm;

偏航角

六轴传感器(包括三轴加速度计和三轴陀螺仪)可以用于估算设备在空间中的姿态,包括俯仰角(Pitch)、横滚角(Roll)和偏航角(Yaw)。然而,六轴传感器仅依赖陀螺仪和加速度计数据,可能无法准确测量偏航角(Yaw),原因如下:
无磁场参考:六轴传感器缺少磁罗盘,没有固定的参考方向。因此,在长时间内,陀螺仪的积分误差可能导致偏航角估计漂移。
陀螺仪误差累积:陀螺仪测量的是角速度,要得到偏航角,需要将角速度积分。由于陀螺仪存在零漂、噪声和温度漂移等误差,这些误差在积分过程中会累积,使得偏航角估计产生较大的漂移。
虽然六轴传感器可能无法准确测量偏航角,但可以通过将其与磁罗盘(三轴磁场传感器)结合,形成九轴传感器(包括三轴加速度计、三轴磁罗盘和三轴陀螺仪),以提高偏航角估计的准确性。九轴传感器融合了磁场信息,为偏航角提供了一个稳定的参考方向,有助于减小陀螺仪误差对偏航角估计的影响。

陀螺仪解析代码

 //加速度单位g,陀螺仪rad/s
void IMUupdate(float gx, float gy, float gz, float ax, float ay, float az)
{float norm;float vx, vy, vz;float ex, ey, ez;  // 测量正常化,把加计的三维向量转成单位向量。norm = sqrt(ax*ax + ay*ay + az*az);      ax = ax / norm;                   //单位化ay = ay / norm;az = az / norm;      // 估计方向的重力,世界坐标系重力分向量是通过方向旋转矩阵的最后一列的三个元素乘上加速度就可以算出机体坐标系中的重力向量。vx = 2*(q1*q3 - q0*q2);//由下向上方向的加速度在加速度计X分量 vy = 2*(q0*q1 + q2*q3);//由下向上方向的加速度在加速度计X分量 vz = q0*q0 - q1*q1 - q2*q2 + q3*q3;//由下向上方向的加速度在加速度计Z分量//这个叉积向量仍旧是位于机体坐标系上的,而陀螺积分误差也是在机体坐标系,而且叉积的大小与陀螺积分误差成正比,正好拿来纠正陀螺。
//(你可以自己拿东西想象一下)由于陀螺是对机体直接积分,所以对陀螺的纠正量会直接体现在对机体坐标系的纠正。ex = (ay*vz - az*vy);ey = (az*vx - ax*vz);ez = (ax*vy - ay*vx);// 积分误差比例积分增益,计算陀螺仪测量的重力向量与估计方向的重力向量之间的误差。exInt = exInt + ex*Ki;eyInt = eyInt + ey*Ki;ezInt = ezInt + ez*Ki;				// 调整后的陀螺仪测量,使用叉积误差来进行比例-积分(PI)修正陀螺仪的零偏。将修正量乘以比例增益Kp,并加上之前计算的积分误差exInt、eyInt和ezInt。gx = gx + Kp*ex + exInt;gy = gy + Kp*ey + eyInt;gz = gz + Kp*ez + ezInt; // 整合四元数率和正常化,根据陀螺仪的测量值和比例-积分修正值,对四元数进行更新。根据微分方程的离散化形式,将四元数的每个分量加上相应的微分项乘以采样周期的一半(halfT)。q0 = q0 + (-q1*gx - q2*gy - q3*gz)*halfT;q1 = q1 + (q0*gx + q2*gz - q3*gy)*halfT;q2 = q2 + (q0*gy - q1*gz + q3*gx)*halfT;q3 = q3 + (q0*gz + q1*gy - q2*gx)*halfT;  // 正常化四元数norm = sqrt(q0*q0 + q1*q1 + q2*q2 + q3*q3);q0 = q0 / norm;q1 = q1 / norm;q2 = q2 / norm;q3 = q3 / norm;Pitch  = asin(2 * q2 * q3 + 2 * q0* q1)* 57.3; // pitch ,转换为度数Roll = atan2(-2 * q1 * q3 + 2 * q0 * q2, q0*q0-q1*q1-q2*q2+q3*q3)* 57.3; // rollvYaw = atan2(2*(q1*q2 - q0*q3),q0*q0-q1*q1+q2*q2-q3*q3) * 57.3;   //偏移太大,等我找一个好用的}

上位机通讯

这里使用的是匿名助手的上位机
https://gitee.com/anotc/AnoAssistant
有专门的通讯协议
在这里插入图片描述

串口通讯协议格式如下所示,需要注意传输为小端模式传输。

在这里插入图片描述
对应的源地址和目标地址分别为0xFD和0xFE。

在这里插入图片描述

我们只需要上报加速度和陀螺仪数据,所以功能码为0x01,数据长度为0x0D,需要主要为小端模式传输。

在这里插入图片描述

加速度演示

实测移动模块分别为X、Y、Z轴向下,可以看见数值基本上为1000mg。

在这里插入图片描述

陀螺仪工作方式

加速度计测量线性加速度,而陀螺仪测量角旋转。为此,他们测量了科里奥利效应产生的力。
陀螺仪是一种运动传感器,能够感测物体在一轴或多轴上的旋转角速度。它能够精确地感测自由空间中复杂的移动动作,因此成为追踪物体移动方位和旋转动作的必要设备。与加速计和电子罗盘不同,陀螺仪不需要依赖外部力量(如重力或磁场),可以自主地发挥其功能。因此,从理论上讲,只使用陀螺仪就可以完成姿态导航的任务。

在这里插入图片描述

陀螺仪的每个通道检测一个轴的旋转。也就是说陀螺仪通过测量自身的旋转状态,判断出设备当前运动状态,是向前、向后、向上、向下、向左还是向右呢,是加速(角速度)还是减速(角速度)呢,都可以实现,但是要判断出设备的方位(东西南北),陀螺仪就没有办法。
在这里插入图片描述

MEMS陀螺仪主要利用科里奥利力(旋转物体在有径向运动时所受到的切向力)原理,公开的微机械陀螺仪均采用振动物体传感角速度的概念,利用振动来诱导和探测科里奥利力。
MEMS陀螺仪的核心是一个微加工机械单元,在设计上按照一个音叉机制共振运动,通过科里奥利力原理把角速率转换成一个特定感测结构的位移。

在这里插入图片描述

两个相同的质量块以方向相反的做水平震荡。当外部施加一个角速率,就会出现一个科氏力,力的方向垂直于质量运动方向,如垂直方向箭头所示。产生的科氏力使感测质量发生位移,位移大小与所施加的角速率大小成正比,科氏力引起的电容变化即可计算出角速率大小。
科里奥利效应指出,当质量 (m) 以速度 (v) 沿特定方向移动并施加外部角速率 (Ω)(红色箭头)时,科里奥利效应会产生一个力(黄色箭头),导致质量垂直移动。该位移的值与应用的角速率直接相关。

在这里插入图片描述

  /* USER CODE BEGIN 2 */printf("123123123");lsm6dsv16x_reset_t rst;stmdev_ctx_t dev_ctx;/* Initialize mems driver interface */dev_ctx.write_reg = platform_write;dev_ctx.read_reg = platform_read;dev_ctx.handle = &SENSOR_BUS;HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_SET);HAL_GPIO_WritePin(SA0_GPIO_Port, SA0_Pin, GPIO_PIN_RESET);/* Wait sensor boot time */platform_delay(BOOT_TIME);/* Check device ID */lsm6dsv16x_device_id_get(&dev_ctx, &whoamI);printf("LSM6DSV16X_ID=0x%x,whoamI=0x%x",LSM6DSV16X_ID,whoamI);if (whoamI != LSM6DSV16X_ID)while (1);/* Restore default configuration */lsm6dsv16x_reset_set(&dev_ctx, LSM6DSV16X_RESTORE_CTRL_REGS);do {lsm6dsv16x_reset_get(&dev_ctx, &rst);} while (rst != LSM6DSV16X_READY);/* Enable Block Data Update */lsm6dsv16x_block_data_update_set(&dev_ctx, PROPERTY_ENABLE);/* Set Output Data Rate.* Selected data rate have to be equal or greater with respect* with MLC data rate.*/lsm6dsv16x_xl_data_rate_set(&dev_ctx, LSM6DSV16X_ODR_AT_960Hz);lsm6dsv16x_gy_data_rate_set(&dev_ctx, LSM6DSV16X_ODR_AT_960Hz);/* Set full scale */lsm6dsv16x_xl_full_scale_set(&dev_ctx, LSM6DSV16X_2g);lsm6dsv16x_gy_full_scale_set(&dev_ctx, LSM6DSV16X_2000dps);/* Configure filtering chain */filt_settling_mask.drdy = PROPERTY_ENABLE;filt_settling_mask.irq_xl = PROPERTY_ENABLE;filt_settling_mask.irq_g = PROPERTY_ENABLE;lsm6dsv16x_filt_settling_mask_set(&dev_ctx, filt_settling_mask);lsm6dsv16x_filt_gy_lp1_set(&dev_ctx, PROPERTY_ENABLE);lsm6dsv16x_filt_gy_lp1_bandwidth_set(&dev_ctx, LSM6DSV16X_GY_ULTRA_LIGHT);lsm6dsv16x_filt_xl_lp2_set(&dev_ctx, PROPERTY_ENABLE);lsm6dsv16x_filt_xl_lp2_bandwidth_set(&dev_ctx, LSM6DSV16X_XL_STRONG);int16_t	acc_int16[3]	={0,0,0};int16_t	gyr_int16[3]		={0,0,0};	float acc[3] = {0};float gyr[3] = {0};	uint8_t data[21]={0};data[0]=0xAB;//帧头data[1]=0xFD;//源地址data[2]=0xFE;//目标地址		data[3]=0x01;//功能码ID	data[4]=0x0D;//数据长度LENdata[5]=0x00;//数据长度LEN 13uint8_t sumcheck = 0;
uint8_t addcheck = 0;		int16_t angular_rate_raw[3]={0,0,0};	//pitch,roll,yawuint8_t data_angular_rate_raw[16]={0};data_angular_rate_raw[0]=0xAB;//帧头data_angular_rate_raw[1]=0xFD;//源地址data_angular_rate_raw[2]=0xFE;//目标地址		data_angular_rate_raw[3]=0x03;//功能码ID	data_angular_rate_raw[4]=0x08;//数据长度LENdata_angular_rate_raw[5]=0x00;//数据长度LEN 8data_angular_rate_raw[6]=0x01;//mode = 1	data_angular_rate_raw[13]=0x00;//FUSION _STA:融合状态	/* USER CODE END 2 */

主程序

  /* Infinite loop *//* USER CODE BEGIN WHILE */while (1){lsm6dsv16x_data_ready_t drdy;/* Read output only if new xl value is available */lsm6dsv16x_flag_data_ready_get(&dev_ctx, &drdy);if (drdy.drdy_xl) {/* Read acceleration field data */memset(data_raw_acceleration, 0x00, 3 * sizeof(int16_t));lsm6dsv16x_acceleration_raw_get(&dev_ctx, data_raw_acceleration);acceleration_mg[0] =lsm6dsv16x_from_fs2_to_mg(data_raw_acceleration[0]);acceleration_mg[1] =lsm6dsv16x_from_fs2_to_mg(data_raw_acceleration[1]);acceleration_mg[2] =lsm6dsv16x_from_fs2_to_mg(data_raw_acceleration[2]);
//			printf("Acceleration [mg]:%4.2f\t%4.2f\t%4.2f\r\n",acceleration_mg[0], acceleration_mg[1], acceleration_mg[2]);}		/* Read output only if new xl value is available */if (drdy.drdy_gy) {/* Read angular rate field data */memset(data_raw_angular_rate, 0x00, 3 * sizeof(int16_t));lsm6dsv16x_angular_rate_raw_get(&dev_ctx, data_raw_angular_rate);angular_rate_mdps[0] =lsm6dsv16x_from_fs2000_to_mdps(data_raw_angular_rate[0]);angular_rate_mdps[1] =lsm6dsv16x_from_fs2000_to_mdps(data_raw_angular_rate[1]);angular_rate_mdps[2] =lsm6dsv16x_from_fs2000_to_mdps(data_raw_angular_rate[2]);
//			printf("Angular rate [mdps]:%4.2f\t%4.2f\t%4.2f\r\n",angular_rate_mdps[0], angular_rate_mdps[1], angular_rate_mdps[2]);}if (drdy.drdy_temp) {/* Read temperature data */memset(&data_raw_temperature, 0x00, sizeof(int16_t));lsm6dsv16x_temperature_raw_get(&dev_ctx, &data_raw_temperature);temperature_degC = lsm6dsv16x_from_lsb_to_celsius(data_raw_temperature);
//			printf("Temperature [degC]:%6.2f\r\n", temperature_degC);}		IMUupdate(angular_rate_mdps[0]/1000,angular_rate_mdps[1]/1000,angular_rate_mdps[2]/1000,acceleration_mg[0]/1000,acceleration_mg[1]/1000,acceleration_mg[2]/1000);
Roll=Roll*100;
Pitch=Pitch*100;
Yaw=Yaw*100;
data_angular_rate_raw[8]=(int16_t)Roll>>8;//roll
data_angular_rate_raw[7]=(int16_t)Roll;
data_angular_rate_raw[10]=(int16_t)Pitch>>8;//pitch
data_angular_rate_raw[9]=(int16_t)Pitch;
data_angular_rate_raw[12]=(int16_t)Yaw>>8;//yaw
data_angular_rate_raw[11]=(int16_t)Yaw;
sumcheck = 0;
addcheck = 0;
for(uint16_t i=0; i < 14; i++)
{
sumcheck += data_angular_rate_raw[i]; //从帧头开始,对每一字节进行求和,直到 DATA 区结束
addcheck += sumcheck; //每一字节的求和操作,进行一次 sumcheck 的累加
}
data_angular_rate_raw[14]=sumcheck;
data_angular_rate_raw[15]=addcheck;HAL_UART_Transmit(&huart1 , (uint8_t *)&data_angular_rate_raw, 16, 0xFFFF);
//printf("Roll=%.2f,Pitch=%.2f,Yaw=%.2f\n",Roll,Pitch,Yaw);HAL_Delay(100);/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */

演示

上报匿名助手能正常进行解析。

在这里插入图片描述

这篇关于陀螺仪LSM6DSV16X与AI集成(2)----姿态解算的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/456737

相关文章

揭秘未来艺术:AI绘画工具全面介绍

📑前言 随着科技的飞速发展,人工智能(AI)已经逐渐渗透到我们生活的方方面面。在艺术创作领域,AI技术同样展现出了其独特的魅力。今天,我们就来一起探索这个神秘而引人入胜的领域,深入了解AI绘画工具的奥秘及其为艺术创作带来的革命性变革。 一、AI绘画工具的崛起 1.1 颠覆传统绘画模式 在过去,绘画是艺术家们通过手中的画笔,蘸取颜料,在画布上自由挥洒的创造性过程。然而,随着AI绘画工

一份LLM资源清单围观技术大佬的日常;手把手教你在美国搭建「百万卡」AI数据中心;为啥大模型做不好简单的数学计算? | ShowMeAI日报

👀日报&周刊合集 | 🎡ShowMeAI官网 | 🧡 点赞关注评论拜托啦! 1. 为啥大模型做不好简单的数学计算?从大模型高考数学成绩不及格说起 司南评测体系 OpenCompass 选取 7 个大模型 (6 个开源模型+ GPT-4o),组织参与了 2024 年高考「新课标I卷」的语文、数学、英语考试,然后由经验丰富的判卷老师评判得分。 结果如上图所

AI儿童绘本创作

之前分享过AI儿童绘画的项目,但是主要问题是角色一致要花费很长的时间! 今天发现了这款,非常奈斯! 只需输入故事主题、风格、模板,软件就会自动创作故事内容,自动生成插画配图,自动根据模板生成成品,测试效果如下图。 变现方式:生成儿童绘本发布到各平台,吸引宝妈群体进私域。  百度网盘 请输入提取码百度网盘为您提供文件的网络备份、同步和分享服务。空间大、速度快、安全

SpringBoot集成Netty,Handler中@Autowired注解为空

最近建了个技术交流群,然后好多小伙伴都问关于Netty的问题,尤其今天的问题最特殊,功能大概是要在Netty接收消息时把数据写入数据库,那个小伙伴用的是 Spring Boot + MyBatis + Netty,所以就碰到了Handler中@Autowired注解为空的问题 参考了一些大神的博文,Spring Boot非controller使用@Autowired注解注入为null的问题,得到

vue项目集成CanvasEditor实现Word在线编辑器

CanvasEditor实现Word在线编辑器 官网文档:https://hufe.club/canvas-editor-docs/guide/schema.html 源码地址:https://github.com/Hufe921/canvas-editor 前提声明: 由于CanvasEditor目前不支持vue、react 等框架开箱即用版,所以需要我们去Git下载源码,拿到其中两个主

人工和AI大语言模型成本对比 ai语音模型

这里既有AI,又有生活大道理,无数渺小的思考填满了一生。 上一专题搭建了一套GMM-HMM系统,来识别连续0123456789的英文语音。 但若不是仅针对数字,而是所有普通词汇,可能达到十几万个词,解码过程将非常复杂,识别结果组合太多,识别结果不会理想。因此只有声学模型是完全不够的,需要引入语言模型来约束识别结果。让“今天天气很好”的概率高于“今天天汽很好”的概率,得到声学模型概率高,又符合表达

智能客服到个人助理,国内AI大模型如何改变我们的生活?

引言 随着人工智能(AI)技术的高速发展,AI大模型越来越多地出现在我们的日常生活和工作中。国内的AI大模型在过去几年里取得了显著的进展,不少独创的技术点和实际应用令人瞩目。 那么,国内的AI大模型有哪些独创的技术点?它们在实际应用中又有哪些出色表现呢?此外,普通人又该如何利用这些大模型提升工作和生活的质量和效率呢?本文将为你一一解析。 一、国内AI大模型的独创技术点 多模态学习 多

【新闻】AI程序员要来了吗?阿里云官宣

内容提要 6 月 21 日,在阿里云上海 AI 峰会上,阿里云宣布推出首个AI 程序员。 据介绍,这个AI程序员具备架构师、开发工程师、测试工程师等多种岗位的技能,能一站式自主完成任务分解、代码编写、测试、问题修复、代码提交整个过程,最快分钟级即可完成应用开发,大幅提升研发效率。 近段时间以来,有关AI的实践应用突破不断,全球开发者加速研发步伐。有业内人士坦言,随着大模型性能逐渐提升,AI应

AI元宇宙

随着科技的迅猛发展,人工智能(AI)迎来了一个宇宙大爆发的时代。特别是以GPT为代表的生成式大模型的诞生和不断进步,彻底改变了人们的工作和生活方式。程序员与AI协同工作写代码已成为常态,大模型不仅提高了工作效率,还为人类带来了无限的可能性。 AI元宇宙http://ai.toolxq.com/#/如同生物进化出眼睛打开了三维世界的元宇宙之后,GPT打开了人+AI工作模式的新时代,程序员的人生被划

AI学习指南机器学习篇-朴素贝叶斯处理连续特征和离散特征

AI学习指南机器学习篇-朴素贝叶斯处理连续特征和离散特征 在机器学习领域,朴素贝叶斯是一种常用的分类算法,它的简单性和高效性使得它在实际应用中得到了广泛的应用。然而,在使用朴素贝叶斯算法进行分类时,我们通常会面临一个重要的问题,就是如何处理连续特征和离散特征。因为朴素贝叶斯算法基于特征的条件独立性假设,所以对于不同类型的特征,我们需要采取不同的处理方式。 在本篇博客中,我们将探讨如何有效地处理