Advertisement
Guest User

Untitled

a guest
Jul 24th, 2018
239
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.33 KB | None | 0 0
  1. void Mahony_Filter::Compute(IMU::Sensor_Data accel, IMU::Sensor_Data gyro, IMU::Euler_Angles &euler)
  2. {
  3.     float delta_t;
  4.  
  5.     if (this->last_time == 0)
  6.     {
  7.         delta_t = 0;
  8.  
  9.         this->last_time = esp_timer_get_time();
  10.     } else
  11.     {
  12.         int64_t tmp = esp_timer_get_time();
  13.         delta_t = (tmp - this->last_time) * 0.000001f;
  14.  
  15.         this->last_time = tmp;
  16.     }
  17.  
  18.     float recip_norm;
  19.  
  20.     IMU::Sensor_Data gyro_rad;
  21.     gyro_rad.x = gyro.x * Math::DEG_TO_RAD;
  22.     gyro_rad.y = gyro.y * Math::DEG_TO_RAD;
  23.     gyro_rad.z = gyro.z * Math::DEG_TO_RAD;
  24.  
  25.     IMU::Sensor_Data v, error;
  26.  
  27.     // normalise accelerometer measurement
  28.     recip_norm = 1 / sqrtf(accel.x * accel.x + accel.y * accel.y + accel.z * accel.z);
  29.     accel.x *= recip_norm;
  30.     accel.y *= recip_norm;
  31.     accel.z *= recip_norm;
  32.  
  33.     // estimated direction of gravity and vector perpendicular to magnetic flux
  34.     v.x = 2 * (this->quaternion.q1 * this->quaternion.q3
  35.                - this->quaternion.q0 * this->quaternion.q2);
  36.     v.y = 2 * (this->quaternion.q0 * this->quaternion.q1
  37.                + this->quaternion.q2 * this->quaternion.q3);
  38.     v.z = +this->quaternion.q0 * this->quaternion.q0
  39.           - this->quaternion.q1 * this->quaternion.q1
  40.           - this->quaternion.q2 * this->quaternion.q2
  41.           + this->quaternion.q3 * this->quaternion.q3;
  42.  
  43.     // error is sum of cross product between estimated and measured direction of gravity
  44.     error.x = (accel.y * v.z - accel.z * v.y);
  45.     error.y = (accel.z * v.x - accel.x * v.z);
  46.     error.z = (accel.x * v.y - accel.y * v.x);
  47.  
  48.     if (this->MAHONY_KI > 0)
  49.     {
  50.         this->error_integral.x += error.x * delta_t;
  51.         this->error_integral.y += error.y * delta_t;
  52.         this->error_integral.z += error.z * delta_t;
  53.     } else
  54.     {
  55.         this->error_integral.x = 0;
  56.         this->error_integral.y = 0;
  57.         this->error_integral.z = 0;
  58.     }
  59.  
  60.     gyro_rad.x += this->MAHONY_KP * error.x + this->MAHONY_KI * error_integral.x;
  61.     gyro_rad.y += this->MAHONY_KP * error.y + this->MAHONY_KI * error_integral.y;
  62.     gyro_rad.z += this->MAHONY_KP * error.z + this->MAHONY_KI * error_integral.z;
  63.  
  64.     float qa = this->quaternion.q0;
  65.     float qb = this->quaternion.q1;
  66.     float qc = this->quaternion.q2;
  67.  
  68.     this->quaternion.q0 += 0.5f * delta_t * (-qb * gyro_rad.x - qc * gyro_rad.y
  69.                                              - this->quaternion.q3 * gyro_rad.z);
  70.     this->quaternion.q1 += 0.5f * delta_t * (qa * gyro_rad.x + qc * gyro_rad.z
  71.                                              - this->quaternion.q3 * gyro_rad.y);
  72.     this->quaternion.q2 += 0.5f * delta_t * (qa * gyro_rad.y - qb * gyro_rad.z
  73.                                              + this->quaternion.q3 * gyro_rad.x);
  74.     this->quaternion.q3 += 0.5f * delta_t * (qa * gyro_rad.z + qb * gyro_rad.y
  75.                                              - qc * gyro_rad.x);
  76.  
  77.     // normalise quaternion
  78.     recip_norm = 1 / sqrtf(this->quaternion.q0 * this->quaternion.q0 +
  79.                            this->quaternion.q1 * this->quaternion.q1 +
  80.                            this->quaternion.q2 * this->quaternion.q2 +
  81.                            this->quaternion.q3 * this->quaternion.q3);
  82.  
  83.     this->quaternion.q0 *= recip_norm;
  84.     this->quaternion.q1 *= recip_norm;
  85.     this->quaternion.q2 *= recip_norm;
  86.     this->quaternion.q3 *= recip_norm;
  87.  
  88.     // convert quaternion to euler
  89.     // https://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles#Quaternion_to_Euler_Angles_Conversion
  90.  
  91.     float q2_sqr = this->quaternion.q2 * this->quaternion.q2;
  92.  
  93.     float t0 = +2.0f * (this->quaternion.q0 * this->quaternion.q1 + this->quaternion.q2 * this->quaternion.q3);
  94.     float t1 = +1.0f - 2.0f * (this->quaternion.q1 * this->quaternion.q1 + q2_sqr);
  95.     euler.roll = atan2f(t0, t1) * Math::RAD_TO_DEG;
  96.  
  97.     float t2 = +2.0f * (this->quaternion.q0 * this->quaternion.q2 - this->quaternion.q3 * this->quaternion.q1);
  98.     t2 = ((t2 > 1.0f) ? 1.0f : t2);
  99.     t2 = ((t2 < -1.0f) ? -1.0f : t2);
  100.     euler.pitch = asinf(t2);
  101.     euler.pitch *= Math::RAD_TO_DEG;
  102.  
  103.     float t3 = +2.0f * (this->quaternion.q0 * this->quaternion.q3 + this->quaternion.q1 * this->quaternion.q2);
  104.     float t4 = +1.0f - 2.0f * (q2_sqr + this->quaternion.q3 * this->quaternion.q3);
  105.     euler.yaw = atan2f(t3, t4) * Math::RAD_TO_DEG;
  106. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement