I have a problem when trying to calculate Yaw(MAg_Heading ). I get bad values, as i consider when they are printed on Serial. I am using Ardupilot 2.5.
#define RADIANI_IN_GRADE 57.32484
#define PI 3.1415
#define ToRad(x) (x*0.01745329252) // *pi/180
#define ToDeg(x) (x*57.2957795131) // *180/pi
AP_Compass_HMC5843 compass;
APM_RC_APM2 radio;
xQueueHandle xQueueIMUData;
xQueueHandle xQueueRadioData;
xTaskHandle xTaskCalculate;
void initTimer()
{
TIMSK1 = 0x01; // enabled global and timer overflow interrupt;
TCCR1A = 0x00; // normal operation page 148 (mode0);
TCNT1 = 0x000; // set initial value to remove time error (16bit counter register)
TCCR1B = 0x04; // start timer/ set clock
}
volatile unsigned long timer_overflow = 0;
volatile uint16_t last_count = 0;
unsigned long updateCounter()
{
if(TCNT1 < last_count) //overflow.
timer_overflow++;
last_count = TCNT1;
return (timer_overflow*COUNTER_MAX + (unsigned long)TCNT1);
}
float comp_filter(float *accDataX, float *accDataY, float *gyroDataX, float *gyroDataY)
{
*gyroDataX = 0.95 * *gyroDataX + 0.05 * *accDataX;
*gyroDataY = 0.95 * *gyroDataY + 0.05 * *accDataY;
}
void vTaskCalculate(void* pvParameters)
{
float imu_data[IMU_DATA_SIZE];
float out_data[5];
unsigned int time_past = 0;
float new_time = 0;
unsigned int new_time1 = 0;
float fXg=0,fYg=0,fZg=0,fXm = 0, fYm = 0, MAG_Heading = 0;
float x=0;
float temp_out_data[3];
enum
{
ACC_roll,
ACC_pitch,
G_roll,
G_pitch,
G_yaw
};
enum
{
Gt1,
Gt2,
Gt3
};
while(1)
{
if(xQueueReceive(xQueueIMUData,&imu_data,RECEIVE_DELAY))
{
//new_time = millis();
//new_time = new_time - time_past;
new_time1 = xTaskGetTickCount();
/*Serial.printf("new_time %u\t",new_time1);*/
new_time = float(new_time1 - time_past);
new_time = new_time / 1000;
fXg=imu_data[ACC_X]*0.05+fXg*0.95;
fZg=imu_data[ACC_Z]*0.05+fZg*0.95;
fYg=imu_data[ACC_Y]*0.05+fYg*0.95;
//out_data[ACC_roll] = RADIANI_IN_GRADE*atan((float)imu_data[ACC_Y]/sqrt(pow((float)imu_data[ACC_X],2) + pow((float)imu_data[ACC_Z],2)));
//out_data[ACC_pitch] = RADIANI_IN_GRADE*atan((float)-imu_data[ACC_X]/sqrt(pow((float)imu_data[ACC_Y],2) + pow((float)imu_data[ACC_Z],2)));
out_data[ACC_roll] = (atan2(-imu_data[ACC_Z] , -imu_data[ACC_Y]))*RADIANI_IN_GRADE - 90.0;
out_data[ACC_pitch] = (atan2(-imu_data[ACC_X] , sqrt(imu_data[ACC_Y]*imu_data[ACC_Y]+imu_data[ACC_Z]*imu_data[ACC_Z])))*RADIANI_IN_GRADE;
temp_out_data[Gt1] = imu_data[GYRO_X]*new_time;
temp_out_data[Gt2] = imu_data[GYRO_Y]*new_time;
temp_out_data[Gt3] = imu_data[GYRO_Z]*new_time;
temp_out_data[Gt1] *= RADIANI_IN_GRADE;
temp_out_data[Gt2] *= RADIANI_IN_GRADE;
temp_out_data[Gt3] *= RADIANI_IN_GRADE;
out_data[G_roll] += temp_out_data[Gt1]; //unghiul din urma
out_data[G_pitch] += temp_out_data[Gt2];
out_data[G_yaw] += temp_out_data[Gt3];
comp_filter(&out_data[ACC_roll],&out_data[ACC_pitch],&out_data[G_roll],&out_data[G_pitch]);
//fXm=imu_data[MAG_X]*cos(out_data[G_pitch])+imu_data[MAG_Y]*sin(out_data[G_roll])*sin(out_data[G_pitch])+imu_data[MAG_Z]*cos(out_data[G_roll])*sin(out_data[G_pitch]);
//fYm=imu_data[MAG_Z]*cos(out_data[G_roll])-imu_data[MAG_Y]*sin(out_data[G_roll]);
fXm=imu_data[MAG_X]*cos(out_data[G_pitch])+imu_data[MAG_Z]*sin(out_data[G_pitch])*sin(out_data[G_roll])+imu_data[MAG_Z]*cos(out_data[G_roll])*sin(out_data[G_pitch]);
fYm=-imu_data[MAG_Y]*cos(out_data[G_roll])+imu_data[MAG_Z]*sin(out_data[G_roll]);
//heading = (float)atan2( (-magneto.Y*cos(rezultat[ruliu]) + magneto.Z*sin(rezultat[ruliu]) ) , (magneto.X*cos(rezultat[tangaj]) + magneto.Z*sin(rezultat[tangaj])*sin(rezultat[ruliu])+ magneto.Z*sin(rezultat[tangaj])*cos(rezultat[ruliu])) ) * RADIANI_IN_GRADE;
MAG_Heading=atan2(fYm,fXm)*RADIANI_IN_GRADE;
/*if(out_data[ACC_pitch]<=180) out_data[ACC_pitch]=-1.0*out_data[ACC_pitch];
/*if(out_data[ACC_pitch]<=180) out_data[ACC_pitch]=-1.0*out_data[ACC_pitch];
if(out_data[ACC_pitch]>180) out_data[ACC_pitch]=360-out_data[ACC_pitch];*/
time_past = new_time1;
//Serial.printf("Diferenta de timp %4.3f\t",new_time);
new_time = 0;
/*Serial.printf("Incercare=%d\n",x);
*/
//Serial.printf("out_data[ACC_roll]= %4.3f\t out_data[ACC_pitch]= %4.3f\t out_data[G_roll]= %4.3f\t out_data[G_pitch]= %4.3f\t out_data[G_yaw]= %4.3f\r\n",out_data[ACC_roll],out_data[ACC_pitch],out_data[G_roll],out_data[G_pitch],out_data[G_yaw]);
Serial.printf("roll= %4.2f\t pitch = %4.2f, MAG_Heading = %4.3f\r\n",out_data[G_roll],out_data[G_pitch],MAG_Heading);
vTaskPrioritySet(xTaskCalculate, tskIDLE_PRIORITY-2);
}
}
}
And some values.
MAG_Heading = -8.798
MAG_Heading = -8.774
MAG_Heading = -8.959
MAG_Heading = -8.888
MAG_Heading = -8.905
MAG_Heading = -9.002
MAG_Heading = -9.004
MAG_Heading = -8.998
MAG_Heading = -8.985
MAG_Heading = -8.953
MAG_Heading = -8.957
MAG_Heading = -8.955
MAG_Heading = -8.964
MAG_Heading = -8.950
MAG_Heading = -8.805
MAG_Heading = -8.973
MAG_Heading = -8.967
MAG_Heading = -8.850
MAG_Heading = -9.004
MAG_Heading = -8.893
MAG_Heading = -8.910
MAG_Heading = -9.073
MAG_Heading = -8.925
MAG_Heading = -9.041
MAG_Heading = -9.030
MAG_Heading = -8.897
MAG_Heading = -8.887
MAG_Heading = -8.898
MAG_Heading = -8.894
MAG_Heading = -8.889
MAG_Heading = -8.884
MAG_Heading = -8.843
MAG_Heading = -8.848
MAG_Heading = -8.979
MAG_Heading = -8.877
MAG_Heading = -8.803
MAG_Heading = -8.831
MAG_Heading = -8.946
MAG_Heading = -8.937
MAG_Heading = -8.881
MAG_Heading = -8.896
MAG_Heading = -8.946
MAG_Heading = -8.824
MAG_Heading = -8.925
MAG_Heading = -8.924
MAG_Heading = -8.889
MAG_Heading = -8.912
MAG_Heading = -8.797
MAG_Heading = -8.827
MAG_Heading = -9.093
MAG_Heading = -8.980
MAG_Heading = -9.098
MAG_Heading = -9.086
MAG_Heading = -8.958
MAG_Heading = -8.971
MAG_Heading = -9.092
MAG_Heading = -9.076
MAG_Heading = -8.983
MAG_Heading = -9.091
MAG_Heading = -9.098
MAG_Heading = -9.128
MAG_Heading = -8.997
MAG_Heading = -9.026
MAG_Heading = -9.150
MAG_Heading = -9.119
MAG_Heading = -9.011
MAG_Heading = -9.138
MAG_Heading = -9.122
MAG_Heading = -8.966
MAG_Heading = -8.814
MAG_Heading = -9.081
MAG_Heading = -9.109
MAG_Heading = -9.128
MAG_Heading = -9.020
MAG_Heading = -9.130
MAG_Heading = -9.104
MAG_Heading = -8.990
MAG_Heading = -8.983
MAG_Heading = -9.089
MAG_Heading = -9.107
MAG_Heading = -9.163
MAG_Heading = -9.187
MAG_Heading = -9.173
MAG_Heading = -9.180
MAG_Heading = -9.187
MAG_Heading = -9.051
MAG_Heading = -9.126
MAG_Heading = -9.112
MAG_Heading = -8.999
MAG_Heading = -8.992
MAG_Heading = -8.977
MAG_Heading = -8.999
MAG_Heading = -9.165
MAG_Heading = -9.195
MAG_Heading = -9.189
MAG_Heading = -9.148
MAG_Heading = -8.990
MAG_Heading = -8.986
MAG_Heading = -9.121
MAG_Heading = -9.089
MAG_Heading = -9.090
MAG_Heading = -8.972
MAG_Heading = -8.966
MAG_Heading = -8.973
MAG_Heading = -9.096
MAG_Heading = -8.987
MAG_Heading = -9.103
MAG_Heading = -9.103
MAG_Heading = -8.978
MAG_Heading = -8.971
MAG_Heading = -9.108
MAG_Heading = -9.087
MAG_Heading = -8.965
MAG_Heading = -8.790
MAG_Heading = -9.046
MAG_Heading = -9.047
MAG_Heading = -9.085
MAG_Heading = -9.091
MAG_Heading = -8.964
MAG_Heading = -8.972
MAG_Heading = -8.973
MAG_Heading = -8.980
MAG_Heading = -9.076
MAG_Heading = -9.089
MAG_Heading = -8.989
MAG_Heading = -9.000
MAG_Heading = -9.114
MAG_Heading = -9.116
MAG_Heading = -9.122
MAG_Heading = -9.022
MAG_Heading = -9.017
MAG_Heading = -9.025
MAG_Heading = -8.832
MAG_Heading = -8.707
MAG_Heading = -8.817
MAG_Heading = -8.845
MAG_Heading = -8.840
MAG_Heading = -8.960
MAG_Heading = -8.969
MAG_Heading = -8.847
MAG_Heading = -9.007
MAG_Heading = -1.614
MAG_Heading = 1.141
MAG_Heading = 3.750