搜索
bottom↓
回复: 136

开始研究姿态解算了

  [复制链接]

出0入0汤圆

发表于 2012-6-25 14:56:38 | 显示全部楼层 |阅读模式
本帖最后由 js200300953 于 2012-6-25 15:56 编辑

    又花了将近一个星期,终于把姿态解算的框架完成了。仅仅是把陀螺仪、加速度计、罗盘融合在一起,得出旋转姿态,没有对加速度积分,没有用到气压计,几乎没有滤波。算是阶段性的工作吧,把框架设计得合理一点,以后添加/修改就很简单了。
从传感器的读取,到四元数的学习,到空间旋转的处理方法,循序渐进,逐个击破。主要参考了以下资料(按阅读的时间循序):

下面总结一下“姿态解算”的过程,分为“传感器”、“四元数与旋转”、“姿态解算框架”、“长期融合”、“快速融合”四部分。

  • 传感器
        我用的是10轴姿态传感器模块,其中陀螺仪是L3G4200D,加速度计是ADXL345,罗盘是HMC5883L,气压计是BMP085。全部都通过一条共用的I2C总线访问,速度都支持400kHz。
        先讲讲I2C库。要配置、读取传感器,首先把通信做好,这里就是I2C库了。现在大部分单片机都有支持中断的硬件I2C了,可以写个高效的I2C库。我只实现了主机发送和主机接收模式,这里简单介绍一下接口。接口函数主要有2个:
    1. uint8_t I2C_transmit           (uint8_t which,I2C_transmitCallback cb);
    2. void I2C_setNextCallback       (uint8_t which,I2C_transmitCallback cb);
    复制代码
    I2C_transmit()用于触发一次传输(发送或接收),异步执行,调用后马上返回。其中有一个I2C_transmitCallback类型的参数,就是决定发送或接收、如何处理数据的回调函数了,其定义如下:
    1. /*
    2. * 数据传输回调函数。
    3. * 每(准备)传输一个字节都调用一次。
    4. * 参数:
    5. *      seq  => 序号,第一次调用时为0,以后每次调用递增。
    6. *      data => seq==0时写(从机地址+W/R)到data。
    7. *              seq!=0时data是数据。发送就写data,接收就读data。
    8. * 返回值表示下一步的行为:
    9. *   I2C_RT_START => 发送开始信号。
    10. *   I2C_RT_STOP  => 发送停止信号。
    11. *   I2C_RT_REPEAT_START_OR_STOP => 如果有下一次传输,就发送RepeatStart,否则发送Stop。
    12. *   I2C_RT_ACK   => 继续传送,回应ACK。
    13. *   I2C_RT_NACK  => 继续传送,回应NACK。  */
    14. typedef uint8_t (* I2C_transmitCallback)(uint8_t seq,uint8_t * data);
    复制代码
    当用I2C_transmit()成功触发一次传输后,I2C库会根据需要调用回调函数,所以使用这个I2C库就是写回调函数了。而I2C_setNextCallback()则是用来设置紧接着的一次传输的。当本次传输结束时,不发送“Stop”信号,而是发送“RepeatStart”信号,然后开始下一个传输。利用这个函数可以发起连续多次传输。
        有了I2C库就可以操作传感器了,以L3G4200D为例讲解。先看看DataSheet,操作L3G4200D有两个步骤,首先配置好寄存器,然后不断获取数据。配置寄存器比较简单,就是发送一段数据,用到两个函数:
    1. /*
    2. * 初始化芯片。
    3. * 返回值 : {L3G4200D_RT_NORMAL,L3G4200D_RT_BUS_BUSY} */
    4. uint8_t l3g4200d_init(void)
    5. {
    6.     if(I2C_transmit(L3G4200D_WHICH_I2C,l3g4200d_init_callback) == I2C_RT_TRANSMIT_NORMAL)
    7.         return L3G4200D_RT_NORMAL;
    8.     return L3G4200D_RT_BUS_BUSY;
    9. }

    10. /*
    11. * 初始化使用的I2C回调函数。 */
    12. uint8_t l3g4200d_init_callback(uint8_t seq,uint8_t * data)
    13. {
    14.     const static uint8_t value[] = {
    15.         I2C_addressToByte_write(L3G4200D_ADDRESS), /* 总线地址。 */
    16.         (0x80 | 0x20), /* 寄存器地址。或0x80表示连续写。*/
    17.         0xEF, /* CTRL_REG1 */
    18.         0x00, /* CTRL_REG2 */
    19.         0x00, /* CTRL_REG3 */
    20.         0x00, /* CTRL_REG4,250dps量程。 */
    21.         /* 其它默认。 */
    22.     };
    23.     //
    24.     if(seq == sizeof(value))
    25.         return I2C_RT_STOP;
    26.     //
    27.     *data = value[seq];
    28.     return I2C_RT_ACK;
    29. }
    复制代码
    读取数据就有点麻烦,因为读之前要设置寄存器指针,所以其实包含两次传输:第一次是发送,设置当前寄存器指针;第二次是接收,获取测量值。第一次传输结束前要用I2C_setNextCallback()设置第二次传输的回调函数。见代码:
    1. /*
    2. * 获取角速度。
    3. * 异步,读取成功后,l3g4200d_measureCompleted()会被调用。
    4. * 返回值 : {L3G4200D_RT_NORMAL,L3G4200D_RT_BUS_BUSY} */
    5. uint8_t l3g4200d_measureOmega(void)
    6. {
    7.     if(I2C_transmit(L3G4200D_WHICH_I2C,l3g4200d_measureOmega_callback_reg) == I2C_RT_TRANSMIT_NORMAL)
    8.         return L3G4200D_RT_NORMAL;
    9.     return L3G4200D_RT_BUS_BUSY;
    10. }

    11. /*
    12. * 读角速度的I2C回调函数,设置当前寄存器地址。 */
    13. uint8_t l3g4200d_measureOmega_callback_reg(uint8_t seq,uint8_t * data)
    14. {
    15.     if(seq == 0)
    16.     {
    17.         *data = I2C_addressToByte_write(L3G4200D_ADDRESS);
    18.         return I2C_RT_ACK;
    19.     }
    20.     if(seq == 1)
    21.     {
    22.         *data = L3G4200D_REG_OMEGA; /* 角速度数据的寄存器地址。 */
    23.         return I2C_RT_ACK;
    24.     }
    25.     //
    26.     I2C_setNextCallback(L3G4200D_WHICH_I2C,l3g4200d_measureOmega_callback_read);
    27.     return I2C_RT_REPEAT_START_OR_STOP;
    28. }

    29. /*
    30. * 读角速度的I2C回调函数,读取数据。 */
    31. uint8_t l3g4200d_measureOmega_callback_read(uint8_t seq,uint8_t * data)
    32. {
    33.     if(seq == 0)
    34.     {
    35.         *data = I2C_addressToByte_read(L3G4200D_ADDRESS);
    36.         return I2C_RT_ACK;
    37.     }
    38.     if(seq > L3G4200D_BUFFER_SIZE)
    39.         return I2C_RT_STOP;
    40.     //
    41.     l3g4200d_var.buffer_8u[seq-1] = *data;
    42.     if(seq == L3G4200D_BUFFER_SIZE)
    43.     {
    44.         l3g4200d_measureCompleted();
    45.         return I2C_RT_NACK;
    46.     }
    47.     return I2C_RT_ACK;
    48. }
    复制代码
    这样就可以读取角速度了。所有数据都是在I2C中断里处理,所以要注意数据安全性,合理利用volatile。
        其他传感器的工作方式几乎一样,Crtl+C,Ctrl+V,然后改改名字,改改参数就可以用了。
  • 四元数与旋转
        姿态解算的核心在于旋转,一般旋转有4种表示方式:矩阵表示、欧拉角表示、轴角表示和四元数表示。矩阵表示适合变换向量,欧拉角最直观,轴角表示则适合几何推导,而在组合旋转方面,四元数表示最佳。因为姿态解算需要频繁组合旋转和用旋转变换向量,所以采用四元数保存组合姿态、辅以矩阵来变换向量的方案。下面介绍一下四元数,然后给出几种旋转表示的转换。

        四元数可以理解为一个实数和一个向量的组合,也可以理解为四维的向量。这里用一个圈表示q是一个四元数,很可能不是规范的表示方式。


        四元数的长度(模)与普通向量相似。


        下面是对四元数的单位化,单位化的四元数可以表示一个旋转。


        四元数相乘,旋转的组合就靠它了。


        旋转的“轴角表示”转“四元数表示”。这里创造一个运算q(w,θ),用于把绕单位向量w转θ角的旋转表示为四元数。


        通过q(w,θ),引伸出一个更方便的运算q(f,t)。有时需要把向量f的方向转到向量t的方向,这个运算就是生成表示对应旋转的四元数的。后面会用到。


        然后是“四元数表示”转“矩阵表示”。再次创造运算,用R(p)表示四元数p对应的矩阵(后面用到)。


        多个旋转的组合可以用四元数的乘法来实现。


        “四元数表示”转“欧拉角表示”。
  • 姿态解算框架
        姿态解算框架其实就是程序框架了。设计框架既要准确,又要高效。总体设计是这样的:
    • 用一个计时器定时触发测量;
    • 所有测量过程都靠中断推进;
    • 在main函数里不断检查测量是否完成,完成就进行解算。
        测量过程比较耗时间,而这样设计,测量和解算可以同时进行,不会浪费CPU时间在(等待)测量上。而通过计时器触发测量,最大限度保证积分间隔的准确。
  • 长期融合
        长期融合的目的有两个:一、得到初始姿态;二、用直接测量的姿态(下称直接姿态),纠正陀螺仪积分得出的姿态。直接测量的量包括加速度和磁场强度。长期融合有两个阶段,第一阶段是获得直接姿态,第二阶段是用直接姿态纠正当前姿态。首先讲第一阶段:用加速度和磁场强度计算直接姿态。
        获取直接姿态的过程,其实是利用了空间中的两个场——重力场和地磁场,把测得的加速度和磁场强度旋转到“原来的位置”,其中的“旋转”就是我们需要的直接姿态了。但由于干扰和误差,测得的值不可能旋转到与实际的场一致。
        用了净两天的时间来思考,还是想不出高效的办法。下面讲我的笨办法。

        首先定义几个量("w" for world,"m" for measure):


        单位化:


        变换到对角线和平面法线。因为不能把加速度和磁场强度旋转到与对应的场一致,于是变换一下,使他们的对角线和平面法线与场对应的量重合,这是可以做到的。("d"for diagonal,"c" for cross)


        然后旋转分两步:首先使对角线重合,得到第一个旋转。


        在第二次旋转前,要用第一个旋转变换一下测量量的平面法线。因为经过第一次旋转,测量量的平面法线也跟着转了。


        接着就是第二次旋转,使平面法线重合。


        组合两次旋转,直接姿态就出来了。第一阶段完成。


        第二阶段是纠正当前姿态,这里用的是最简单的——线性插值再单位化。
  • 快速融合
        快速融合比长期融合简单多了。

        先用测得的角速度和积分间隔构造“微旋转”,这里用了小角三角近似,sin(Δ)≈Δ,cos(Δ)≈1。


        然后用四元数乘法组合,就成了。


