2 ******************************************************************************
4 * @file vtolbrakefsm.cpp
5 * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2015.
6 * @brief Vtol brake finate state machine to regulate behaviour of the
8 * @see The GNU Public License (GPL) Version 3
10 *****************************************************************************/
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 3 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 * You should have received a copy of the GNU General Public License along
23 * with this program; if not, write to the Free Software Foundation, Inc.,
24 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 #include <openpilot.h>
32 #include <CoordinateConversions.h>
33 #include <sin_lookup.h>
34 #include <pathdesired.h>
37 #include <sanitycheck.h>
39 #include <vtolpathfollowersettings.h>
40 #include <flightstatus.h>
41 #include <flightmodesettings.h>
42 #include <pathstatus.h>
43 #include <positionstate.h>
44 #include <velocitystate.h>
45 #include <velocitydesired.h>
46 #include <stabilizationdesired.h>
47 #include <attitudestate.h>
48 #include <manualcontrolcommand.h>
49 #include <systemsettings.h>
50 #include <stabilizationbank.h>
51 #include <stabilizationdesired.h>
52 #include <vtolselftuningstats.h>
53 #include <pathsummary.h>
57 #include <vtolbrakefsm.h>
61 #define TIMER_COUNT_PER_SECOND (1000 / vtolPathFollowerSettings->UpdatePeriod)
62 #define BRAKE_FRACTIONALPROGRESS_STARTVELOCITYCHECK 0.95f
63 #define BRAKE_EXIT_VELOCITY_LIMIT 0.15f
65 VtolBrakeFSM::PathFollowerFSM_BrakeStateHandler_T
VtolBrakeFSM::sBrakeStateTable
[BRAKE_STATE_SIZE
] = {
66 [BRAKE_STATE_INACTIVE
] = { .setup
= 0, .run
= 0 },
67 [BRAKE_STATE_BRAKE
] = { .setup
= &VtolBrakeFSM::setup_brake
, .run
= &VtolBrakeFSM::run_brake
},
68 [BRAKE_STATE_HOLD
] = { .setup
= 0, .run
= 0 }
71 // pointer to a singleton instance
72 VtolBrakeFSM
*VtolBrakeFSM::p_inst
= 0;
75 VtolBrakeFSM::VtolBrakeFSM()
76 : mBrakeData(0), vtolPathFollowerSettings(0), pathDesired(0), flightStatus(0)
85 * Initialise the module, called on startup
86 * \returns 0 on success or -1 if initialisation failed
88 int32_t VtolBrakeFSM::Initialize(VtolPathFollowerSettingsData
*ptr_vtolPathFollowerSettings
,
89 PathDesiredData
*ptr_pathDesired
,
90 FlightStatusData
*ptr_flightStatus
,
91 PathStatusData
*ptr_pathStatus
)
93 PIOS_Assert(ptr_vtolPathFollowerSettings
);
94 PIOS_Assert(ptr_pathDesired
);
95 PIOS_Assert(ptr_flightStatus
);
97 // allow for Initialize being called more than once.
99 mBrakeData
= (VtolBrakeFSMData_T
*)pios_malloc(sizeof(VtolBrakeFSMData_T
));
100 PIOS_Assert(mBrakeData
);
102 memset(mBrakeData
, 0, sizeof(VtolBrakeFSMData_T
));
103 vtolPathFollowerSettings
= ptr_vtolPathFollowerSettings
;
104 pathDesired
= ptr_pathDesired
;
105 flightStatus
= ptr_flightStatus
;
106 pathStatus
= ptr_pathStatus
;
112 void VtolBrakeFSM::Inactive(void)
114 memset(mBrakeData
, 0, sizeof(VtolBrakeFSMData_T
));
118 // Initialise the FSM
119 void VtolBrakeFSM::initFSM(void)
121 mBrakeData
->currentState
= BRAKE_STATE_INACTIVE
;
124 void VtolBrakeFSM::Activate()
126 memset(mBrakeData
, 0, sizeof(VtolBrakeFSMData_T
));
127 mBrakeData
->currentState
= BRAKE_STATE_INACTIVE
;
128 setState(BRAKE_STATE_BRAKE
, FSMBRAKESTATUS_STATEEXITREASON_NONE
);
131 PathFollowerFSMState_T
VtolBrakeFSM::GetCurrentState(void)
133 switch (mBrakeData
->currentState
) {
134 case BRAKE_STATE_INACTIVE
:
135 return PFFSM_STATE_INACTIVE
;
139 return PFFSM_STATE_ACTIVE
;
145 void VtolBrakeFSM::Update()
150 int32_t VtolBrakeFSM::runState(void)
152 uint8_t flTimeout
= false;
154 mBrakeData
->stateRunCount
++;
156 if (mBrakeData
->stateTimeoutCount
> 0 && mBrakeData
->stateRunCount
> mBrakeData
->stateTimeoutCount
) {
160 // If the current state has a static function, call it
161 if (sBrakeStateTable
[mBrakeData
->currentState
].run
) {
162 (this->*sBrakeStateTable
[mBrakeData
->currentState
].run
)(flTimeout
);
167 // Set the new state and perform setup for subsequent state run calls
168 // This is called by state run functions on event detection that drive
169 // state transitions.
170 void VtolBrakeFSM::setState(PathFollowerFSM_BrakeState_T newState
, __attribute__((unused
)) VtolBrakeFSMStatusStateExitReasonOptions reason
)
172 // mBrakeData->fsmBrakeStatus.StateExitReason[mBrakeData->currentState] = reason;
174 if (mBrakeData
->currentState
== newState
) {
177 mBrakeData
->currentState
= newState
;
179 // Restart state timer counter
180 mBrakeData
->stateRunCount
= 0;
182 // Reset state timeout to disabled/zero
183 mBrakeData
->stateTimeoutCount
= 0;
185 if (sBrakeStateTable
[mBrakeData
->currentState
].setup
) {
186 (this->*sBrakeStateTable
[mBrakeData
->currentState
].setup
)();
191 // Timeout utility function for use by state init implementations
192 void VtolBrakeFSM::setStateTimeout(int32_t count
)
194 mBrakeData
->stateTimeoutCount
= count
;
197 // FSM Setup and Run method implementation
199 // State: WAITING FOR DESCENT RATE
200 void VtolBrakeFSM::setup_brake(void)
202 setStateTimeout(TIMER_COUNT_PER_SECOND
* pathDesired
->ModeParameters
[PATHDESIRED_MODEPARAMETER_BRAKE_TIMEOUT
]);
203 mBrakeData
->observationCount
= 0;
204 mBrakeData
->observation2Count
= 0;
208 void VtolBrakeFSM::run_brake(uint8_t flTimeout
)
210 // Brake mode end condition checks
211 bool exit_brake
= false;
212 VelocityStateData velocityState
;
213 PathSummaryData pathSummary
;
216 pathSummary
.brake_exit_reason
= PATHSUMMARY_BRAKE_EXIT_REASON_TIMEOUT
;
218 } else if (pathStatus
->fractional_progress
> BRAKE_FRACTIONALPROGRESS_STARTVELOCITYCHECK
) {
219 VelocityStateGet(&velocityState
);
220 if (fabsf(velocityState
.East
) < BRAKE_EXIT_VELOCITY_LIMIT
&& fabsf(velocityState
.North
) < BRAKE_EXIT_VELOCITY_LIMIT
) {
221 pathSummary
.brake_exit_reason
= PATHSUMMARY_BRAKE_EXIT_REASON_PATHCOMPLETED
;
227 // Calculate the distance error between the originally desired
228 // stopping point and the actual brake-exit point.
231 PositionStateGet(&p
);
232 float north_offset
= pathDesired
->End
.North
- p
.North
;
233 float east_offset
= pathDesired
->End
.East
- p
.East
;
234 float down_offset
= pathDesired
->End
.Down
- p
.Down
;
235 pathSummary
.brake_distance_offset
= sqrtf(north_offset
* north_offset
+ east_offset
* east_offset
+ down_offset
* down_offset
);
236 pathSummary
.time_remaining
= pathDesired
->ModeParameters
[PATHDESIRED_MODEPARAMETER_BRAKE_TIMEOUT
] - pathStatus
->path_time
;
237 pathSummary
.fractional_progress
= pathStatus
->fractional_progress
;
238 float cur_velocity
= velocityState
.North
* velocityState
.North
+ velocityState
.East
* velocityState
.East
+ velocityState
.Down
* velocityState
.Down
;
239 cur_velocity
= sqrtf(cur_velocity
);
240 pathSummary
.decelrate
= (pathDesired
->StartingVelocity
- cur_velocity
) / pathStatus
->path_time
;
241 pathSummary
.brakeRateActualDesiredRatio
= pathSummary
.decelrate
/ vtolPathFollowerSettings
->BrakeRate
;
242 pathSummary
.velocityIntoHold
= cur_velocity
;
243 pathSummary
.Mode
= PATHSUMMARY_MODE_BRAKE
;
244 pathSummary
.UID
= pathStatus
->UID
;
245 PathSummarySet(&pathSummary
);
247 setState(BRAKE_STATE_HOLD
, FSMBRAKESTATUS_STATEEXITREASON_NONE
);
251 uint8_t VtolBrakeFSM::PositionHoldState(void)
253 return mBrakeData
->currentState
== BRAKE_STATE_HOLD
;