void powerDistribution(const control_t *control)
{
  #ifdef QUAD_FORMATION_X
    int16_t r = control->roll / 2.0f;
    int16_t p = control->pitch / 2.0f;
    motorPower.m1 = limitThrust(control->thrust - r + p + control->yaw);
    motorPower.m2 = limitThrust(control->thrust - r - p - control->yaw);
    motorPower.m3 =  limitThrust(control->thrust + r - p + control->yaw);
    motorPower.m4 =  limitThrust(control->thrust + r + p - control->yaw);
  #else // QUAD_FORMATION_NORMAL
    motorPower.m1 = limitThrust(control->thrust + control->pitch +
                               control->yaw);
    motorPower.m2 = limitThrust(control->thrust - control->roll -
                               control->yaw);
    motorPower.m3 =  limitThrust(control->thrust - control->pitch +
                               control->yaw);
    motorPower.m4 =  limitThrust(control->thrust + control->roll -
                               control->yaw);
  #endif

  if (motorSetEnable)
  {
    motorsSetRatio(MOTOR_M1, motorPowerSet.m1);
    motorsSetRatio(MOTOR_M2, motorPowerSet.m2);
    motorsSetRatio(MOTOR_M3, motorPowerSet.m3);
    motorsSetRatio(MOTOR_M4, motorPowerSet.m4);
  }
  else
  {
    motorsSetRatio(MOTOR_M1, motorPower.m1);
    motorsSetRatio(MOTOR_M2, motorPower.m2);
    motorsSetRatio(MOTOR_M3, motorPower.m3);
    motorsSetRatio(MOTOR_M4, motorPower.m4);
  }
}
		// compute new thrust
		actuatorThrust = max(altHoldMinThrust, min(altHoldMaxThrust, limitThrust( thrustVal )));

		// i part should compensate for voltage drop
	} else {
		altHoldTarget = 0.0;
		altHoldErr = 0.0;
	}
}