原文:http://blog.sina.com.cn/s/blog_81f1e26801016ub2.html

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2012-6-25 15:18:46 | 显示全部楼层
沙发!
关注ing......

出0入0汤圆

发表于 2012-6-25 15:22:12 | 显示全部楼层
不错啊.....  我还在跟四元数挣扎呢..

出0入0汤圆

发表于 2012-6-25 15:22:37 | 显示全部楼层
lz 辛苦  持续关注

出0入0汤圆

发表于 2012-6-25 15:22:42 | 显示全部楼层
不错,学习了

出0入0汤圆

发表于 2012-6-25 15:48:03 | 显示全部楼层
一直不明白三轴加速度和磁传感器的融合是怎么做到的。。。。

出0入0汤圆

发表于 2012-6-25 17:55:42 | 显示全部楼层
mark   以后看看

出0入0汤圆

发表于 2012-6-25 18:54:05 | 显示全部楼层
支持原创,LZ辛苦,我也在研究四元数,今晚漫漫看

出0入0汤圆

发表于 2012-6-25 19:09:49 | 显示全部楼层
持续关注着                                 
                                                                                                                     

出0入0汤圆

发表于 2012-6-25 20:14:52 | 显示全部楼层
mark.......  好贴

出0入0汤圆

发表于 2012-6-25 20:21:05 | 显示全部楼层
高深的理论,非常欠缺啊,看不懂。。。。。

出0入0汤圆

发表于 2012-6-25 20:45:28 | 显示全部楼层
好久没有看到这样的强帖了!!!必须顶起!!!!!!!!!!!!!11

出0入0汤圆

发表于 2012-6-25 21:03:38 | 显示全部楼层
好资料,Mark

出0入0汤圆

发表于 2012-6-26 22:11:50 | 显示全部楼层
很经典。。。

