Good afternoon,
I'm involved in a project in which I have to be able to measure a joint angle while doing flexion/extension using two SparkFun 9DoF IMU Breakout - ICM-20948 IMU's and a ESP32 W-ROOM 32D microcontroller.
I'm not familiar to working with IMUs and quaternions, hence I've been struggling a bit to understand what is necessary mathmatical wise.
In my understanding of the problem, I require the Pitch provided by the IMU which sits on top of the limb that is moving (while the other limb that is connected to the joint is stationary).
I've started working from the DMP_Quat6 example by Sparkfun's library using DMP sensor fusion to obtain the quaternions (using the option INV_ICM20948_SENSOR_ROTATION_VECTOR) and had some realistic readings in terms of the pitch angle being measured.
Though since the limb might be in horizontal or vertical position, the origin of the readings have to change from horizontally to vertically (not sure if I'm being clear), if for example I'm trying to read the flexion angle of the arm in regards to the elbow joint, if my arm is laying flat on a table the readings should be 0, but if I'm standing up with my arm down, here the readings should also be 0.
Is this the right way to approach this or should I consider an alternative? I've tried doing a rotation on the quaternion readings provided by the IMU following some quaternion formulas I've researched.
Any help or guidance is appreciated.
Best regards,
normie
double q1 = ((double)data.Quat9.Data.Q1) / 1073741824.0; // Convert to double x
double q2 = ((double)data.Quat9.Data.Q2) / 1073741824.0; // y
double q3 = ((double)data.Quat9.Data.Q3) / 1073741824.0; // z
Quaternion PointIn = { 0,q2,0,0 };
Quaternion Rotation = { 0, SIN_45, 0, COS_45 };
Quaternion ConjugRotation = ConjugateQuaternion(Rotation);
Quaternion PointOut = MultiplyQuaternions(MultiplyQuaternions(Rotation,PointIn),ConjugRotation);
Quaternion ConjugateQuaternion(Quaternion quat){
Quaternion res;
res.x = -quat.x;
res.y = -quat.y;
res.z = -quat.z;
res.w = quat.w;
return res;
}
Quaternion MultiplyQuaternions(Quaternion quat1, Quaternion quat2){
Quaternion res;
res.x = (quat1.w * quat2.x) + (quat1.x * quat2.w) + (quat1.y * quat2.z) + (-quat1.z * quat2.y);
res.y = (quat1.w * quat2.y) + (-quat1.x * quat2.z) + (quat1.y * quat2.w) + (quat1.z * quat2.x);
res.z = (quat1.w * quat2.z) + (quat1.x * quat2.y) + (-quat1.y * quat2.x) + (quat1.z * quat2.w);
res.w = (quat1.w * quat2.w) + (-quat1.x * quat2.x) + (-quat1.y * quat2.y) + (-quat1.z * quat2.z);
return res;
}