在靜止狀態下根據IMU(加速度計)計算姿態角

   一、 姿態角定義:

   1. 滾轉角的定義:機體Z軸與過機體x軸的垂面的夾角。向右滾轉爲正,範圍【-180deg-180deg】。

    2.俯仰角的定義:機體x軸與水平面的夾角。向上爲正,範圍【-90deg-90deg】。

   二、根據重力加速度 計算姿態角的原理:

    1.滾轉角計算,首先通過機體x軸與重力加速度的外積,計算出“過機體x軸的垂面”的法向量。然後通過計算內積的方法,求該法向量與機體z軸的夾角,這個夾角與滾轉角互餘。

    2.俯仰角計算:通過計算內積的方法,求機體x軸與重力加速度的夾角,這個夾角與俯仰角互餘。

    三、代碼實現:

    本人親自測試,計算結果合格。
 

  extern void makekam_gacc_to_att(float gravity_acc[3]/*輸入靜止狀態下的加速度*/,float *ret_roll/*計算結果*/,float *ret_pitch);

/*通過內積法,求兩個向量的夾角*/
float makekam_vec_ang(const float vec_a[3],const float vec_b[3])/*return 0~180deg*/
{
  float angle = 0.0f;
  float mod_of_vec_a = 0.0f;
  float mod_of_vec_b = 0.0f;
  mod_of_vec_a = get_vector_mod(vec_a);
  mod_of_vec_b = get_vector_mod(vec_b);
  if((0.01f >= mod_of_vec_a) || (0.01f >= mod_of_vec_b)){
    Serial.println("vect is zero,can not caculate angle");
  }else{
    float cos_value = (vec_a[0]*vec_b[0] + vec_a[1]*vec_b[1] + vec_a[2]*vec_b[2]) / (mod_of_vec_a * mod_of_vec_b);
  if(cos_value > 1.0f){
    cos_value=1.0f;}
  if(cos_value < -1.0f){
    cos_value=-1.0f;}
    angle = acos(cos_value);
    angle = angle * 180.0f / 3.1415f;
  }
  return angle;
}

/*通過外積法,求平面兩個非同向向量所在平面的法向量*/
inline void makekam_outer_product(const float vec1[3],const float vec2[3],float vecDst[3])
{
   vecDst[0] = vec1[1]*vec2[2] - vec2[1]*vec1[2];/*y1z2-y2z1*/
   vecDst[1] = vec2[0]*vec1[2] - vec1[0]*vec2[2];/*x2z1-x1z2*/
   vecDst[2] = vec1[0]*vec2[1] - vec2[0]*vec1[1];/*x1y2-x2y1*/
}

/*根據重力加速度,計算姿態角*/
void makekam_gacc_to_att(float gravity_acc[3],float *ret_roll,float *ret_pitch)
{
  float roll = 0.0f;
  float pitch = 0.0f;
  float flight_z_acc[3] = {0.0f,0.0f,10.0f};
  float flight_x_acc[3] = {10.0f,0.0f,0.0f};
  float plane_xog_normal_vec[3] ={0};

  makekam_outer_product(flight_x_acc,gravity_acc,plane_xog_normal_vec);
  roll = makekam_vec_ang(flight_z_acc,plane_xog_normal_vec) - 90.0f;
  if(gravity_acc[2] > 0.0f){
      if(roll < 0.0f){
      roll = -180.0f - roll;
      }else{
      roll = 180 - roll;
      }
  }
  pitch = 90.0f - makekam_vec_ang(flight_x_acc,gravity_acc);
  *ret_roll = roll;
  *ret_pitch = pitch;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章