出0入0汤圆

发表于 2012-7-1 17:05:10 | 显示全部楼层
支持原创,很好的帖子,楼主好人。

出0入0汤圆

发表于 2012-7-1 23:38:33 | 显示全部楼层
mark

出0入0汤圆

发表于 2012-7-2 23:58:20 | 显示全部楼层
不错,学习了,楼主好人啊

出0入0汤圆

发表于 2012-7-9 12:33:48 来自手机 | 显示全部楼层
马可马可马可马可马可!

出0入0汤圆

发表于 2012-7-9 17:09:48 | 显示全部楼层
以前笑人家读研究生的人是浪费时间,现在才发现自己的短视,好多数学理论都欠缺。

出0入0汤圆

发表于 2012-7-9 21:37:04 | 显示全部楼层
学习学习学习学习学习学习

出0入0汤圆

发表于 2012-7-10 14:13:46 | 显示全部楼层
MARK!!!学习学习

出0入0汤圆

发表于 2012-7-10 14:22:08 | 显示全部楼层
楼主很认真 说的很详细哈 谢谢

出0入0汤圆

发表于 2012-7-12 22:10:47 | 显示全部楼层
强帖、顶.

出0入0汤圆

发表于 2012-7-12 22:24:00 | 显示全部楼层
mark ,讲的太好了

出0入0汤圆

 楼主| 发表于 2012-7-13 13:31:16 | 显示全部楼层
怎么不能编辑了?
有两个公式错了:


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2012-7-23 14:01:14 | 显示全部楼层
LZ,照我的理解,快速融合就是我2.5ms(比如)一次中断,中断里采集一次陀螺仪的测量值,并且标致位置1,while(1)里循环检测,置1了则开始快速融合,四元数A初始化为(1,0,0,0);b1=1,b2=data_x*t/2,
b2=data_y*t/2,b3=data_z*t/2,然后A=A*B进行四元数更新,若要显示的话,把A单位化,用你的公式转换成rool,pitch,yaw,不知道这么理解对不对,既然陀螺仪测出角速度后乘以t是角增量,应该就是对应的欧拉角,那四元数B能不能用陀螺仪测出的角增量来转换成四元数表示,而不是用我开始写的那样,还有,对B需不需单位化呢???

出0入0汤圆

 楼主| 发表于 2012-7-23 14:43:52 | 显示全部楼层
蓝海de梦 发表于 2012-7-23 14:01
LZ,照我的理解,快速融合就是我2.5ms(比如)一次中断,中断里采集一次陀螺仪的测量值,并且标致位置1,whil ...

1.“快速融合就是我2.5ms(比如)一次中断,中断里采集一次陀螺仪的测量值,并且标致位置1,while(1)里循环检测,置1了则开始快速融合”
    我的方法就是这样的。
2.“四元数A初始化为(1,0,0,0)”
    这个不大完整,因为实际的初始姿态是不可预知的。我想到两种方法来确定初始姿态:
        一、用几何旋转法(就是本文所说的长期融合的第一阶段),把上电进行的第一次长期融合的结果作为初始姿态;
        二、或者,就取为[1 0 0 0],然后用梯度下降法进行足够次数的迭代。
3.“b1=1,b2=data_x*t/2,b2=data_y*t/2,b3=data_z*t/2,然后A=A*B进行四元数更新”
    对。
4.“若要显示的话,把A单位化,用你的公式转换成rool,pitch,yaw“
    只有长度为1的四元数才表示姿态,所以A始终长度为1,不需单位化。尽量少用或不用四元数转姿态角的公式,因为三角函数的运算量大得离谱。
5.“四元数B能不能用陀螺仪测出的角增量来转换成四元数表示”
    这句话不明白。
6.其实,之所以能够“b1=1,b2=data_x*t/2,b2=data_y*t/2,b3=data_z*t/2,然后A=A*B”,是用了小角三角替代,实际的公式很复杂。也是因为用了近似替代,同时考虑到运算误差,所以乘完后,要加个单位化。

出0入0汤圆

发表于 2012-7-23 17:38:06 | 显示全部楼层
js200300953 发表于 2012-7-23 14:43
1.“快速融合就是我2.5ms(比如)一次中断,中断里采集一次陀螺仪的测量值,并且标致位置1,while(1)里循 ...

非常感谢你的回复,很详细!我PC端显示就是把欧拉角传回PC,所以还是要解耦角度的,确实计算量非常大,有公式可以将欧拉角转换成四元数,所以那个第五点我的意思是四元数B应该可以用陀螺仪积分出的增量角度转换吧,额。。。感觉这样计算量更大了,就是不晓得能否这么求四元数B?

出0入0汤圆

 楼主| 发表于 2012-7-23 17:49:36 | 显示全部楼层
蓝海de梦 发表于 2012-7-23 17:38
非常感谢你的回复,很详细!我PC端显示就是把欧拉角传回PC,所以还是要解耦角度的,确实计算量非常大,有 ...

不明白你的“积分”是怎么个积分法。
其实A=A*B就是积分了。

出0入0汤圆

发表于 2012-7-24 10:32:23 | 显示全部楼层
js200300953 发表于 2012-7-23 17:49
不明白你的“积分”是怎么个积分法。
其实A=A*B就是积分了。

非常奇怪啊!解耦出的角度变化很大呢,LZ的公式Pitch解算范围是正负90度,另外两个是正负180度,这样不能全角度显示欧拉角,如果要显示的话应该要修正的,

因为我要涉及求欧拉角,只能解算时候关闭定时器,不知道是不是这原因,我转动45度不到,传回电脑显示都180度了,造成陀螺仪静止不动的时候很明显看到在漂,

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

 楼主| 发表于 2012-7-24 11:01:49 | 显示全部楼层
蓝海de梦 发表于 2012-7-24 10:32
非常奇怪啊!解耦出的角度变化很大呢,LZ的公式Pitch解算范围是正负90度,另外两个是正负180度,这样不能 ...

那个已经是全姿态,如果全部(-π,π],就有冗余了。
类似:用(-π,π]的经度和(-π/2,π/2]的纬度可以确定任意方向,然后绕这个方向可以转(-π,π]。

你整个运算过程是怎么的?

出0入0汤圆

发表于 2012-7-24 11:37:19 | 显示全部楼层
js200300953 发表于 2012-7-24 11:01
那个已经是全姿态,如果全部(-π,π],就有冗余了。
类似:用(-π,π]的经度和(-π/2,π/2]的纬度可以确 ...

