xioTechnologies/Fusion

what is the default IMU coordinate look like ?

Closed this issue · 3 comments

i have an 6-axis IMU which coordinate is( X+: represent moving forward, Y+: represent left, Z+: represent Up ), typical right-hand coordinate ,right ? just like ENU system , but i have no magnetometer because it's 6-axis imu. How does Fusion know what is the Yaw angle in any (ENU, NED, NWU) cooridinate ?? cause there is no infomation about the real direction in earth.

what i really want use Fusion is i want measure the IMU pose (Mainly roll and pitch) angle more smoothly, here is how i try to use:

  1. i changed the default NWU coordinate to ENU coordinate , because my 6-axis imu is right-hand coordinate , right ?
  2. feed the data to Fusion

here is code below:

void ImuFilter::filter(const mapping::imu_t* msg){
  float acc_x_g, acc_y_g, acc_z_g;
  float angular_x_degree, angular_y_degree, angular_z_degree;

  acc_x_g = (float)(msg->linear_acceleration.x ) / DEFAULT_IMU_GRAVITY;//(9.81)
  acc_y_g = (float)(msg->linear_acceleration.y ) / DEFAULT_IMU_GRAVITY;
  acc_z_g = (float)(msg->linear_acceleration.z ) / DEFAULT_IMU_GRAVITY;

  angular_x_degree = (float)(msg->angular_velocity.x/M_PI )*180.0;
  angular_y_degree = (float)(msg->angular_velocity.y/M_PI)*180.0;
  angular_z_degree = (float)(msg->angular_velocity.z/M_PI)*180.0;


  const FusionVector gyroscope = {angular_x_degree, angular_y_degree, angular_z_degree}; // replace this with actual gyroscope data in degrees/s
  const FusionVector accelerometer = {acc_x_g, acc_y_g, acc_z_g}; // replace this with actual accelerometer data in g
  FusionAhrsUpdateNoMagnetometer(&ahrs_, gyroscope, accelerometer, sample_rate_);
  const FusionEuler euler = FusionQuaternionToEuler(FusionAhrsGetQuaternion(&ahrs_));
  printf("Roll %0.1f, Pitch %0.1f, Yaw %0.1f\n", euler.angle.roll, euler.angle.pitch, euler.angle.yaw);
  std::lock_guard<std::mutex> lock(mtx_);
  current_pose_->roll = euler.angle.roll;
  current_pose_->pitch = euler.angle.pitch;
  current_pose_->yaw = euler.angle.yaw;
  return;
}

The wired thing is when IMU is placed horizontally, the output of Roll: -90, Pitch: 0, yaw: random_value
and **the Pitch seems represent real roll of the imu , the Roll seems represent the real Pitch., i dont know what the yaw represent what, :( ** , how to make the roll pitch yaw represent the real pose of the IMU?

Can anybody tell me , what's the problem of the usage, very appreciate , thanks very much ~~

You have described your XYZ directions as: forwards, left, up. These directions follow the right-hand convention. If you are not using a magnetometer then axes conventions ENU and NWU will be functionality identical. The measurement of heading (yaw) will be relative to the direction the device was facing when it was switched on, and will slowly drift over time and with motion.

In your code you are passing sample_rate_ for the argument deltaTime. This is an error and you should instead pass 1.0f / sample_rate_ . I also suggest you add the gyroscope offset correction algorithm to your code as demonstrated by lines 24 and 52.

@xioTechnologies Thanks very much for your quickly response, sorry for my less description or misunderstanding naming for sample_rate_ , the value dose is 1.0f / IMU_FREQUENCY.

i added gyroscope correction algorithorm as you suggested , The RPY euler output seems correct, but the Euler angle seems have heave time delay(IMU is 200HZ), which param may cause the Fusion Delay ? do you have any clue ? Very appreciate for your help.

I do not understand your description. Please can you share an plot demonstrating the issue.