static void distributePower(const uint16_t thrust, const int16_t roll, const int16_t pitch,
		const int16_t yaw) {
#ifdef QUAD_FORMATION_X
	roll = roll >> 1;
	pitch = pitch >> 1;
	motorPowerM1 = limitThrust(thrust - roll + pitch + yaw);
	motorPowerM2 = limitThrust(thrust - roll - pitch - yaw);
	motorPowerM3 = limitThrust(thrust + roll - pitch + yaw);
	motorPowerM4 = limitThrust(thrust + roll + pitch - yaw);
#else // QUAD_FORMATION_NORMAL
	motorPowerM1 = limitThrust(thrust + pitch + yaw);
	motorPowerM2 = limitThrust(thrust - roll - yaw);
	motorPowerM3 = limitThrust(thrust - pitch + yaw);
	motorPowerM4 = limitThrust(thrust + roll - yaw);
#endif

	motorsSetRatio(MOTOR_M1, motorPowerM1);
	motorsSetRatio(MOTOR_M2, motorPowerM2);
	motorsSetRatio(MOTOR_M3, motorPowerM3);
	motorsSetRatio(MOTOR_M4, motorPowerM4);
}
static void stabilizerAltHoldUpdate() {
	// Get the time
	float altitudeError = 0;
	static float altitudeError_i = 0;
	float instAcceleration = 0;
	float deltaVertSpeed = 0;
	static uint32_t timeStart = 0;
	static uint32_t timeCurrent = 0;


	// Get altitude hold commands from pilot
	commanderGetAltHold(&altHold, &setAltHold, &altHoldChange);

	// Get barometer height estimates
	//TODO do the smoothing within getData
	ms5611GetData(&pressure, &temperature, &aslRaw);

	// Compute the altitude
	altitudeError = aslRaw - estimatedAltitude;
	altitudeError_i = fmin(50.0, fmax(-50.0, altitudeError_i + altitudeError));

	instAcceleration = deadband(accWZ, vAccDeadband) * 9.80665 + altitudeError_i * altEstKi;

	deltaVertSpeed = instAcceleration * ALTHOLD_UPDATE_DT + (altEstKp1 * ALTHOLD_UPDATE_DT) * altitudeError;
    estimatedAltitude += (vSpeedComp * 2.0 + deltaVertSpeed) * (ALTHOLD_UPDATE_DT / 2) + (altEstKp2 * ALTHOLD_UPDATE_DT) * altitudeError;
    vSpeedComp += deltaVertSpeed;

	aslLong = estimatedAltitude;		// Override aslLong

	// Estimate vertical speed based on Acc - fused with baro to reduce drift
	vSpeedComp = constrain(vSpeedComp, -vSpeedLimit, vSpeedLimit);

	// Reset Integral gain of PID controller if being charged
	if (!pmIsDischarging()) {
		altHoldPID.integ = 0.0;
	}

	// Altitude hold mode just activated, set target altitude as current altitude. Reuse previous integral term as a starting point
	if (setAltHold) {
		// Set to current altitude
		altHoldTarget = estimatedAltitude;

		// Set the start time
		timeStart = xTaskGetTickCount();
		timeCurrent = 0;

		// Reset PID controller
		pidInit(&altHoldPID, estimatedAltitude, altHoldKp, altHoldKi, altHoldKd, ALTHOLD_UPDATE_DT);

		// Cache last integral term for reuse after pid init
		// const float pre_integral = hoverPID.integ;

		// Reset the PID controller for the hover controller. We want zero vertical velocity
		pidInit(&hoverPID, 0, hoverKp, hoverKi, hoverKd, ALTHOLD_UPDATE_DT);
		pidSetIntegralLimit(&hoverPID, 3);
		// TODO set low and high limits depending on voltage
		// TODO for now just use previous I value and manually set limits for whole voltage range
		//                    pidSetIntegralLimit(&altHoldPID, 12345);
		//                    pidSetIntegralLimitLow(&altHoldPID, 12345);              /


		// hoverPID.integ = pre_integral;
	}

	// In altitude hold mode
	if (altHold) {
		// Get current time
		timeCurrent = xTaskGetTickCount();

		// Update target altitude from joy controller input
		altHoldTarget += altHoldChange / altHoldChange_SENS;
		pidSetDesired(&altHoldPID, altHoldTarget);

		// Compute error (current - target), limit the error
		altHoldErr = constrain(deadband(estimatedAltitude - altHoldTarget, errDeadband), -altHoldErrMax, altHoldErrMax);
		pidSetError(&altHoldPID, -altHoldErr);

		// Get control from PID controller, dont update the error (done above)
		float altHoldPIDVal = pidUpdate(&altHoldPID, estimatedAltitude, false);

		// Get the PID value for the hover
		float hoverPIDVal = pidUpdate(&hoverPID, vSpeedComp, true);

		float thrustValFloat;

		// Use different weights depending on time into altHold mode
		if (timeCurrent > 150) {
			// Compute the mixture between the alt hold and the hover PID
			thrustValFloat = 0.5*hoverPIDVal + 0.5*altHoldPIDVal;
		} else {
			// Compute the mixture between the alt hold and the hover PID
			thrustValFloat = 0.1*hoverPIDVal + 0.9*altHoldPIDVal;
		}
		// float thrustVal = 0.5*hoverPIDVal + 0.5*altHoldPIDVal;
		uint32_t thrustVal = altHoldBaseThrust + (int32_t)(thrustValFloat*pidAslFac);

		// compute new thrust
		actuatorThrust = max(altHoldMinThrust, min(altHoldMaxThrust, limitThrust( thrustVal )));

		// i part should compensate for voltage drop
	} else {
		altHoldTarget = 0.0;
		altHoldErr = 0.0;
	}
}
Example #4
0
    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
}

