mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-10-16 07:23:33 +08:00
Merge branch master into dataman_state_nav_rewrite
This commit is contained in:
@@ -128,6 +128,7 @@ extern struct system_load_s system_load;
|
||||
#define FAILSAFE_DEFAULT_TIMEOUT (3 * 1000 * 1000) /**< hysteresis time - the failsafe will trigger after 3 seconds in this state */
|
||||
#define RC_TIMEOUT 500000
|
||||
#define DL_TIMEOUT 5 * 1000* 1000
|
||||
#define OFFBOARD_TIMEOUT 500000
|
||||
#define DIFFPRESS_TIMEOUT 2000000
|
||||
|
||||
#define PRINT_INTERVAL 5000000
|
||||
@@ -168,6 +169,7 @@ static struct vehicle_status_s status;
|
||||
static struct actuator_armed_s armed;
|
||||
static struct safety_s safety;
|
||||
static struct vehicle_control_mode_s control_mode;
|
||||
static struct offboard_control_setpoint_s sp_offboard;
|
||||
|
||||
/* tasks waiting for low prio thread */
|
||||
typedef enum {
|
||||
@@ -441,6 +443,10 @@ bool handle_command(struct vehicle_status_s *status, const struct safety_s *safe
|
||||
} else if (custom_main_mode == PX4_CUSTOM_MAIN_MODE_ACRO) {
|
||||
/* ACRO */
|
||||
main_ret = main_state_transition(status, MAIN_STATE_ACRO);
|
||||
|
||||
} else if (custom_main_mode == PX4_CUSTOM_MAIN_MODE_OFFBOARD) {
|
||||
/* OFFBOARD */
|
||||
main_ret = main_state_transition(status, MAIN_STATE_OFFBOARD);
|
||||
}
|
||||
|
||||
} else {
|
||||
@@ -644,6 +650,7 @@ int commander_thread_main(int argc, char *argv[])
|
||||
main_states_str[MAIN_STATE_AUTO_LOITER] = "AUTO_LOITER";
|
||||
main_states_str[MAIN_STATE_AUTO_RTL] = "AUTO_RTL";
|
||||
main_states_str[MAIN_STATE_ACRO] = "ACRO";
|
||||
main_states_str[MAIN_STATE_OFFBOARD] = "OFFBOARD";
|
||||
|
||||
const char *arming_states_str[ARMING_STATE_MAX];
|
||||
arming_states_str[ARMING_STATE_INIT] = "INIT";
|
||||
@@ -666,6 +673,7 @@ int commander_thread_main(int argc, char *argv[])
|
||||
nav_states_str[NAVIGATION_STATE_LAND] = "LAND";
|
||||
nav_states_str[NAVIGATION_STATE_DESCEND] = "DESCEND";
|
||||
nav_states_str[NAVIGATION_STATE_TERMINATION] = "TERMINATION";
|
||||
nav_states_str[NAVIGATION_STATE_OFFBOARD] = "OFFBOARD";
|
||||
|
||||
/* pthread for slow low prio thread */
|
||||
pthread_t commander_low_prio_thread;
|
||||
@@ -817,7 +825,6 @@ int commander_thread_main(int argc, char *argv[])
|
||||
|
||||
/* Subscribe to offboard control data */
|
||||
int sp_offboard_sub = orb_subscribe(ORB_ID(offboard_control_setpoint));
|
||||
struct offboard_control_setpoint_s sp_offboard;
|
||||
memset(&sp_offboard, 0, sizeof(sp_offboard));
|
||||
|
||||
/* Subscribe to telemetry status topics */
|
||||
@@ -979,6 +986,19 @@ int commander_thread_main(int argc, char *argv[])
|
||||
orb_copy(ORB_ID(offboard_control_setpoint), sp_offboard_sub, &sp_offboard);
|
||||
}
|
||||
|
||||
if (sp_offboard.timestamp != 0 &&
|
||||
sp_offboard.timestamp + OFFBOARD_TIMEOUT > hrt_absolute_time()) {
|
||||
if (status.offboard_control_signal_lost) {
|
||||
status.offboard_control_signal_lost = false;
|
||||
status_changed = true;
|
||||
}
|
||||
} else {
|
||||
if (!status.offboard_control_signal_lost) {
|
||||
status.offboard_control_signal_lost = true;
|
||||
status_changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < TELEMETRY_STATUS_ORB_ID_NUM; i++) {
|
||||
orb_check(telemetry_subs[i], &updated);
|
||||
|
||||
@@ -1696,6 +1716,18 @@ set_main_state_rc(struct vehicle_status_s *status, struct manual_control_setpoin
|
||||
/* set main state according to RC switches */
|
||||
transition_result_t res = TRANSITION_DENIED;
|
||||
|
||||
/* offboard switch overrides main switch */
|
||||
if (sp_man->offboard_switch == SWITCH_POS_ON) {
|
||||
res = main_state_transition(status, MAIN_STATE_OFFBOARD);
|
||||
if (res == TRANSITION_DENIED) {
|
||||
print_reject_mode(status, "OFFBOARD");
|
||||
|
||||
} else {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
/* offboard switched off or denied, check main mode switch */
|
||||
switch (sp_man->mode_switch) {
|
||||
case SWITCH_POS_NONE:
|
||||
res = TRANSITION_NOT_CHANGED;
|
||||
@@ -1815,6 +1847,7 @@ set_control_mode()
|
||||
/* TODO: check this */
|
||||
control_mode.flag_external_manual_override_ok = !status.is_rotary_wing;
|
||||
control_mode.flag_system_hil_enabled = status.hil_state == HIL_STATE_ON;
|
||||
control_mode.flag_control_offboard_enabled = false;
|
||||
|
||||
switch (status.nav_state) {
|
||||
case NAVIGATION_STATE_MANUAL:
|
||||
@@ -1853,6 +1886,54 @@ set_control_mode()
|
||||
control_mode.flag_control_termination_enabled = false;
|
||||
break;
|
||||
|
||||
case NAVIGATION_STATE_OFFBOARD:
|
||||
control_mode.flag_control_manual_enabled = false;
|
||||
control_mode.flag_control_auto_enabled = false;
|
||||
control_mode.flag_control_offboard_enabled = true;
|
||||
|
||||
switch (sp_offboard.mode) {
|
||||
case OFFBOARD_CONTROL_MODE_DIRECT_RATES:
|
||||
control_mode.flag_control_rates_enabled = true;
|
||||
control_mode.flag_control_attitude_enabled = false;
|
||||
control_mode.flag_control_altitude_enabled = false;
|
||||
control_mode.flag_control_climb_rate_enabled = false;
|
||||
control_mode.flag_control_position_enabled = false;
|
||||
control_mode.flag_control_velocity_enabled = false;
|
||||
break;
|
||||
case OFFBOARD_CONTROL_MODE_DIRECT_ATTITUDE:
|
||||
control_mode.flag_control_rates_enabled = true;
|
||||
control_mode.flag_control_attitude_enabled = true;
|
||||
control_mode.flag_control_altitude_enabled = false;
|
||||
control_mode.flag_control_climb_rate_enabled = false;
|
||||
control_mode.flag_control_position_enabled = false;
|
||||
control_mode.flag_control_velocity_enabled = false;
|
||||
break;
|
||||
case OFFBOARD_CONTROL_MODE_DIRECT_VELOCITY:
|
||||
control_mode.flag_control_rates_enabled = true;
|
||||
control_mode.flag_control_attitude_enabled = true;
|
||||
control_mode.flag_control_altitude_enabled = true; /* XXX: hack for now */
|
||||
control_mode.flag_control_climb_rate_enabled = true;
|
||||
control_mode.flag_control_position_enabled = true; /* XXX: hack for now */
|
||||
control_mode.flag_control_velocity_enabled = true;
|
||||
break;
|
||||
case OFFBOARD_CONTROL_MODE_DIRECT_POSITION:
|
||||
control_mode.flag_control_rates_enabled = true;
|
||||
control_mode.flag_control_attitude_enabled = true;
|
||||
control_mode.flag_control_altitude_enabled = true;
|
||||
control_mode.flag_control_climb_rate_enabled = true;
|
||||
control_mode.flag_control_position_enabled = true;
|
||||
control_mode.flag_control_velocity_enabled = true;
|
||||
break;
|
||||
default:
|
||||
control_mode.flag_control_rates_enabled = false;
|
||||
control_mode.flag_control_attitude_enabled = false;
|
||||
control_mode.flag_control_altitude_enabled = false;
|
||||
control_mode.flag_control_climb_rate_enabled = false;
|
||||
control_mode.flag_control_position_enabled = false;
|
||||
control_mode.flag_control_velocity_enabled = false;
|
||||
}
|
||||
break;
|
||||
|
||||
case NAVIGATION_STATE_POSCTL:
|
||||
control_mode.flag_control_manual_enabled = true;
|
||||
control_mode.flag_control_auto_enabled = false;
|
||||
|
||||
@@ -183,12 +183,12 @@ bool StateMachineHelperTest::armingStateTransitionTest(void)
|
||||
|
||||
// Safety switch arming tests
|
||||
|
||||
{ "transition: init to standby, no safety switch",
|
||||
{ "transition: standby to armed, no safety switch",
|
||||
{ ARMING_STATE_STANDBY, ATT_DISARMED, ATT_READY_TO_ARM }, HIL_STATE_OFF, ATT_SENSORS_INITIALIZED, ATT_SAFETY_NOT_AVAILABLE, ATT_SAFETY_OFF,
|
||||
ARMING_STATE_ARMED,
|
||||
{ ARMING_STATE_ARMED, ATT_ARMED, ATT_READY_TO_ARM }, TRANSITION_CHANGED },
|
||||
|
||||
{ "transition: init to standby, safety switch off",
|
||||
{ "transition: standby to armed, safety switch off",
|
||||
{ ARMING_STATE_STANDBY, ATT_DISARMED, ATT_READY_TO_ARM }, HIL_STATE_OFF, ATT_SENSORS_INITIALIZED, ATT_SAFETY_AVAILABLE, ATT_SAFETY_OFF,
|
||||
ARMING_STATE_ARMED,
|
||||
{ ARMING_STATE_ARMED, ATT_ARMED, ATT_READY_TO_ARM }, TRANSITION_CHANGED },
|
||||
@@ -286,7 +286,7 @@ bool StateMachineHelperTest::armingStateTransitionTest(void)
|
||||
armed.ready_to_arm = test->current_state.ready_to_arm;
|
||||
|
||||
// Attempt transition
|
||||
transition_result_t result = arming_state_transition(&status, &safety, test->requested_state, &armed);
|
||||
transition_result_t result = arming_state_transition(&status, &safety, test->requested_state, &armed, 0 /* no mavlink_fd */);
|
||||
|
||||
// Validate result of transition
|
||||
ut_assert(test->assertMsg, test->expected_transition_result == result);
|
||||
@@ -300,70 +300,151 @@ bool StateMachineHelperTest::armingStateTransitionTest(void)
|
||||
|
||||
bool StateMachineHelperTest::mainStateTransitionTest(void)
|
||||
{
|
||||
struct vehicle_status_s current_state;
|
||||
main_state_t new_main_state;
|
||||
// This structure represent a single test case for testing Main State transitions.
|
||||
typedef struct {
|
||||
const char* assertMsg; // Text to show when test case fails
|
||||
uint8_t condition_bits; // Bits for various condition_* values
|
||||
main_state_t from_state; // State prior to transition request
|
||||
main_state_t to_state; // State to transition to
|
||||
transition_result_t expected_transition_result; // Expected result from main_state_transition call
|
||||
} MainTransitionTest_t;
|
||||
|
||||
// Identical states.
|
||||
current_state.main_state = MAIN_STATE_MANUAL;
|
||||
new_main_state = MAIN_STATE_MANUAL;
|
||||
ut_assert("no transition: identical states",
|
||||
TRANSITION_NOT_CHANGED == main_state_transition(¤t_state, new_main_state));
|
||||
ut_assert("current state: manual", MAIN_STATE_MANUAL == current_state.main_state);
|
||||
// Bits for condition_bits
|
||||
#define MTT_ALL_NOT_VALID 0
|
||||
#define MTT_ROTARY_WING 1 << 0
|
||||
#define MTT_LOC_ALT_VALID 1 << 1
|
||||
#define MTT_LOC_POS_VALID 1 << 2
|
||||
#define MTT_HOME_POS_VALID 1 << 3
|
||||
#define MTT_GLOBAL_POS_VALID 1 << 4
|
||||
|
||||
static const MainTransitionTest_t rgMainTransitionTests[] = {
|
||||
|
||||
// TRANSITION_NOT_CHANGED tests
|
||||
|
||||
{ "no transition: identical states",
|
||||
MTT_ALL_NOT_VALID,
|
||||
MAIN_STATE_MANUAL, MAIN_STATE_MANUAL, TRANSITION_NOT_CHANGED },
|
||||
|
||||
// TRANSITION_CHANGED tests
|
||||
|
||||
{ "transition: MANUAL to ACRO",
|
||||
MTT_ALL_NOT_VALID,
|
||||
MAIN_STATE_MANUAL, MAIN_STATE_ACRO, TRANSITION_CHANGED },
|
||||
|
||||
// AUTO to MANUAL.
|
||||
current_state.main_state = MAIN_STATE_AUTO;
|
||||
new_main_state = MAIN_STATE_MANUAL;
|
||||
ut_assert("transition changed: auto to manual",
|
||||
TRANSITION_CHANGED == main_state_transition(¤t_state, new_main_state));
|
||||
ut_assert("new state: manual", MAIN_STATE_MANUAL == current_state.main_state);
|
||||
{ "transition: ACRO to MANUAL",
|
||||
MTT_ALL_NOT_VALID,
|
||||
MAIN_STATE_ACRO, MAIN_STATE_MANUAL, TRANSITION_CHANGED },
|
||||
|
||||
// MANUAL to ALTCTRL.
|
||||
current_state.main_state = MAIN_STATE_MANUAL;
|
||||
current_state.condition_local_altitude_valid = true;
|
||||
new_main_state = MAIN_STATE_ALTCTL;
|
||||
ut_assert("tranisition: manual to altctrl",
|
||||
TRANSITION_CHANGED == main_state_transition(¤t_state, new_main_state));
|
||||
ut_assert("new state: altctrl", MAIN_STATE_ALTCTL == current_state.main_state);
|
||||
{ "transition: MANUAL to AUTO_MISSION - global position valid",
|
||||
MTT_GLOBAL_POS_VALID,
|
||||
MAIN_STATE_MANUAL, MAIN_STATE_AUTO_MISSION, TRANSITION_CHANGED },
|
||||
|
||||
// MANUAL to ALTCTRL, invalid local altitude.
|
||||
current_state.main_state = MAIN_STATE_MANUAL;
|
||||
current_state.condition_local_altitude_valid = false;
|
||||
new_main_state = MAIN_STATE_ALTCTL;
|
||||
ut_assert("no transition: invalid local altitude",
|
||||
TRANSITION_DENIED == main_state_transition(¤t_state, new_main_state));
|
||||
ut_assert("current state: manual", MAIN_STATE_MANUAL == current_state.main_state);
|
||||
{ "transition: AUTO_MISSION to MANUAL - global position valid",
|
||||
MTT_GLOBAL_POS_VALID,
|
||||
MAIN_STATE_AUTO_MISSION, MAIN_STATE_MANUAL, TRANSITION_CHANGED },
|
||||
|
||||
// MANUAL to POSCTRL.
|
||||
current_state.main_state = MAIN_STATE_MANUAL;
|
||||
current_state.condition_local_position_valid = true;
|
||||
new_main_state = MAIN_STATE_POSCTL;
|
||||
ut_assert("transition: manual to posctrl",
|
||||
TRANSITION_CHANGED == main_state_transition(¤t_state, new_main_state));
|
||||
ut_assert("current state: posctrl", MAIN_STATE_POSCTL == current_state.main_state);
|
||||
{ "transition: MANUAL to AUTO_LOITER - global position valid",
|
||||
MTT_GLOBAL_POS_VALID,
|
||||
MAIN_STATE_MANUAL, MAIN_STATE_AUTO_LOITER, TRANSITION_CHANGED },
|
||||
|
||||
// MANUAL to POSCTRL, invalid local position.
|
||||
current_state.main_state = MAIN_STATE_MANUAL;
|
||||
current_state.condition_local_position_valid = false;
|
||||
new_main_state = MAIN_STATE_POSCTL;
|
||||
ut_assert("no transition: invalid position",
|
||||
TRANSITION_DENIED == main_state_transition(¤t_state, new_main_state));
|
||||
ut_assert("current state: manual", MAIN_STATE_MANUAL == current_state.main_state);
|
||||
{ "transition: AUTO_LOITER to MANUAL - global position valid",
|
||||
MTT_GLOBAL_POS_VALID,
|
||||
MAIN_STATE_AUTO_LOITER, MAIN_STATE_MANUAL, TRANSITION_CHANGED },
|
||||
|
||||
// MANUAL to AUTO.
|
||||
current_state.main_state = MAIN_STATE_MANUAL;
|
||||
current_state.condition_global_position_valid = true;
|
||||
new_main_state = MAIN_STATE_AUTO;
|
||||
ut_assert("transition: manual to auto",
|
||||
TRANSITION_CHANGED == main_state_transition(¤t_state, new_main_state));
|
||||
ut_assert("current state: auto", MAIN_STATE_AUTO == current_state.main_state);
|
||||
{ "transition: MANUAL to AUTO_RTL - global position valid, home position valid",
|
||||
MTT_GLOBAL_POS_VALID | MTT_HOME_POS_VALID,
|
||||
MAIN_STATE_MANUAL, MAIN_STATE_AUTO_RTL, TRANSITION_CHANGED },
|
||||
|
||||
{ "transition: AUTO_RTL to MANUAL - global position valid, home position valid",
|
||||
MTT_GLOBAL_POS_VALID | MTT_HOME_POS_VALID,
|
||||
MAIN_STATE_AUTO_RTL, MAIN_STATE_MANUAL, TRANSITION_CHANGED },
|
||||
|
||||
{ "transition: MANUAL to ALTCTL - not rotary",
|
||||
MTT_ALL_NOT_VALID,
|
||||
MAIN_STATE_MANUAL, MAIN_STATE_ALTCTL, TRANSITION_CHANGED },
|
||||
|
||||
{ "transition: MANUAL to ALTCTL - rotary, global position not valid, local altitude valid",
|
||||
MTT_ROTARY_WING | MTT_LOC_ALT_VALID,
|
||||
MAIN_STATE_MANUAL, MAIN_STATE_ALTCTL, TRANSITION_CHANGED },
|
||||
|
||||
{ "transition: MANUAL to ALTCTL - rotary, global position valid, local altitude not valid",
|
||||
MTT_ROTARY_WING | MTT_GLOBAL_POS_VALID,
|
||||
MAIN_STATE_MANUAL, MAIN_STATE_ALTCTL, TRANSITION_CHANGED },
|
||||
|
||||
{ "transition: ALTCTL to MANUAL - local altitude valid",
|
||||
MTT_LOC_ALT_VALID,
|
||||
MAIN_STATE_ALTCTL, MAIN_STATE_MANUAL, TRANSITION_CHANGED },
|
||||
|
||||
{ "transition: MANUAL to POSCTL - local position not valid, global position valid",
|
||||
MTT_GLOBAL_POS_VALID,
|
||||
MAIN_STATE_MANUAL, MAIN_STATE_POSCTL, TRANSITION_CHANGED },
|
||||
|
||||
{ "transition: MANUAL to POSCTL - local position valid, global position not valid",
|
||||
MTT_LOC_POS_VALID,
|
||||
MAIN_STATE_MANUAL, MAIN_STATE_POSCTL, TRANSITION_CHANGED },
|
||||
|
||||
{ "transition: POSCTL to MANUAL - local position valid, global position valid",
|
||||
MTT_LOC_POS_VALID,
|
||||
MAIN_STATE_POSCTL, MAIN_STATE_MANUAL, TRANSITION_CHANGED },
|
||||
|
||||
// TRANSITION_DENIED tests
|
||||
|
||||
{ "no transition: MANUAL to AUTO_MISSION - global position not valid",
|
||||
MTT_ALL_NOT_VALID,
|
||||
MAIN_STATE_MANUAL, MAIN_STATE_AUTO_MISSION, TRANSITION_DENIED },
|
||||
|
||||
{ "no transition: MANUAL to AUTO_LOITER - global position not valid",
|
||||
MTT_ALL_NOT_VALID,
|
||||
MAIN_STATE_MANUAL, MAIN_STATE_AUTO_LOITER, TRANSITION_DENIED },
|
||||
|
||||
{ "no transition: MANUAL to AUTO_RTL - global position not valid, home position not valid",
|
||||
MTT_ALL_NOT_VALID,
|
||||
MAIN_STATE_MANUAL, MAIN_STATE_AUTO_RTL, TRANSITION_DENIED },
|
||||
|
||||
{ "no transition: MANUAL to AUTO_RTL - global position not valid, home position valid",
|
||||
MTT_HOME_POS_VALID,
|
||||
MAIN_STATE_MANUAL, MAIN_STATE_AUTO_RTL, TRANSITION_DENIED },
|
||||
|
||||
{ "no transition: MANUAL to AUTO_RTL - global position valid, home position not valid",
|
||||
MTT_GLOBAL_POS_VALID,
|
||||
MAIN_STATE_MANUAL, MAIN_STATE_AUTO_RTL, TRANSITION_DENIED },
|
||||
|
||||
{ "no transition: MANUAL to ALTCTL - rotary, global position not valid, local altitude not valid",
|
||||
MTT_ROTARY_WING,
|
||||
MAIN_STATE_MANUAL, MAIN_STATE_ALTCTL, TRANSITION_DENIED },
|
||||
|
||||
{ "no transition: MANUAL to POSCTL - local position not valid, global position not valid",
|
||||
MTT_ALL_NOT_VALID,
|
||||
MAIN_STATE_MANUAL, MAIN_STATE_POSCTL, TRANSITION_DENIED },
|
||||
};
|
||||
|
||||
size_t cMainTransitionTests = sizeof(rgMainTransitionTests) / sizeof(rgMainTransitionTests[0]);
|
||||
for (size_t i=0; i<cMainTransitionTests; i++) {
|
||||
const MainTransitionTest_t* test = &rgMainTransitionTests[i];
|
||||
|
||||
// Setup initial machine state
|
||||
struct vehicle_status_s current_state;
|
||||
current_state.main_state = test->from_state;
|
||||
current_state.is_rotary_wing = test->condition_bits & MTT_ROTARY_WING;
|
||||
current_state.condition_local_altitude_valid = test->condition_bits & MTT_LOC_ALT_VALID;
|
||||
current_state.condition_local_position_valid = test->condition_bits & MTT_LOC_POS_VALID;
|
||||
current_state.condition_home_position_valid = test->condition_bits & MTT_HOME_POS_VALID;
|
||||
current_state.condition_global_position_valid = test->condition_bits & MTT_GLOBAL_POS_VALID;
|
||||
|
||||
// Attempt transition
|
||||
transition_result_t result = main_state_transition(¤t_state, test->to_state);
|
||||
|
||||
// Validate result of transition
|
||||
ut_assert(test->assertMsg, test->expected_transition_result == result);
|
||||
if (test->expected_transition_result == result) {
|
||||
if (test->expected_transition_result == TRANSITION_CHANGED) {
|
||||
ut_assert(test->assertMsg, test->to_state == current_state.main_state);
|
||||
} else {
|
||||
ut_assert(test->assertMsg, test->from_state == current_state.main_state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MANUAL to AUTO, invalid global position.
|
||||
current_state.main_state = MAIN_STATE_MANUAL;
|
||||
current_state.condition_global_position_valid = false;
|
||||
new_main_state = MAIN_STATE_AUTO;
|
||||
ut_assert("no transition: invalid global position",
|
||||
TRANSITION_DENIED == main_state_transition(¤t_state, new_main_state));
|
||||
ut_assert("current state: manual", MAIN_STATE_MANUAL == current_state.main_state);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ enum PX4_CUSTOM_MAIN_MODE {
|
||||
PX4_CUSTOM_MAIN_MODE_POSCTL,
|
||||
PX4_CUSTOM_MAIN_MODE_AUTO,
|
||||
PX4_CUSTOM_MAIN_MODE_ACRO,
|
||||
PX4_CUSTOM_MAIN_MODE_OFFBOARD,
|
||||
};
|
||||
|
||||
enum PX4_CUSTOM_SUB_MODE_AUTO {
|
||||
|
||||
@@ -286,6 +286,15 @@ main_state_transition(struct vehicle_status_s *status, main_state_t new_main_sta
|
||||
}
|
||||
break;
|
||||
|
||||
case MAIN_STATE_OFFBOARD:
|
||||
|
||||
/* need offboard signal */
|
||||
if (!status->offboard_control_signal_lost) {
|
||||
ret = TRANSITION_CHANGED;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case MAIN_STATE_MAX:
|
||||
default:
|
||||
break;
|
||||
@@ -584,6 +593,25 @@ bool set_nav_state(struct vehicle_status_s *status, const bool data_link_loss_en
|
||||
}
|
||||
break;
|
||||
|
||||
case MAIN_STATE_OFFBOARD:
|
||||
/* require offboard control, otherwise stay where you are */
|
||||
if (status->offboard_control_signal_lost && !status->rc_signal_lost) {
|
||||
status->failsafe = true;
|
||||
|
||||
status->nav_state = NAVIGATION_STATE_POSCTL;
|
||||
} else if (status->offboard_control_signal_lost && status->rc_signal_lost) {
|
||||
status->failsafe = true;
|
||||
|
||||
if (status->condition_local_position_valid) {
|
||||
status->nav_state = NAVIGATION_STATE_LAND;
|
||||
} else if (status->condition_local_altitude_valid) {
|
||||
status->nav_state = NAVIGATION_STATE_DESCEND;
|
||||
} else {
|
||||
status->nav_state = NAVIGATION_STATE_TERMINATION;
|
||||
}
|
||||
} else {
|
||||
status->nav_state = NAVIGATION_STATE_OFFBOARD;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user