18 changes: 9 additions & 9 deletions sw/airborne/firmwares/rotorcraft/autopilot_arming_yaw.h
Expand Up @@ -136,13 +136,13 @@ static inline void autopilot_arming_check_motors_on(void)
autopilot_check_motor_status = STATUS_MOTORS_ON;
} else {
autopilot_check_motor_status = STATUS_MOTORS_AUTOMATICALLY_OFF;
autopilot.motors_on = false;
autopilot_arming_motors_on(false);
}
break;
case STATUS_MOTORS_AUTOMATICALLY_OFF: // Motors were disarmed externally
//(possibly due to crash)
//wait extra delay before enabling the normal arming state machine
autopilot.motors_on = false;
autopilot_arming_motors_on(false);
autopilot_motors_on_counter = 0;
if (autopilot_arming_check_valid(YAW_MUST_BE_CENTERED)) {
autopilot_check_motor_status = STATUS_MOTORS_AUTOMATICALLY_OFF_SAFETY_WAIT;
Expand All @@ -157,15 +157,15 @@ static inline void autopilot_arming_check_motors_on(void)
}
break;
case STATUS_MOTORS_OFF:
autopilot.motors_on = false;
autopilot_arming_motors_on(false);
autopilot_motors_on_counter = 0;
autopilot.arming_status = AP_ARMING_STATUS_WAITING;
if (autopilot_arming_check_valid(YAW_MUST_BE_PUSHED)) { // stick pushed
autopilot_check_motor_status = STATUS_M_OFF_STICK_PUSHED;
}
break;
case STATUS_M_OFF_STICK_PUSHED:
autopilot.motors_on = false;
autopilot_arming_motors_on(false);
autopilot_motors_on_counter++;
if (autopilot_motors_on_counter >= MOTOR_ARMING_DELAY) {
autopilot_check_motor_status = STATUS_START_MOTORS;
Expand All @@ -176,7 +176,7 @@ static inline void autopilot_arming_check_motors_on(void)
}
break;
case STATUS_START_MOTORS:
autopilot.motors_on = true;
autopilot_arming_motors_on(true);
autopilot_motors_on_counter = MOTOR_ARMING_DELAY;
autopilot_set_in_flight(false); // stop fc from starting control (integration and yaw) till arm process is complete
if (YAW_STICK_CENTERED()) { // wait until stick released
Expand All @@ -185,14 +185,14 @@ static inline void autopilot_arming_check_motors_on(void)
break;
case STATUS_MOTORS_ON:
autopilot.arming_status = AP_ARMING_STATUS_ARMED;
autopilot.motors_on = true;
autopilot_arming_motors_on(true);
autopilot_motors_on_counter = MOTOR_ARMING_DELAY;
if (THROTTLE_STICK_DOWN() && YAW_STICK_PUSHED()) { // stick pushed
autopilot_check_motor_status = STATUS_M_ON_STICK_PUSHED;
}
break;
case STATUS_M_ON_STICK_PUSHED:
autopilot.motors_on = true;
autopilot_arming_motors_on(true);
autopilot_motors_on_counter--;
if (autopilot_motors_on_counter == 0) {
autopilot_check_motor_status = STATUS_STOP_MOTORS;
Expand All @@ -203,7 +203,7 @@ static inline void autopilot_arming_check_motors_on(void)
}
break;
case STATUS_STOP_MOTORS:
autopilot.motors_on = false;
autopilot_arming_motors_on(false);
autopilot_motors_on_counter = 0;
if (autopilot_arming_check_valid(YAW_MUST_BE_CENTERED)) { // wait till release disarm stick before allowing to re-arm
autopilot_check_motor_status = STATUS_MOTORS_OFF;
Expand All @@ -215,7 +215,7 @@ static inline void autopilot_arming_check_motors_on(void)
} else {
autopilot.arming_status = AP_ARMING_STATUS_KILLED;
if (kill_switch_is_on()) {
autopilot.motors_on = false;
autopilot_arming_motors_on(false);
}
}
}
Expand Down
11 changes: 3 additions & 8 deletions sw/airborne/firmwares/rotorcraft/autopilot_generated.c
Expand Up @@ -88,7 +88,7 @@ void autopilot_generated_set_mode(uint8_t new_autopilot_mode)

