小四轴姿态融合

  • 1、四旋翼涉及的内容比较多,硬件电路、C程序、控制算法、上位机Java、Android等等。

    2、一般而言四旋翼程序分为几个部分

    1. 更新姿态角
      1. 基于加速度计、陀螺仪和磁力计的姿态融合,实时更新四元数,并由四元数解算姿态角
        1. 首先由加速度值初始化俯仰角和横滚角,由磁力计初始化航向角,由上面的姿态角初始化四元数
          init_ax=(float)(accel[0] / Accel_4_Scale_Factor);           //单位转化成重力加速单位:m/s2
          init_ay=(float)(accel[1] / Accel_4_Scale_Factor);
          init_az=(float)((accel[2]+600) / Accel_4_Scale_Factor);
          //进行x y轴的校准,未对z轴进行校准,参考MEMSense的校准方法
          init_mx =(float)1.046632*mag[0]-1.569948;
          init_my =(float)mag[1]-8;
          init_mz =(float)mag[2];
          init_Roll  =  atan2(init_ay, init_az);
          init_Pitch = -asin(init_ax);              //init_Pitch = asin(ax / 1);
          init_Yaw   = -atan2(init_mx*cos(init_Roll) + init_my*sin(init_Roll)*sin(init_Pitch) + init_mz*sin(init_Roll)*cos(init_Pitch),init_my*cos(init_Pitch) - init_mz*sin(init_Pitch));                       //atan2(mx, my);
          q0 = cos(0.5*init_Roll)*cos(0.5*init_Pitch)*cos(0.5*init_Yaw) + sin(0.5*init_Roll)*sin(0.5*init_Pitch)*sin(0.5*init_Yaw);  //w
          q1 = sin(0.5*init_Roll)*cos(0.5*init_Pitch)*cos(0.5*init_Yaw) - cos(0.5*init_Roll)*sin(0.5*init_Pitch)*sin(0.5*init_Yaw);  //x   绕x轴旋转是roll
          q2 = cos(0.5*init_Roll)*sin(0.5*init_Pitch)*cos(0.5*init_Yaw) + sin(0.5*init_Roll)*cos(0.5*init_Pitch)*sin(0.5*init_Yaw);  //y   绕y轴旋转是pitch
          q3 = cos(0.5*init_Roll)*cos(0.5*init_Pitch)*sin(0.5*init_Yaw) - sin(0.5*init_Roll)*sin(0.5*init_Pitch)*cos(0.5*init_Yaw);  //z   绕z轴旋转是Yaw
          Yaw = init_Yaw * 57.3;
        1. 归一化各个传感器参数,根据磁力计测量数据利用四元数矩阵得到地理坐标系下磁场矢量(测量值),计算地理坐标系下的磁场矢量(参考值)
          //normalise the measurements
          norm = invSqrt(ax*ax + ay*ay + az*az);      
          ax = ax * norm;
          ay = ay * norm;
          az = az * norm;
          norm = invSqrt(mx*mx + my*my + mz*mz);         
          mx = mx * norm;
          my = my * norm;
          mz = mz * norm;
          //从机体坐标系的电子罗盘测到的矢量转成地理坐标系下的磁场矢量hxyz(测量值),下面这个是从飞行器坐标系到世界坐标系的转换公式
          //compute reference direction of flux
          hx = 2*mx*(0.5 - q2q2 - q3q3) + 2*my*(q1q2 - q0q3) + 2*mz*(q1q3 + q0q2);
          hy = 2*mx*(q1q2 + q0q3) + 2*my*(0.5 - q1q1 - q3q3) + 2*mz*(q2q3 - q0q1);
          hz = 2*mx*(q1q3 - q0q2) + 2*my*(q2q3 + q0q1) + 2*mz*(0.5 - q1q1 - q2q2);
          //计算地理坐标系下的磁场矢量bxyz(参考值)
          bx = sqrtf((hx*hx) + (hy*hy));
          bz = hz; 
        1. 根据四元数矩阵,将地理坐标系下加速度矢量变换到飞行器坐标下(参考值)
           //estimated direction of gravity and flux (v and w),下面这个是从世界坐标系到飞行器坐标系的转换公式(转置矩阵)
          //地理坐标系下加速度为(0,0,1g)
          vx = 2*(q1q3 -q0q2);
          vy = 2*(q0q1 +q2q3);
          vz = q0q0 - q1q1 -q2q2 + q3q3;
        1. 将地理坐标系下磁场矢量(参考值)通过四元数矩阵变换到飞行器坐标下
          wx = 2*bx*(0.5 - q2q2 - q3q3) + 2*bz*(q1q3 - q0q2);
          wy = 2*bx*(q1q2 - q0q3) + 2*bz*(q0q1 + q2q3);
          wz = 2*bx*(q0q2 + q1q3) + 2*bz*(0.5 - q1q1 - q2q2);
        1. 将加速度的测量矢量与参考矢量做叉积,把磁场的测量矢量与参考矢量做叉积,得到加速度误差和磁场误差,用于修正陀螺
          // error is sum of cross product between reference direction of fields and direction measured by sensors
          ex = (ay*vz - az*vy) + (my*wz - mz*wy);
          ey = (az*vx - ax*vz) + (mz*wx - mx*wz);
          ez = (ax*vy - ay*vx) + (mx*wy - my*wx);
        1. 误差积分,陀螺仪积分
          // integral error scaled integral gain
          exInt = exInt + ex*Ki;
          eyInt = eyInt + ey*Ki;
          ezInt = ezInt + ez*Ki;
          // adjusted gyroscope measurements
          gx = gx + Kp*ex + exInt;
          gy = gy + Kp*ey + eyInt;
          gz = gz + Kp*ez + ezInt;
        1. 龙格-库塔法更新四元数
          // integrate quaternion rate and normalise,四元数更新算法
          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;
          
        1. 归一化四元数,由四元数计算姿态角
          // normalise quaternion
          norm = invSqrt(q0*q0 + q1*q1 + q2*q2 + q3*q3);
          q0 = q0 * norm;       //w
          q1 = q1 * norm;       //x
          q2 = q2 * norm;       //y
          q3 = q3 * norm;       //z
          Pitch = asin(-2*q1*q3 + 2*q0*q2) * 57.3; //俯仰角,绕y轴转动	 
          Roll  = atan2(2*q2*q3 + 2*q0*q1,-2*q1*q1 - 2*q2*q2 + 1) * 57.3; //滚动角,绕x轴转动
          Yaw   = atan2(2*q1*q2 + 2*q0*q3,-2*q2*q2 - 2*q3*q3 + 1) * 57.3;  //偏航角,绕z轴转?
          


    四元数矩阵

    1. 利用扩展卡尔曼滤波器对加速度计和磁力计的观测值来修正陀螺积分得到的姿态角

     

    1. 在这后面还有位置控制和姿态控制
    1. 姿态控制要实现实时精确控制四旋翼飞行器的飞行姿态,首先通过航姿参考系统检测其三个轴向的欧拉角度和角速率,然后对其实施闭环控制,使飞行器达到期望的姿态
    1. 位置控制

    位置回路控制律设计是为了使四旋翼无人飞行器可以快速、准确的跟踪给定轨迹。位置回路控制算法首先需要计算得到所需姿态角度,然后由姿态控制回路计算得出给定姿态角度,实现位置回路跟踪控制。所以,外环为位置环、内环为姿态环


  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