因为涉及解耦角度,所以解算时候关闭定时器,2.5ms定时到,连续采集陀螺仪数据,置标志位--->while(1)循环检测,置1时候进if,标志位置0同时关闭定时器--->数据*0.00875,四元数B更新--->四元数A更新--->转换成欧拉角后*180/3.14(弧度转角度),--->(int)((pitch)*10)像这么处理,转换成16位整型,精度0.1,所以乘以10,之后usart传回电脑,并开定时器。
担心解耦耗时就每次开关定时器,找到的欧拉角定义比较多,也没个准的,想找个最适合四轴的欧拉角定义,现在卡姿态显示了,ADXL345和HMC5883L可以用,不过ADXL345抗震能力太差了,用手弹模块偏差实在太大,试过几种滤波效果不明显,看来卡儿曼还是要抽空搞明白的
之前说的角度问题找到个图给你看看   可能接触四元数时间太短吧!哪里疏忽了

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

 楼主| 发表于 2012-7-24 11:47:47 | 显示全部楼层
蓝海de梦 发表于 2012-7-24 11:37
因为涉及解耦角度,所以解算时候关闭定时器,2.5ms定时到,连续采集陀螺仪数据,置标志位--->while(1) ...

有个问题:定时器开开关关的,积分周期难保正确。
而且每次积分,有两个过程非常耗时间——算角度和串口发送,可能会令积分周期加长。
建议仅发送四元数,把角度运算放在上位机。

如果你不介意,放段代码来,我帮你看看。

出0入0汤圆

发表于 2012-7-24 12:09:44 | 显示全部楼层
js200300953 发表于 2012-7-24 11:47
有个问题:定时器开开关关的,积分周期难保正确。
而且每次积分,有两个过程非常耗时间——算角度和串口 ...

呵呵  代码啥的无所谓的  我也想把解角度放在上位机啊!不过机电专业的pc编程还是硬伤啊!叫我画个CAD啥的编个PLC啥的倒没问题,
int main(void)
{
        SystemInit();//72M
        USART1_Config();串口
        I2C_GPIO_Config();模拟IIC
        Init_L3G4200D();//陀螺仪
        TIM2_NVIC_Configuration();//定时中断向量
        TIM2_Configuration();//定时初始化
        flag_over = 0;
        START_TIME;//开定时
        t = 0.004;//积分周期
        while (1)
        {
                if(flag_over == 1)
                {
                        STOP_TIME;//关定时
                        flag_over = 0;
                        /*if(L3_X<0)
                                L3_X = -L3_X;     //补码转原码,通信协议里有了   注释掉
                        if(L3_Y<0)
                                L3_Y = -L3_Y;
                        if(L3_Z<0)
                                L3_Z = -L3_Z;*/
                        D_X = (float)L3_X * 0.00875;
                                D_Y = (float)L3_Y * 0.00875;
                        D_Z = (float)L3_Z * 0.00875;
                        B[0] = 1;
                        B[1] = (D_X * t)/2;
                        B[2] = (D_Y * t)/2;
                        B[3] = (D_Z * t)/2;
                                /*B[0] = 1 + ((D_X * t)/2) * ((D_Y * t)/2) * ((D_Z * t)/2);   //这是我前几楼跟你说的,瞬时角曾量转换成四元数   也是用的微小角度近似
                        B[1] = (D_X * t)/2 - ((D_Y * t)/2) * ((D_Z * t)/2);
                        B[2] = (D_Y * t)/2 + ((D_Z * t)/2) * ((D_X * t)/2);
                        B[3] = (D_Z * t)/2 - ((D_X * t)/2) * ((D_Y * t)/2);*/
                        /*b =  B[0] * B[0] + B[1] * B[1] + B[2] * B[2] + B[3] * B[3] ;//单位化   不需要了
                        SQRT_B = Q_rsqrt(b);//平方根倒数速算   这边也用不到了
                        B[0] = B[0] * SQRT_B;
                        B[1] = B[1] * SQRT_B;
                        B[2] = B[2] * SQRT_B;
                        B[3] = B[3] * SQRT_B;*/
                        A[0] = A[0] * B[0] - A[1] * B[1] - A[2] * B[2] - A[3] * B[3];//更新A
                        A[1] = A[0] * B[1] + A[1] * B[0] + A[2] * B[3] - A[3] * B[2];
                        A[2] = A[0] * B[2] - A[1] * B[3] + A[2] * B[0] + A[3] * B[1];
                        A[3] = A[0] * B[3] + A[1] * B[2] - A[2] * B[1] + A[3] * B[0];
                        /*a =  A[0] * A[0] + A[1] * A[1] + A[2] * A[2] + A[3] * A[3] ;
                        SQRT_A = Q_rsqrt(a);
                        A[0] = A[0] * SQRT_A;
                        A[1] = A[1] * SQRT_A;
                        A[2] = A[2] * SQRT_A;
                        A[3] = A[3] * SQRT_A;*/
                        Yaw =  ((atan2( 2 * ( A[0] * A[3] + A[1] * A[2] ), 1 - 2 * ( A[2] * A[2] + A[3] * A[3] )) * 180 ) / 3.14159265 );//角度转换
                        Pitch = ((asin( 2 * ( A[0] * A[2] - A[3] * A[1] )) * 180 ) / 3.14159265 );
                        Roll = ((atan2( 2 * ( A[0] * A[1] + A[2] * A[3] ), 1 - 2 * ( A[1] * A[1] + A[2] * A[2] )) * 180 ) / 3.14159265 );
                        Roll_Send = (int)(Roll * 10);//精度0.1
                        Pitch_Send = (int)(Pitch * 10);
                        Yaw_Send = (int)(Yaw * 10);
                        UART1_ReportIMU(Yaw_Send, Pitch_Send, Roll_Send, 0x0000, 0x0000, 0x0000, 0x0000);//发送
                        Delayms(5);//速度太快上位机溢出,哎  等LabView自学完看看能不能自己做
                        START_TIME;//开定时
                }
        }
}
这是中断函数
void TIM2_IRQHandler(void)
{
        if ( TIM_GetITStatus(TIM2 , TIM_IT_Update) != RESET ) //查询
        {       
                TIM_ClearITPendingBit(TIM2 , TIM_FLAG_Update);//清标致位
                time++;
                if(time == 4)
                {
                        time = 0;
                        Multiple_ReadL3G4200D();//地址A8  连续读出
                        flag_over = 1;
                }
        }                        
}

出0入0汤圆

 楼主| 发表于 2012-7-24 12:36:13 | 显示全部楼层
