四轴姿态解算_第1页
四轴姿态解算_第2页
四轴姿态解算_第3页
四轴姿态解算_第4页
四轴姿态解算_第5页
已阅读5页,还剩3页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、又花了将近一个星期,终于把姿态解算的框架完成了。仅仅是把陀螺仪、加速度计、罗盘融合在一起,得出旋转姿态,没有对加速度积分,没有用到气压计,几乎没有滤波。算是阶段性的工作吧,把框架设计得合理一点,以后添加/修改就很简单了。从传感器的读取,到四元数的学习,到空间旋转的处理方法,循序渐进,逐个击破。主要参考了以下资料(按阅读的时间循序):计算机图形学几何工具算法详解(四元数转矩阵的公式是错的!)交互式计算机图形学基于OpenGL的自顶向下方法维基百科四元数框框的日记四元数青衫湮痕四元数Heath's blog四元数与欧拉角之间的转换阿莫电子论坛【原创】姿态估计下面总结一下“姿态解算”的过程,

2、分为“传感器”、“四元数与旋转”、“姿态解算框架”、“长期融合”、“快速融合”四部分。1.传感器我用的是10轴姿态传感器模块,其中陀螺仪是L3G4200D,加速度计是ADXL345,罗盘是HMC5883L,气压计是BMP085。全部都通过一条共用的I2C总线访问,速度都支持400kHz。先讲讲I2C库。要配置、读取传感器,首先把通信做好,这里就是I2C库了。现在大部分单片机都有支持中断的硬件I2C了,可以写个高效的I2C库。我只实现了主机发送和主机接收模式,这里简单介绍一下接口。接口函数主要有2个:uint8_t I2C_transmit    

3、0;      (uint8_t which,I2C_transmitCallback cb);void I2C_setNextCallback       (uint8_t which,I2C_transmitCallback cb);I2C_transmit()用于触发一次传输(发送或接收),异步执行,调用后马上返回。其中有一个I2C_transmitCallback类型的参数,就是决定发送或接收、如何处理数据的回调函数了,其定义如下:/* 数据传输回

4、调函数。 * 每(准备)传输一个字节都调用一次。 * 参数: *      seq  => 序号,第一次调用时为0,以后每次调用递增。 *      data => seq=0时写(从机地址+W/R)到data。 *              seq!=0时

5、data是数据。发送就写data,接收就读data。 * 返回值表示下一步的行为: *   I2C_RT_START => 发送开始信号。 *   I2C_RT_STOP  => 发送停止信号。 *   I2C_RT_REPEAT_START_OR_STOP => 如果有下一次传输,就发送RepeatStart,否则发送Stop。 *   I2C_RT_ACK  

6、60;=> 继续传送,回应ACK。 *   I2C_RT_NACK  => 继续传送,回应NACK。  */typedef uint8_t (* I2C_transmitCallback)(uint8_t seq,uint8_t * data);当用I2C_transmit()成功触发一次传输后,I2C库会根据需要调用回调函数,所以使用这个I2C库就是写回调函数了。而I2C_setNextCallback()则是用来设置紧接着的一次传输的。当本次传输结束时,不发送“Stop”信号,而是发送“Repeat

7、 Start”信号,然后开始下一个传输。利用这个函数可以发起连续多次传输。有了I2C库就可以操作传感器了,以L3G4200D为例讲解。先看看DataSheet,操作L3G4200D有两个步骤,首先配置好寄存器,然后不断获取数据。配置寄存器比较简单,就是发送一段数据,用到两个函数:/*  * 初始化芯片。 * 返回值 : L3G4200D_RT_NORMAL,L3G4200D_RT_BUS_BUSY */uint8_t l3g4200d_init(void)    if(I2C_transmit(L3G4200D_WHICH_

8、I2C,l3g4200d_init_callback) = I2C_RT_TRANSMIT_NORMAL)        return L3G4200D_RT_NORMAL;    return L3G4200D_RT_BUS_BUSY;/* * 初始化使用的I2C回调函数。 */uint8_t l3g4200d_init_callback(uint8_t seq,uint8_t * data)    const static

9、 uint8_t value =         I2C_addressToByte_write(L3G4200D_ADDRESS), /* 总线地址。 */        (0x80 | 0x20), /* 寄存器地址。或0x80表示连续写。*/        0xEF, /* CTRL_REG1 */  

10、      0x00, /* CTRL_REG2 */        0x00, /* CTRL_REG3 */        0x00, /* CTRL_REG4,250dps量程。 */        /* 其它默认。 */   

