Liste der Anhänge anzeigen (Anzahl: 2)
Tilt Heading Berechnung arbeitet nicht korrekt
Hallo Zusammen,
hatte eine Lange Pause an meinem Robby (beruflich/private Ursache), bin aber hoffentlich jetzt wieder dran, mein letztes Problem zu lösen.
Ich arbeite derzeit an meiner Heading Berechnung für eine verbesserte Navigation.
Aus diesem Grund habe ich derzeit nur einen kleinen Testaufbau auf dem Schreibtisch mittels eines "Atomic IMU6".
Hierbei habe ich festgestellt, das sich meine Heading Werte auch ändern, wenn ich die Platine nur im Roll oder Pitch ändere.
Ich verwende hierbei die folgenden Tilt- Kompensation:
Code:
temp=sqrt(Atomic_accel[ROLL] * Atomic_accel[ROLL]+ Atomic_accel[PITCH] * Atomic_accel[PITCH] + Atomic_accel[HEADING] * Atomic_accel[HEADING]);
Atomic_Xnorm = Atomic_accel[ROLL]/temp;
Atomic_Ynorm = Atomic_accel[PITCH]/temp;
Angle[PITCH] = asin(Atomic_Xnorm);
Angle[ROLL]= -asin(Atomic_Ynorm/cos(Angle[PITCH])); float magXcomp = LM303_magnet[ROLL]*cos(asin(Atomic_Xnorm))+LM303_magnet[HEADING]*sin(Angle[PITCH]);
float magYcomp = LM303_magnet[ROLL]*sin(asin(Atomic_Ynorm/cos(Angle[PITCH])))*sin(asin(Atomic_Xnorm)) +
LM303_magnet[PITCH]*cos(asin(Atomic_Ynorm/cos(Angle[PITCH])))-
LM303_magnet[HEADING]*sin(asin(Atomic_Ynorm/cos(Angle[PITCH]))) * cos(asin(Atomic_Xnorm));
Angle[HEADING] = atan2(magYcomp,magXcomp);
Quelle der Tilt Infos:
Teilweise habe ich die Infos von dieser Seite: http://ozzmaker.com/compass2/
Ebenso
http://www.dfrobot.com/wiki/index.ph...s%28SEN0079%29
Ist den die Annahme richtig, das diese Kompensation eine Änderung von Pitch/Roll auf die
Berechnung von Heading entsprechend anpasst. (Wenn Pitch oder Roll < 45°).
Für Tips zur Beseitigung des Fehlers bin ich dankbar.
Edit: oder muss ich diese Fallbetrachtung noch einbringen:
Anhang 31402
Edit 1: So Ich habe die Ausrichtung beider Boards jetzt auch angepasst und hier mal als Bild dargestellt.
Anhang 31409
Edit2:
Hier einige Datenpakete
Datenpaket beider Sensoren für die horizontale Lage
Zitat:
Atomic_accel[ROLL] Atomic_accel[PITCH] Atomic_accel[HEADING] Angle[ROLL] Angle[PITCH] Angle[HEADING] LM303_magnet[ROLL] LM303_magnet[PITCH] LM303_magnet[HEADING]
0.0000 -0.0108 -2.5806 0.0042 0.0000 0.5994 411.2640 279.9200 265.1440
-0.0054 -0.0108 -2.5806 0.0042 -0.0021 0.5964 412.4160 278.4800 263.4720
-0.0108 0.0000 -2.5753 -0.0000 -0.0042 0.5950 410.5440 277.1200 263.5600
-0.0054 0.0000 -2.5699 -0.0000 -0.0021 0.5956 411.3360 278.4000 262.1520
-0.0054 0.0000 -2.5699 -0.0000 -0.0021 0.5920 411.3360 276.2400 257.0480
-0.0054 -0.0054 -2.5753 0.0021 -0.0021 0.5996 411.4800 280.3200 264.3520
-0.0054 -0.0054 -2.5753 0.0021 -0.0021 0.5954 411.8400 278.0800 264.3520
-0.0161 0.0000 -2.5699 -0.0000 -0.0063 0.5965 411.1920 278.0800 264.8800
0.0108 -0.0054 -2.5699 0.0021 0.0042 0.5954 411.6240 279.0400 263.1200
Datenpaket beider Sensoren für die Schraglage Roll 90 Grad
Zitat:
Atomic_accel[ROLL] Atomic_accel[PITCH] Atomic_accel[HEADING] Angle[ROLL] Angle[PITCH] Angle[HEADING] LM303_magnet[ROLL] LM303_magnet[PITCH] LM303_magnet[HEADING]
0.9731 0.0108 -2.5591 -0.0042 0.3634 1.7547 -47.3040 511.1200 -143.3520
0.9624 0.0108 -2.5591 -0.0042 0.3597 1.7557 -47.6640 509.2800 -144.1440
0.9677 0.0108 -2.5591 -0.0042 0.3615 1.7569 -48.0240 509.7600 -144.5840
0.9409 0.0161 -2.5591 -0.0063 0.3523 1.7536 -47.4480 508.4000 -143.7040
0.9731 0.0000 -2.5699 -0.0000 0.3620 1.7575 -48.1680 509.1200 -144.3200
0.9677 0.0108 -2.5645 -0.0042 0.3608 1.7562 -48.6000 509.2000 -142.0320
0.9677 0.0108 -2.5591 -0.0042 0.3615 1.7554 -48.8880 509.0400 -139.7440
0.9731 0.0000 -2.5645 -0.0000 0.3627 1.7584 -47.5200 508.3200 -146.6960
0.9731 0.0108 -2.5591 -0.0042 0.3634 1.7563 -47.8080 509.6800 -143.7040
Datenpaket beider Sensoren für die Schraglage Pitch 90 Grad
Zitat:
Atomic_accel[ROLL] Atomic_accel[PITCH] Atomic_accel[HEADING] Angle[ROLL] Angle[PITCH] Angle[HEADING] LM303_magnet[ROLL] LM303_magnet[PITCH] LM303_magnet[HEADING]
0.0269 1.0161 -1.5699 -0.5744 0.0144 0.1066 380.6640 132.2400 134.4640
0.0161 1.0108 -1.5699 -0.5720 0.0086 0.1084 380.6640 132.9600 133.0560
0.0215 1.0054 -1.5645 -0.5712 0.0116 0.1132 381.0240 134.3200 132.9680
0.0108 1.0054 -1.5699 -0.5696 0.0058 0.1205 380.7360 135.4400 128.0400
0.0215 1.0054 -1.5753 -0.5681 0.0115 0.1145 380.6640 134.2400 133.0560
0.0484 1.0269 -1.5591 -0.5824 0.0259 0.1196 381.2400 137.3600 134.4640
0.0269 1.0161 -1.5591 -0.5776 0.0144 0.1194 380.3760 135.1200 128.8320
0.0269 1.0215 -1.5538 -0.5816 0.0145 0.1177 381.3840 134.6400 127.8640
0.0161 1.0161 -1.5591 -0.5776 0.0087 0.1054 381.4560 133.8400 134.5520
0.0269 1.0108 -1.5591 -0.5752 0.0145 0.1140 380.9520 135.3600 133.7600
0.0323 1.0215 -1.5538 -0.5816 0.0173 0.1113 381.5280 135.4400 134.5520
0.0323 1.0215 -1.5591 -0.5800 0.0173 0.1067 381.1680 133.6000 135.6080
0.0323 1.0215 -1.5591 -0.5800 0.0173 0.1107 381.4560 134.0800 133.4080
Die Datenpaket für 90 Grad sind nicht korrekt, da die Tilt Routinen nur bis 45 Grad arbeiten. Hier kommen am Wochenende nochmals neue Versuchsdaten hinzu.
Für weitere Infos wäre ich dankbar.
Viele Grüße
R.
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo Zusammen,
ich habe mir jetzt die ganze Formel nochmals angesehen und wenn ich das richtig sehe stimmt die Umsetzung der Formel
laut Application note.
Quellcode:
Code:
//==================================================================
// Get the Pitch / Row and heading
//==================================================================
void getAtomicTiltHeading(void)
{
float Atomic_Xnorm;
float Atomic_Ynorm;
float temp;
temp=sqrt(Atomic_accel[X] * Atomic_accel[X]+ Atomic_accel[Y] * Atomic_accel[Y] + Atomic_accel[Z] * Atomic_accel[Z]);
Atomic_Xnorm = Atomic_accel[X]/temp;
Atomic_Ynorm = Atomic_accel[Y]/temp;
Angle[PITCH] = asin(-Atomic_Xnorm);
Angle[ROLL]= asin(Atomic_Ynorm/cos(Angle[PITCH]));
float AccXcomp = LM303_magnet[X]*cos(Angle[PITCH])+LM303_magnet[Z]*sin(Angle[PITCH]);
float AccYcomp = LM303_magnet[Y]*sin(Angle[ROLL])*sin(Angle[PITCH])+LM303_magnet[Y]*cos(Angle[ROLL])-LM303_magnet[Z]*sin(Angle[ROLL])*cos(Angle[PITCH]);
Angle[HEADING] = atan2(AccYcomp,AccXcomp);
}
Formel:
Anhang 31429
Eigentlich kann es jetzt nur noch an den Werten der Sensoren und deren Ausrichtung liegen (oder ?) .
Keine eine Idee wo mein Fehler sein könnte ?
Viele Grüße
R.
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo Zusammen,
ich habe das mit folgender Routine bis jetzt immer versucht, bin mir aber nicht sicher ob das so richtig ist.
Code:
void getLSM303_CalibrationValues(void)
{
int16_t MinValues[3],MaxValues[3];
int16_t Average[3],i,y,iValue;
float Average_rad;
for (i=0;i<3;i++) // Setup the Min/max values
{
MaxValues[i]= -32760;
MinValues[i] = 32760;
}
Serial_string_printf("\n\nStart of calibration Move around all directions\n\r");
Serial_string_printf("Press any key to abort the calibration\n\r");
read_Array_LH_I2c(LM303_ADR,ADDR_READ_AUTOINCREMENT + ADDR_OUT_X_L_M,LM303_magnet_raw,sizeof(LM303_magnet_raw));
write_Byte_i2c(LM303_ADR, ADDR_OFFSET_X_L_M, 0); // Clear the existing Offset value of the chip
write_Byte_i2c(LM303_ADR, ADDR_OFFSET_X_H_M, 0);
write_Byte_i2c(LM303_ADR, ADDR_OFFSET_Y_L_M, 0); // Clear the existing Offset value of the chip
write_Byte_i2c(LM303_ADR, ADDR_OFFSET_Y_H_M, 0);
write_Byte_i2c(LM303_ADR, ADDR_OFFSET_Z_L_M, 0); // Clear the existing Offset value of the chip
write_Byte_i2c(LM303_ADR, ADDR_OFFSET_Z_H_M, 0);
for(i=0;i<32000;i++)
{
read_LSM303();
// read_Array_LH_I2c(LM303_ADR,ADDR_READ_AUTOINCREMENT + ADDR_OUT_X_L_M,LM303_magnet_raw,sizeof(LM303_magnet_raw));
if( (i % 100) == 0 ) // show every 100 readings
STATUS_LED_TOOGLE; // Show Updating of values by toggle bit
if( (i % 1000) == 0 ) // show every 1000 readings
{
Serial_string_printf("Loop Value : ");
Serial_int16_printf(i);
Serial_string_printf("\r");
}
for (y=0;y<3;y++) // Setup the Min/max values
{
if (LM303_magnet[y] > MaxValues[y] ) // Find the max value of the Sensor
MaxValues[y] = LM303_magnet[y];
if (LM303_magnet[y] < MinValues[y] ) // Find the min value of the sensor
MinValues[y] = LM303_magnet[y];
}
}
for (i=0;i<3;i++) // Average distance from the center
{
iValue =((MinValues[i] + MaxValues[i]) / 2); // get the average distance from the center
MaxValues[i] = MaxValues[i] - iValue ; //
MinValues[i] = MinValues[i] - iValue ;
Serial_string_printf("\r\n Min: ");
Serial_float_printf(MinValues[i]);
Serial_string_printf(" Max: ");
Serial_float_printf(MaxValues[i]);
}
Average_rad =0.0;
for (i=0;i<3;i++) // Setup the Min/max values
{
Average[i] = (MaxValues[i] + (-1*MinValues[i]) / 2 );
LM303_magnet_offset[i] = (MaxValues[i] + MinValues[i]) / 2 ;
Average_rad += (float) Average[i];
}
Average_rad /= 3.0;
//Finally calculate the scale factor by dividing average radius by average value for that axis.
for (i=0;i<3;i++)
{
LM303_magnet_scaling[i] = Average_rad / Average[i];
}
// Store the final values in the chip
initLSM303_Offset();
cli();
eeprom_write_block((void*)&LM303_magnet_scaling, (void *) LSM303_MAG_GAIN, sizeof(LM303_magnet_scaling));
eeprom_write_block((void*)&LM303_magnet_offset, (void *) LSM303_MAG_OFFSET, sizeof(LM303_magnet_offset));
sei();
// Gain of the value
Serial_string_printf("\n\n\rCalibration is finished\n\n\r");
}
Init des Offset vom Chip direkt:
Code:
void initLSM303_Offset(void)
{
int8_t LowByte,HighByte;
LowByte = (int8_t) (LM303_magnet_offset[0] & 0xFF);
HighByte = (int8_t) (LM303_magnet_offset[0] >> 8);
write_Byte_i2c(LM303_ADR, ADDR_OFFSET_X_L_M, LowByte); // Store the new value of the X offset
write_Byte_i2c(LM303_ADR, ADDR_OFFSET_X_H_M, HighByte);
LowByte = (int8_t) (LM303_magnet_offset[1] & 0xFF);
HighByte = (int8_t) (LM303_magnet_offset[1] >> 8);
write_Byte_i2c(LM303_ADR, ADDR_OFFSET_Y_L_M, LowByte); // Store the new value of the Y offset
write_Byte_i2c(LM303_ADR, ADDR_OFFSET_Y_H_M, HighByte);
LowByte = (int8_t) (LM303_magnet_offset[2] & 0xFF);
HighByte = (int8_t) (LM303_magnet_offset[2] >> 8);
write_Byte_i2c(LM303_ADR, ADDR_OFFSET_Z_L_M, LowByte); // Store the new value of the Z offset
write_Byte_i2c(LM303_ADR, ADDR_OFFSET_Z_H_M, HighByte);
}
gelesen wird dann hiermit
Code:
void read_LSM303(void)
{
int8_t i;
read_Array_LH_I2c(LM303_ADR,ADDR_READ_AUTOINCREMENT + ADDR_OUT_X_L_M,LM303_magnet_raw,sizeof(LM303_magnet_raw));
read_Array_LH_I2c(LM303_ADR,ADDR_READ_AUTOINCREMENT + ADDR_OUT_X_L_A,LM303_accel_raw,sizeof(LM303_accel_raw));
for(i=0;i<3;i++)
{
LM303_magnet[i] = (float)(LM303_magnet_raw[i]) * LM303_magnet_scaling[i] * LSM303D_M_GN_2MG_GAUSS;
LM303_accel[i] = LM303_accel_raw[i] * LSM303D_LA_SO_2G;
}
}
Wenn ich dann die grafische Kontrolle mache, sehe ich eigentlich, das es noch nicht sauber zentriert ist.
Anhang 31452
Wo ist mein Fehler ?
Ich kann die Werte auch direkt eingeben und komme aber nicht zu einem "sauberen" Kreis" in der Grafik.
In welcher Einheit arbeitet Ihr eigentlich für die einzelnen Sensoren ?
mg und mgauss oder in g und gauss
Viele Grüße
R.