蓝海de梦 发表于 2012-7-24 12:09
呵呵  代码啥的无所谓的  我也想把解角度放在上位机啊!不过机电专业的pc编程还是硬伤啊!叫我画个CAD啥 ...

公式没问题,我用过都可以。

L3G4200D的量程是多少?我设成2000dps,参数就这样:
  1. /*
  2. * 比例因子,(rad/s)/LSB。 */
  3. #define L3G4200D_GAIN_X 0.001264f
  4. #define L3G4200D_GAIN_Y 0.001311f
  5. #define L3G4200D_GAIN_Z 0.001300f
  6. /*
  7. * 漂移校正。单位:LSB */
  8. #define L3G4200D_OFFSET_X  2.5f
  9. #define L3G4200D_OFFSET_Y -0.7f
  10. #define L3G4200D_OFFSET_Z -4.7f
复制代码
还有那个积分周期肯定是不准确的!建议你在运算的前后加个GPIO反转,用示波器看看实际的周期,你会被吓到的。

还有,那个A是要单位化的。

出0入0汤圆

 楼主| 发表于 2012-7-24 12:51:26 | 显示全部楼层
蓝海de梦 发表于 2012-7-24 12:09
呵呵  代码啥的无所谓的  我也想把解角度放在上位机啊!不过机电专业的pc编程还是硬伤啊!叫我画个CAD啥 ...

还有!A=A*B算错了,因为算A[1]的时候,A[0]已经不是原来的A[0]了。应该这样:
  1. tmp=A*B;
  2. A=tmp
复制代码

出0入0汤圆

发表于 2012-7-24 13:07:22 | 显示全部楼层
收藏了
谢谢lz了

出0入0汤圆

发表于 2012-7-24 13:10:08 | 显示全部楼层
解释的很详细,学习中

出0入0汤圆

发表于 2012-7-24 13:35:45 | 显示全部楼层
非常详细了

出0入0汤圆

发表于 2012-7-24 13:51:07 | 显示全部楼层
js200300953 发表于 2012-7-24 12:51
还有!A=A*B算错了,因为算A[1]的时候,A[0]已经不是原来的A[0]了。应该这样: ...

非常感谢!确实是积分周期问题,很郁闷,写程序时候就是怕周期出问题才开关定时的。还有,示波器嘛!真没有,就搞不明白物理实验室的示波器不准我用,放那也浪费啊!想当初刚开学时候我们几个人参加飞思卡尔,一个废的实验室给我们,桌子啥的都是不要的给我们,辛辛苦苦一天隔一天的熬夜调车,把属于我们自己的实验室创立起来,协会也有自己的地方,临了说要收回那地方,现在被我们占着,要领导批点钱买点设备,就一句话,没钱。吃吃喝喝倒有钱了,后来去问老师,他们说他们想示波器都想几年了。。。。。由次吃饭他们说起,这的企业当初给了学院100万说建实验室,找点学生,老师培训钱企业来,妈的这钱被院里人吃吃喝喝花了60万,企业来人一看,直接走了,剩40万没人敢动,说给创实验室的,又不批,真火大。。。奖学金什么的也是都给的学生会那帮货,期末成绩加分最多也他们,全加满。。。反正现在我学东西全自己掏钱,他们说项目里报点,我说不要,只希望实验室能建好就好,暑假就自己一个人待这,很孤独啊!!!

出0入0汤圆

发表于 2012-7-24 22:06:22 | 显示全部楼层
mark!!!!!!

出0入0汤圆

发表于 2012-8-4 20:41:20 | 显示全部楼层
nice

出0入0汤圆

发表于 2012-8-5 04:22:16 | 显示全部楼层
不错,先收下,慢慢学

出0入0汤圆

发表于 2012-8-6 15:43:51 | 显示全部楼层
这个必须马克

出0入143汤圆

发表于 2012-8-6 17:20:19 | 显示全部楼层
每天來學習一下

出0入0汤圆

发表于 2012-8-23 02:11:55 | 显示全部楼层
楼主你好,请问需要进行长期融合的判定条件是什么?

出0入0汤圆

 楼主| 发表于 2012-8-23 15:25:33 | 显示全部楼层
Casey_zjx 发表于 2012-8-23 02:11
楼主你好,请问需要进行长期融合的判定条件是什么?

  • 加速度、磁场强度的长度不正常,平时这两个都比较稳定的。
  • 预知即将发生大加速运动时。

出0入0汤圆

发表于 2012-9-1 21:15:53 | 显示全部楼层
好文章 哎 数学啊 欧拉啊

出0入0汤圆

发表于 2012-9-2 23:21:28 来自手机 | 显示全部楼层
马克。特意买台打印机把资料print出来慢慢学。

出0入0汤圆

发表于 2012-9-3 20:29:50 | 显示全部楼层
咱俩传感器选得差不多,我也还买的10轴姿态传感器。用STM32做主控。正在研究四元数。我QQ663875089,一起研究吧。

出0入0汤圆

发表于 2012-9-5 12:04:31 | 显示全部楼层
支持楼主开源,共同学习!

出0入0汤圆

 楼主| 发表于 2012-9-5 15:03:26 | 显示全部楼层
421054972 发表于 2012-9-5 12:04
支持楼主开源,共同学习!

“开源”代码没意思,要“开源”就“开源”思想。

出0入0汤圆

发表于 2012-9-5 18:41:37 | 显示全部楼层
本帖最后由 wanxuncpx 于 2012-9-5 18:43 编辑

按楼主的思路和公式行不通啊
假如陀螺仪1s钟内,yaw偏航角偏航了10度,pitch俯仰角偏了10度,roll偏了0度, 将这个角度转为弧度,然后按400Hz陀螺仪速度切割为400份后构成的小三角近似的四元数qn,
然后用qn去叉乘更新四元数quaternion 400次,照说得到的欧拉角应为10°  10°  0°啊可我计算的结果roll不为0啊


求帮助,求分析!

代码如下:

/* 输入欧拉角,能看到四元数,以及再转换回去成欧拉角
    Yaw范围(-180~180)
    Pitch范围(-90~90)
    Roll范围(-180~180)
*/  
#include "stdio.h"  
#include "math.h"  
#include "conio.h"  

/*---------------------*
*    A- 数据类型定义   *
*----------------------*/
typedef struct
{
    float gx;
    float gy;
    float gz;
}tg_L3G4200D_TYPE;

typedef struct{
    float w;
    float x;
    float y;
    float z;
}tg_Quaternion;

typedef struct
{
    float  yaw;
    float  pitch;
    float  roll;
}tg_AHRS_TYPE;


