2 ******************************************************************************
4 * @file altitudeloop.cpp
5 * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2014.
6 * @brief This module compared @ref PositionActuatl to @ref ActiveWaypoint
7 * and sets @ref AttitudeDesired. It only does this when the FlightMode field
8 * of @ref ManualControlCommand is Auto.
10 * @see The GNU Public License (GPL) Version 3
12 *****************************************************************************/
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 3 of the License, or
17 * (at your option) any later version.
19 * This program is distributed in the hope that it will be useful, but
20 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
21 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
24 * You should have received a copy of the GNU General Public License along
25 * with this program; if not, write to the Free Software Foundation, Inc.,
26 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30 #include <openpilot.h>
32 #include <callbackinfo.h>
35 #include <altitudeloop.h>
36 #include <CoordinateConversions.h>
37 #include <altitudeholdsettings.h>
38 #include <altitudeholdstatus.h>
39 #include <velocitystate.h>
40 #include <positionstate.h>
41 #include <vtolselftuningstats.h>
42 #include <stabilization.h>
45 #include <pidcontroldown.h>
52 #define UPDATE_EXPECTED (1.0f / PIOS_SENSOR_RATE)
53 #define UPDATE_MIN 1.0e-6f
54 #define UPDATE_MAX 1.0f
55 #define UPDATE_ALPHA 1.0e-2f
57 #define CALLBACK_PRIORITY CALLBACK_PRIORITY_LOW
58 #define CBTASK_PRIORITY CALLBACK_TASK_FLIGHTCONTROL
63 static DelayedCallbackInfo
*altitudeHoldCBInfo
;
64 static PIDControlDown controlDown
;
65 static AltitudeHoldSettingsData altitudeHoldSettings
;
66 static ThrustModeType thrustMode
;
67 static float thrustDemand
= 0.0f
;
71 static void SettingsUpdatedCb(UAVObjEvent
*ev
);
72 static void altitudeHoldTask(void);
73 static void VelocityStateUpdatedCb(UAVObjEvent
*ev
);
76 * Setup mode and setpoint
78 * reinit: true when althold/vario mode selected over a previous alternate thrust mode
80 float stabilizationAltitudeHold(float setpoint
, ThrustModeType mode
, bool reinit
)
82 static bool newaltitude
= true;
84 if (reinit
|| !controlDown
.IsActive()) {
85 controlDown
.Activate();
87 // calculate a thrustDemand on reinit only
92 const float DEADBAND
= 0.20f
;
93 const float DEADBAND_HIGH
= 1.0f
/ 2 + DEADBAND
/ 2;
94 const float DEADBAND_LOW
= 1.0f
/ 2 - DEADBAND
/ 2;
97 if (altitudeHoldSettings
.CutThrustWhenZero
&& setpoint
<= 0) {
98 // Cut thrust if desired
99 controlDown
.UpdateVelocitySetpoint(0.0f
);
104 } else if (mode
== ALTITUDEVARIO
&& setpoint
> DEADBAND_HIGH
) {
105 // being the two band symmetrical I can divide by DEADBAND_LOW to scale it to a value betweeon 0 and 1
106 // then apply an "exp" f(x,k) = (k*x*x*x + (255-k)*x) / 255
107 controlDown
.UpdateVelocitySetpoint(-((altitudeHoldSettings
.ThrustExp
* powf((setpoint
- DEADBAND_HIGH
) / (DEADBAND_LOW
), 3.0f
) + (255.0f
- altitudeHoldSettings
.ThrustExp
) * (setpoint
- DEADBAND_HIGH
) / DEADBAND_LOW
) / 255.0f
* altitudeHoldSettings
.ThrustRate
));
108 thrustMode
= ALTITUDEVARIO
;
110 } else if (mode
== ALTITUDEVARIO
&& setpoint
< DEADBAND_LOW
) {
111 controlDown
.UpdateVelocitySetpoint(-(-(altitudeHoldSettings
.ThrustExp
* powf((DEADBAND_LOW
- (setpoint
< 0 ? 0 : setpoint
)) / DEADBAND_LOW
, 3.0f
) + (255.0f
- altitudeHoldSettings
.ThrustExp
) * (DEADBAND_LOW
- setpoint
) / DEADBAND_LOW
) / 255.0f
* altitudeHoldSettings
.ThrustRate
));
112 thrustMode
= ALTITUDEVARIO
;
114 } else if (newaltitude
== true) {
115 controlDown
.UpdateVelocitySetpoint(0.0f
);
116 PositionStateData posState
;
117 PositionStateGet(&posState
);
118 controlDown
.UpdatePositionSetpoint(posState
.Down
);
119 thrustMode
= ALTITUDEHOLD
;
123 thrustDemand
= boundf(thrustDemand
, altitudeHoldSettings
.ThrustLimits
.Min
, altitudeHoldSettings
.ThrustLimits
.Max
);
129 * Disable the alt hold task loop velocity controller to save cpu cycles
131 void stabilizationDisableAltitudeHold(void)
133 controlDown
.Deactivate();
138 * Module thread, should not return.
140 static void altitudeHoldTask(void)
142 if (!controlDown
.IsActive()) {
146 AltitudeHoldStatusData altitudeHoldStatus
;
147 AltitudeHoldStatusGet(&altitudeHoldStatus
);
149 float velocityStateDown
;
150 VelocityStateDownGet(&velocityStateDown
);
151 controlDown
.UpdateVelocityState(velocityStateDown
);
153 float local_thrustDemand
= 0.0f
;
155 switch (thrustMode
) {
158 float positionStateDown
;
159 PositionStateDownGet(&positionStateDown
);
160 controlDown
.UpdatePositionState(positionStateDown
);
161 controlDown
.ControlPosition();
162 altitudeHoldStatus
.VelocityDesired
= controlDown
.GetVelocityDesired();
163 altitudeHoldStatus
.State
= ALTITUDEHOLDSTATUS_STATE_ALTITUDEHOLD
;
164 local_thrustDemand
= controlDown
.GetDownCommand();
169 altitudeHoldStatus
.VelocityDesired
= controlDown
.GetVelocityDesired();
170 altitudeHoldStatus
.State
= ALTITUDEHOLDSTATUS_STATE_ALTITUDEVARIO
;
171 local_thrustDemand
= controlDown
.GetDownCommand();
175 altitudeHoldStatus
.VelocityDesired
= 0.0f
;
176 altitudeHoldStatus
.State
= ALTITUDEHOLDSTATUS_STATE_DIRECT
;
180 thrustDemand
= local_thrustDemand
;
181 AltitudeHoldStatusSet(&altitudeHoldStatus
);
184 static void VelocityStateUpdatedCb(__attribute__((unused
)) UAVObjEvent
*ev
)
186 PIOS_CALLBACKSCHEDULER_Dispatch(altitudeHoldCBInfo
);
190 * Initialise the module, called on startup
192 void stabilizationAltitudeloopInit()
194 AltitudeHoldSettingsInitialize();
195 AltitudeHoldStatusInitialize();
196 PositionStateInitialize();
197 VelocityStateInitialize();
198 VtolSelfTuningStatsInitialize();
200 AltitudeHoldSettingsConnectCallback(&SettingsUpdatedCb
);
201 VtolSelfTuningStatsConnectCallback(&SettingsUpdatedCb
);
202 SettingsUpdatedCb(NULL
);
204 altitudeHoldCBInfo
= PIOS_CALLBACKSCHEDULER_Create(&altitudeHoldTask
, CALLBACK_PRIORITY
, CBTASK_PRIORITY
, CALLBACKINFO_RUNNING_ALTITUDEHOLD
, STACK_SIZE_BYTES
);
205 VelocityStateConnectCallback(&VelocityStateUpdatedCb
);
209 static void SettingsUpdatedCb(__attribute__((unused
)) UAVObjEvent
*ev
)
211 AltitudeHoldSettingsGet(&altitudeHoldSettings
);
213 controlDown
.UpdateParameters(altitudeHoldSettings
.VerticalVelPID
.Kp
,
214 altitudeHoldSettings
.VerticalVelPID
.Ki
,
215 altitudeHoldSettings
.VerticalVelPID
.Kd
,
216 altitudeHoldSettings
.VerticalVelPID
.Beta
,
217 (float)(UPDATE_EXPECTED
),
218 altitudeHoldSettings
.ThrustRate
);
220 controlDown
.UpdatePositionalParameters(altitudeHoldSettings
.VerticalPosP
);
222 VtolSelfTuningStatsData vtolSelfTuningStats
;
223 VtolSelfTuningStatsGet(&vtolSelfTuningStats
);
224 controlDown
.UpdateNeutralThrust(vtolSelfTuningStats
.NeutralThrustOffset
+ altitudeHoldSettings
.ThrustLimits
.Neutral
);
226 // initialise limits on thrust but note the FSM can override.
227 controlDown
.SetThrustLimits(altitudeHoldSettings
.ThrustLimits
.Min
, altitudeHoldSettings
.ThrustLimits
.Max
);
229 // disable neutral thrust calcs which should only be done in a hold mode.
230 controlDown
.DisableNeutralThrustCalc();
234 #endif /* ifdef REVOLUTION */