static void distributePower(const uint16_t thrust, const int16_t roll,
                            const int16_t pitch, const int16_t yaw)
{
#if defined QUAD_X
  roll = roll >> 1;
  pitch = pitch >> 1;
  m0_val = limitThrust(thrust - roll + pitch + yaw);
  m1_val = limitThrust(thrust - roll - pitch - yaw);
  m2_val =  limitThrust(thrust + roll - pitch + yaw);
  m3_val =  limitThrust(thrust + roll + pitch - yaw);
#elif defined QUAD_PLUS
  m0_val = limitThrust(thrust + pitch + yaw);
  m1_val = limitThrust(thrust - roll - yaw);
  m2_val =  limitThrust(thrust - pitch + yaw);
  m3_val =  limitThrust(thrust + roll - yaw);
#elif defined broken_QUAD_X
  m0_val = thrust + roll + pitch + yaw;
  m1_val = thrust - roll + pitch - yaw;
  m2_val = thrust + roll - pitch - yaw;
  m3_val = thrust - roll - pitch + yaw;
#elif defined broken_QUAD_PLUS
  m0_val = thrust + pitch + yaw;
static void stabilizerAltHoldUpdate(void)
{
  // Get altitude hold commands from pilot
  commanderGetAltHold(&altHold, &setAltHold, &altHoldChange);

  // Get barometer height estimates
  //TODO do the smoothing within getData
  ms5611GetData(&pressure, &temperature, &aslRaw);
  asl = asl * aslAlpha + aslRaw * (1 - aslAlpha);
  aslLong = aslLong * aslAlphaLong + aslRaw * (1 - aslAlphaLong);
  // Estimate vertical speed based on successive barometer readings. This is ugly :)
  vSpeedASL = deadband(asl - aslLong, vSpeedASLDeadband);

  // Estimate vertical speed based on Acc - fused with baro to reduce drift
  vSpeed = constrain(vSpeed, -vSpeedLimit, vSpeedLimit);
  vSpeed = vSpeed * vBiasAlpha + vSpeedASL * (1.f - vBiasAlpha);
  vSpeedAcc = vSpeed;

  // Reset Integral gain of PID controller if being charged
  if (!pmIsDischarging())
  {
    altHoldPID.integ = 0.0;
  }

  // Altitude hold mode just activated, set target altitude as current altitude. Reuse previous integral term as a starting point
  if (setAltHold)
  {
    // Set to current altitude
    altHoldTarget = asl;

    // Cache last integral term for reuse after pid init
    const float pre_integral = altHoldPID.integ;

    // Reset PID controller
    pidInit(&altHoldPID, asl, altHoldKp, altHoldKi, altHoldKd,
            ALTHOLD_UPDATE_DT);
    // TODO set low and high limits depending on voltage
    // TODO for now just use previous I value and manually set limits for whole voltage range
    //                    pidSetIntegralLimit(&altHoldPID, 12345);
    //                    pidSetIntegralLimitLow(&altHoldPID, 12345);              /

    altHoldPID.integ = pre_integral;

    // Reset altHoldPID
    altHoldPIDVal = pidUpdate(&altHoldPID, asl, false);
  }

  // In altitude hold mode
  if (altHold)
  {
    // Update target altitude from joy controller input
    altHoldTarget += altHoldChange / altHoldChange_SENS;
    pidSetDesired(&altHoldPID, altHoldTarget);

    // Compute error (current - target), limit the error
    altHoldErr = constrain(deadband(asl - altHoldTarget, errDeadband),
                           -altHoldErrMax, altHoldErrMax);
    pidSetError(&altHoldPID, -altHoldErr);

    // Get control from PID controller, dont update the error (done above)
    // Smooth it and include barometer vspeed
    // TODO same as smoothing the error??
    altHoldPIDVal = (pidAlpha) * altHoldPIDVal + (1.f - pidAlpha) * ((vSpeedAcc * vSpeedAccFac) +
                    (vSpeedASL * vSpeedASLFac) + pidUpdate(&altHoldPID, asl, false));

    // compute new thrust
    actuatorThrust =  max(altHoldMinThrust, min(altHoldMaxThrust,
                          limitThrust( altHoldBaseThrust + (int32_t)(altHoldPIDVal*pidAslFac))));

    // i part should compensate for voltage drop

  }
  else
  {
    altHoldTarget = 0.0;
    altHoldErr = 0.0;
    altHoldPIDVal = 0.0;
  }
}
  }
  else
  {
    altHoldTarget = 0.0;
    altHoldErr = 0.0;
    altHoldPIDVal = 0.0;
  }
}

static void distributePower(const uint16_t thrust, const int16_t roll,
                            const int16_t pitch, const int16_t yaw)
{
#ifdef QUAD_FORMATION_X
  int16_t r = roll >> 1;
  int16_t p = pitch >> 1;
  motorPowerM1 = limitThrust(thrust - r + p + yaw);
  motorPowerM2 = limitThrust(thrust - r - p - yaw);
  motorPowerM3 =  limitThrust(thrust + r - p + yaw);
  motorPowerM4 =  limitThrust(thrust + r + p - yaw);
#else // QUAD_FORMATION_NORMAL
  motorPowerM1 = limitThrust(thrust + pitch + yaw);
  motorPowerM2 = limitThrust(thrust - roll - yaw);
  motorPowerM3 =  limitThrust(thrust - pitch + yaw);
  motorPowerM4 =  limitThrust(thrust + roll - yaw);
#endif

  motorsSetRatio(MOTOR_M1, motorPowerM1);
  motorsSetRatio(MOTOR_M2, motorPowerM2);
  motorsSetRatio(MOTOR_M3, motorPowerM3);
  motorsSetRatio(MOTOR_M4, motorPowerM4);
}
            (int32_t)(eulerPitchActual*100),
            (int32_t)(eulerYawActual*100));
        i = 0;
      }