tg_Quaternion quaternion={1,0,0,0};
tg_AHRS_TYPE  ahrs={0,0,0};
tg_L3G4200D_TYPE l3g4200={0,0,0};

#define PI      3.141592654
#define halfT   0.5f

/******************************************************************************
/ 函数功能:快速陀螺仪四元数更新
/ 修改日期:none
/ 输入参数:none
/ 输出参数:none
/ 使用说明:none
******************************************************************************/
void FastFormat(tg_Quaternion * pSrc,tg_Quaternion * pDst)
{
    tg_Quaternion dQ,Qn,Qdst;
    float sq;

    //用小三角近似法快速得到微旋转的四元数,省去了大量的三角函数变换
    dQ.w = pSrc->w;
    dQ.x = pSrc->x;
    dQ.y = pSrc->y;
    dQ.z = pSrc->z;
   
    //提取目标四元数
    Qdst.w = pDst->w;
    Qdst.x = pDst->x;
    Qdst.y = pDst->y;
    Qdst.z = pDst->z;
   
   
   
    //四元数乘法
    Qn.w = (Qdst.w * dQ.w) - (Qdst.x * dQ.x) - (Qdst.y * dQ.y) - (Qdst.z* dQ.z);
    Qn.x = (Qdst.w * dQ.x) + (Qdst.x * dQ.w) + (Qdst.y * dQ.z) - (Qdst.z* dQ.y);
    Qn.y = (Qdst.w * dQ.y) - (Qdst.x * dQ.z) + (Qdst.y * dQ.w) + (Qdst.z* dQ.x);
    Qn.z = (Qdst.w * dQ.z) + (Qdst.x * dQ.y) - (Qdst.y * dQ.x) + (Qdst.z* dQ.w);
   
    //单位化,并返回四元数
    sq = Qn.w * Qn.w + Qn.x*Qn.x + Qn.y*Qn.y + Qn.z*Qn.z;
    sq = sqrt(sq);
    pDst->w = Qn.w / sq;
    pDst->x = Qn.x / sq;
    pDst->y = Qn.y / sq;
    pDst->z = Qn.z / sq;

}

/******************************************************************************
/ 函数功能:欧拉角转四元数
/ 修改日期:none
/ 输入参数:none
/ 输出参数:none
/ 使用说明:none
******************************************************************************/
tg_Quaternion FromEulerAngle(tg_L3G4200D_TYPE *pIn)
{
    tg_Quaternion Qn;
    float sq;

    //用小三角近似法快速得到微旋转的四元数,省去了海量的三角函数变换
    Qn.w = 1;
    Qn.x = ((float)pIn->gx)*(0.07*0.5*0.0025);
    Qn.y = ((float)pIn->gy)*(0.07*0.5*0.0025);
    Qn.z = ((float)pIn->gz)*(0.07*0.5*0.0025);
    return Qn;
    //*/
}
/******************************************************************************
/ 函数功能:将四元数转换为欧拉角
/ 修改日期:none
/ 输入参数:
/ 输出参数:
/ 使用说明:none
******************************************************************************/
void ToEulerAngle(tg_Quaternion * pIn,tg_AHRS_TYPE * pOut)
{
    tg_Quaternion Qn;
    float a,b,c,d,e,sq;
    float T[3][3],Q[4];


    /* 获取四元数数据 */
    Qn.w = pIn->w;
    Qn.x = pIn->x;
    Qn.y = pIn->y;
    Qn.z = pIn->z;

    /* 计算中间量 */
    ///*
    a = 2*(Qn.w * Qn.z + Qn.x * Qn.y);
    b = 1 - 2 * ( Qn.y * Qn.y + Qn.z * Qn.z);
    c = 2 * (Qn.w * Qn.y - Qn.z *Qn.x );
    d = 2 * (Qn.w * Qn.x + Qn.y * Qn.z );
    e = 1 - 2 * (Qn.x * Qn.x + Qn.y * Qn.y );
    // 计算欧拉角
    pOut->yaw   = (float)(atan2(a,b)*(180.0/PI));  // yaw:  z轴,偏航角
    pOut->pitch = (float)(asin(c)* (180.0/PI));  // pitch:y轴,俯仰角
    pOut->roll  = (float)(atan2(d,e)*(180.0/PI));  // roll: x轴,滚动角
}




void main(void)
{
    int i;
    tg_Quaternion qn;

    do{
        /* 模拟陀螺仪的输出欧拉角(积分一秒) */
        printf("\nYaw = ");
        scanf("%f",&l3g4200.gz);  
        printf("\nPitch = ");
        scanf("%f",&l3g4200.gy);  
        printf("\nRoll = ");
        scanf("%f",&l3g4200.gx);
        l3g4200.gz *= (PI/180f)/0.07f;
        l3g4200.gy *= (PI/180f)/0.07f;
        l3g4200.gx *= (PI/180f)/0.07f;

        qn = FromEulerAngle(&l3g4200);
        printf("\nQ=[ %f %f %f %f]",qn.w,qn.x,qn.y,qn.z);
        printf("\n\nPlease wait!\n") ;

        /* 将角度变化模拟为L3g4200的采集数据值 */


        for(i=0; i<400;i++)
        {
            FastFormat(&qn,&quaternion);    //qn是陀螺仪积分的四元数,quaternion是待更新四元数
        }
        ToEulerAngle(&quaternion, &ahrs);   //将四元数转为角度
        printf("\nQ=[ %f %f %f %f]",quaternion.w,quaternion.x,quaternion.y,quaternion.z);
        printf("\nYaw   = %f\nPitch = %f\nRoll = %f\n",ahrs.yaw,ahrs.pitch,ahrs.roll);

        getch();
    }while(1);
}

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2012-9-5 19:19:55 | 显示全部楼层
哭了,很多看不懂···

出0入0汤圆

发表于 2012-9-5 19:31:46 | 显示全部楼层
看起来好像很复杂的样子···

出0入0汤圆

 楼主| 发表于 2012-9-6 08:13:47 | 显示全部楼层
本帖最后由 js200300953 于 2012-9-6 08:15 编辑
wanxuncpx 发表于 2012-9-5 18:41
按楼主的思路和公式行不通啊
假如陀螺仪1s钟内,yaw偏航角偏航了10度,pitch俯仰角偏了10度,roll偏了0度, 将 ...
  • 10度的欧拉角是不能通过除以400,来分成400份的。只有仅单轴变化时才可以,如果多轴,轴之间会相互影响。
  • 这两段怎么理解?gx是角速度还是角度?0.07?
  1.     Qn.x = ((float)pIn->gx)*(0.07*0.5*0.0025);
  2.     Qn.y = ((float)pIn->gy)*(0.07*0.5*0.0025);
  3.     Qn.z = ((float)pIn->gz)*(0.07*0.5*0.0025);
