Sensors orientations
Posted: Sat Jul 23, 2011 11:14 am
I've been digging a bit into the most recent svn MultiWii version to understand how sensors are being read, especially with respect to their orientation with respect to the holding IMU and the quadcopter itself.
Well, I think that the current code has quite some strange things happening. Let's make an example with the HMC5883:
If I do define the orientation of my magnetometer to be as:
I would then expect that the magnetometer axis would be in line with the quadricopter axis such as that magnetometer X is pointing left, Y is pointing forward and Z is pointing the sky.
But this is really not the case, because the invocation of MAG_ORIENTATION treat them in a completely different way:
So basically, magADC[ROLL] will read sensor's Y axis, magADC[PITCH] will read sensor's -X axis and magADC[YAW] will read sensor's -Z axis.
In my opinion, sensor reading code should be transparent and should really just read the raw data from the sensors, without doing any rotations/negations on the sensors axis. The above code would then become:
The place in which rotations should happen is definitely in def.h in the various boards declarations. For example, FreeFlight IMU v1.22 doesn't have the axis of the magnetometer aligned with those of the other two sensors: there is a clockwise 90 deg rotation on the magnetometer Z axis with respect to the accel and gyro. Thus, a correct def.h definition of such board would then define such rotation:
Also, I don't really understand why all the sensors have their Z axis negated.
Hope this helps,
Fabio
Well, I think that the current code has quite some strange things happening. Let's make an example with the HMC5883:
If I do define the orientation of my magnetometer to be as:
Code: Select all
#define MAG_ORIENTATION(X, Y, Z) {magADC[ROLL] = X; magADC[PITCH] = Y; magADC[YAW] = Z;}
I would then expect that the magnetometer axis would be in line with the quadricopter axis such as that magnetometer X is pointing left, Y is pointing forward and Z is pointing the sky.
But this is really not the case, because the invocation of MAG_ORIENTATION treat them in a completely different way:
Code: Select all
MAG_ORIENTATION( ((rawADC[4]<<8) | rawADC[5]) ,
-((rawADC[0]<<8) | rawADC[1]) ,
-((rawADC[2]<<8) | rawADC[3]) );
So basically, magADC[ROLL] will read sensor's Y axis, magADC[PITCH] will read sensor's -X axis and magADC[YAW] will read sensor's -Z axis.
In my opinion, sensor reading code should be transparent and should really just read the raw data from the sensors, without doing any rotations/negations on the sensors axis. The above code would then become:
Code: Select all
MAG_ORIENTATION( ((rawADC[0]<<8) | rawADC[1]) ,
((rawADC[4]<<8) | rawADC[5]) ,
((rawADC[2]<<8) | rawADC[3]) );
The place in which rotations should happen is definitely in def.h in the various boards declarations. For example, FreeFlight IMU v1.22 doesn't have the axis of the magnetometer aligned with those of the other two sensors: there is a clockwise 90 deg rotation on the magnetometer Z axis with respect to the accel and gyro. Thus, a correct def.h definition of such board would then define such rotation:
Code: Select all
#if defined(FFIMUv2)
#define ITG3200
#define BMA180
#define BMP085
#define HMC5883
#define ACC_ORIENTATION(X, Y, Z) {accADC[ROLL] = X; accADC[PITCH] = Y; accADC[YAW] = Z;}
#define GYRO_ORIENTATION(X, Y, Z) {gyroADC[ROLL] = X; gyroADC[PITCH] = Y; gyroADC[YAW] = Z;}
#define MAG_ORIENTATION(X, Y, Z) {magADC[ROLL] = Y; magADC[PITCH] = -X; magADC[YAW] = Z;}
#define BMA180_ADDRESS 0x80
#define ITG3200_ADDRESS 0XD0
#endif
Also, I don't really understand why all the sensors have their Z axis negated.
Hope this helps,
Fabio