static void stabilizerTask(void* param) {
	uint32_t attitudeCounter = 0;
	uint32_t altHoldCounter = 0;
	uint32_t lastWakeTime;

	vTaskSetApplicationTaskTag(0, (void*) TASK_STABILIZER_ID_NBR);

	//Wait for the system to be fully started to start stabilization loop
	systemWaitStart();

	lastWakeTime = xTaskGetTickCount();

	while (1) {
		vTaskDelayUntil(&lastWakeTime, F2T(IMU_UPDATE_FREQ)); // 500Hz

		// Magnetometer not yet used more then for logging.
		imu9Read(&gyro, &acc, &mag);

		if (imu6IsCalibrated()) {
			commanderGetRPY(&eulerRollDesired, &eulerPitchDesired, &eulerYawDesired);
			commanderGetRPYType(&rollType, &pitchType, &yawType);

			// 250HZ
			if (++attitudeCounter >= ATTITUDE_UPDATE_RATE_DIVIDER) {
				sensfusion6UpdateQ(gyro.x, gyro.y, gyro.z, acc.x, acc.y, acc.z, FUSION_UPDATE_DT);
				sensfusion6GetEulerRPY(&eulerRollActual, &eulerPitchActual, &eulerYawActual);

				accWZ = sensfusion6GetAccZWithoutGravity(acc.x, acc.y, acc.z);
				accMAG = (acc.x * acc.x) + (acc.y * acc.y) + (acc.z * acc.z);
				// Estimate speed from acc (drifts)
				vSpeed += deadband(accWZ, vAccDeadband) * FUSION_UPDATE_DT;

				controllerCorrectAttitudePID(eulerRollActual, eulerPitchActual, eulerYawActual,
						eulerRollDesired, eulerPitchDesired, -eulerYawDesired, &rollRateDesired,
						&pitchRateDesired, &yawRateDesired);
				attitudeCounter = 0;
			}

			// 100HZ
			if (imuHasBarometer() && (++altHoldCounter >= ALTHOLD_UPDATE_RATE_DIVIDER)) {
				stabilizerAltHoldUpdate();
				altHoldCounter = 0;
			}

			if (rollType == RATE) {
				rollRateDesired = eulerRollDesired;
			}
			if (pitchType == RATE) {
				pitchRateDesired = eulerPitchDesired;
			}
			if (yawType == RATE) {
				yawRateDesired = -eulerYawDesired;
			}

			// TODO: Investigate possibility to subtract gyro drift.
			controllerCorrectRatePID(gyro.x, -gyro.y, gyro.z, rollRateDesired, pitchRateDesired,
					yawRateDesired);

			controllerGetActuatorOutput(&actuatorRoll, &actuatorPitch, &actuatorYaw);

			if (!altHold || !imuHasBarometer()) {
				// Use thrust from controller if not in altitude hold mode
				commanderGetThrust(&actuatorThrust);
			} else {
				// Added so thrust can be set to 0 while in altitude hold mode after disconnect
				commanderWatchdog();
			}

			if (actuatorThrust > 0) {
#if defined(TUNE_ROLL)
				distributePower(actuatorThrust, actuatorRoll, 0, 0);
#elif defined(TUNE_PITCH)
				distributePower(actuatorThrust, 0, actuatorPitch, 0);
#elif defined(TUNE_YAW)
				distributePower(actuatorThrust, 0, 0, -actuatorYaw);
#else
				distributePower(actuatorThrust, actuatorRoll, actuatorPitch, -actuatorYaw);
#endif
			} else {
				distributePower(0, 0, 0, 0);
				controllerResetAllPID();
			}
		}
	}
}
Beispiel #2
0
void flightControl(void) {



  // this should run at 500Hz
  if ((micros() - elapsed_micros) >= (2000)) {
    elapsed_micros = micros();

    // flicker the leds to measure correct speed
    GPIOA->ODR ^= 1<<15;
    GPIOB->ODR ^= 1<<2;

    // read gyro
    gyro_read(&gyro_data);

    // controls
/*
    throttle   = payload[0] * 0xff;
    yaw        = payload[1] * 0xff;
    pitch      = payload[3] * 0xff;
    roll       = payload[4] * 0xff;

    // trims
    yaw_trim   = payload[2];
    pitch_trim = payload[5];
    roll_trim  = payload[6];
*/


    // convert channels for crazyflie PID:
#if 0
    rollRateDesired = (float) (payload[4] - 128.0) * 256;
    pitchRateDesired = (float) (payload[3] - 128.0) * 256;
    yawRateDesired = (float) (payload[1] - 128.0) * 256;

#else
    actuatorThrust = payload[0] * 256;
    // Roll, aka aileron, float +- 50.0 in degrees
    s32 f_roll = (payload[4] - 0x80) * 0x50 * FRAC_SCALE / (10000 / 400);
    frac2float(f_roll, &rollRateDesired);

    // Pitch, aka elevator, float +- 50.0 degrees
    s32 f_pitch = (payload[3] - 0x80) * 0x50 * FRAC_SCALE / (10000 / 400);
    frac2float(f_pitch, &pitchRateDesired);

    // Thrust, aka throttle 0..65535, working range 5535..65535
    // No space for overshoot here, hard limit Channel3 by -10000..10000
/*
    s32 ch = payload[0] * 0xff;
    if (ch < CHAN_MIN_VALUE) {
        ch = CHAN_MIN_VALUE;
    } else if (ch > CHAN_MAX_VALUE) {
        ch = CHAN_MAX_VALUE;
    }
    actuatorThrust  = ch*3L + 35535L;
*/

    // Yaw, aka rudder, float +- 400.0 deg/s
    s32 f_yaw = (payload[1] - 0x80) * 0x50 * FRAC_SCALE / (10000 / 400);
    frac2float(f_yaw, &yawRateDesired);
#endif

    // gyro.* == *rateActual == Data measured by IMU
    // *rateDesired == Data from RX
    controllerCorrectRatePID(-gyro_data.x, gyro_data.y, -gyro_data.z, rollRateDesired, pitchRateDesired, yawRateDesired);

//#define TUNE_ROLL

    if (actuatorThrust > 0)
    {
#if defined(TUNE_ROLL)
      distributePower(actuatorThrust, rollOutput, 0, 0);
#elif defined(TUNE_PITCH)
      distributePower(actuatorThrust, 0, pitchOutput, 0);
#elif defined(TUNE_YAW)
      distributePower(actuatorThrust, 0, 0, -yawOutput);
#else
      distributePower(actuatorThrust, rollOutput, pitchOutput, -yawOutput);
#endif
    }
    else
    {
      distributePower(0, 0, 0, 0);
      pidReset(&pidRollRate);
      pidReset(&pidPitchRate);
      pidReset(&pidYawRate);
    }


  }
#if 0
    m0_val = actuatorThrust;
    m1_val = actuatorThrust;
    m2_val = actuatorThrust;
    m3_val = ((yawOutput * 1000) / 0xffff) + 1000;
    TIM2->CCR4  = m0_val; // Motor "B"
    TIM1->CCR1  = m1_val; // Motor "L"
    TIM1->CCR4  = m2_val; // Motor "R"
    TIM16->CCR1 = m3_val; // Motor "F"
#endif
}