48 #include "actuatordesired.h"
49 #include "attitudeactual.h"
50 #include "cameradesired.h"
51 #include "flightstatus.h"
53 #include "ratedesired.h"
54 #include "systemident.h"
55 #include "stabilizationdesired.h"
56 #include "stabilizationsettings.h"
58 #include "subtrimsettings.h"
59 #include "systemsettings.h"
60 #include "manualcontrolcommand.h"
61 #include "vbarsettings.h"
62 #include "lqgsettings.h"
63 #include "rtkfestimate.h"
64 #include "lqgsolution.h"
65 #include "systemalarms.h"
67 #include "altitudeholdsettings.h"
68 #include "altitudeholdstate.h"
69 #include "positionactual.h"
70 #include "velocityactual.h"
74 #include "physical_constants.h"
90 #define MAX_QUEUE_SIZE 1
92 #if defined(PIOS_STABILIZATION_STACK_SIZE)
93 #define STACK_SIZE_BYTES PIOS_STABILIZATION_STACK_SIZE
95 #define STACK_SIZE_BYTES 1200
98 #define TASK_PRIORITY PIOS_THREAD_PRIO_HIGHEST
99 #define FAILSAFE_TIMEOUT_MS 30
100 #define COORDINATED_FLIGHT_MIN_ROLL_THRESHOLD 3.0f
101 #define COORDINATED_FLIGHT_MAX_YAW_THRESHOLD 0.05f
106 #define HORIZON_MODE_MAX_BLEND 0.85f
109 #define THROTTLE_EPSILON 0.000001f
134 LevelAngleConstantRoll);
136 LevelAngleConstantPitch);
138 LevelAngleConstantYaw);
143 #if defined(TARGET_MAY_HAVE_BARO)
163 #if defined(TARGET_MAY_HAVE_BARO)
164 static struct pid vertspeed_pid;
166 static uint8_t altitude_hold_expo;
167 static float altitude_hold_maxclimbrate;
168 static float altitude_hold_maxdescentrate;
173 #if defined(STABILIZATION_LQG)
177 #ifndef NO_CONTROL_DEADBANDS
187 #ifndef NO_CONTROL_DEADBANDS
188 #define get_deadband(axis) (deadbands ? (deadbands + axis) : NULL)
190 #define get_deadband(axis) NULL
195 if (*airframe_type == SYSTEMSETTINGS_AIRFRAMETYPE_HELICP) {
197 ManualControlCommandThrottleGet( &heli_throttle );
199 if (heli_throttle < 0) {
203 return heli_throttle;
209 return actuator_desired->Thrust;
233 if (StabilizationSettingsInitialize() == -1
234 || ActuatorDesiredInitialize() == -1
235 || SubTrimInitialize() == -1
236 || SubTrimSettingsInitialize() == -1
237 || ManualControlCommandInitialize() == -1
238 || VbarSettingsInitialize() == -1) {
242 #if defined(STABILIZATION_LQG)
243 if (LQGSettingsInitialize() == -1 ||
244 SystemIdentInitialize() == -1 ||
245 RTKFEstimateInitialize() == -1 ||
246 LQGSolutionInitialize() == -1) {
251 #if defined(RATEDESIRED_DIAGNOSTICS)
252 if (RateDesiredInitialize() == -1) {
257 #if defined(TARGET_MAY_HAVE_BARO)
258 if (AltitudeHoldStateInitialize() == -1
259 || AltitudeHoldSettingsInitialize() == -1) {
272 ActuatorDesiredData *actuator_desired,
274 float *input, uint8_t *
mode)
276 bool failsafed =
false;
277 float *
rate = &stab_desired->Roll;
280 mode[
i] = stab_desired->StabilizationMode[
i];
283 if (mode[
i] == STABILIZATIONDESIRED_STABILIZATIONMODE_FAILSAFE) {
286 if ((airframe_type != SYSTEMSETTINGS_AIRFRAMETYPE_FIXEDWING) &&
287 (airframe_type != SYSTEMSETTINGS_AIRFRAMETYPE_FIXEDWINGELEVON) &&
288 (airframe_type != SYSTEMSETTINGS_AIRFRAMETYPE_FIXEDWINGVTAIL)) {
289 actuator_desired->Thrust = 0.0f;
292 mode[
i] = STABILIZATIONDESIRED_STABILIZATIONMODE_ATTITUDE;
297 mode[
i] = STABILIZATIONDESIRED_STABILIZATIONMODE_ATTITUDE;
301 mode[
i] = STABILIZATIONDESIRED_STABILIZATIONMODE_RATE;
308 actuator_desired->Thrust = 0.0f;
312 mode[
i] = STABILIZATIONDESIRED_STABILIZATIONMODE_ATTITUDE;
317 mode[
i] = STABILIZATIONDESIRED_STABILIZATIONMODE_ATTITUDE;
321 mode[
i] = STABILIZATIONDESIRED_STABILIZATIONMODE_RATE;
332 AttitudeActualData *attitudeActual,
333 float *local_attitude_error,
float *horizon_rate_fraction)
335 float trimmed_setpoint[
YAW+1];
336 float *cur_attitude = &attitudeActual->Roll;
340 raw_input[
ROLL] + subTrim.Roll,
341 -settings.MaxLevelAngle[
ROLL] + subTrim.Roll,
342 settings.MaxLevelAngle[
ROLL] + subTrim.Roll);
344 raw_input[
PITCH] + subTrim.Pitch,
345 -settings.MaxLevelAngle[
PITCH] + subTrim.Roll,
346 settings.MaxLevelAngle[
PITCH] + subTrim.Roll);
347 trimmed_setpoint[
YAW] = raw_input[
YAW];
351 *horizon_rate_fraction = 0.0f;
353 if (axis_mode[
ROLL] == STABILIZATIONDESIRED_STABILIZATIONMODE_HORIZON) {
355 raw_input[
ROLL] * settings.MaxLevelAngle[
ROLL]
357 -settings.MaxLevelAngle[
ROLL] + subTrim.Roll,
358 settings.MaxLevelAngle[
ROLL] + subTrim.Roll);
359 *horizon_rate_fraction = fabsf(raw_input[
ROLL]);
361 if (axis_mode[
PITCH] == STABILIZATIONDESIRED_STABILIZATIONMODE_HORIZON) {
363 raw_input[
PITCH] * settings.MaxLevelAngle[
PITCH]
365 -settings.MaxLevelAngle[
PITCH] + subTrim.Roll,
366 settings.MaxLevelAngle[
PITCH] + subTrim.Roll);
367 *horizon_rate_fraction =
368 MAX(*horizon_rate_fraction, fabsf(raw_input[
PITCH]));
370 if (axis_mode[
YAW] == STABILIZATIONDESIRED_STABILIZATIONMODE_HORIZON) {
371 trimmed_setpoint[
YAW] =
372 raw_input[
YAW] * settings.MaxLevelAngle[
YAW];
373 *horizon_rate_fraction =
374 MAX(*horizon_rate_fraction, fabsf(raw_input[
YAW]));
378 if (axis_mode[
ROLL] == STABILIZATIONDESIRED_STABILIZATIONMODE_WEAKLEVELING) {
379 trimmed_setpoint[
ROLL] = subTrim.Roll;
381 if (axis_mode[
PITCH] == STABILIZATIONDESIRED_STABILIZATIONMODE_WEAKLEVELING) {
382 trimmed_setpoint[
PITCH] = subTrim.Pitch;
384 if (axis_mode[
YAW] == STABILIZATIONDESIRED_STABILIZATIONMODE_WEAKLEVELING) {
385 trimmed_setpoint[
YAW] = 0;
389 switch (axis_mode[
i]) {
390 case STABILIZATIONDESIRED_STABILIZATIONMODE_HORIZON:
391 case STABILIZATIONDESIRED_STABILIZATIONMODE_WEAKLEVELING:
392 case STABILIZATIONDESIRED_STABILIZATIONMODE_ATTITUDE:
393 case STABILIZATIONDESIRED_STABILIZATIONMODE_ATTITUDELQG:
394 case STABILIZATIONDESIRED_STABILIZATIONMODE_SYSTEMIDENT:
400 trimmed_setpoint[
i] = cur_attitude[
i];
408 float desired_quat[4], atti_inverse[4], vehicle_reprojected[4];
412 quat_copy(&attitudeActual->q1, atti_inverse);
415 quat_mult(atti_inverse, desired_quat, vehicle_reprojected);
427 #if defined(STABILIZATION_LQG)
428 static void initialize_lqg_controllers(
float dT)
430 if (SystemIdentHandle()) {
431 SystemIdentData sysIdent;
432 SystemIdentGet(&sysIdent);
434 LQGSettingsData lqgSettings;
435 LQGSettingsGet(&lqgSettings);
442 lqgSettings.LQRegulator[i ==
YAW ? LQGSETTINGS_LQREGULATOR_YAWQ1 : LQGSETTINGS_LQREGULATOR_Q1],
443 lqgSettings.LQRegulator[i ==
YAW ? LQGSETTINGS_LQREGULATOR_YAWQ2 : LQGSETTINGS_LQREGULATOR_Q2],
444 lqgSettings.LQRegulator[i ==
YAW ? LQGSETTINGS_LQREGULATOR_YAWR : LQGSETTINGS_LQREGULATOR_R]
448 float beta = sysIdent.Beta[
i];
449 float tau = (sysIdent.Tau[0] + sysIdent.Tau[1]) * 0.5
f;
451 if (tau > 0.001
f && beta >= 6) {
453 lqgSettings.RTKF[i ==
YAW ? LQGSETTINGS_RTKF_YAWR : LQGSETTINGS_RTKF_R],
454 lqgSettings.RTKF[LQGSETTINGS_RTKF_Q1],
455 lqgSettings.RTKF[LQGSETTINGS_RTKF_Q2],
456 lqgSettings.RTKF[LQGSETTINGS_RTKF_Q3],
457 lqgSettings.RTKF[LQGSETTINGS_RTKF_BIASLIMIT]
460 lqgSettings.LQRegulator[i ==
YAW ? LQGSETTINGS_LQREGULATOR_YAWQ1 : LQGSETTINGS_LQREGULATOR_Q1],
461 lqgSettings.LQRegulator[i ==
YAW ? LQGSETTINGS_LQREGULATOR_YAWQ2 : LQGSETTINGS_LQREGULATOR_Q2],
462 lqgSettings.LQRegulator[i ==
YAW ? LQGSETTINGS_LQREGULATOR_YAWR : LQGSETTINGS_LQREGULATOR_R]
471 static void dump_lqg_solution(
lqg_t lqg,
int axis)
474 LQGSolutionData lqgsol;
475 LQGSolutionGet(&lqgsol);
483 lqgsol.RollK[0] = K[0];
484 lqgsol.RollK[1] = K[1];
487 lqgsol.PitchK[0] = K[0];
488 lqgsol.PitchK[1] = K[1];
491 lqgsol.YawK[0] = K[0];
492 lqgsol.YawK[1] = K[1];
496 LQGSolutionSet(&lqgsol);
504 FlightStatusData *flightStatus,
506 float desired_thrust)
509 static uint32_t last_nonzero_thrust_time = 0;
510 static bool last_thrust_pos =
true;
512 if (airframe_type == SYSTEMSETTINGS_AIRFRAMETYPE_HELICP) {
518 }
else if (flightStatus->Armed != FLIGHTSTATUS_ARMED_ARMED) {
519 last_thrust_pos =
true;
520 last_nonzero_thrust_time = 0;
525 float force_disable_hangtime =
false;
527 #ifdef TARGET_MAY_HAVE_BARO
528 bool do_alt_control =
false;
529 bool do_vertspeed_control =
false;
531 static bool prev_vertspeed_control;
533 static float prev_thrust;
535 static float alt_desired;
536 float vertspeed_desired = 0;
539 case STABILIZATIONDESIRED_THRUSTMODE_ALTITUDEWITHSTICKSCALING:
540 do_vertspeed_control =
true;
543 if (desired_thrust == 0) {
545 do_alt_control =
true;
546 }
else if (desired_thrust > 0) {
547 vertspeed_desired = -
expo3(desired_thrust,
548 altitude_hold_expo) *
549 altitude_hold_maxclimbrate;
551 vertspeed_desired = -
expo3(desired_thrust,
552 altitude_hold_expo) *
553 altitude_hold_maxdescentrate;
558 case STABILIZATIONDESIRED_THRUSTMODE_ALTITUDE:
559 do_alt_control =
true;
560 do_vertspeed_control =
true;
562 alt_desired = desired_thrust;
566 case STABILIZATIONDESIRED_THRUSTMODE_VERTICALSPEED:
567 do_vertspeed_control =
true;
568 vertspeed_desired = desired_thrust;
571 case STABILIZATIONDESIRED_THRUSTMODE_FLIPOVERMODETHRUSTREVERSED:
572 desired_thrust = -desired_thrust;
575 case STABILIZATIONDESIRED_THRUSTMODE_FLIPOVERMODE:
576 force_disable_hangtime =
true;
584 PositionActualDownGet(&position_z);
586 if (do_alt_control) {
587 float altitude_error;
589 altitude_error = alt_desired - position_z;
591 vertspeed_desired = altitudeHoldSettings.PositionKp * altitude_error;
593 alt_desired = position_z;
596 if (do_vertspeed_control) {
597 if (!prev_vertspeed_control) {
599 vertspeed_pid.iAccumulator =
605 VelocityActualDownGet(&velocity_z);
613 -(vertspeed_desired - velocity_z),
618 AltitudeHoldStateData altitudeHoldState;
619 altitudeHoldState.VelocityDesired = vertspeed_desired;
620 altitudeHoldState.Integral = vertspeed_pid.iAccumulator;
621 altitudeHoldState.AngleGain = 1.0f;
623 if (altitudeHoldSettings.AttitudeComp > 0) {
627 AttitudeActualData attitudeActual;
628 AttitudeActualGet(&attitudeActual);
632 float fraction = attitudeActual.q1 * attitudeActual.q1 -
633 attitudeActual.q2 * attitudeActual.q2 -
634 attitudeActual.q3 * attitudeActual.q3 +
635 attitudeActual.q4 * attitudeActual.q4;
639 fraction = powf(fraction, (
float)altitudeHoldSettings.AttitudeComp / 100.0f);
646 if (fraction > 0.1
f) {
648 throttle_desired / fraction,
655 altitudeHoldState.AngleGain = 1.0f / fraction;
658 altitudeHoldState.Thrust = throttle_desired;
659 AltitudeHoldStateSet(&altitudeHoldState);
661 desired_thrust = throttle_desired;
663 prev_thrust = desired_thrust;
666 prev_vertspeed_control = do_vertspeed_control;
669 case STABILIZATIONDESIRED_THRUSTMODE_FLIPOVERMODETHRUSTREVERSED:
670 desired_thrust = -desired_thrust;
673 case STABILIZATIONDESIRED_THRUSTMODE_FLIPOVERMODE:
674 force_disable_hangtime =
true;
683 if (settings.LowPowerStabilizationMaxTime) {
684 last_nonzero_thrust_time = this_systime;
685 last_thrust_pos = desired_thrust >= 0;
687 }
else if (last_nonzero_thrust_time) {
688 if (((this_systime - last_nonzero_thrust_time) < 1000.0
f * settings.LowPowerStabilizationMaxTime) &&
689 !force_disable_hangtime) {
693 if (last_thrust_pos) {
699 last_nonzero_thrust_time = 0;
707 return desired_thrust;
718 ActuatorDesiredData actuatorDesired;
719 StabilizationDesiredData stabDesired;
720 RateDesiredData rateDesired;
721 AttitudeActualData attitudeActual;
723 FlightStatusData flightStatus;
727 volatile bool flightstatus_updated =
true;
728 volatile bool lqgsettings_updated =
true;
730 float *actuatorDesiredAxis = &actuatorDesired.Roll;
731 float *rateDesiredAxis = &rateDesired.Roll;
735 FlightStatusConnectCallbackCtx(
UAVObjCbSetFlag, &flightstatus_updated);
737 StabilizationSettingsConnectCallbackCtx(
UAVObjCbSetFlag, &settings_updated);
740 #ifdef TARGET_MAY_HAVE_BARO
741 AltitudeHoldSettingsConnectCallbackCtx(
UAVObjCbSetFlag, &settings_updated);
755 uint32_t iteration = 0;
756 float dT_measured = 0;
758 uint8_t ident_shift = 5;
765 dT_expected = 1.0f / samp_rate;
770 if (dT_expected < 0.0004
f) {
773 }
else if (dT_expected < 0.0008
f) {
777 }
else if (dT_expected < 0.0014
f) {
790 ident_wiggle_points = (1 << (ident_shift + 3));
791 uint32_t ident_mask = ident_wiggle_points - 1;
801 if (settings_updated) {
804 SystemSettingsAirframeTypeGet(&airframe_type);
810 max_rate_alpha = expf(-dT_expected / settings.AcroDynamicTau);
813 if (vbar_settings.VbarTau < 0.001f) {
816 vbar_decay = expf(-dT_expected / vbar_settings.VbarTau);
819 settings_updated =
false;
827 AlarmsSet(SYSTEMALARMS_ALARM_STABILIZATION,
828 SYSTEMALARMS_ALARM_CRITICAL);
832 static bool frequency_wrong =
false;
837 if (iteration < 100) {
839 }
else if (iteration < 2100) {
841 }
else if (iteration == 2100) {
848 if ((dT_measured > dT_expected * 1.15
f) ||
849 (dT_measured < dT_expected * 0.85f)) {
850 frequency_wrong =
true;
853 printf(
"Stabilization: frequency wrong. dT_measured=%f, expected=%f\n",
854 dT_measured, dT_expected);
856 frequency_wrong =
false;
862 bool error = frequency_wrong;
864 if (flightstatus_updated) {
865 FlightStatusGet(&flightStatus);
866 flightstatus_updated =
false;
869 if (lqgsettings_updated) {
870 #if defined(STABILIZATION_LQG)
872 initialize_lqg_controllers(dT_expected);
874 lqgsettings_updated =
false;
877 StabilizationDesiredGet(&stabDesired);
878 AttitudeActualGet(&attitudeActual);
879 GyrosGet(&gyrosData);
884 stabDesired.ThrustMode, &flightStatus,
885 airframe_type, stabDesired.Thrust);
887 actuatorDesired.FlipOverThrustMode =
888 (stabDesired.ThrustMode == STABILIZATIONDESIRED_THRUSTMODE_FLIPOVERMODE) ||
889 (stabDesired.ThrustMode == STABILIZATIONDESIRED_THRUSTMODE_FLIPOVERMODETHRUSTREVERSED);
892 uint8_t reprojection = stabDesired.ReprojectionMode;
893 static uint8_t previous_reprojection = 255;
895 if (reprojection == STABILIZATIONDESIRED_REPROJECTIONMODE_CAMERAANGLE) {
896 float camera_tilt_angle = settings.CameraTilt;
897 if (camera_tilt_angle) {
898 float roll = stabDesired.Roll;
899 float yaw = stabDesired.Yaw;
902 stabDesired.Roll = (cosf(DEG2RAD * camera_tilt_angle) * roll +
903 (sinf(DEG2RAD * camera_tilt_angle) *
yaw));
906 stabDesired.Yaw = (-1 * sinf(DEG2RAD * camera_tilt_angle) *
roll) +
907 (cosf(DEG2RAD * camera_tilt_angle) *
yaw);
909 }
else if (reprojection == STABILIZATIONDESIRED_REPROJECTIONMODE_HEADFREE) {
910 static float reference_yaw;
912 if (previous_reprojection != reprojection) {
913 reference_yaw = attitudeActual.Yaw;
916 float rotation_angle = attitudeActual.Yaw - reference_yaw;
917 float roll = stabDesired.Roll;
918 float pitch = stabDesired.Pitch;
920 stabDesired.Roll = cosf(DEG2RAD * rotation_angle) * roll
921 + sinf(DEG2RAD * rotation_angle) *
pitch;
922 stabDesired.Pitch = cosf(DEG2RAD * rotation_angle) * pitch
923 + sinf(DEG2RAD * rotation_angle) * -
roll;
926 previous_reprojection = reprojection;
928 #if defined(RATEDESIRED_DIAGNOSTICS)
929 RateDesiredGet(&rateDesired);
936 raw_input, axis_mode);
939 static uint8_t previous_mode[
MAX_AXES] = {255,255,255};
942 for(
int i = 0;
i < 3;
i++) {
943 if (axis_mode[
i] != previous_mode[
i] || failsafed) {
953 float horizon_rate_fraction;
954 float local_attitude_error[
MAX_AXES];
957 local_attitude_error, &horizon_rate_fraction);
959 float *gyro_filtered = &gyrosData.x;
965 static float max_rate_filtered[
MAX_AXES];
967 actuatorDesired.SystemIdentCycle = 0xffff;
971 #if defined(STABILIZATION_LQG)
972 bool lqg_in_use =
false;
978 SystemAlarmsConfigErrorOptions err;
979 SystemAlarmsConfigErrorGet(&err);
983 dump_lqg_solution(lqg[i], i);
988 if (err != SYSTEMALARMS_CONFIGERROR_LQG) {
989 err = SYSTEMALARMS_CONFIGERROR_LQG;
990 SystemAlarmsConfigErrorSet(&err);
991 AlarmsSet(SYSTEMALARMS_ALARM_SYSTEMCONFIGURATION, SYSTEMALARMS_ALARM_ERROR);
996 if (err == SYSTEMALARMS_CONFIGERROR_LQG) {
997 err = SYSTEMALARMS_CONFIGERROR_NONE;
998 SystemAlarmsConfigErrorSet(&err);
999 AlarmsClear(SYSTEMALARMS_ALARM_SYSTEMCONFIGURATION);
1012 bool reinit = (axis_mode[
i] != previous_mode[
i]);
1014 previous_mode[
i] = axis_mode[
i];
1017 switch(axis_mode[
i]) {
1018 case STABILIZATIONDESIRED_STABILIZATIONMODE_FAILSAFE:
1022 case STABILIZATIONDESIRED_STABILIZATIONMODE_LQG:
1023 #if defined(STABILIZATION_LQG)
1031 rateDesiredAxis[
i] =
bound_sym(raw_input[i], settings.ManualRate[i]);
1034 actuatorDesiredAxis[
i] =
lqg_controller(lqg[i], gyro_filtered[i], rateDesiredAxis[i]);
1036 actuatorDesiredAxis[
i] =
bound_sym(actuatorDesiredAxis[i], 1.0
f);
1043 case STABILIZATIONDESIRED_STABILIZATIONMODE_RATE:
1049 rateDesiredAxis[
i] =
bound_sym(raw_input[i], settings.ManualRate[i]);
1056 case STABILIZATIONDESIRED_STABILIZATIONMODE_ACRODYNE:
1059 max_rate_filtered[
i] = settings.ManualRate[
i];
1064 float curve_cmd =
expoM(raw_input[i],
1065 settings.RateExpo[i],
1066 settings.RateExponent[i]*0.1f);
1068 const float break_point = settings.AcroDynamicTransition[
i]/100.0f;
1070 uint16_t calc_max_rate = settings.ManualRate[
i];
1072 float abs_cmd = fabsf(raw_input[i]);
1074 uint16_t acro_dynrate = settings.AcroDynamicRate[
i];
1076 if (!acro_dynrate) {
1077 acro_dynrate = settings.ManualRate[
i] + settings.ManualRate[
i] / 2;
1080 if (acro_dynrate > max_safe_rate) {
1081 acro_dynrate = max_safe_rate;
1085 if (abs_cmd > break_point) {
1086 calc_max_rate = (settings.ManualRate[
i] * (abs_cmd - 1.0f) * (2 * break_point - abs_cmd - 1.0
f) + acro_dynrate * powf(break_point - abs_cmd, 2.0
f)) / powf(break_point - 1.0
f, 2.0
f);
1089 calc_max_rate =
MIN(calc_max_rate,
1092 max_rate_filtered[
i] = max_rate_filtered[
i] * max_rate_alpha + calc_max_rate * (1 -
max_rate_alpha);
1095 rateDesiredAxis[
i] =
bound_sym(curve_cmd * max_rate_filtered[i], max_rate_filtered[i]);
1102 case STABILIZATIONDESIRED_STABILIZATIONMODE_ACROPLUS:
1112 float factor = fabsf(raw_input[i]) * settings.AcroInsanityFactor / 100.0f;
1115 rateDesiredAxis[
i] =
bound_sym(raw_input[i] * settings.ManualRate[i], settings.ManualRate[i]);
1118 if ((i < 2 && fabsf(gyro_filtered[i]) > settings.AcroZeroIntegralGyro) ||
1119 (i == 0 && fabsf(raw_input[i]) > settings.AcroZeroIntegralStick / 100.0f)) {
1125 actuatorDesiredAxis[
i] = factor * raw_input[
i] + (1.0f - factor) * actuatorDesiredAxis[i];
1126 actuatorDesiredAxis[
i] =
bound_sym(actuatorDesiredAxis[i], 1.0
f);
1130 case STABILIZATIONDESIRED_STABILIZATIONMODE_ATTITUDELQG:
1131 #if defined(STABILIZATION_LQG)
1142 rateDesiredAxis[
i] =
bound_sym(rateDesiredAxis[i], settings.MaximumRate[i]);
1145 actuatorDesiredAxis[
i] =
lqg_controller(lqg[i], gyro_filtered[i], rateDesiredAxis[i]);
1147 actuatorDesiredAxis[
i] =
bound_sym(actuatorDesiredAxis[i], 1.0
f);
1155 case STABILIZATIONDESIRED_STABILIZATIONMODE_ATTITUDE:
1163 rateDesiredAxis[
i] =
bound_sym(rateDesiredAxis[i], settings.MaximumRate[i]);
1167 actuatorDesiredAxis[
i] =
bound_sym(actuatorDesiredAxis[i],1.0
f);
1171 case STABILIZATIONDESIRED_STABILIZATIONMODE_VIRTUALBAR:
1173 rateDesiredAxis[
i] =
bound_sym(raw_input[i], 1.0
f);
1180 case STABILIZATIONDESIRED_STABILIZATIONMODE_WEAKLEVELING:
1187 weak_leveling =
bound_sym(weak_leveling, weak_leveling_max);
1190 rateDesiredAxis[
i] =
bound_sym(raw_input[i] + weak_leveling, settings.ManualRate[i]);
1195 case STABILIZATIONDESIRED_STABILIZATIONMODE_AXISLOCK:
1200 if (fabsf(raw_input[i]) > max_axislock_rate) {
1202 rateDesiredAxis[
i] =
bound_sym(raw_input[i], settings.ManualRate[i]);
1205 axis_lock_accum[
i] = 0;
1208 axis_lock_accum[
i] += (raw_input[
i] - gyro_filtered[
i]) * dT_expected;
1209 axis_lock_accum[
i] =
bound_sym(axis_lock_accum[i], max_axis_lock);
1213 rateDesiredAxis[
i] =
bound_sym(tmpRateDesired, settings.MaximumRate[i]);
1220 case STABILIZATIONDESIRED_STABILIZATIONMODE_HORIZON:
1232 float rateDesiredRate =
bound_sym(raw_input[i], 1.0
f) * settings.ManualRate[
i];
1238 rateDesiredAxis[
i] = rateDesiredAttitude * (1.0f - horizon_rate_fraction) + rateDesiredRate * horizon_rate_fraction;
1239 rateDesiredAxis[
i] =
bound_sym(rateDesiredAxis[i], settings.ManualRate[i]);
1243 actuatorDesiredAxis[
i] =
bound_sym(actuatorDesiredAxis[i],1.0
f);
1246 case STABILIZATIONDESIRED_STABILIZATIONMODE_SYSTEMIDENT:
1247 case STABILIZATIONDESIRED_STABILIZATIONMODE_SYSTEMIDENTRATE:
1249 static bool measuring;
1250 static uint32_t enter_time;
1252 static uint32_t measure_remaining;
1257 const uint32_t PREPARE_TIME = 1250000;
1264 enter_time = timeval;
1272 ((timeval - enter_time) > PREPARE_TIME)) {
1273 if (!(iteration & ident_mask)) {
1278 measure_remaining &= ~ident_mask;
1282 if (flightStatus.Armed != FLIGHTSTATUS_ARMED_ARMED) {
1286 if (axis_mode[i] == STABILIZATIONDESIRED_STABILIZATIONMODE_SYSTEMIDENT) {
1289 rateDesiredAxis[
i] =
bound_sym(rateDesiredAxis[i], settings.MaximumRate[i]);
1295 rateDesiredAxis[
i] =
bound_sym(raw_input[i], settings.ManualRate[i]);
1301 const float scale = settings.AutotuneActuationEffort[
i];
1303 uint32_t ident_iteration =
1304 iteration >> ident_shift;
1306 if (measuring && measure_remaining) {
1310 measure_remaining--;
1313 actuatorDesired.SystemIdentCycle = (iteration & ident_mask);
1315 switch (ident_iteration & 0x07) {
1318 actuatorDesiredAxis[
i] +=
scale;
1323 actuatorDesiredAxis[
i] +=
scale;
1328 actuatorDesiredAxis[
i] -=
scale;
1333 actuatorDesiredAxis[
i] -=
scale;
1338 actuatorDesiredAxis[
i] +=
scale;
1343 actuatorDesiredAxis[
i] +=
scale;
1348 actuatorDesiredAxis[
i] -=
scale;
1353 actuatorDesiredAxis[
i] -=
scale;
1358 actuatorDesiredAxis[
i] =
bound_sym(actuatorDesiredAxis[i],1.0
f);
1363 case STABILIZATIONDESIRED_STABILIZATIONMODE_COORDINATEDFLIGHT:
1369 axis_lock_accum[
YAW] = 0;
1373 if (axis_mode[
ROLL] != STABILIZATIONDESIRED_STABILIZATIONMODE_ATTITUDE)
1382 AccelsyGet(&accelsDataY);
1385 if ((stabDesired.Roll > 0 && actuatorDesiredAxis[
YAW] < 0) ||
1386 (stabDesired.Roll < 0 && actuatorDesiredAxis[
YAW] > 0)){
1394 float errorSlip = -accelsDataY;
1401 axis_lock_accum[
YAW] = 0;
1404 axis_lock_accum[
YAW] += (0 - gyro_filtered[
YAW]) * dT_expected;
1407 rateDesiredAxis[
YAW] =
bound_sym(rateDesiredAxis[YAW], settings.MaximumRate[YAW]);
1410 actuatorDesiredAxis[
YAW] =
bound_sym(actuatorDesiredAxis[YAW],1.0
f);
1421 axis_lock_accum[
YAW] = 0;
1434 case STABILIZATIONDESIRED_STABILIZATIONMODE_POI:
1442 float angle_error = 0;
1444 if (CameraDesiredHandle()) {
1447 CameraDesiredDeclinationGet(&angle);
1452 uint8_t roll_fraction = 0;
1456 CameraDesiredRollGet(&angle);
1457 angle *= roll_fraction / 100.0f;
1462 CameraDesiredBearingGet(&angle);
1471 rateDesiredAxis[
i] =
bound_sym(rateDesiredAxis[i], settings.PoiMaximumRate[i]);
1477 case STABILIZATIONDESIRED_STABILIZATIONMODE_DISABLED:
1478 actuatorDesiredAxis[
i] = 0.0;
1480 case STABILIZATIONDESIRED_STABILIZATIONMODE_MANUAL:
1481 actuatorDesiredAxis[
i] =
bound_sym(raw_input[i],1.0
f);
1489 #if defined(STABILIZATION_LQG)
1491 if (lqg_in_use && (lqg[0] || lqg[1] || lqg[2])) {
1492 RTKFEstimateData est = { 0 };
1495 &est.Rate[RTKFESTIMATE_RATE_ROLL], &est.Torque[RTKFESTIMATE_TORQUE_ROLL], &est.Bias[RTKFESTIMATE_BIAS_ROLL]);
1499 &est.Rate[RTKFESTIMATE_RATE_PITCH], &est.Torque[RTKFESTIMATE_TORQUE_PITCH], &est.Bias[RTKFESTIMATE_BIAS_PITCH]);
1503 &est.Rate[RTKFESTIMATE_RATE_YAW], &est.Torque[RTKFESTIMATE_TORQUE_YAW], &est.Bias[RTKFESTIMATE_BIAS_YAW]);
1505 RTKFEstimateSet(&est);
1520 if (vbar_settings.VbarPiroComp == VBARSETTINGS_VBARPIROCOMP_TRUE)
1523 #if defined(RATEDESIRED_DIAGNOSTICS)
1524 RateDesiredSet(&rateDesired);
1528 actuatorDesired.UpdateTime = dT * 1000;
1530 ActuatorDesiredSet(&actuatorDesired);
1532 if(flightStatus.Armed != FLIGHTSTATUS_ARMED_ARMED ||
1533 (lowThrottleZeroIntegral &&
get_throttle(&actuatorDesired, &airframe_type) == 0))
1537 previous_mode[
i] = 255;
1543 AlarmsSet(SYSTEMALARMS_ALARM_STABILIZATION, SYSTEMALARMS_ALARM_ERROR);
1559 for(uint8_t i = 0; i < 3; i++)
1560 axis_lock_accum[i] = 0.0
f;
1570 case STABILIZATIONSETTINGS_MANUALCONTROLSMOOTHING_NONE:
1572 case STABILIZATIONSETTINGS_MANUALCONTROLSMOOTHING_NORMAL:
1574 case STABILIZATIONSETTINGS_MANUALCONTROLSMOOTHING_LINEAR:
1583 settings.RollRatePID[STABILIZATIONSETTINGS_ROLLRATEPID_KP],
1584 settings.RollRatePID[STABILIZATIONSETTINGS_ROLLRATEPID_KI],
1585 settings.RollRatePID[STABILIZATIONSETTINGS_ROLLRATEPID_KD],
1586 settings.RollRatePID[STABILIZATIONSETTINGS_ROLLRATEPID_ILIMIT],
1591 settings.PitchRatePID[STABILIZATIONSETTINGS_PITCHRATEPID_KP],
1592 settings.PitchRatePID[STABILIZATIONSETTINGS_PITCHRATEPID_KI],
1593 settings.PitchRatePID[STABILIZATIONSETTINGS_PITCHRATEPID_KD],
1594 settings.PitchRatePID[STABILIZATIONSETTINGS_PITCHRATEPID_ILIMIT],
1599 settings.YawRatePID[STABILIZATIONSETTINGS_YAWRATEPID_KP],
1600 settings.YawRatePID[STABILIZATIONSETTINGS_YAWRATEPID_KI],
1601 settings.YawRatePID[STABILIZATIONSETTINGS_YAWRATEPID_KD],
1602 settings.YawRatePID[STABILIZATIONSETTINGS_YAWRATEPID_ILIMIT],
1607 settings.RollPI[STABILIZATIONSETTINGS_ROLLPI_KP],
1608 settings.RollPI[STABILIZATIONSETTINGS_ROLLPI_KI], 0,
1609 settings.RollPI[STABILIZATIONSETTINGS_ROLLPI_ILIMIT],
1614 settings.PitchPI[STABILIZATIONSETTINGS_PITCHPI_KP],
1615 settings.PitchPI[STABILIZATIONSETTINGS_PITCHPI_KI], 0,
1616 settings.PitchPI[STABILIZATIONSETTINGS_PITCHPI_ILIMIT],
1621 settings.YawPI[STABILIZATIONSETTINGS_YAWPI_KP],
1622 settings.YawPI[STABILIZATIONSETTINGS_YAWPI_KI], 0,
1623 settings.YawPI[STABILIZATIONSETTINGS_YAWPI_ILIMIT],
1628 vbar_settings.VbarRollPID[VBARSETTINGS_VBARROLLPID_KP],
1629 vbar_settings.VbarRollPID[VBARSETTINGS_VBARROLLPID_KI],
1630 vbar_settings.VbarRollPID[VBARSETTINGS_VBARROLLPID_KD],
1636 vbar_settings.VbarPitchPID[VBARSETTINGS_VBARPITCHPID_KP],
1637 vbar_settings.VbarPitchPID[VBARSETTINGS_VBARPITCHPID_KI],
1638 vbar_settings.VbarPitchPID[VBARSETTINGS_VBARPITCHPID_KD],
1644 vbar_settings.VbarYawPID[VBARSETTINGS_VBARYAWPID_KP],
1645 vbar_settings.VbarYawPID[VBARSETTINGS_VBARYAWPID_KI],
1646 vbar_settings.VbarYawPID[VBARSETTINGS_VBARYAWPID_KD],
1652 settings.CoordinatedFlightYawPI[STABILIZATIONSETTINGS_COORDINATEDFLIGHTYAWPI_KP],
1653 settings.CoordinatedFlightYawPI[STABILIZATIONSETTINGS_COORDINATEDFLIGHTYAWPI_KI],
1655 settings.CoordinatedFlightYawPI[STABILIZATIONSETTINGS_COORDINATEDFLIGHTYAWPI_ILIMIT],
1661 #ifndef NO_CONTROL_DEADBANDS
1663 settings.DeadbandWidth[STABILIZATIONSETTINGS_DEADBANDWIDTH_ROLL] ||
1664 settings.DeadbandWidth[STABILIZATIONSETTINGS_DEADBANDWIDTH_PITCH] ||
1665 settings.DeadbandWidth[STABILIZATIONSETTINGS_DEADBANDWIDTH_YAW])
1669 pid_configure_deadband(deadbands + PID_RATE_ROLL, (
float)settings.DeadbandWidth[STABILIZATIONSETTINGS_DEADBANDWIDTH_ROLL],
1670 0.01f * (
float)settings.DeadbandSlope[STABILIZATIONSETTINGS_DEADBANDSLOPE_ROLL]);
1671 pid_configure_deadband(deadbands + PID_RATE_PITCH, (
float)settings.DeadbandWidth[STABILIZATIONSETTINGS_DEADBANDWIDTH_PITCH],
1672 0.01f * (
float)settings.DeadbandSlope[STABILIZATIONSETTINGS_DEADBANDSLOPE_PITCH]);
1673 pid_configure_deadband(deadbands + PID_RATE_YAW, (
float)settings.DeadbandWidth[STABILIZATIONSETTINGS_DEADBANDWIDTH_YAW],
1674 0.01f * (
float)settings.DeadbandSlope[STABILIZATIONSETTINGS_DEADBANDSLOPE_YAW]);
1681 #if defined(TARGET_MAY_HAVE_BARO)
1682 AltitudeHoldSettingsGet(&altitudeHoldSettings);
1684 pid_configure(&vertspeed_pid, altitudeHoldSettings.VelocityKp,
1685 altitudeHoldSettings.VelocityKi, 0.0f, 1.0f,
1692 SubTrimSettingsData subTrimSettings;
1694 SubTrimGet(&subTrim);
1695 SubTrimSettingsGet(&subTrimSettings);
1698 subTrim.Roll = subTrimSettings.Roll;
1699 subTrim.Pitch = subTrimSettings.Pitch;
1701 SubTrimSet(&subTrim);
1703 StabilizationSettingsGet(&settings);
1704 VbarSettingsGet(&vbar_settings);
1710 max_axis_lock = settings.MaxAxisLock;
1711 max_axislock_rate = settings.MaxAxisLockRate;
1714 weak_leveling_kp = settings.WeakLevelingKp;
1715 weak_leveling_max = settings.MaxWeakLevelingRate;
1718 lowThrottleZeroIntegral = settings.LowThrottleZeroIntegral == STABILIZATIONSETTINGS_LOWTHROTTLEZEROINTEGRAL_TRUE;
1720 #if defined(TARGET_MAY_HAVE_BARO)
1721 uint8_t altitude_hold_maxclimbrate10;
1722 uint8_t altitude_hold_maxdescentrate10;
1723 AltitudeHoldSettingsMaxClimbRateGet(&altitude_hold_maxclimbrate10);
1724 AltitudeHoldSettingsMaxDescentRateGet(&altitude_hold_maxdescentrate10);
1727 altitude_hold_maxclimbrate = altitude_hold_maxclimbrate10 * 0.1f;
1728 altitude_hold_maxdescentrate = altitude_hold_maxdescentrate10 * 0.1f;
1730 AltitudeHoldSettingsExpoGet(&altitude_hold_expo);
1733 uint8_t s_mode =
remap_smoothing_mode(settings.ManualControlSmoothing[STABILIZATIONSETTINGS_MANUALCONTROLSMOOTHING_AXES]);
1734 uint8_t duty_cycle = settings.ManualControlSmoothingDutyCycle;
1739 settings.ManualControlSmoothing[STABILIZATIONSETTINGS_MANUALCONTROLSMOOTHING_THRUST]
float pid_apply_setpoint_antiwindup(struct pid *pid, struct pid_deadband *deadband, const float setpoint, const float measured, float min_bound, float max_bound, float aw_bound)
static uint8_t weak_leveling_max
static float get_throttle(ActuatorDesiredData *actuator_desired, SystemSettingsAirframeTypeOptions *airframe_type)
uint32_t PIOS_Thread_Systime(void)
uint32_t PIOS_DELAY_DiffuS(uint32_t raw)
Subtract raw time from now and convert to us.
void smoothcontrol_set_mode(smoothcontrol_state state, uint8_t axis_num, uint8_t mode, uint8_t duty_cycle)
static StabilizationSettingsData settings
static void update_settings(float dT)
float expoM(float x, int32_t g, float exponent)
bool stabilization_failsafe_checks(StabilizationDesiredData *stab_desired, ActuatorDesiredData *actuator_desired, SystemSettingsAirframeTypeOptions airframe_type, float *input, uint8_t *mode)
void RPY2Quaternion(const float rpy[3], float q[4])
static uint8_t remap_smoothing_mode(uint8_t m)
int stabilization_virtual_flybar(float gyro, float command, float *output, float dT, bool reinit, uint32_t axis, struct pid *pid, VbarSettingsData *settings)
void quat_copy(const float q[4], float qnew[4])
Duplicate a quaternion.
int32_t PIOS_SENSORS_GetMaxGyro()
Get the maximum gyro rate in deg/s.
#define get_deadband(axis)
struct _msp_pid_item pitch
static float max_rate_alpha
static bool lowThrottleZeroIntegral
lqg_t lqg_create(rtkf_t rtkf, lqr_t lqr)
static float scale(float val, float inMin, float inMax, float outMin, float outMax)
#define LQG_SOLVER_RUNNING
void lqr_get_gains(lqr_t lqr, float K[2])
bool PIOS_WDG_RegisterFlag(uint16_t flag_requested)
Register a module against the watchdog.
struct _msp_pid_item roll
bool PIOS_WDG_UpdateFlag(uint16_t flag)
Function called by modules to indicate they are still running.
void * PIOS_malloc(size_t size)
void UAVObjCbSetFlag(const UAVObjEvent *objEv, void *ctx, void *obj, int len)
lqr_t lqg_get_lqr(lqg_t lqg)
int32_t AlarmsSet(SystemAlarmsAlarmElem alarm, SystemAlarmsAlarmOptions severity)
void quat_mult(const float q1[4], const float q2[4], float qout[4])
Multiply two quaternions into a third.
static VbarSettingsData vbar_settings
volatile bool settings_updated
void lqg_set_x0(lqg_t lqg, float x0)
static struct pid pids[PID_MAX]
uint32_t PIOS_SENSORS_GetSampleRate(enum pios_sensor_type type)
Get the sample rate of a sensor (Hz)
void smoothcontrol_update_dT(smoothcontrol_state state, float dT)
#define COORDINATED_FLIGHT_MIN_ROLL_THRESHOLD
static void calculate_attitude_errors(uint8_t *axis_mode, float *raw_input, AttitudeActualData *attitudeActual, float *local_attitude_error, float *horizon_rate_fraction)
void pid_configure(struct pid *pid, float p, float i, float d, float iLim, float dT)
void lqr_update(lqr_t lqr, float q1, float q2, float r)
static void zero_pids(void)
void pid_configure_deadband(struct pid_deadband *deadband, float width, float slope)
int32_t StabilizationStart()
static SubTrimData subTrim
float circular_modulus_deg(float err)
Circular modulus.
bool PIOS_SENSORS_IsRegistered(enum pios_sensor_type type)
Checks if a sensor type is registered with the PIOS_SENSORS interface.
void smoothcontrol_reinit_thrust(smoothcontrol_state state, float new_signal)
void smoothcontrol_next(smoothcontrol_state state)
void smoothcontrol_initialize(smoothcontrol_state *state)
struct pid_deadband * deadbands
static float weak_leveling_kp
#define HORIZON_MODE_MAX_BLEND
Set the stick position that maximally transitions to rate.
static uint8_t max_axislock_rate
struct pios_thread * PIOS_Thread_Create(void(*fp)(void *), const char *namep, size_t stack_bytes, void *argp, enum pios_thread_prio_e prio)
DONT_BUILD_IF((MAX_AXES+0!=3), stabAxisWrongCount)
int32_t TaskMonitorAdd(TaskInfoRunningElem task, struct pios_thread *threadp)
float bound_min_max(float val, float min, float max)
Bound input value between min and max.
float bound_sym(float val, float range)
Bound input value within range (plus or minus)
void lqg_run_covariance(lqg_t lqg, int iter)
void lqg_get_rtkf_state(lqg_t lqg, float *rate, float *torque, float *bias)
#define LQG_SOLVER_FAILED
void pid_zero(struct pid *pid)
int stabilization_virtual_flybar_pirocomp(float z_gyro, float dT)
uint16_t ident_wiggle_points
#define PIOS_WDG_STABILIZATION
float pid_apply(struct pid *pid, const float err)
Methods to use the pid structures.
Header for Coordinate conversions library in coordinate_conversions.c.
static uint8_t max_axis_lock
static SystemSettingsAirframeTypeOptions airframe_type
lqr_t lqr_create(float beta, float tau, float Ts, float q1, float q2, float r)
Attitude stabilization module.
rtkf_t rtkf_create(float beta, float tau, float Ts, float R, float q1, float q2, float q3, float biaslim)
bool * smoothcontrol_get_ringer(smoothcontrol_state state)
Includes PiOS and core architecture components.
int32_t AlarmsClear(SystemAlarmsAlarmElem alarm)
void quat_inverse(float q[4])
Compute the inverse of a quaternion.
static void calculate_vert_pids(float dT)
static void stabilizationTask(void *parameters)
int printf(const char *format,...)
MODULE_HIPRI_INITCALL(StabilizationInitialize, StabilizationStart)
void smoothcontrol_run_thrust(smoothcontrol_state state, float *new_signal)
static float calculate_thrust(StabilizationDesiredThrustModeOptions mode, FlightStatusData *flightStatus, SystemSettingsAirframeTypeOptions airframe_type, float desired_thrust)
int32_t StabilizationInitialize()
float pid_apply_setpoint(struct pid *pid, struct pid_deadband *deadband, const float setpoint, const float measured)
float pid_apply_antiwindup(struct pid *pid, const float err, float min_bound, float max_bound, float aw_bound)
static void calculate_pids(float dT)
float lqg_controller(lqg_t lqg, float signal, float setpoint)
int32_t sensors_init(void)
void pid_configure_derivative(float cutoff, float g)
Configure the common terms that alter ther derivative.
#define COORDINATED_FLIGHT_MAX_YAW_THRESHOLD
Attitude stabilization module.
#define PIOS_Assert(test)
void smoothcontrol_run(smoothcontrol_state state, uint8_t axis_num, float *new_signal)
#define THROTTLE_EPSILON
Minimum sane positive value for throttle.
static AltitudeHoldSettingsData altitudeHoldSettings
void Quaternion2RPY(const float q[4], float rpy[3])
float expo3(float x, int32_t g)
Approximation an exponential scale curve.
static float axis_lock_accum[MAX_AXES]
void smoothcontrol_reinit(smoothcontrol_state state, uint8_t axis_num, float new_signal)
bool PIOS_Thread_FakeClock_IsActive(void)
int lqg_solver_status(lqg_t lqg)
uint32_t PIOS_DELAY_GetRaw()
Get the raw delay timer, useful for timing.
static smoothcontrol_state rc_smoothing
static struct pios_thread * taskHandle