コード例 #1
0
ファイル: adc.c プロジェクト: tenyan/quadfork
void adcCalibOffsets(void) {
    unsigned long lastUpdate;
    float sumRate[3];
    float dTemp, dTemp2, dTemp3;
    int i;

    delay(100);

#ifndef USE_DIGITAL_IMU
    imuQuasiStatic(ADC_RATE_CALIB_SAMPLES);
#endif

    sumRate[0] = sumRate[1] = sumRate[2] = 0.0;

    lastUpdate = adcData.lastUpdate;
    for (i = 0; i < ADC_RATE_CALIB_SAMPLES; i++) {
        while (lastUpdate == adcData.lastUpdate)
            ;

        lastUpdate = adcData.lastUpdate;

        sumRate[0] += adcData.voltages[ADC_VOLTS_RATEX];
        sumRate[1] += adcData.voltages[ADC_VOLTS_RATEY];
        sumRate[2] += adcData.voltages[ADC_VOLTS_RATEZ];
    }

    dTemp = adcData.temperature - IMU_ROOM_TEMP;
    dTemp2 = dTemp*dTemp;
    dTemp3 = dTemp*dTemp2;

    adcData.rateBiasX = -(sumRate[0] / ADC_RATE_CALIB_SAMPLES + p[IMU_GYO_BIAS1_X]*dTemp + p[IMU_GYO_BIAS2_X]*dTemp2 +
                          p[IMU_GYO_BIAS3_X]*dTemp3);
    adcData.rateBiasY = -(sumRate[1] / ADC_RATE_CALIB_SAMPLES + p[IMU_GYO_BIAS1_Y]*dTemp + p[IMU_GYO_BIAS2_Y]*dTemp2 +
                          p[IMU_GYO_BIAS3_Y]*dTemp3);
    adcData.rateBiasZ = -(sumRate[2] / ADC_RATE_CALIB_SAMPLES + p[IMU_GYO_BIAS1_Z]*dTemp + p[IMU_GYO_BIAS2_Z]*dTemp2 +
                          p[IMU_GYO_BIAS3_Z]*dTemp3);

    adcData.rateX = 0.0f;
    adcData.rateY = 0.0f;
    adcData.rateZ = 0.0f;
}
コード例 #2
0
ファイル: nav_ukf.c プロジェクト: benzeng/AutoQuad
void navUkfInitState(void) {
    uint32_t lastUpdate;
    float acc[3], mag[3];
    float estAcc[3], estMag[3];
    float m[3*3];
    int i;

    // vel
    UKF_VELN = 0.0f;
    UKF_VELE = 0.0f;
    UKF_VELD = 0.0f;

    // pos
    UKF_POSN = 0.0f;
    UKF_POSE = 0.0f;
    UKF_POSD = navUkfPresToAlt(AQ_PRESSURE);

    // acc bias
    UKF_ACC_BIAS_X = 0.0f;
    UKF_ACC_BIAS_Y = 0.0f;
    UKF_ACC_BIAS_Z = 0.0f;

    // gyo bias
    UKF_GYO_BIAS_X = 0.0f;
    UKF_GYO_BIAS_Y = 0.0f;
    UKF_GYO_BIAS_Z = 0.0f;

    // quat
    UKF_Q1 =  1.0f;
    UKF_Q2 =  0.0f;
    UKF_Q3 =  0.0f;
    UKF_Q4 =  0.0f;

    UKF_PRES_ALT = navUkfPresToAlt(AQ_PRESSURE);

    // wait for lack of movement
    imuQuasiStatic(UKF_GYO_AVG_NUM);

    // estimate initial orientation
    i = 0;
    do {
	float rotError[3];

	lastUpdate = IMU_LASTUPD;
	while (lastUpdate == IMU_LASTUPD)
	    yield(1);

	mag[0] = IMU_MAGX;
	mag[1] = IMU_MAGY;
	mag[2] = IMU_MAGZ;

	acc[0] = IMU_ACCX;
	acc[1] = IMU_ACCY;
	acc[2] = IMU_ACCZ;

	navUkfNormalizeVec3(acc, acc);
	navUkfNormalizeVec3(mag, mag);

	navUkfQuatToMatrix(m, &UKF_Q1, 1);

	// rotate gravity to body frame of reference
	navUkfRotateVecByRevMatrix(estAcc, navUkfData.v0a, m);

	// rotate mags to body frame of reference
	navUkfRotateVecByRevMatrix(estMag, navUkfData.v0m, m);

	// measured error, starting with accel vector
	rotError[0] = -(acc[2] * estAcc[1] - estAcc[2] * acc[1]) * 1.0f;
	rotError[1] = -(acc[0] * estAcc[2] - estAcc[0] * acc[2]) * 1.0f;
	rotError[2] = -(acc[1] * estAcc[0] - estAcc[1] * acc[0]) * 1.0f;

	// add in mag vector
	if (AQ_MAG_ENABLED && i < UKF_GYO_AVG_NUM*2) {
	    rotError[0] += -(mag[2] * estMag[1] - estMag[2] * mag[1]) * 0.50f;
	    rotError[1] += -(mag[0] * estMag[2] - estMag[0] * mag[2]) * 0.50f;
	    rotError[2] += -(mag[1] * estMag[0] - estMag[1] * mag[0]) * 0.50f;
	}

        navUkfRotateQuat(&UKF_Q1, &UKF_Q1, rotError, 0.1f);

	i++;
    } while (i <= UKF_GYO_AVG_NUM*5);
}