根据提供的引用[1],无法回答关于MadgwickAHRS六轴姿态融合的问题。但是,MadgwickAHRS是一种常用的姿态解算算法,可以用于将加速度计和陀螺仪的数据融合,从而得到更加准确的姿态信息。以下是一个使用MadgwickAHRS算法实现六轴姿态融合的C语言代码示例: ```c #include <math.h> #define sampleFreq 512.0f #define betaDef 0.1f void MadgwickAHRSupdate(float gx, float gy, float gz, float ax, float ay, float az, float *q) { float q0 = q[0], q1 = q[1], q2 = q[2], q3 = q[3]; float beta = betaDef; float recipNorm; float s0, s1, s2, s3; float qDot1, qDot2, qDot3, qDot4; float hx, hy; float _2q0mx, _2q0my, _2q0mz, _2q1mx, _2bx, _2bz, _4bx, _4bz, _2q0, _2q1, _2q2, _2q3, _2q0q2, _2q2q3, q0q0, q0q1, q0q2, q0q3, q1q1, q1q2, q1q3, q2q2, q2q3, q3q3; // Rate of change of quaternion from gyroscope qDot1 = 0.5f * (-q1 * gx - q2 * gy - q3 * gz); qDot2 = 0.5f * (q0 * gx + q2 * gz - q3 * gy); qDot3 = 0.5f * (q0 * gy - q1 * gz + q3 * gx); qDot4 = 0.5f * (q0 * gz + q1 * gy - q2 * gx); // Compute feedback only if accelerometer measurement valid (avoids NaN in accelerometer normalisation) if(!(ax == 0.0f && ay == 0.0f && az == 0.0f)) { // Normalise accelerometer measurement recipNorm = 1.0f / sqrtf(ax * ax + ay * ay + az * az); ax *= recipNorm; ay *= recipNorm; az *= recipNorm; // Estimated direction of gravity and magnetic field _2q0mx = 2.0f * q0 * ax; _2q0my = 2.0f * q0 * ay; _2q0mz = 2.0f * q0 * az; _2q1mx = 2.0f * q1 * ax; _2q0 = 2.0f * q0; _2q1 = 2.0f * q1; _2q2 = 2.0f * q2; _2q3 = 2.0f * q3; _2q0q2 = 2.0f * q0 * q2; _2q2q3 = 2.0f * q2 * q3; q0q0 = q0 * q0; q0q1 = q0 * q1; q0q2 = q0 * q2; q0q3 = q0 * q3; q1q1 = q1 * q1; q1q2 = q1 * q2; q1q3 = q1 * q3; q2q2 = q2 * q2; q2q3 = q2 * q3; q3q3 = q3 * q3; hx = _2q0mx * q2 - _2q0my * q3 + _2q0mz * q1 + _2q1mx * q3 + _2q1 * ax + _2q2 * az - _2q3 * ay + _2q2q3 * ay - _2q1q2 * az; hy = _2q0mx * q3 + _2q0my * q2 - _2q0mz * q0 + _2q1mx * q2 - _2q1my * ax + _2q2 * ay + _2q3 * az + _2q1q2 * ay + _2q2q3 * az; _2bx = sqrtf(hx * hx + hy * hy); _2bz = -_2q0mx * q1 + _2q0my * q0 + _2q1mx * q0 + _2q1my * q1 - _2q2 * ax + _2q3 * az + _2q1q2 * ax - _2q2q3 * ay; _4bx = 2.0f * _2bx; _4bz = 2.0f * _2bz; // Gradient decent algorithm corrective step s0 = -_2q2 * (2.0f * (q1q3 - q0q2) - ax) + _2q1 * (2.0f * (q0q1 + q2q3) - ay) - _4bz * q2 * (_4bx * (0.5f - q2q2 - q3q3) + _4bz * (q1q3 - q0q2)) + (-_4bx * q3 + _4bz * q1) * (_4bx * (q1q2 - q0q3) + _4bz * (q0q1 + q2q3)) + _4bx * q2 * (_4bx * (q0q2 + q1q3) + _4bz * (0.5f - q1q1 - q2q2)); s1 = _2q3 * (2.0f * (q1q3 - q0q2) - ax) + _2q0 * (2.0f * (q0q1 + q2q3) - ay) - 4.0f * q1 * (2.0f * (0.5f - q1q1 - q2q2) - az) + _4bz * q3 * (_4bx * (0.5f - q2q2 - q3q3) + _4bz * (q1q3 - q0q2)) + (_4bx * q2 + _4bz * q0) * (_4bx * (q1q2 - q0q3) + _4bz * (q0q1 + q2q3)) + (_4bx * q3 - _8bz * q1) * (_4bx * (q0q2 + q1q3) + _4bz * (0.5f - q1q1 - q2q2)); s2 = -_2q0 * (2.0f * (q1q3 - q0q2) - ax) + _2q3 * (2.0f * (q0q1 + q2q3) - ay) - 4.0f * q2 * (2.0f * (0.5f - q1q1 - q2q2) - az) + (-_8bx * q2 - _4bz * q0) * (_4bx * (0.5f - q2q2 - q3q3) + _4bz * (q1q3 - q0q2)) + (_4bx * q1 + _4bz * q3) * (_4bx * (q1q2 - q0q3) + _4bz * (q0q1 + q2q3)) + (_4bx * q0 - _8bz * q2) * (_4bx * (q0q2 + q1q3) + _4bz * (0.5f - q1q1 - q2q2)); s3 = _2q1 * (2.0f * (q1q3 - q0q2) - ax) + _2q2 * (2.0f * (q0q1 + q2q3) - ay) + (-_8bx * q3 + _4bz * q1) * (_4bx * (0.5f - q2q2 - q3q3) + _4bz * (q1q3 - q0q2)) + (-_4bx * q0 + _4bz * q2) * (_4bx * (q1q2 - q0q3) + _4bz * (q0q1 + q2q3)) + _4bx * q1 * (_4bx * (q0q2 + q1q3) + _4bz * (0.5f - q1q1 - q2q2)); // Normalise step magnitude recipNorm = 1.0f / sqrtf(s0 * s0 + s1 * s1 + s2 * s2 + s3 * s3); s0 *= recipNorm; s1 *= recipNorm; s2 *= recipNorm; s3 *= recipNorm; // Apply feedback step qDot1 -= beta * s0; qDot2 -= beta * s1; qDot3 -= beta * s2; qDot4 -= beta * s3; } // Integrate rate of change of quaternion to yield quaternion q0 += qDot1 / sampleFreq; q1 += qDot2 / sampleFreq; q2 += qDot3 / sampleFreq; q3 += qDot4 / sampleFreq; // Normalise quaternion recipNorm = 1.0f / sqrtf(q0 * q0 + q1 * q1 + q2 * q2 + q3 * q3); q[0] = q0 * recipNorm; q[1] = q1 * recipNorm; q[2] = q2 * recipNorm; q[3] = q3 * recipNorm; } ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值