2 ******************************************************************************
4 * @file vtolbrakecontroller.cpp
5 * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2015.
6 * @brief This landing state machine is a helper state machine to the
7 * pathfollower task/thread to implement detailed landing controls.
8 * This is to be called only from the pathfollower task.
9 * Note that initiation of the land occurs in the manual control
10 * command thread calling plans.c plan_setup_land which writes
11 * the required PathDesired LAND mode.
12 * @see The GNU Public License (GPL) Version 3
14 *****************************************************************************/
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 3 of the License, or
19 * (at your option) any later version.
21 * This program is distributed in the hope that it will be useful, but
22 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
23 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
26 * You should have received a copy of the GNU General Public License along
27 * with this program; if not, write to the Free Software Foundation, Inc.,
28 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
32 #include <openpilot.h>
37 #include <CoordinateConversions.h>
38 #include <sin_lookup.h>
39 #include <pathdesired.h>
42 #include <sanitycheck.h>
44 #include <accelstate.h>
45 #include <vtolpathfollowersettings.h>
46 #include <flightstatus.h>
47 #include <flightmodesettings.h>
48 #include <pathstatus.h>
49 #include <positionstate.h>
50 #include <velocitystate.h>
51 #include <velocitydesired.h>
52 #include <stabilizationdesired.h>
53 #include <attitudestate.h>
54 #include <takeofflocation.h>
55 #include <manualcontrolcommand.h>
56 #include <systemsettings.h>
57 #include <stabilizationbank.h>
58 #include <stabilizationdesired.h>
59 #include <vtolselftuningstats.h>
60 #include <pathsummary.h>
64 #include "vtolbrakecontroller.h"
65 #include "pathfollowerfsm.h"
66 #include "vtolbrakefsm.h"
67 #include "pidcontroldown.h"
70 #define BRAKE_RATE_MINIMUM 0.2f
72 // pointer to a singleton instance
73 VtolBrakeController
*VtolBrakeController::p_inst
= 0;
75 VtolBrakeController::VtolBrakeController()
76 : fsm(0), vtolPathFollowerSettings(0), mActive(false), mHoldActive(false), mManualThrust(false)
79 // Called when mode first engaged
80 void VtolBrakeController::Activate(void)
85 mManualThrust
= false;
88 controlDown
.Activate();
93 uint8_t VtolBrakeController::IsActive(void)
98 uint8_t VtolBrakeController::Mode(void)
100 return PATHDESIRED_MODE_BRAKE
;
103 // Objective updated in pathdesired
104 void VtolBrakeController::ObjectiveUpdated(void)
106 // Set the objective's target velocity
107 controlDown
.UpdateVelocitySetpoint(pathDesired
->ModeParameters
[PATHDESIRED_MODEPARAMETER_BRAKE_STARTVELOCITYVECTOR_DOWN
]);
108 controlNE
.UpdateVelocitySetpoint(pathDesired
->ModeParameters
[PATHDESIRED_MODEPARAMETER_BRAKE_STARTVELOCITYVECTOR_NORTH
],
109 pathDesired
->ModeParameters
[PATHDESIRED_MODEPARAMETER_BRAKE_STARTVELOCITYVECTOR_EAST
]);
110 if (pathDesired
->ModeParameters
[PATHDESIRED_MODEPARAMETER_BRAKE_TIMEOUT
] > 0.0f
) {
111 pathStatus
->path_time
= 0.0f
;
114 void VtolBrakeController::Deactivate(void)
119 mManualThrust
= false;
121 controlDown
.Deactivate();
122 controlNE
.Deactivate();
127 void VtolBrakeController::SettingsUpdated(void)
129 const float dT
= vtolPathFollowerSettings
->UpdatePeriod
/ 1000.0f
;
131 controlNE
.UpdateParameters(vtolPathFollowerSettings
->BrakeHorizontalVelPID
.Kp
,
132 vtolPathFollowerSettings
->BrakeHorizontalVelPID
.Ki
,
133 vtolPathFollowerSettings
->BrakeHorizontalVelPID
.Kd
,
134 vtolPathFollowerSettings
->BrakeHorizontalVelPID
.Beta
,
136 10.0f
* vtolPathFollowerSettings
->HorizontalVelMax
); // avoid constraining initial fast entry into brake
137 controlNE
.UpdatePositionalParameters(vtolPathFollowerSettings
->HorizontalPosP
);
138 controlNE
.UpdateCommandParameters(-vtolPathFollowerSettings
->BrakeMaxPitch
, vtolPathFollowerSettings
->BrakeMaxPitch
, vtolPathFollowerSettings
->BrakeVelocityFeedforward
);
140 controlDown
.UpdateParameters(vtolPathFollowerSettings
->VerticalVelPID
.Kp
,
141 vtolPathFollowerSettings
->VerticalVelPID
.Ki
,
142 vtolPathFollowerSettings
->VerticalVelPID
.Kd
,
143 vtolPathFollowerSettings
->VerticalVelPID
.Beta
,
145 10.0f
* vtolPathFollowerSettings
->VerticalVelMax
); // avoid constraining initial fast entry into brake
146 controlDown
.UpdatePositionalParameters(vtolPathFollowerSettings
->VerticalPosP
);
147 controlDown
.SetThrustLimits(vtolPathFollowerSettings
->ThrustLimits
.Min
, vtolPathFollowerSettings
->ThrustLimits
.Max
);
149 VtolSelfTuningStatsData vtolSelfTuningStats
;
150 VtolSelfTuningStatsGet(&vtolSelfTuningStats
);
151 controlDown
.UpdateNeutralThrust(vtolSelfTuningStats
.NeutralThrustOffset
+ vtolPathFollowerSettings
->ThrustLimits
.Neutral
);
152 fsm
->SettingsUpdated();
156 * Initialise the module, called on startup
157 * \returns 0 on success or -1 if initialisation failed
159 int32_t VtolBrakeController::Initialize(VtolPathFollowerSettingsData
*ptr_vtolPathFollowerSettings
)
161 PIOS_Assert(ptr_vtolPathFollowerSettings
);
162 vtolPathFollowerSettings
= ptr_vtolPathFollowerSettings
;
164 VtolBrakeFSM::instance()->Initialize(vtolPathFollowerSettings
, pathDesired
, flightStatus
, pathStatus
);
165 fsm
= (PathFollowerFSM
*)VtolBrakeFSM::instance();
166 controlDown
.Initialize(fsm
);
172 void VtolBrakeController::UpdateVelocityDesired()
174 VelocityStateData velocityState
;
176 VelocityStateGet(&velocityState
);
177 VelocityDesiredData velocityDesired
;
179 float brakeRate
= vtolPathFollowerSettings
->BrakeRate
;
180 if (brakeRate
< BRAKE_RATE_MINIMUM
) {
181 brakeRate
= BRAKE_RATE_MINIMUM
; // set a minimum to avoid a divide by zero potential below
184 if (fsm
->PositionHoldState()) {
185 PositionStateData positionState
;
186 PositionStateGet(&positionState
);
188 // On first engagement set the position setpoint
191 controlNE
.UpdatePositionSetpoint(positionState
.North
, positionState
.East
);
192 if (!mManualThrust
) {
193 controlDown
.UpdatePositionSetpoint(positionState
.Down
);
197 FlightStatusFlightModeAssistOptions flightModeAssist
;
198 FlightStatusFlightModeAssistGet(&flightModeAssist
);
199 if (flightModeAssist
!= FLIGHTSTATUS_FLIGHTMODEASSIST_NONE
) {
200 // Notify manualcommand via setting hold state in flightstatus assistedcontrolstate
201 FlightStatusAssistedControlStateOptions assistedControlFlightMode
;
202 FlightStatusAssistedControlStateGet(&assistedControlFlightMode
);
203 // sanity check that we are in brake state according to flight status, which means
204 // we are being used for gpsassist
205 if (assistedControlFlightMode
== FLIGHTSTATUS_ASSISTEDCONTROLSTATE_BRAKE
) {
206 assistedControlFlightMode
= FLIGHTSTATUS_ASSISTEDCONTROLSTATE_HOLD
;
207 FlightStatusAssistedControlStateSet(&assistedControlFlightMode
);
212 // Update position state and control position to create inputs to velocity control
213 controlNE
.UpdatePositionState(positionState
.North
, positionState
.East
);
214 controlNE
.ControlPosition();
215 if (!mManualThrust
) {
216 controlDown
.UpdatePositionState(positionState
.Down
);
217 controlDown
.ControlPosition();
220 controlNE
.UpdateVelocityState(velocityState
.North
, velocityState
.East
);
221 if (!mManualThrust
) {
222 controlDown
.UpdateVelocityState(velocityState
.Down
);
225 controlNE
.UpdateVelocityStateWithBrake(velocityState
.North
, velocityState
.East
, pathStatus
->path_time
, brakeRate
);
226 if (!mManualThrust
) {
227 controlDown
.UpdateVelocityStateWithBrake(velocityState
.Down
, pathStatus
->path_time
, brakeRate
);
231 if (!mManualThrust
) {
232 velocityDesired
.Down
= controlDown
.GetVelocityDesired();
233 } else { velocityDesired
.Down
= 0.0f
; }
236 controlNE
.GetVelocityDesired(&north
, &east
);
237 velocityDesired
.North
= north
;
238 velocityDesired
.East
= east
;
240 VelocityDesiredSet(&velocityDesired
);
243 float cur_velocity
= velocityState
.North
* velocityState
.North
+ velocityState
.East
* velocityState
.East
+ velocityState
.Down
* velocityState
.Down
;
244 cur_velocity
= sqrtf(cur_velocity
);
245 float desired_velocity
= velocityDesired
.North
* velocityDesired
.North
+ velocityDesired
.East
* velocityDesired
.East
+ velocityDesired
.Down
* velocityDesired
.Down
;
246 desired_velocity
= sqrtf(desired_velocity
);
247 pathStatus
->error
= cur_velocity
- desired_velocity
;
248 pathStatus
->fractional_progress
= 1.0f
;
249 if (pathDesired
->StartingVelocity
> 0.0f
) {
250 pathStatus
->fractional_progress
= (pathDesired
->StartingVelocity
- cur_velocity
) / pathDesired
->StartingVelocity
;
252 // sometimes current velocity can exceed starting velocity due to initial acceleration
253 if (pathStatus
->fractional_progress
< 0.0f
) {
254 pathStatus
->fractional_progress
= 0.0f
;
257 pathStatus
->path_direction_north
= velocityDesired
.North
;
258 pathStatus
->path_direction_east
= velocityDesired
.East
;
259 pathStatus
->path_direction_down
= velocityDesired
.Down
;
261 pathStatus
->correction_direction_north
= velocityDesired
.North
- velocityState
.North
;
262 pathStatus
->correction_direction_east
= velocityDesired
.East
- velocityState
.East
;
265 int8_t VtolBrakeController::UpdateStabilizationDesired(void)
268 StabilizationDesiredData stabDesired
;
269 AttitudeStateData attitudeState
;
270 StabilizationBankData stabSettings
;
274 StabilizationDesiredGet(&stabDesired
);
275 AttitudeStateGet(&attitudeState
);
276 StabilizationBankGet(&stabSettings
);
278 controlNE
.GetNECommand(&northCommand
, &eastCommand
);
280 float angle_radians
= DEG2RAD(attitudeState
.Yaw
);
281 float cos_angle
= cosf(angle_radians
);
282 float sine_angle
= sinf(angle_radians
);
283 float maxPitch
= vtolPathFollowerSettings
->BrakeMaxPitch
;
284 stabDesired
.StabilizationMode
.Pitch
= STABILIZATIONDESIRED_STABILIZATIONMODE_ATTITUDE
;
285 stabDesired
.Pitch
= boundf(-northCommand
* cos_angle
- eastCommand
* sine_angle
, -maxPitch
, maxPitch
); // this should be in the controller
286 stabDesired
.StabilizationMode
.Roll
= STABILIZATIONDESIRED_STABILIZATIONMODE_ATTITUDE
;
287 stabDesired
.Roll
= boundf(-northCommand
* sine_angle
+ eastCommand
* cos_angle
, -maxPitch
, maxPitch
);
289 ManualControlCommandData manualControl
;
290 ManualControlCommandGet(&manualControl
);
292 stabDesired
.StabilizationMode
.Yaw
= STABILIZATIONDESIRED_STABILIZATIONMODE_AXISLOCK
;
293 stabDesired
.Yaw
= stabSettings
.MaximumRate
.Yaw
* manualControl
.Yaw
;
295 // default thrust mode to cruise control
296 stabDesired
.StabilizationMode
.Thrust
= STABILIZATIONDESIRED_STABILIZATIONMODE_CRUISECONTROL
;
298 // when flight mode assist is active but in primary-thrust mode, the thrust mode must be set to the same as per the primary mode.
299 if (flightStatus
->FlightModeAssist
== FLIGHTSTATUS_FLIGHTMODEASSIST_GPSASSIST_PRIMARYTHRUST
) {
300 FlightModeSettingsData settings
;
301 FlightModeSettingsGet(&settings
);
302 uint8_t thrustMode
= FLIGHTMODESETTINGS_STABILIZATION1SETTINGS_CRUISECONTROL
;
304 switch (flightStatus
->FlightMode
) {
305 case FLIGHTSTATUS_FLIGHTMODE_STABILIZED1
:
306 thrustMode
= settings
.Stabilization1Settings
.Thrust
;
308 case FLIGHTSTATUS_FLIGHTMODE_STABILIZED2
:
309 thrustMode
= settings
.Stabilization2Settings
.Thrust
;
311 case FLIGHTSTATUS_FLIGHTMODE_STABILIZED3
:
312 thrustMode
= settings
.Stabilization3Settings
.Thrust
;
314 case FLIGHTSTATUS_FLIGHTMODE_STABILIZED4
:
315 thrustMode
= settings
.Stabilization4Settings
.Thrust
;
317 case FLIGHTSTATUS_FLIGHTMODE_STABILIZED5
:
318 thrustMode
= settings
.Stabilization5Settings
.Thrust
;
320 case FLIGHTSTATUS_FLIGHTMODE_STABILIZED6
:
321 thrustMode
= settings
.Stabilization6Settings
.Thrust
;
323 case FLIGHTSTATUS_FLIGHTMODE_POSITIONHOLD
:
324 thrustMode
= FLIGHTMODESETTINGS_STABILIZATION1SETTINGS_ALTITUDEVARIO
;
326 case FLIGHTSTATUS_FLIGHTMODE_VELOCITYROAM
:
327 thrustMode
= FLIGHTMODESETTINGS_STABILIZATION1SETTINGS_ALTITUDEVARIO
;
332 stabDesired
.StabilizationMode
.Thrust
= (StabilizationDesiredStabilizationModeOptions
)thrustMode
;
335 // set the thrust value
337 stabDesired
.Thrust
= manualControl
.Thrust
;
339 stabDesired
.Thrust
= controlDown
.GetDownCommand();
342 StabilizationDesiredSet(&stabDesired
);
348 void VtolBrakeController::UpdateAutoPilot()
350 if (pathDesired
->ModeParameters
[PATHDESIRED_MODEPARAMETER_BRAKE_TIMEOUT
] > 0.0f
) {
351 pathStatus
->path_time
+= vtolPathFollowerSettings
->UpdatePeriod
/ 1000.0f
;
354 if (flightStatus
->FlightModeAssist
&& flightStatus
->AssistedThrottleState
== FLIGHTSTATUS_ASSISTEDTHROTTLESTATE_MANUAL
) {
355 mManualThrust
= true;
357 mManualThrust
= false;
360 fsm
->Update(); // This will run above end condition checks
362 UpdateVelocityDesired();
364 int8_t result
= UpdateStabilizationDesired();
367 AlarmsSet(SYSTEMALARMS_ALARM_GUIDANCE
, SYSTEMALARMS_ALARM_OK
);
369 pathStatus
->Status
= PATHSTATUS_STATUS_CRITICAL
;
370 AlarmsSet(SYSTEMALARMS_ALARM_GUIDANCE
, SYSTEMALARMS_ALARM_WARNING
);
373 PathStatusSet(pathStatus
);