void autopilot_generated_set_motors_on(bool motors_on)
{
if (ap_ahrs_is_aligned() && motors_on
if (motors_on
#ifdef AP_MODE_KILL
&& autopilot.mode != AP_MODE_KILL
#endif
Expand All @@ -107,14 +107,9 @@ void autopilot_generated_on_rc_frame(void)
// FIXME what to do here ?

/* an arming sequence is used to start/stop motors.
* only allow arming if ahrs is aligned
*/
if (ap_ahrs_is_aligned()) {
autopilot_arming_check_motors_on();
autopilot.kill_throttle = ! autopilot.motors_on;
} else {
autopilot.arming_status = AP_ARMING_STATUS_AHRS_NOT_ALLIGNED;
}
autopilot_arming_check_motors_on();
autopilot.kill_throttle = ! autopilot.motors_on;

/* if not in FAILSAFE or HOME mode, read RC and set commands accordingly */
// if (autopilot.mode != AP_MODE_FAILSAFE && autopilot.mode != AP_MODE_HOME) {
Expand Down
17 changes: 3 additions & 14 deletions sw/airborne/firmwares/rotorcraft/autopilot_static.c
Expand Up @@ -191,12 +191,6 @@ void autopilot_static_SetModeHandler(float mode)

void autopilot_static_set_mode(uint8_t new_autopilot_mode)
{

/* force startup mode (default is kill) as long as AHRS is not aligned */
if (!ap_ahrs_is_aligned()) {
new_autopilot_mode = MODE_STARTUP;
}

if (new_autopilot_mode != autopilot.mode) {
/* horizontal mode */
switch (new_autopilot_mode) {
Expand Down Expand Up @@ -317,7 +311,7 @@ void autopilot_static_set_mode(uint8_t new_autopilot_mode)

void autopilot_static_set_motors_on(bool motors_on)
{
if (autopilot.mode != AP_MODE_KILL && ap_ahrs_is_aligned() && motors_on) {
if (autopilot.mode != AP_MODE_KILL && motors_on) {
autopilot.motors_on = true;
} else {
autopilot.motors_on = false;
Expand Down Expand Up @@ -362,14 +356,9 @@ void autopilot_static_on_rc_frame(void)
}

/* an arming sequence is used to start/stop motors.
* only allow arming if ahrs is aligned
*/
if (ap_ahrs_is_aligned()) {
autopilot_arming_check_motors_on();
autopilot.kill_throttle = ! autopilot.motors_on;
} else {
autopilot.arming_status = AP_ARMING_STATUS_AHRS_NOT_ALLIGNED;
}
autopilot_arming_check_motors_on();
autopilot.kill_throttle = ! autopilot.motors_on;

/* if not in FAILSAFE or HOME mode, read RC and set commands accordingly */
if (autopilot.mode != AP_MODE_FAILSAFE && autopilot.mode != AP_MODE_HOME) {
Expand Down
14 changes: 0 additions & 14 deletions sw/airborne/firmwares/rotorcraft/autopilot_utils.c
Expand Up @@ -36,20 +36,6 @@
PRINT_CONFIG_VAR(FAILSAFE_DESCENT_SPEED)


// Utility functions
#ifndef AUTOPILOT_DISABLE_AHRS_KILL
bool ap_ahrs_is_aligned(void)
{
return stateIsAttitudeValid();
}
#else
PRINT_CONFIG_MSG("Using AUTOPILOT_DISABLE_AHRS_KILL")
bool ap_ahrs_is_aligned(void)
{
return true;
}
#endif

#if defined RADIO_MODE_2x3

#define THRESHOLD_1d3_PPRZ (MAX_PPRZ / 3)
Expand Down
1 change: 0 additions & 1 deletion sw/airborne/firmwares/rotorcraft/autopilot_utils.h
Expand Up @@ -37,7 +37,6 @@
#define FAILSAFE_DESCENT_SPEED 1.5
#endif

extern bool ap_ahrs_is_aligned(void);
#if defined RADIO_MODE_2x3
extern uint8_t ap_mode_of_3x2way_switch(void);
#else
Expand Down
4 changes: 2 additions & 2 deletions sw/airborne/firmwares/rotorcraft/navigation.h
Expand Up @@ -231,11 +231,11 @@ extern bool nav_detect_ground(void);
/* switching motors on/off */
static inline void NavKillThrottle(void)
{
if (autopilot_get_mode() == AP_MODE_NAV) { autopilot_set_motors_on(FALSE); }
if (autopilot_get_mode() == AP_MODE_NAV) { autopilot_set_motors_on(false); }
}
static inline void NavResurrect(void)
{
if (autopilot_get_mode() == AP_MODE_NAV) { autopilot_set_motors_on(TRUE); }
if (autopilot_get_mode() == AP_MODE_NAV) { autopilot_set_motors_on(true); }
}


Expand Down
2 changes: 1 addition & 1 deletion sw/airborne/firmwares/rover/autopilot_generated.c
Expand Up @@ -84,7 +84,7 @@ void autopilot_generated_set_mode(uint8_t new_autopilot_mode)

void autopilot_generated_set_motors_on(bool motors_on)
{
if (ap_ahrs_is_aligned() && motors_on
if (motors_on
#ifdef AP_MODE_KILL
&& autopilot.mode != AP_MODE_KILL
#endif
Expand Down
15 changes: 0 additions & 15 deletions sw/airborne/firmwares/rover/autopilot_utils.c
Expand Up @@ -34,21 +34,6 @@
/** Display descent speed in failsafe mode if needed */
PRINT_CONFIG_VAR(FAILSAFE_DESCENT_SPEED)


// Utility functions
#ifndef AUTOPILOT_DISABLE_AHRS_KILL
bool ap_ahrs_is_aligned(void)
{
return stateIsAttitudeValid();
}
#else
PRINT_CONFIG_MSG("Using AUTOPILOT_DISABLE_AHRS_KILL")
bool ap_ahrs_is_aligned(void)
{
return true;
}
#endif

#define THRESHOLD_1_PPRZ (MIN_PPRZ / 2)
#define THRESHOLD_2_PPRZ (MAX_PPRZ / 2)

Expand Down
1 change: 0 additions & 1 deletion sw/airborne/firmwares/rover/autopilot_utils.h
Expand Up @@ -31,7 +31,6 @@
#include "std.h"
#include "modules/core/commands.h"

extern bool ap_ahrs_is_aligned(void);
extern uint8_t ap_mode_of_3way_switch(void);

extern void set_rotorcraft_commands(pprz_t *cmd_out, int32_t *cmd_in, bool in_flight, bool motors_on);
Expand Down
4 changes: 2 additions & 2 deletions sw/airborne/firmwares/rover/navigation.h
Expand Up @@ -190,11 +190,11 @@ extern void nav_set_failsafe(void);
/* switching motors on/off */
static inline void NavKillThrottle(void)
{
if (autopilot_get_mode() == AP_MODE_NAV) { autopilot_set_motors_on(FALSE); }
if (autopilot_get_mode() == AP_MODE_NAV) { autopilot_set_motors_on(false); }
}
static inline void NavResurrect(void)
{
if (autopilot_get_mode() == AP_MODE_NAV) { autopilot_set_motors_on(TRUE); }
if (autopilot_get_mode() == AP_MODE_NAV) { autopilot_set_motors_on(true); }
}


Expand Down
171 changes: 171 additions & 0 deletions sw/airborne/modules/checks/preflight_checks.c
@@ -0,0 +1,171 @@
/*
* Copyright (C) 2022 Freek van Tienen <freek.v.tienen@gmail.com>
*
* This file is part of paparazzi
*
* paparazzi is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* paparazzi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with paparazzi; see the file COPYING. If not, see
* <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
*/

#include "preflight_checks.h"
#include "modules/datalink/telemetry.h"
#include <stdio.h>

/** Maximum combined message size for storing the errors */
#ifndef PREFLIGHT_CHECK_MAX_MSGBUF
#define PREFLIGHT_CHECK_MAX_MSGBUF 512
#endif

/** Seperating character for storing the errors */
#ifndef PREFLIGHT_CHECK_SEPERATOR
#define PREFLIGHT_CHECK_SEPERATOR ';'
#endif

/** Only send messages down every xx amount of seconds */
#ifndef PREFLIGHT_CHECK_INFO_TIMEOUT
#define PREFLIGHT_CHECK_INFO_TIMEOUT 5
#endif

static struct preflight_check_t *preflight_head = NULL;
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) {
// Prepend the preflight check
struct preflight_check_t *next = preflight_head;
preflight_head = check;
check->func = func;
check->next = next;
}

/**
* @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) {
static float last_info_time = 0;
char error_msg[PREFLIGHT_CHECK_MAX_MSGBUF];
struct preflight_result_t result = {
.message = error_msg,
.max_len = PREFLIGHT_CHECK_MAX_MSGBUF,
.fail_cnt = 0,
.success_cnt = 0
};

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

// We failed a check
if(result.fail_cnt > 0) {
// Only send every xx amount of seconds
if((get_sys_time_float() - last_info_time) > PREFLIGHT_CHECK_INFO_TIMEOUT) {
// Record the total
int rc = snprintf(result.message, result.max_len, "Preflight fail [%d/%d]", result.fail_cnt, (result.fail_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;
}
}

// Update the time
last_info_time = get_sys_time_float();
}

return false;
}

// Send success down
int rc = snprintf(error_msg, PREFLIGHT_CHECK_MAX_MSGBUF, "Preflight success [%d]", result.success_cnt);
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
*
* @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, ...) {
// Record the error count
result->fail_cnt++;

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

// Add the error
va_list args;
va_start(args, fmt);
int rc = vsnprintf(result->message, result->max_len, fmt, args);
va_end(args);

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

// Add seperator if it fits
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)
result->message[0] = 0;
}
}
}

/**
* @brief Register a preflight success used inside the preflight checking functions
*
* @param result
* @param __attribute__
* @param ...
*/
void preflight_success(struct preflight_result_t *result, const char *fmt __attribute__((unused)), ...) {
// Record the success count
result->success_cnt++;
}
53 changes: 53 additions & 0 deletions sw/airborne/modules/checks/preflight_checks.h
@@ -0,0 +1,53 @@
/*
* Copyright (C) 2022 Freek van Tienen <freek.v.tienen@gmail.com>
*
* This file is part of paparazzi
*
* paparazzi is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* paparazzi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with paparazzi; see the file COPYING. If not, see
* <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
*/

#ifndef PREFLIGHT_CHECKS_H
#define PREFLIGHT_CHECKS_H

#include "std.h"
#include <stdarg.h>

struct preflight_result_t {
char *message;
uint16_t max_len;
uint16_t fail_cnt;
uint16_t success_cnt;
};

typedef void (*preflight_check_f)(struct preflight_result_t *result);

struct preflight_check_t {
preflight_check_f func;
struct preflight_check_t *next;
};

extern bool preflight_bypass;
extern void preflight_check_register(struct preflight_check_t *check, preflight_check_f func);
extern bool preflight_check(void);
extern void preflight_error(struct preflight_result_t *result, const char *fmt, ...);
extern void preflight_success(struct preflight_result_t *result, const char *fmt, ...);

#endif /* PREFLIGHT_CHECKS_H */
6 changes: 4 additions & 2 deletions sw/airborne/modules/ctrl/ctrl_eff_sched_rot_wing.c
Expand Up @@ -98,14 +98,16 @@ float pprz_angle_step = 9600. / 45.; // CMD per degree
static void send_rotating_wing_state(struct transport_tx *trans, struct link_device *dev)
{
uint8_t state = 0; // Quadrotor
uint16_t adc_pos = 0;
int32_t pprz_cmd = 0;
float angle = eff_sched_var.wing_rotation_rad / M_PI * 180.f;
pprz_msg_send_ROTATING_WING_STATE(trans, dev, AC_ID,
&state,
&state,
&angle,
&rotation_angle_setpoint_deg,
0,
0);
&adc_pos,
&pprz_cmd);
}
#endif

Expand Down
64 changes: 44 additions & 20 deletions sw/airborne/modules/energy/electrical.c
Expand Up @@ -33,6 +33,7 @@
#include "autopilot.h"

#include "generated/airframe.h"
#include "generated/modules.h"
#include BOARD_CONFIG

#ifdef MILLIAMP_PER_PERCENT
Expand All @@ -52,17 +53,39 @@
#define BAT_CHECKER_DELAY 5
#endif

#define ELECTRICAL_PERIODIC_FREQ 10
static float period_to_hour = 1 / 3600.f / ELECTRICAL_PERIODIC_FREQ;

#ifndef MIN_BAT_LEVEL
#define MIN_BAT_LEVEL 3
#endif

#ifndef TAKEOFF_BAT_LEVEL
#define TAKEOFF_BAT_LEVEL LOW_BAT_LEVEL
#endif
PRINT_CONFIG_VAR(TAKEOFF_BAT_LEVEL)

PRINT_CONFIG_VAR(LOW_BAT_LEVEL)
PRINT_CONFIG_VAR(CRITIC_BAT_LEVEL)
PRINT_CONFIG_VAR(MIN_BAT_LEVEL)

#ifndef VoltageOfAdc
#define VoltageOfAdc(adc) DefaultVoltageOfAdc(adc)
#endif
#ifndef MilliAmpereOfAdc
#define MilliAmpereOfAdc(adc) DefaultMilliAmpereOfAdc(adc)
#endif

#ifndef CURRENT_ESTIMATION_NONLINEARITY
#define CURRENT_ESTIMATION_NONLINEARITY 1.2
#endif
PRINT_CONFIG_VAR(CURRENT_ESTIMATION_NONLINEARITY)

#if defined MILLIAMP_AT_FULL_THROTTLE && !defined MILLIAMP_AT_IDLE_THROTTLE
PRINT_CONFIG_MSG("Assuming 0 mA at idle throttle")
#define MILLIAMP_AT_IDLE_THROTTLE 0
#endif

PRINT_CONFIG_VAR(MILLIAMP_AT_IDLE_THROTTLE)

/* Main external structure */
struct Electrical electrical;

#if defined ADC_CHANNEL_VSUPPLY || (defined ADC_CHANNEL_CURRENT && !defined SITL) || defined MILLIAMP_AT_FULL_THROTTLE
Expand All @@ -82,23 +105,19 @@ static struct {
} electrical_priv;
#endif

#ifndef VoltageOfAdc
#define VoltageOfAdc(adc) DefaultVoltageOfAdc(adc)
#endif
#ifndef MilliAmpereOfAdc
#define MilliAmpereOfAdc(adc) DefaultMilliAmpereOfAdc(adc)
#endif
#ifdef PREFLIGHT_CHECKS
/* Preflight checks */
#include "modules/checks/preflight_checks.h"
static struct preflight_check_t electrical_pfc;

#ifndef CURRENT_ESTIMATION_NONLINEARITY
#define CURRENT_ESTIMATION_NONLINEARITY 1.2
#endif

#if defined MILLIAMP_AT_FULL_THROTTLE && !defined MILLIAMP_AT_IDLE_THROTTLE
PRINT_CONFIG_MSG("Assuming 0 mA at idle throttle")
#define MILLIAMP_AT_IDLE_THROTTLE 0
#endif

PRINT_CONFIG_VAR(MILLIAMP_AT_IDLE_THROTTLE)
static void electrical_preflight(struct preflight_result_t *result) {
if(electrical.vsupply < TAKEOFF_BAT_LEVEL) {
preflight_error(result, "Battery level %.2fV below minimum takeoff level %.2fV", electrical.vsupply, TAKEOFF_BAT_LEVEL);
} else {
preflight_success(result, "Battery level %.2fV above takeoff level %.2fV", electrical.vsupply, TAKEOFF_BAT_LEVEL);
}
}
#endif // PREFLIGHT_CHECKS

void electrical_init(void)
{
Expand All @@ -124,9 +143,13 @@ void electrical_init(void)
adc_buf_channel(ADC_CHANNEL_CURRENT2, &electrical_priv.current2_adc_buf, DEFAULT_AV_NB_SAMPLE);
#endif
#elif defined MILLIAMP_AT_FULL_THROTTLE
PRINT_CONFIG_VAR(CURRENT_ESTIMATION_NONLINEARITY)
electrical_priv.nonlin_factor = CURRENT_ESTIMATION_NONLINEARITY;
#endif

/* Register preflight checks */
#if PREFLIGHT_CHECKS
preflight_check_register(&electrical_pfc, electrical_preflight);
#endif
}

void electrical_periodic(void)
Expand Down Expand Up @@ -188,6 +211,7 @@ void electrical_periodic(void)
#endif
#endif /* ADC_CHANNEL_CURRENT */

static const float period_to_hour = 1 / 3600.f / ELECTRICAL_PERIODIC_FREQ;
float consumed_since_last = electrical.current * period_to_hour;

electrical.charge += consumed_since_last;
Expand Down
19 changes: 19 additions & 0 deletions sw/airborne/modules/gps/gps.c
Expand Up @@ -77,6 +77,20 @@ static uint8_t current_gps_id = GpsId(PRIMARY_GPS);

uint8_t multi_gps_mode;

#if PREFLIGHT_CHECKS
/* Preflight checks */
#include "modules/checks/preflight_checks.h"
static struct preflight_check_t gps_pfc;

static void gps_preflight(struct preflight_result_t *result) {
if(!gps_fix_valid()) {
preflight_error(result, "No valid GPS fix");
} else {
preflight_success(result, "GPS fix ok");
}
}
#endif // PREFLIGHT_CHECKS


#if PERIODIC_TELEMETRY
#include "modules/datalink/telemetry.h"
Expand Down Expand Up @@ -353,6 +367,11 @@ void gps_init(void)
register_periodic_telemetry(DefaultPeriodic, PPRZ_MSG_ID_GPS_RXMRTCM, send_gps_rxmrtcm);
#endif

/* Register preflight checks */
#if PREFLIGHT_CHECKS
preflight_check_register(&gps_pfc, gps_preflight);
#endif

// Initializing counter variables to count the number of Rtcm msgs in the input stream(for each msg type)
rtcm_man.Cnt105 = 0;
rtcm_man.Cnt177 = 0;
Expand Down
18 changes: 18 additions & 0 deletions sw/airborne/modules/loggers/sdlog_chibios.c
Expand Up @@ -106,6 +106,20 @@ static enum {
static char chibios_sdlog_filenames[68];
static char NO_FILE_NAME[] = "none";

#if PREFLIGHT_CHECKS
/* Preflight checks */
#include "modules/checks/preflight_checks.h"
static struct preflight_check_t sdlog_pfc;

static void sdlog_preflight(struct preflight_result_t *result) {
if(chibios_sdlog_status != SDLOG_RUNNING) {
preflight_error(result, "SDLogger is not running [%d: %d]", chibios_sdlog_status, sdLogGetStorageStatus());
} else {
preflight_success(result, "SDLogger running");
}
}
#endif // PREFLIGHT_CHECKS

#if PERIODIC_TELEMETRY
#include "modules/datalink/telemetry.h"
static void send_sdlog_status(struct transport_tx *trans, struct link_device *dev)
Expand Down Expand Up @@ -184,6 +198,10 @@ void sdlog_chibios_init(void)
register_periodic_telemetry(DefaultPeriodic, PPRZ_MSG_ID_LOGGER_STATUS, send_sdlog_status);
#endif

#if PREFLIGHT_CHECKS
preflight_check_register(&sdlog_pfc, sdlog_preflight);
#endif

// Start polling on USB
usbStorageStartPolling();

Expand Down
19 changes: 19 additions & 0 deletions sw/airborne/state.c
Expand Up @@ -35,6 +35,20 @@

struct State state;

#if PREFLIGHT_CHECKS && !defined(AUTOPILOT_DISABLE_AHRS_KILL)
/* Preflight checks */
#include "modules/checks/preflight_checks.h"
static struct preflight_check_t state_pfc;

static void state_preflight(struct preflight_result_t *result) {
if(!stateIsAttitudeValid()) {
preflight_error(result, "State attitude is invalid");
} else {
preflight_success(result, "State attitude is valid");
}
}
#endif // PREFLIGHT_CHECKS

/**
* @addtogroup state_interface
* @{
Expand All @@ -54,6 +68,11 @@ void stateInit(void)

/* setting to zero forces recomputation of zone using lla when utm uninitialised*/
state.utm_origin_f.zone = 0;

/* Register preflight checks */
#if PREFLIGHT_CHECKS && !defined(AUTOPILOT_DISABLE_AHRS_KILL)
preflight_check_register(&state_pfc, state_preflight);
#endif
}


Expand Down