#endif
    }
  }
}

static void distributePower(const uint16_t thrust, const int16_t roll,
                            const int16_t pitch, const int16_t yaw)
{
#ifdef QUAD_FORMATION_X
  roll = roll >> 1;
  pitch = pitch >> 1;
  motorPowerLeft =  limitThrust(thrust + roll + pitch - yaw);
  motorPowerRight = limitThrust(thrust - roll - pitch - yaw);
  motorPowerFront = limitThrust(thrust - roll + pitch + yaw);
  motorPowerRear =  limitThrust(thrust + roll - pitch + yaw);
#else // QUAD_FORMATION_NORMAL
  motorPowerLeft =  limitThrust(thrust + roll - yaw);
  motorPowerRight = limitThrust(thrust - roll - yaw);
  motorPowerFront = limitThrust(thrust + pitch + yaw);
  motorPowerRear =  limitThrust(thrust - pitch + yaw);
#endif

  motorsSetRatio(MOTOR_LEFT, motorPowerLeft);
  motorsSetRatio(MOTOR_RIGHT, motorPowerRight);
  motorsSetRatio(MOTOR_FRONT, motorPowerFront);
  motorsSetRatio(MOTOR_REAR, motorPowerRear);
}
Example #8
0
static void distributePower(const uint16_t thrust, const int16_t roll,
                            const int16_t pitch, const int16_t yaw)
{

float motors_max;
float motors_min;
float motors_spread;

motor_saturated = false;

  int16_t r = roll >> 1;
  int16_t p = pitch >> 1;
  motorPowerM1 = thrust - r + p + yaw;
  motorPowerM2 = thrust - r - p - yaw;
  motorPowerM3 = thrust + r - p + yaw;
  motorPowerM4 = thrust + r + p - yaw;

  motors_max = max(motorPowerM1,max(motorPowerM2,max(motorPowerM3,motorPowerM4)));
  motors_min = min(motorPowerM1,min(motorPowerM2,min(motorPowerM3,motorPowerM4)));

  motors_spread = motors_max - motors_min;

  //"Air Mode" - Maintain the total commanded differences in thrust to provide better control at low and high throttle.
  if (motors_spread > UINT16_MAX) {

	  motor_saturated = true;
	  motorPowerM1 -= motors_min;
	  motorPowerM2 -= motors_min;
	  motorPowerM3 -= motors_min;
	  motorPowerM4 -= motors_min;
	  motors_max   -= motors_min;
	  motors_spread = (motors_max-motors_min)/UINT16_MAX;
	  motorPowerM1 /= motors_spread;
	  motorPowerM2 /= motors_spread;
	  motorPowerM3 /= motors_spread;
	  motorPowerM4 /= motors_spread;

  } else if (motors_min < 0) {

	  motor_saturated = true;
	  motorPowerM1 -= motors_min;
	  motorPowerM2 -= motors_min;
	  motorPowerM3 -= motors_min;
	  motorPowerM4 -= motors_min;

  } else if (motors_max > UINT16_MAX) {

	  motor_saturated = true;
	  motors_max -= UINT16_MAX;
	  motorPowerM1 -= motors_max;
	  motorPowerM2 -= motors_max;
	  motorPowerM3 -= motors_max;
	  motorPowerM4 -= motors_max;
  }

  //In case of floating point rounding weirdness
  motorPowerM1 = limitThrust(motorPowerM1);
  motorPowerM2 = limitThrust(motorPowerM2);
  motorPowerM3 = limitThrust(motorPowerM3);
  motorPowerM4 = limitThrust(motorPowerM4);

  motorsSetRatio(MOTOR_M1, motorPowerM1);
  motorsSetRatio(MOTOR_M2, motorPowerM2);
  motorsSetRatio(MOTOR_M3, motorPowerM3);
  motorsSetRatio(MOTOR_M4, motorPowerM4);
}