11、60;    /    if(seq = sizeof(value)        return I2C_RT_STOP;    /    *data = valueseq;    return I2C_RT_ACK;读取数据就有点麻烦,因为读之前要设置寄存器指针,所以其实包含两次传输:第一次是发送,设置当前寄存器指针

12、;第二次是接收,获取测量值。第一次传输结束前要用I2C_setNextCallback()设置第二次传输的回调函数。见代码:/* * 获取角速度。 * 异步,读取成功后,l3g4200d_measureCompleted()会被调用。 * 返回值 : L3G4200D_RT_NORMAL,L3G4200D_RT_BUS_BUSY */uint8_t l3g4200d_measureOmega(void)    if(I2C_transmit(L3G4200D_WHICH_I2C,l3g4200d_measureOmega_c

13、allback_reg) = I2C_RT_TRANSMIT_NORMAL)        return L3G4200D_RT_NORMAL;    return L3G4200D_RT_BUS_BUSY;/* * 读角速度的I2C回调函数,设置当前寄存器地址。 */uint8_t l3g4200d_measureOmega_callback_reg(uint8_t seq,uint8_t * data)    if(seq

14、 = 0)            *data = I2C_addressToByte_write(L3G4200D_ADDRESS);        return I2C_RT_ACK;        if(seq = 1)        

15、    *data = L3G4200D_REG_OMEGA; /* 角速度数据的寄存器地址。 */        return I2C_RT_ACK;        /    I2C_setNextCallback(L3G4200D_WHICH_I2C,l3g4200d_measureOmega_callback_read); 

16、0;  return I2C_RT_REPEAT_START_OR_STOP;/* * 读角速度的I2C回调函数,读取数据。 */uint8_t l3g4200d_measureOmega_callback_read(uint8_t seq,uint8_t * data)    if(seq = 0)            *data = I2C_addressToByte_read(L3G4200D_AD

17、DRESS);        return I2C_RT_ACK;        if(seq > L3G4200D_BUFFER_SIZE)        return I2C_RT_STOP;    /    l3g4200d_var.buffer_8useq-1 =

18、*data;    if(seq = L3G4200D_BUFFER_SIZE)            l3g4200d_measureCompleted();        return I2C_RT_NACK;        return I2C_RT_ACK;这样就可以读取

19、角速度了。所有数据都是在I2C中断里处理,所以要注意数据安全性,合理利用volatile。其他传感器的工作方式几乎一样,Crtl+C,Ctrl+V,然后改改名字,改改参数就可以用了。2.四元数与旋转姿态解算的核心在于旋转,一般旋转有4种表示方式:矩阵表示、欧拉角表示、轴角表示和四元数表示。矩阵表示适合变换向量,欧拉角最直观,轴角表示则适合几何推导,而在组合旋转方面,四元数表示最佳。因为姿态解算需要频繁组合旋转和用旋转变换向量,所以采用四元数保存组合姿态、辅以矩阵来变换向量的方案。下面介绍一下四元数,然后给出几种旋转表示的转换。四元数可以理解为一个实数和一个向量的组合,也可以理解为四维的向量。这

20、里用一个圈表示q是一个四元数(很可能不是规范的表示方式)。四元数的长度(模)与普通向量相似。下面是对四元数的单位化,单位化的四元数可以表示一个旋转。四元数相乘,旋转的组合就靠它了。旋转的“轴角表示”转“四元数表示”。这里创造一个运算q(w,),用于把绕单位向量w转角的旋转表示为四元数。通过q(w,),引伸出一个更方便的运算q(f,t)。有时需要把向量f的方向转到向量t的方向,这个运算就是生成表示对应旋转的四元数的(后面会用到)。然后是“四元数表示”转“矩阵表示”。再次创造运算,用R(q)表示四元数q对应的矩阵(后面用到)。多个旋转的组合可以用四元数的乘法来实现。“四元数表示”转“欧拉角表示”。用于显示。3.姿态解算框架姿态解算框架其实就是程序框架了。设计框架既要准确,又要高效。总体设计是这样的:用一个计时器定时触发测量;所有测量过程都靠中断推进;在main函数里不断检查测量是否完成,完成就进行解算。测量过程比较耗时间,而这样设计,测量和解算可以同时进行,不会浪费CPU时间在(等待)测量上。而通过计时器触发测量,最大限度保证积分间隔的准确。4.长期

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论