Skip to content

Commit a3e7e3c

Browse files
committed
[LAUNCH] Some readability refactoring; Fix bug with throttling up at zero throttle
1 parent 02e1fb8 commit a3e7e3c

File tree

1 file changed

+97
-38
lines changed

1 file changed

+97
-38
lines changed

src/main/navigation/navigation_fw_launch.c

Lines changed: 97 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ static const fixedWingLaunchStateDescriptor_t launchStateMachine[FW_LAUNCH_STATE
119119
},
120120
.messageType = FW_LAUNCH_MESSAGE_TYPE_NONE
121121
},
122+
122123
[FW_LAUNCH_STATE_WAIT_THROTTLE] = {
123124
.onEntry = fwLaunchState_FW_LAUNCH_STATE_WAIT_THROTTLE,
124125
.onEvent = {
@@ -127,6 +128,7 @@ static const fixedWingLaunchStateDescriptor_t launchStateMachine[FW_LAUNCH_STATE
127128
},
128129
.messageType = FW_LAUNCH_MESSAGE_TYPE_WAIT_THROTTLE
129130
},
131+
130132
[FW_LAUNCH_STATE_MOTOR_IDLE] = {
131133
.onEntry = fwLaunchState_FW_LAUNCH_STATE_MOTOR_IDLE,
132134
.onEvent = {
@@ -135,6 +137,7 @@ static const fixedWingLaunchStateDescriptor_t launchStateMachine[FW_LAUNCH_STATE
135137
},
136138
.messageType = FW_LAUNCH_MESSAGE_TYPE_WAIT_THROTTLE
137139
},
140+
138141
[FW_LAUNCH_STATE_WAIT_DETECTION] = {
139142
.onEntry = fwLaunchState_FW_LAUNCH_STATE_WAIT_DETECTION,
140143
.onEvent = {
@@ -143,13 +146,15 @@ static const fixedWingLaunchStateDescriptor_t launchStateMachine[FW_LAUNCH_STATE
143146
},
144147
.messageType = FW_LAUNCH_MESSAGE_TYPE_WAIT_DETECTION
145148
},
149+
146150
[FW_LAUNCH_STATE_DETECTED] = {
147151
.onEntry = fwLaunchState_FW_LAUNCH_STATE_DETECTED,
148152
.onEvent = {
149153
// waiting for the navigation to move on the next state FW_LAUNCH_STATE_MOTOR_DELAY
150154
},
151155
.messageType = FW_LAUNCH_MESSAGE_TYPE_WAIT_DETECTION
152156
},
157+
153158
[FW_LAUNCH_STATE_MOTOR_DELAY] = {
154159
.onEntry = fwLaunchState_FW_LAUNCH_STATE_MOTOR_DELAY,
155160
.onEvent = {
@@ -158,6 +163,7 @@ static const fixedWingLaunchStateDescriptor_t launchStateMachine[FW_LAUNCH_STATE
158163
},
159164
.messageType = FW_LAUNCH_MESSAGE_TYPE_IN_PROGRESS
160165
},
166+
161167
[FW_LAUNCH_STATE_MOTOR_SPINUP] = {
162168
.onEntry = fwLaunchState_FW_LAUNCH_STATE_MOTOR_SPINUP,
163169
.onEvent = {
@@ -166,6 +172,7 @@ static const fixedWingLaunchStateDescriptor_t launchStateMachine[FW_LAUNCH_STATE
166172
},
167173
.messageType = FW_LAUNCH_MESSAGE_TYPE_IN_PROGRESS
168174
},
175+
169176
[FW_LAUNCH_STATE_IN_PROGRESS] = {
170177
.onEntry = fwLaunchState_FW_LAUNCH_STATE_IN_PROGRESS,
171178
.onEvent = {
@@ -174,6 +181,7 @@ static const fixedWingLaunchStateDescriptor_t launchStateMachine[FW_LAUNCH_STATE
174181
},
175182
.messageType = FW_LAUNCH_MESSAGE_TYPE_IN_PROGRESS
176183
},
184+
177185
[FW_LAUNCH_STATE_FINISH] = {
178186
.onEntry = fwLaunchState_FW_LAUNCH_STATE_FINISH,
179187
.onEvent = {
@@ -186,39 +194,52 @@ static const fixedWingLaunchStateDescriptor_t launchStateMachine[FW_LAUNCH_STATE
186194

187195
/* Current State Handlers */
188196

189-
static timeMs_t currentStateElapsedMs(timeUs_t currentTimeUs) {
197+
static timeMs_t currentStateElapsedMs(timeUs_t currentTimeUs)
198+
{
190199
return US2MS(currentTimeUs - fwLaunch.currentStateTimeUs);
191200
}
192201

193-
static void setCurrentState(fixedWingLaunchState_t nextState, timeUs_t currentTimeUs) {
202+
static void setCurrentState(fixedWingLaunchState_t nextState, timeUs_t currentTimeUs)
203+
{
194204
fwLaunch.currentState = nextState;
195205
fwLaunch.currentStateTimeUs = currentTimeUs;
196206
}
197207

198208
/* Wing control Helpers */
199209

200-
static bool isThrottleIdleEnabled(void) {
210+
static bool isThrottleIdleEnabled(void)
211+
{
201212
return navConfig()->fw.launch_idle_throttle > getThrottleIdleValue();
202213
}
203214

204-
static void applyThrottleIdle(void) {
215+
static void forceMotorStopOrIdle(void)
216+
{
217+
ENABLE_STATE(NAV_MOTOR_STOP_OR_IDLE); // If MOTOR_STOP is enabled mixer will keep motor stopped
218+
rcCommand[THROTTLE] = getThrottleIdleValue(); // If MOTOR_STOP is disabled, motors will spin at minthrottle
219+
}
220+
221+
static void applyThrottleIdleLogic(void)
222+
{
205223
if (isThrottleIdleEnabled()) {
206224
rcCommand[THROTTLE] = navConfig()->fw.launch_idle_throttle;
207-
} else {
208-
ENABLE_STATE(NAV_MOTOR_STOP_OR_IDLE); // If MOTOR_STOP is enabled mixer will keep motor stopped
209-
rcCommand[THROTTLE] = getThrottleIdleValue(); // If MOTOR_STOP is disabled, motors will spin at minthrottle
225+
}
226+
else {
227+
forceMotorStopOrIdle();
210228
}
211229
}
212230

213-
static inline bool isThrottleLow(void) {
231+
static inline bool isThrottleLow(void)
232+
{
214233
return calculateThrottleStatus(THROTTLE_STATUS_TYPE_RC) == THROTTLE_LOW;
215234
}
216235

217-
static inline bool isLaunchMaxAltitudeReached(void) {
236+
static inline bool isLaunchMaxAltitudeReached(void)
237+
{
218238
return (navConfig()->fw.launch_max_altitude > 0) && (getEstimatedActualPosition(Z) >= navConfig()->fw.launch_max_altitude);
219239
}
220240

221-
static inline bool areSticksMoved(timeMs_t initialTime, timeUs_t currentTimeUs) {
241+
static inline bool areSticksMoved(timeMs_t initialTime, timeUs_t currentTimeUs)
242+
{
222243
return (initialTime + currentStateElapsedMs(currentTimeUs)) > navConfig()->fw.launch_min_time && areSticksDeflectedMoreThanPosHoldDeadband();
223244
}
224245

@@ -230,7 +251,8 @@ static void resetPidsIfNeeded(void) {
230251
}
231252
}
232253

233-
static void updateRcCommand(void) {
254+
static void updateRcCommand(void)
255+
{
234256
// lock roll and yaw and apply needed pitch angle
235257
rcCommand[ROLL] = 0;
236258
rcCommand[PITCH] = pidAngleToRcCommand(-DEGREES_TO_DECIDEGREES(fwLaunch.pitchAngle), pidProfile()->max_angle_inclination[FD_PITCH]);
@@ -239,57 +261,68 @@ static void updateRcCommand(void) {
239261

240262
/* onEntry state handlers */
241263

242-
static fixedWingLaunchEvent_t fwLaunchState_FW_LAUNCH_STATE_IDLE(timeUs_t currentTimeUs) {
264+
static fixedWingLaunchEvent_t fwLaunchState_FW_LAUNCH_STATE_IDLE(timeUs_t currentTimeUs)
265+
{
243266
UNUSED(currentTimeUs);
244267

245268
return FW_LAUNCH_EVENT_NONE;
246269
}
247270

248-
static fixedWingLaunchEvent_t fwLaunchState_FW_LAUNCH_STATE_WAIT_THROTTLE(timeUs_t currentTimeUs) {
271+
static fixedWingLaunchEvent_t fwLaunchState_FW_LAUNCH_STATE_WAIT_THROTTLE(timeUs_t currentTimeUs)
272+
{
249273
UNUSED(currentTimeUs);
250274

251275
if (!isThrottleLow()) {
252276
if (isThrottleIdleEnabled()) {
253277
return FW_LAUNCH_EVENT_SUCCESS;
254-
} else {
278+
}
279+
else {
255280
fwLaunch.pitchAngle = navConfig()->fw.launch_climb_angle;
256281
return FW_LAUNCH_EVENT_GOTO_DETECTION;
257282
}
258283
}
284+
else {
285+
forceMotorStopOrIdle();
286+
}
287+
259288
fwLaunch.pitchAngle = 0;
260289

261290
return FW_LAUNCH_EVENT_NONE;
262291
}
263292

264-
static fixedWingLaunchEvent_t fwLaunchState_FW_LAUNCH_STATE_MOTOR_IDLE(timeUs_t currentTimeUs) {
293+
static fixedWingLaunchEvent_t fwLaunchState_FW_LAUNCH_STATE_MOTOR_IDLE(timeUs_t currentTimeUs)
294+
{
265295
if (isThrottleLow()) {
266296
return FW_LAUNCH_EVENT_THROTTLE_LOW; // go back to FW_LAUNCH_STATE_WAIT_THROTTLE
267297
}
298+
268299
const timeMs_t elapsedTimeMs = currentStateElapsedMs(currentTimeUs);
269300
if (elapsedTimeMs > LAUNCH_MOTOR_IDLE_SPINUP_TIME) {
270-
applyThrottleIdle();
301+
applyThrottleIdleLogic();
271302
return FW_LAUNCH_EVENT_SUCCESS;
272-
} else {
303+
}
304+
else {
273305
rcCommand[THROTTLE] = scaleRangef(elapsedTimeMs, 0.0f, LAUNCH_MOTOR_IDLE_SPINUP_TIME, getThrottleIdleValue(), navConfig()->fw.launch_idle_throttle);
274306
fwLaunch.pitchAngle = scaleRangef(elapsedTimeMs, 0.0f, LAUNCH_MOTOR_IDLE_SPINUP_TIME, 0, navConfig()->fw.launch_climb_angle);
275307
}
276308

277309
return FW_LAUNCH_EVENT_NONE;
278310
}
279311

280-
static fixedWingLaunchEvent_t fwLaunchState_FW_LAUNCH_STATE_WAIT_DETECTION(timeUs_t currentTimeUs) {
312+
static fixedWingLaunchEvent_t fwLaunchState_FW_LAUNCH_STATE_WAIT_DETECTION(timeUs_t currentTimeUs)
313+
{
281314
if (isThrottleLow()) {
282315
return FW_LAUNCH_EVENT_THROTTLE_LOW; // go back to FW_LAUNCH_STATE_WAIT_THROTTLE
283316
}
284-
317+
285318
const float swingVelocity = (fabsf(imuMeasuredRotationBF.z) > SWING_LAUNCH_MIN_ROTATION_RATE) ? (imuMeasuredAccelBF.y / imuMeasuredRotationBF.z) : 0;
286319
const bool isForwardAccelerationHigh = (imuMeasuredAccelBF.x > navConfig()->fw.launch_accel_thresh);
287320
const bool isAircraftAlmostLevel = (calculateCosTiltAngle() >= cos_approx(DEGREES_TO_RADIANS(navConfig()->fw.launch_max_angle)));
288321

289322
const bool isBungeeLaunched = isForwardAccelerationHigh && isAircraftAlmostLevel;
290323
const bool isSwingLaunched = (swingVelocity > navConfig()->fw.launch_velocity_thresh) && (imuMeasuredAccelBF.x > 0);
291324

292-
applyThrottleIdle();
325+
applyThrottleIdleLogic();
293326

294327
if (isBungeeLaunched || isSwingLaunched) {
295328
if (currentStateElapsedMs(currentTimeUs) > navConfig()->fw.launch_time_thresh) {
@@ -302,28 +335,32 @@ static fixedWingLaunchEvent_t fwLaunchState_FW_LAUNCH_STATE_WAIT_DETECTION(timeU
302335
return FW_LAUNCH_EVENT_NONE;
303336
}
304337

305-
static fixedWingLaunchEvent_t fwLaunchState_FW_LAUNCH_STATE_DETECTED(timeUs_t currentTimeUs) {
338+
static fixedWingLaunchEvent_t fwLaunchState_FW_LAUNCH_STATE_DETECTED(timeUs_t currentTimeUs)
339+
{
306340
UNUSED(currentTimeUs);
307341
// waiting for the navigation to move it to next step FW_LAUNCH_STATE_MOTOR_DELAY
308-
applyThrottleIdle();
342+
applyThrottleIdleLogic();
309343

310344
return FW_LAUNCH_EVENT_NONE;
311345
}
312346

313-
static fixedWingLaunchEvent_t fwLaunchState_FW_LAUNCH_STATE_MOTOR_DELAY(timeUs_t currentTimeUs) {
314-
applyThrottleIdle();
347+
static fixedWingLaunchEvent_t fwLaunchState_FW_LAUNCH_STATE_MOTOR_DELAY(timeUs_t currentTimeUs)
348+
{
349+
applyThrottleIdleLogic();
315350

316351
if (areSticksMoved(0, currentTimeUs)) {
317352
return FW_LAUNCH_EVENT_ABORT; // jump to FW_LAUNCH_STATE_IDLE
318353
}
354+
319355
if (currentStateElapsedMs(currentTimeUs) > navConfig()->fw.launch_motor_timer) {
320356
return FW_LAUNCH_EVENT_SUCCESS;
321357
}
322358

323359
return FW_LAUNCH_EVENT_NONE;
324360
}
325361

326-
static fixedWingLaunchEvent_t fwLaunchState_FW_LAUNCH_STATE_MOTOR_SPINUP(timeUs_t currentTimeUs) {
362+
static fixedWingLaunchEvent_t fwLaunchState_FW_LAUNCH_STATE_MOTOR_SPINUP(timeUs_t currentTimeUs)
363+
{
327364
if (areSticksMoved(navConfig()->fw.launch_motor_timer, currentTimeUs)) {
328365
return FW_LAUNCH_EVENT_ABORT; // jump to FW_LAUNCH_STATE_IDLE
329366
}
@@ -335,31 +372,40 @@ static fixedWingLaunchEvent_t fwLaunchState_FW_LAUNCH_STATE_MOTOR_SPINUP(timeUs_
335372
if (elapsedTimeMs > motorSpinUpMs) {
336373
rcCommand[THROTTLE] = launchThrottle;
337374
return FW_LAUNCH_EVENT_SUCCESS;
338-
} else {
375+
}
376+
else {
339377
const uint16_t minIdleThrottle = MAX(getThrottleIdleValue(), navConfig()->fw.launch_idle_throttle);
340378
rcCommand[THROTTLE] = scaleRangef(elapsedTimeMs, 0.0f, motorSpinUpMs, minIdleThrottle, launchThrottle);
341379
}
342380

343381
return FW_LAUNCH_EVENT_NONE;
344382
}
345383

346-
static fixedWingLaunchEvent_t fwLaunchState_FW_LAUNCH_STATE_IN_PROGRESS(timeUs_t currentTimeUs) {
384+
static fixedWingLaunchEvent_t fwLaunchState_FW_LAUNCH_STATE_IN_PROGRESS(timeUs_t currentTimeUs)
385+
{
347386
rcCommand[THROTTLE] = navConfig()->fw.launch_throttle;
348387

388+
if (isLaunchMaxAltitudeReached()) {
389+
return FW_LAUNCH_EVENT_SUCCESS; // cancel the launch and do the FW_LAUNCH_STATE_FINISH state
390+
}
391+
349392
if (areSticksMoved(navConfig()->fw.launch_motor_timer + navConfig()->fw.launch_motor_spinup_time, currentTimeUs)) {
350393
return FW_LAUNCH_EVENT_ABORT; // cancel the launch and do the FW_LAUNCH_STATE_IDLE state
351394
}
395+
352396
if (isLaunchMaxAltitudeReached()) {
353397
return FW_LAUNCH_EVENT_SUCCESS; // cancel the launch and do the FW_LAUNCH_STATE_FINISH state
354398
}
399+
355400
if (currentStateElapsedMs(currentTimeUs) > navConfig()->fw.launch_timeout) {
356401
return FW_LAUNCH_EVENT_SUCCESS; // launch timeout. go to FW_LAUNCH_STATE_FINISH
357402
}
358403

359404
return FW_LAUNCH_EVENT_NONE;
360405
}
361406

362-
static fixedWingLaunchEvent_t fwLaunchState_FW_LAUNCH_STATE_FINISH(timeUs_t currentTimeUs) {
407+
static fixedWingLaunchEvent_t fwLaunchState_FW_LAUNCH_STATE_FINISH(timeUs_t currentTimeUs)
408+
{
363409
const timeMs_t elapsedTimeMs = currentStateElapsedMs(currentTimeUs);
364410
const timeMs_t endTimeMs = navConfig()->fw.launch_end_time;
365411

@@ -368,7 +414,8 @@ static fixedWingLaunchEvent_t fwLaunchState_FW_LAUNCH_STATE_FINISH(timeUs_t curr
368414
}
369415
if (elapsedTimeMs > endTimeMs) {
370416
return FW_LAUNCH_EVENT_SUCCESS;
371-
} else {
417+
}
418+
else {
372419
// make a smooth transition from the launch state to the current state for throttle and the pitch angle
373420
rcCommand[THROTTLE] = scaleRangef(elapsedTimeMs, 0.0f, endTimeMs, navConfig()->fw.launch_throttle, rcCommand[THROTTLE]);
374421
fwLaunch.pitchAngle = scaleRangef(elapsedTimeMs, 0.0f, endTimeMs, navConfig()->fw.launch_climb_angle, rcCommand[PITCH]);
@@ -379,9 +426,10 @@ static fixedWingLaunchEvent_t fwLaunchState_FW_LAUNCH_STATE_FINISH(timeUs_t curr
379426

380427
// Public methods ---------------------------------------------------------------
381428

382-
void applyFixedWingLaunchController(timeUs_t currentTimeUs) {
429+
void applyFixedWingLaunchController(timeUs_t currentTimeUs)
430+
{
383431
// Called at PID rate
384-
432+
385433
// process the current state, set the next state or exit if FW_LAUNCH_EVENT_NONE
386434
while (launchStateMachine[fwLaunch.currentState].onEntry) {
387435
fixedWingLaunchEvent_t newEvent = launchStateMachine[fwLaunch.currentState].onEntry(currentTimeUs);
@@ -397,41 +445,52 @@ void applyFixedWingLaunchController(timeUs_t currentTimeUs) {
397445
// Control beeper
398446
if (fwLaunch.currentState == FW_LAUNCH_STATE_WAIT_THROTTLE) {
399447
beeper(BEEPER_LAUNCH_MODE_LOW_THROTTLE);
400-
} else {
448+
}
449+
else {
401450
beeper(BEEPER_LAUNCH_MODE_ENABLED);
402451
}
403452
}
404453

405-
void resetFixedWingLaunchController(timeUs_t currentTimeUs) {
454+
void resetFixedWingLaunchController(timeUs_t currentTimeUs)
455+
{
406456
setCurrentState(FW_LAUNCH_STATE_WAIT_THROTTLE, currentTimeUs);
407457
}
408458

409-
bool isFixedWingLaunchDetected(void) {
459+
bool isFixedWingLaunchDetected(void)
460+
{
410461
return fwLaunch.currentState == FW_LAUNCH_STATE_DETECTED;
411462
}
412463

413-
void enableFixedWingLaunchController(timeUs_t currentTimeUs) {
464+
void enableFixedWingLaunchController(timeUs_t currentTimeUs)
465+
{
414466
setCurrentState(FW_LAUNCH_STATE_MOTOR_DELAY, currentTimeUs);
415467
}
416468

417-
bool isFixedWingLaunchFinishedOrAborted(void) {
469+
bool isFixedWingLaunchFinishedOrAborted(void)
470+
{
418471
return fwLaunch.currentState == FW_LAUNCH_STATE_IDLE;
419472
}
420473

421-
void abortFixedWingLaunch(void) {
474+
void abortFixedWingLaunch(void)
475+
{
422476
setCurrentState(FW_LAUNCH_STATE_IDLE, 0);
423477
}
424478

425-
const char * fixedWingLaunchStateMessage(void) {
479+
const char * fixedWingLaunchStateMessage(void)
480+
{
426481
switch (launchStateMachine[fwLaunch.currentState].messageType) {
427482
case FW_LAUNCH_MESSAGE_TYPE_WAIT_THROTTLE:
428483
return FW_LAUNCH_MESSAGE_TEXT_WAIT_THROTTLE;
484+
429485
case FW_LAUNCH_MESSAGE_TYPE_WAIT_DETECTION:
430486
return FW_LAUNCH_MESSAGE_TEXT_WAIT_DETECTION;
487+
431488
case FW_LAUNCH_MESSAGE_TYPE_IN_PROGRESS:
432489
return FW_LAUNCH_MESSAGE_TEXT_IN_PROGRESS;
490+
433491
case FW_LAUNCH_MESSAGE_TYPE_FINISHING:
434492
return FW_LAUNCH_MESSAGE_TEXT_FINISHING;
493+
435494
default:
436495
return NULL;
437496
}

0 commit comments

Comments
 (0)