复制代码
  1.     l3g4200.gz *= (PI/180f)/0.07f;
  2.     l3g4200.gy *= (PI/180f)/0.07f;
  3.     l3g4200.gx *= (PI/180f)/0.07f;
复制代码

出0入0汤圆

发表于 2012-9-6 10:23:14 | 显示全部楼层
本帖最后由 wanxuncpx 于 2012-9-6 10:50 编辑
js200300953 发表于 2012-9-6 08:13
  • 10度的欧拉角是不能通过除以400,来分成400份的。只有仅单轴变化时才可以,如果多轴,轴之间会相互影响 ...


  • 感谢js200300953,和各位朋友, 这么快就能为我解惑实在让人非常感动.

    js200300953大大的疑问解释如下:

    1. 10度的欧拉角是不能通过除以400,来分成400份的。只有仅单轴变化时才可以,如果多轴,轴之间会相互影响。
    回复:10度是角度,1s内转动了10度,即角速度为v=((10*PI)/180 )弧度每秒,400Hz采样速率,每2.5ms的弧度积分即为0.0025*v(这个值就是欧拉角了)

    2.这两段怎么理解?gx是角速度还是角度?0.07?
    回复:
    陀螺仪使用的是L3G4200D,陀螺仪采样精度为2000dps,按datasheet描述,陀螺仪输出值乘以0.07,即转换为陀螺仪该轴的角速度(弧度每秒)

    这段代码是将输入的角度值转换模拟为陀螺仪的直接输出值
        l3g4200.gz *= (PI/180f)/0.07f;
        l3g4200.gy *= (PI/180f)/0.07f;
        l3g4200.gx *= (PI/180f)/0.07f;
    这段代码是将2.5ms内的陀螺仪直接输出值算成角度积分值(与欧拉角相对应),pIn->gx等已经是等效的陀螺仪直接输出值.
        Qn.x = ((float)pIn->gx)*(0.07*0.5*0.0025);
        Qn.y = ((float)pIn->gy)*(0.07*0.5*0.0025);
        Qn.z = ((float)pIn->gz)*(0.07*0.5*0.0025);

    顺便上传飞控的原理图和L3G4200D,ADXL345, BMP085, HMC5883L等传感器的成功调试代码弘扬各位大大的开源精神!!
    驱动程序框架如下:(有框架分析程序会比较容易)

    测试程序:


    飞控原理图:

    pdf版本:


    本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有帐号?注册

    x

    出0入0汤圆

     楼主| 发表于 2012-9-6 11:38:37 | 显示全部楼层
    wanxuncpx 发表于 2012-9-6 10:23
    感谢js200300953,和各位朋友, 这么快就能为我解惑实在让人非常感动.

    js200300953大大的疑问解释如下:

    dsp for "degree per second".
    乘0.07后不是弧度。

    把欧拉角等分,并不等价于把它拆成多次旋转,只有特殊的情况才是,例如单轴:

    本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有帐号?注册

    x

    出0入0汤圆

    发表于 2012-9-6 11:58:24 | 显示全部楼层
    js200300953 发表于 2012-9-6 11:38
    dsp for "degree per second".
    乘0.07后不是弧度。


    dsp for "degree per second"
    哦,这个我忽视了,我之前一直以为是弧度呢,这暂时不影响仿真.


    "把欧拉角等分,并不等价于把它拆成多次旋转"为什么?
    将飞控按yaw和pttch轴 10角度/s的速度旋转1s后 得到的更新四元素,求出欧拉角难道不应该是10度,10度,0度吗?
    1s的时间内, 这个转动假设是匀速的 , L3G4200的周期是2.5ms, 这个时间片内的转动弧度角就是Dx = (0.0025s * 10角度/s *PI/180)啊,
    难道每次陀螺仪的快速融合不是用[1,Dx/2, Dy/2, Dz/2 ]来乘以和更新目标四元数?

    出0入0汤圆

     楼主| 发表于 2012-9-6 12:29:17 | 显示全部楼层
    wanxuncpx 发表于 2012-9-6 11:58
    dsp for "degree per second"
    哦,这个我忽视了,我之前一直以为是弧度呢,这暂时不影响仿真.

    对x和y轴转10次1度,效果不等于对x和y轴转1次10度。
    即使是同样1次10度,x先和y先都不同。

    出0入0汤圆

    发表于 2012-9-20 21:45:20 | 显示全部楼层
    请问看姿态变化的那个软件是???能否共享
    http://v.youku.com/v_show/id_XNDI3NTgwODgw.html

    出0入0汤圆

    发表于 2012-9-20 23:37:09 | 显示全部楼层
    好帖子啊,仔细学习……

    出0入0汤圆

    发表于 2012-9-25 00:03:16 | 显示全部楼层
    AkeBest 发表于 2012-9-20 23:37
    好帖子啊,仔细学习……

    好贴啊,学习了

    出0入0汤圆

    发表于 2012-9-25 09:04:08 | 显示全部楼层
    解释的太详细了!看数据手册有点头大!@@@

    出0入0汤圆

     楼主| 发表于 2012-9-28 12:03:45 | 显示全部楼层
    gadwgdsk77gg 发表于 2012-9-20 21:45
    请问看姿态变化的那个软件是???能否共享
    http://v.youku.com/v_show/id_XNDI3NTgwODgw.html ...

    这个是Scilab,相当于开源的Matlab。

    出0入0汤圆

    发表于 2012-10-19 20:54:41 | 显示全部楼层
    蓝海de梦 发表于 2012-7-23 14:01
    LZ,照我的理解,快速融合就是我2.5ms(比如)一次中断,中断里采集一次陀螺仪的测量值,并且标致位置1,whil ...

    b1=1,b2=data_x*t/2,
    b2=data_y*t/2,b3=data_z*t/2  请都一下,这个是什么,从哪里来的,小角替代?

    出0入0汤圆

    发表于 2012-10-20 11:02:48 | 显示全部楼层
    mark  留着用

    出0入0汤圆

    发表于 2012-10-20 19:33:17 | 显示全部楼层
    我也到这步了,好好学习学习。

    出0入0汤圆

    发表于 2012-10-21 19:00:42 | 显示全部楼层
    mark                                                   

    出0入0汤圆

    发表于 2012-10-26 17:14:48 | 显示全部楼层
    济南电子爱好者 发表于 2012-10-19 20:54
    b1=1,b2=data_x*t/2,
    b2=data_y*t/2,b3=data_z*t/2  请都一下,这个是什么,从哪里来的,小角替代? ...

    好久不登    才看到   抱歉    这个是按照他给的公式来的啊    依照积分周期进行快速融合,这些只是我的变量罢了,真理解了很容易看的

    出0入0汤圆

    发表于 2012-10-26 18:49:14 | 显示全部楼层
    留个爪,以后用。。。

    出0入0汤圆

    发表于 2012-10-29 14:38:18 | 显示全部楼层
    谢谢了,学习学习

    出0入0汤圆

    发表于 2012-11-1 13:54:22 | 显示全部楼层
    333QQQQQQQQQQQQQQQQQ

    出0入0汤圆

    发表于 2012-11-6 11:20:00 | 显示全部楼层
    js200300953 发表于 2012-7-13 13:31
    怎么不能编辑了?
    有两个公式错了:

    请教一下如何引出的这个公式?  这里的后面会用到指的是哪里?谢谢

    本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有帐号?注册

    x

    出0入0汤圆

     楼主| 发表于 2012-11-6 12:22:05 | 显示全部楼层
    济南电子爱好者 发表于 2012-11-6 11:20
    请教一下如何引出的这个公式?  这里的后面会用到指的是哪里?谢谢

    这个是用四元数的定义,从空间几何推出来的。
    这里会用到:

    本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有帐号?注册

    x

    出0入0汤圆

    发表于 2012-11-6 19:45:38 | 显示全部楼层
    mark

    出0入0汤圆

    发表于 2012-11-28 00:09:27 | 显示全部楼层
    本帖最后由 john800422 于 2012-11-28 00:10 编辑

    旋转的“轴角表示”转“四元数表示”。这里创造一个运算q(w,θ),用于把绕单位向量w转θ角的旋转表示为四元数。


    不是很懂以上式子是如何出來的

    出0入0汤圆

     楼主| 发表于 2012-11-28 08:19:21 | 显示全部楼层
    john800422 发表于 2012-11-28 00:09
    旋转的“轴角表示”转“四元数表示”。这里创造一个运算q(w,θ),用于把绕单位向量w转θ角的旋转表示为四元 ...

    四元数表示旋转时,的几何意义。

    出0入0汤圆

    发表于 2012-11-28 12:17:31 | 显示全部楼层
    js200300953 发表于 2012-11-28 08:19
    四元数表示旋转时,的几何意义。

    較為在意的是為何是θ/2?
    似乎很多資料都沒有細講
    還有w*sin(θ/2), 這裡的w是指四元數的單位向量嗎?

    我慣性的書籍上看到的是
    q = cos(θ/2) + u*sin(θ/2)
    u = cos(A)*i + cos(B)*j + cos(C)*k
    u為一向量, 而非單位向量

    是因為瞬時轉動的角度(A, B, C)很小時,
    cos(A) =  cos(B) =  cos(C) = 1 的結果?

    出0入0汤圆

    发表于 2012-11-28 12:28:52 | 显示全部楼层

    出0入0汤圆

    发表于 2012-11-28 12:45:58 | 显示全部楼层
    mark         

    出0入0汤圆

     楼主| 发表于 2012-11-28 18:19:08 | 显示全部楼层
    john800422 发表于 2012-11-28 12:17
    較為在意的是為何是θ/2?
    似乎很多資料都沒有細講
    還有w*sin(θ/2), 這裡的w是指四元數的單位向量嗎?

    为何是θ/2,我也不清楚。
    w是转轴方向的单位向量。

    出0入0汤圆

    发表于 2012-11-29 12:40:27 | 显示全部楼层
    好东西,mark一下,以后需要用的时候慢慢研究

    出0入0汤圆

    发表于 2012-11-30 13:32:09 | 显示全部楼层
    js200300953 发表于 2012-11-28 18:19
    为何是θ/2,我也不清楚。
    w是转轴方向的单位向量。

    感謝~大概理解了

    這篇的檔案有說明θ/2的由來(9.2.24)
    http://www.amobbs.com/thread-3294247-1-1.html

    出0入0汤圆

    发表于 2012-12-1 21:45:59 | 显示全部楼层
    研究精神可嘉

    出0入0汤圆

    发表于 2012-12-3 08:16:44 | 显示全部楼层
    表明。。。应该早点关注LZ的。。。。

    出0入0汤圆

    发表于 2012-12-3 13:56:20 | 显示全部楼层
    mark!!!!!!!!!!!!!

    出0入0汤圆

    发表于 2012-12-29 16:17:16 | 显示全部楼层
    mark~~ 学习

    出0入0汤圆

    发表于 2013-1-1 23:23:39 | 显示全部楼层
    学习中。。。。。。

    出0入0汤圆

    发表于 2013-1-2 11:49:14 | 显示全部楼层
    thankyou!

    出0入0汤圆

    发表于 2013-1-27 19:22:01 | 显示全部楼层
    不错啊!要好好学习一下!

    出0入0汤圆

    发表于 2013-1-27 20:59:03 | 显示全部楼层
    太深奥了,

    出0入0汤圆

    发表于 2013-1-29 11:39:40 | 显示全部楼层
    这个论坛牛人真多。。
    初学者路过。

    出0入0汤圆

    发表于 2013-1-29 13:05:21 | 显示全部楼层
    十分详细,学习中!

    出0入0汤圆

    发表于 2013-1-30 18:56:20 | 显示全部楼层
    向楼主学习,向楼主致敬

    出10入0汤圆

    发表于 2013-1-31 15:49:53 | 显示全部楼层
    学习了,顺便收藏一下

    出0入0汤圆

    发表于 2013-2-6 17:55:36 | 显示全部楼层
    正好看到这里了,先标记下

    出0入0汤圆

    发表于 2013-3-11 14:19:45 | 显示全部楼层
    表示还没有看懂

    出0入0汤圆

    发表于 2013-3-12 15:23:20 | 显示全部楼层
    楼主你好,我想问一下你的w,x,y,z是怎么确定的?用欧拉角变换来的?
       

    本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有帐号?注册

    x

    出0入0汤圆

     楼主| 发表于 2013-3-20 18:04:23 | 显示全部楼层
    业未央 发表于 2013-3-12 15:23
    楼主你好,我想问一下你的w,x,y,z是怎么确定的?用欧拉角变换来的?

    没见过这个公式。
    回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

    GMT+8, 2024-4-18 16:01

    © Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

    快速回复 返回顶部 返回列表