Showing with 66 additions and 49 deletions.
  1. +1 −1 conf/settings/fixedwing_basic.xml
  2. +11 −7 sw/airborne/autopilot.c
  3. +1 −1 sw/airborne/autopilot.h
  4. +52 −39 sw/airborne/modules/checks/preflight_checks.c
  5. +1 −1 sw/airborne/modules/checks/preflight_checks.h
2 changes: 1 addition & 1 deletion conf/settings/fixedwing_basic.xml
Expand Up @@ -20,7 +20,7 @@
<dl_settings NAME="mode">
<dl_setting MAX="2" MIN="0" STEP="1" VAR="autopilot.mode" module="autopilot" values="MANUAL|AUTO1|AUTO2|HOME|NOGPS|FAILSAFE"/>
<dl_setting MAX="1" MIN="0" STEP="1" VAR="autopilot.launch"/>
<dl_setting MAX="1" MIN="0" STEP="1" VAR="autopilot.kill_throttle"/>
<dl_setting MAX="1" MIN="0" STEP="1" VAR="autopilot.kill_throttle" module="autopilot" values="Resurrect|Kill" handler="KillThrottle"/>
</dl_settings>

<dl_settings NAME="mcu">
Expand Down
18 changes: 11 additions & 7 deletions sw/airborne/autopilot.c
Expand Up @@ -245,15 +245,17 @@ void autopilot_force_motors_on(bool motors_on)
bool autopilot_set_motors_on(bool motors_on)
{
// Prevent unnessary preflight checks
if(autopilot.motors_on == motors_on)
if (autopilot.motors_on == motors_on) {
return true;
}

#if PREFLIGHT_CHECKS
// When we fail the preflight checks abort
if(motors_on && !preflight_check()) {
if (motors_on && !preflight_check()) {
// Bypass the preflight checks even if they fail but still preform them
if(!preflight_bypass)
if (!preflight_bypass) {
return false;
}
}
#endif
autopilot_force_motors_on(motors_on);
Expand All @@ -266,15 +268,17 @@ bool autopilot_set_motors_on(bool motors_on)
bool autopilot_arming_motors_on(bool motors_on)
{
// Prevent unnessary preflight checks
if(autopilot.motors_on == motors_on)
if (autopilot.motors_on == motors_on) {
return true;

}

#if PREFLIGHT_CHECKS
// When we fail the preflight checks abort
if(motors_on && !preflight_check()) {
if (motors_on && !preflight_check()) {
// Bypass the preflight checks even if they fail but still preform them
if(!preflight_bypass)
if (!preflight_bypass) {
return false;
}
}
#endif
autopilot.motors_on = motors_on;
Expand Down
2 changes: 1 addition & 1 deletion sw/airborne/autopilot.h
Expand Up @@ -125,7 +125,7 @@ extern void autopilot_reset_flight_time(void);
/**
* @brief Force start/stop the motors
* WARNING This will skip he preflight checks
*
*
* @param motors_on Wheter the motors should be forced on/off
*/
extern void autopilot_force_motors_on(bool motors_on);
Expand Down
91 changes: 52 additions & 39 deletions sw/airborne/modules/checks/preflight_checks.c
Expand Up @@ -18,7 +18,7 @@
* <http://www.gnu.org/licenses/>.
*/

/**
/**
* @file "modules/checks/preflight_checks.c"
* @author Freek van Tienen <freek.v.tienen@gmail.com>
* Adds preflight checks for takeoff
Expand Down Expand Up @@ -48,11 +48,12 @@ bool preflight_bypass = FALSE;

/**
* @brief Register a preflight check and add it to the linked list
*
*
* @param check The check to add containing a linked list
* @param func The function to register for the check
*/
void preflight_check_register(struct preflight_check_t *check, preflight_check_f func) {
void preflight_check_register(struct preflight_check_t *check, preflight_check_f func)
{
// Prepend the preflight check
struct preflight_check_t *next = preflight_head;
preflight_head = check;
Expand All @@ -62,11 +63,12 @@ void preflight_check_register(struct preflight_check_t *check, preflight_check_f

/**
* @brief Perform all the preflight checks
*
*
* @return true When all preflight checks are successful
* @return false When one or more preflight checks fail
*/
bool preflight_check(void) {
bool preflight_check(void)
{
static float last_info_time = 0;
char error_msg[PREFLIGHT_CHECK_MAX_MSGBUF];
struct preflight_result_t result = {
Expand All @@ -79,31 +81,35 @@ bool preflight_check(void) {

// Go through all the checks
struct preflight_check_t *check = preflight_head;
while(check != NULL) {
while (check != NULL) {
// Peform the check and register errors
check->func(&result);
check = check->next;
}

// We failed a check or have a warning
if(result.fail_cnt > 0 || result.warning_cnt > 0) {
if (result.fail_cnt > 0 || result.warning_cnt > 0) {
// Only send every xx amount of seconds
if((get_sys_time_float() - last_info_time) > PREFLIGHT_CHECK_INFO_TIMEOUT) {
if ((get_sys_time_float() - last_info_time) > PREFLIGHT_CHECK_INFO_TIMEOUT) {
// Record the total
int rc = 0;
if(result.fail_cnt > 0)
rc = snprintf(result.message, result.max_len, "Preflight fail [fail:%d warn:%d tot:%d]", result.fail_cnt, result.warning_cnt, (result.fail_cnt+result.warning_cnt+result.success_cnt));
else
rc = snprintf(result.message, result.max_len, "Preflight success with warnings [%d/%d]", result.warning_cnt, (result.fail_cnt+result.warning_cnt+result.success_cnt));
if(rc > 0)
if (result.fail_cnt > 0) {
rc = snprintf(result.message, result.max_len, "Preflight fail [fail:%d warn:%d tot:%d]", result.fail_cnt,
result.warning_cnt, (result.fail_cnt + result.warning_cnt + result.success_cnt));
} else {
rc = snprintf(result.message, result.max_len, "Preflight success with warnings [%d/%d]", result.warning_cnt,
(result.fail_cnt + result.warning_cnt + result.success_cnt));
}
if (rc > 0) {
result.max_len -= rc;
}

// Send the errors seperatly
uint8_t last_sendi = 0;
for(uint8_t i = 0; i <= PREFLIGHT_CHECK_MAX_MSGBUF-result.max_len; i++) {
if(error_msg[i] == PREFLIGHT_CHECK_SEPERATOR || i == (PREFLIGHT_CHECK_MAX_MSGBUF-result.max_len)) {
DOWNLINK_SEND_INFO_MSG(DefaultChannel, DefaultDevice, i-last_sendi, &error_msg[last_sendi]);
last_sendi = i+1;
for (uint8_t i = 0; i <= PREFLIGHT_CHECK_MAX_MSGBUF - result.max_len; i++) {
if (error_msg[i] == PREFLIGHT_CHECK_SEPERATOR || i == (PREFLIGHT_CHECK_MAX_MSGBUF - result.max_len)) {
DOWNLINK_SEND_INFO_MSG(DefaultChannel, DefaultDevice, i - last_sendi, &error_msg[last_sendi]);
last_sendi = i + 1;
}
}

Expand All @@ -112,34 +118,37 @@ bool preflight_check(void) {
}

// Only if we fail a check
if(result.fail_cnt > 0)
if (result.fail_cnt > 0) {
return false;
else
} else {
return true;
}
}

// Send success down
int rc = snprintf(error_msg, PREFLIGHT_CHECK_MAX_MSGBUF, "Preflight success [%d]", result.success_cnt);
if(rc > 0)
if (rc > 0) {
DOWNLINK_SEND_INFO_MSG(DefaultChannel, DefaultDevice, rc, error_msg);
}

// Return success if we didn't fail a preflight check
return true;
}

/**
* @brief Register a preflight error used inside the preflight checking functions
*
* @brief Register a preflight error used inside the preflight checking functions
*
* @param result Where the error gets registered
* @param fmt A formatted string describing the error used in a vsnprintf
* @param ... The arguments for the vsnprintf
*/
void preflight_error(struct preflight_result_t *result, const char *fmt, ...) {
void preflight_error(struct preflight_result_t *result, const char *fmt, ...)
{
// Record the error count
result->fail_cnt++;

// No more space in the message
if(result->max_len <= 0) {
if (result->max_len <= 0) {
return;
}

Expand All @@ -150,36 +159,38 @@ void preflight_error(struct preflight_result_t *result, const char *fmt, ...) {
va_end(args);

// Remove the length from the buffer if it was successfull
if(rc > 0) {
if (rc > 0) {
result->max_len -= rc;
result->message += rc;

// Add seperator if it fits
if(result->max_len > 0) {
if (result->max_len > 0) {
result->message[0] = PREFLIGHT_CHECK_SEPERATOR;
result->max_len--;
result->message++;

// Add the '\0' character
if(result->max_len > 0)
if (result->max_len > 0) {
result->message[0] = 0;
}
}
}
}

/**
* @brief Register a preflight error used inside the preflight checking functions
*
* @brief Register a preflight error used inside the preflight checking functions
*
* @param result Where the error gets registered
* @param fmt A formatted string describing the error used in a vsnprintf
* @param ... The arguments for the vsnprintf
*/
void preflight_warning(struct preflight_result_t *result, const char *fmt, ...) {
void preflight_warning(struct preflight_result_t *result, const char *fmt, ...)
{
// Record the warning count
result->warning_cnt++;

// No more space in the message
if(result->max_len <= 0) {
if (result->max_len <= 0) {
return;
}

Expand All @@ -190,31 +201,33 @@ void preflight_warning(struct preflight_result_t *result, const char *fmt, ...)
va_end(args);

// Remove the length from the buffer if it was successfull
if(rc > 0) {
if (rc > 0) {
result->max_len -= rc;
result->message += rc;

// Add seperator if it fits
if(result->max_len > 0) {
if (result->max_len > 0) {
result->message[0] = PREFLIGHT_CHECK_SEPERATOR;
result->max_len--;
result->message++;

// Add the '\0' character
if(result->max_len > 0)
if (result->max_len > 0) {
result->message[0] = 0;
}
}
}
}

/**
* @brief Register a preflight success used inside the preflight checking functions
*
* @param result
* @param __attribute__
* @param ...
*
* @param result
* @param __attribute__
* @param ...
*/
void preflight_success(struct preflight_result_t *result, const char *fmt __attribute__((unused)), ...) {
void preflight_success(struct preflight_result_t *result, const char *fmt __attribute__((unused)), ...)
{
// Record the success count
result->success_cnt++;
}
2 changes: 1 addition & 1 deletion sw/airborne/modules/checks/preflight_checks.h
Expand Up @@ -18,7 +18,7 @@
* <http://www.gnu.org/licenses/>.
*/

/**
/**
* @file "modules/checks/preflight_checks.h"
* @author Freek van Tienen <freek.v.tienen@gmail.com>
* Adds preflight checks for takeoff
Expand Down