1
0
Fork 0
mirror of https://github.com/iNavFlight/inav.git synced 2025-07-15 12:25:17 +03:00

7.1-RC1-Autoland-Fix

This commit is contained in:
Scavanger 2024-03-13 17:01:49 -03:00
parent bc45aa74ff
commit 2fa82a33e7
11 changed files with 87 additions and 51 deletions

View file

@ -105,6 +105,7 @@ typedef enum {
TURTLE_MODE = (1 << 15), TURTLE_MODE = (1 << 15),
SOARING_MODE = (1 << 16), SOARING_MODE = (1 << 16),
ANGLEHOLD_MODE = (1 << 17), ANGLEHOLD_MODE = (1 << 17),
NAV_FW_AUTOLAND = (1 << 18),
} flightModeFlags_e; } flightModeFlags_e;
extern uint32_t flightModeFlags; extern uint32_t flightModeFlags;

View file

@ -239,6 +239,10 @@ static void failsafeActivate(failsafePhase_e newPhase)
ENABLE_FLIGHT_MODE(FAILSAFE_MODE); ENABLE_FLIGHT_MODE(FAILSAFE_MODE);
failsafeState.landingShouldBeFinishedAt = millis() + failsafeConfig()->failsafe_off_delay * MILLIS_PER_TENTH_SECOND; failsafeState.landingShouldBeFinishedAt = millis() + failsafeConfig()->failsafe_off_delay * MILLIS_PER_TENTH_SECOND;
#ifdef USE_FW_AUTOLAND
posControl.fwLandState.landAborted = false;
#endif
failsafeState.events++; failsafeState.events++;
} }

View file

@ -594,7 +594,7 @@ static float computePidLevelTarget(flight_dynamics_index_t axis) {
// Automatically pitch down if the throttle is manually controlled and reduced bellow cruise throttle // Automatically pitch down if the throttle is manually controlled and reduced bellow cruise throttle
#ifdef USE_FW_AUTOLAND #ifdef USE_FW_AUTOLAND
if ((axis == FD_PITCH) && STATE(AIRPLANE) && FLIGHT_MODE(ANGLE_MODE) && !navigationIsControllingThrottle() && !isFwLandInProgess()) { if ((axis == FD_PITCH) && STATE(AIRPLANE) && FLIGHT_MODE(ANGLE_MODE) && !navigationIsControllingThrottle() && !FLIGHT_MODE(NAV_FW_AUTOLAND)) {
#else #else
if ((axis == FD_PITCH) && STATE(AIRPLANE) && FLIGHT_MODE(ANGLE_MODE) && !navigationIsControllingThrottle()) { if ((axis == FD_PITCH) && STATE(AIRPLANE) && FLIGHT_MODE(ANGLE_MODE) && !navigationIsControllingThrottle()) {
#endif #endif

View file

@ -986,7 +986,7 @@ static const char * osdFailsafePhaseMessage(void)
static const char * osdFailsafeInfoMessage(void) static const char * osdFailsafeInfoMessage(void)
{ {
if (failsafeIsReceivingRxData()) { if (failsafeIsReceivingRxData() && !FLIGHT_MODE(NAV_FW_AUTOLAND)) {
// User must move sticks to exit FS mode // User must move sticks to exit FS mode
return OSD_MESSAGE_STR(OSD_MSG_MOVE_EXIT_FS); return OSD_MESSAGE_STR(OSD_MSG_MOVE_EXIT_FS);
} }
@ -2278,7 +2278,7 @@ static bool osdDrawSingleElement(uint8_t item)
{ {
char *p = "ACRO"; char *p = "ACRO";
#ifdef USE_FW_AUTOLAND #ifdef USE_FW_AUTOLAND
if (isFwLandInProgess()) if (FLIGHT_MODE(NAV_FW_AUTOLAND))
p = "LAND"; p = "LAND";
else else
#endif #endif
@ -5151,7 +5151,7 @@ textAttributes_t osdGetSystemMessage(char *buff, size_t buff_size, bool isCenter
if (ARMING_FLAG(ARMED)) { if (ARMING_FLAG(ARMED)) {
#ifdef USE_FW_AUTOLAND #ifdef USE_FW_AUTOLAND
if (FLIGHT_MODE(FAILSAFE_MODE) || FLIGHT_MODE(NAV_RTH_MODE) || FLIGHT_MODE(NAV_WP_MODE) || navigationIsExecutingAnEmergencyLanding() || isFwLandInProgess()) { if (FLIGHT_MODE(FAILSAFE_MODE) || FLIGHT_MODE(NAV_RTH_MODE) || FLIGHT_MODE(NAV_WP_MODE) || navigationIsExecutingAnEmergencyLanding() || FLIGHT_MODE(NAV_FW_AUTOLAND)) {
if (isWaypointMissionRTHActive() && !posControl.fwLandState.landWp) { if (isWaypointMissionRTHActive() && !posControl.fwLandState.landWp) {
#else #else
if (FLIGHT_MODE(FAILSAFE_MODE) || FLIGHT_MODE(NAV_RTH_MODE) || FLIGHT_MODE(NAV_WP_MODE) || navigationIsExecutingAnEmergencyLanding()) { if (FLIGHT_MODE(FAILSAFE_MODE) || FLIGHT_MODE(NAV_RTH_MODE) || FLIGHT_MODE(NAV_WP_MODE) || navigationIsExecutingAnEmergencyLanding()) {
@ -5192,7 +5192,7 @@ textAttributes_t osdGetSystemMessage(char *buff, size_t buff_size, bool isCenter
#ifdef USE_FW_AUTOLAND #ifdef USE_FW_AUTOLAND
if (canFwLandCanceld()) { if (canFwLandCanceld()) {
messages[messageCount++] = OSD_MESSAGE_STR(OSD_MSG_MOVE_STICKS); messages[messageCount++] = OSD_MESSAGE_STR(OSD_MSG_MOVE_STICKS);
} else if (!isFwLandInProgess()) { } else if (!FLIGHT_MODE(NAV_FW_AUTOLAND)) {
#endif #endif
const char *navStateMessage = navigationStateMessage(); const char *navStateMessage = navigationStateMessage();
if (navStateMessage) { if (navStateMessage) {

View file

@ -1059,6 +1059,10 @@ static bool djiFormatMessages(char *buff)
if (FLIGHT_MODE(MANUAL_MODE)) { if (FLIGHT_MODE(MANUAL_MODE)) {
messages[messageCount++] = "(MANUAL)"; messages[messageCount++] = "(MANUAL)";
} }
if (FLIGHT_MODE(NAV_FW_AUTOLAND)) {
messages[messageCount++] = "(LAND)";
}
} }
} }
// Pick one of the available messages. Each message lasts // Pick one of the available messages. Each message lasts

View file

@ -64,6 +64,7 @@
#include "sensors/boardalignment.h" #include "sensors/boardalignment.h"
#include "sensors/battery.h" #include "sensors/battery.h"
#include "sensors/gyro.h" #include "sensors/gyro.h"
#include "sensors/diagnostics.h"
#include "programming/global_variables.h" #include "programming/global_variables.h"
#include "sensors/rangefinder.h" #include "sensors/rangefinder.h"
@ -1045,13 +1046,14 @@ static const navigationFSMStateDescriptor_t navFSM[NAV_STATE_COUNT] = {
} }
}, },
/** Advanced Fixed Wing Autoland **/
#ifdef USE_FW_AUTOLAND #ifdef USE_FW_AUTOLAND
[NAV_STATE_FW_LANDING_CLIMB_TO_LOITER] = { [NAV_STATE_FW_LANDING_CLIMB_TO_LOITER] = {
.persistentId = NAV_PERSISTENT_ID_FW_LANDING_CLIMB_TO_LOITER, .persistentId = NAV_PERSISTENT_ID_FW_LANDING_CLIMB_TO_LOITER,
.onEntry = navOnEnteringState_NAV_STATE_FW_LANDING_CLIMB_TO_LOITER, .onEntry = navOnEnteringState_NAV_STATE_FW_LANDING_CLIMB_TO_LOITER,
.timeoutMs = 10, .timeoutMs = 10,
.stateFlags = NAV_CTL_ALT | NAV_CTL_POS | NAV_CTL_YAW | NAV_REQUIRE_ANGLE | NAV_REQUIRE_MAGHOLD | NAV_REQUIRE_THRTILT | NAV_AUTO_RTH, .stateFlags = NAV_CTL_ALT | NAV_CTL_POS | NAV_CTL_YAW | NAV_REQUIRE_ANGLE | NAV_AUTO_RTH,
.mapToFlightModes = NAV_RTH_MODE | NAV_ALTHOLD_MODE, .mapToFlightModes = NAV_FW_AUTOLAND,
.mwState = MW_NAV_STATE_LAND_IN_PROGRESS, .mwState = MW_NAV_STATE_LAND_IN_PROGRESS,
.mwError = MW_NAV_ERROR_NONE, .mwError = MW_NAV_ERROR_NONE,
.onEvent = { .onEvent = {
@ -1071,8 +1073,8 @@ static const navigationFSMStateDescriptor_t navFSM[NAV_STATE_COUNT] = {
.persistentId = NAV_PERSISTENT_ID_FW_LANDING_LOITER, .persistentId = NAV_PERSISTENT_ID_FW_LANDING_LOITER,
.onEntry = navOnEnteringState_NAV_STATE_FW_LANDING_LOITER, .onEntry = navOnEnteringState_NAV_STATE_FW_LANDING_LOITER,
.timeoutMs = 10, .timeoutMs = 10,
.stateFlags = NAV_CTL_ALT | NAV_CTL_POS | NAV_CTL_YAW | NAV_REQUIRE_ANGLE | NAV_REQUIRE_MAGHOLD | NAV_REQUIRE_THRTILT | NAV_AUTO_RTH, .stateFlags = NAV_CTL_ALT | NAV_CTL_POS | NAV_CTL_YAW | NAV_REQUIRE_ANGLE | NAV_AUTO_RTH,
.mapToFlightModes = NAV_RTH_MODE | NAV_ALTHOLD_MODE, .mapToFlightModes = NAV_FW_AUTOLAND,
.mwState = MW_NAV_STATE_LAND_IN_PROGRESS, .mwState = MW_NAV_STATE_LAND_IN_PROGRESS,
.mwError = MW_NAV_ERROR_NONE, .mwError = MW_NAV_ERROR_NONE,
.onEvent = { .onEvent = {
@ -1092,8 +1094,8 @@ static const navigationFSMStateDescriptor_t navFSM[NAV_STATE_COUNT] = {
.persistentId = NAV_PERSISTENT_ID_FW_LANDING_APPROACH, .persistentId = NAV_PERSISTENT_ID_FW_LANDING_APPROACH,
.onEntry = navOnEnteringState_NAV_STATE_FW_LANDING_APPROACH, .onEntry = navOnEnteringState_NAV_STATE_FW_LANDING_APPROACH,
.timeoutMs = 10, .timeoutMs = 10,
.stateFlags = NAV_CTL_ALT | NAV_CTL_POS | NAV_CTL_YAW | NAV_REQUIRE_ANGLE | NAV_REQUIRE_MAGHOLD | NAV_REQUIRE_THRTILT | NAV_AUTO_WP, .stateFlags = NAV_CTL_ALT | NAV_CTL_POS | NAV_CTL_YAW | NAV_REQUIRE_ANGLE | NAV_AUTO_WP,
.mapToFlightModes = NAV_WP_MODE | NAV_ALTHOLD_MODE, .mapToFlightModes = NAV_FW_AUTOLAND,
.mwState = MW_NAV_STATE_LAND_IN_PROGRESS, .mwState = MW_NAV_STATE_LAND_IN_PROGRESS,
.mwError = MW_NAV_ERROR_NONE, .mwError = MW_NAV_ERROR_NONE,
.onEvent = { .onEvent = {
@ -1114,7 +1116,7 @@ static const navigationFSMStateDescriptor_t navFSM[NAV_STATE_COUNT] = {
.onEntry = navOnEnteringState_NAV_STATE_FW_LANDING_GLIDE, .onEntry = navOnEnteringState_NAV_STATE_FW_LANDING_GLIDE,
.timeoutMs = 10, .timeoutMs = 10,
.stateFlags = NAV_CTL_POS | NAV_CTL_YAW | NAV_REQUIRE_ANGLE | NAV_RC_POS | NAV_RC_YAW, .stateFlags = NAV_CTL_POS | NAV_CTL_YAW | NAV_REQUIRE_ANGLE | NAV_RC_POS | NAV_RC_YAW,
.mapToFlightModes = NAV_COURSE_HOLD_MODE, .mapToFlightModes = NAV_FW_AUTOLAND,
.mwState = MW_NAV_STATE_LAND_IN_PROGRESS, .mwState = MW_NAV_STATE_LAND_IN_PROGRESS,
.mwError = MW_NAV_ERROR_NONE, .mwError = MW_NAV_ERROR_NONE,
.onEvent = { .onEvent = {
@ -1135,7 +1137,7 @@ static const navigationFSMStateDescriptor_t navFSM[NAV_STATE_COUNT] = {
.onEntry = navOnEnteringState_NAV_STATE_FW_LANDING_FLARE, .onEntry = navOnEnteringState_NAV_STATE_FW_LANDING_FLARE,
.timeoutMs = 10, .timeoutMs = 10,
.stateFlags = NAV_CTL_POS | NAV_CTL_YAW | NAV_REQUIRE_ANGLE | NAV_RC_POS | NAV_RC_YAW, .stateFlags = NAV_CTL_POS | NAV_CTL_YAW | NAV_REQUIRE_ANGLE | NAV_RC_POS | NAV_RC_YAW,
.mapToFlightModes = NAV_COURSE_HOLD_MODE, .mapToFlightModes = NAV_FW_AUTOLAND,
.mwState = MW_NAV_STATE_LAND_IN_PROGRESS, .mwState = MW_NAV_STATE_LAND_IN_PROGRESS,
.mwError = MW_NAV_ERROR_NONE, .mwError = MW_NAV_ERROR_NONE,
.onEvent = { .onEvent = {
@ -1148,8 +1150,8 @@ static const navigationFSMStateDescriptor_t navFSM[NAV_STATE_COUNT] = {
.persistentId = NAV_PERSISTENT_ID_FW_LANDING_ABORT, .persistentId = NAV_PERSISTENT_ID_FW_LANDING_ABORT,
.onEntry = navOnEnteringState_NAV_STATE_FW_LANDING_ABORT, .onEntry = navOnEnteringState_NAV_STATE_FW_LANDING_ABORT,
.timeoutMs = 10, .timeoutMs = 10,
.stateFlags = NAV_CTL_ALT | NAV_CTL_POS | NAV_CTL_YAW | NAV_REQUIRE_ANGLE | NAV_REQUIRE_MAGHOLD | NAV_REQUIRE_THRTILT | NAV_AUTO_RTH | NAV_RC_POS | NAV_RC_YAW, .stateFlags = NAV_CTL_ALT | NAV_CTL_POS | NAV_CTL_YAW | NAV_REQUIRE_ANGLE | NAV_AUTO_RTH | NAV_RC_POS | NAV_RC_YAW,
.mapToFlightModes = NAV_WP_MODE | NAV_ALTHOLD_MODE, .mapToFlightModes = NAV_FW_AUTOLAND,
.mwState = MW_NAV_STATE_LAND_IN_PROGRESS, .mwState = MW_NAV_STATE_LAND_IN_PROGRESS,
.mwError = MW_NAV_ERROR_NONE, .mwError = MW_NAV_ERROR_NONE,
.onEvent = { .onEvent = {
@ -1711,7 +1713,7 @@ static navigationFSMEvent_t navOnEnteringState_NAV_STATE_RTH_LANDING(navigationF
/* If position sensors unavailable - land immediately (wait for timeout on GPS) /* If position sensors unavailable - land immediately (wait for timeout on GPS)
* Continue to check for RTH sanity during landing */ * Continue to check for RTH sanity during landing */
if (posControl.flags.estHeadingStatus == EST_NONE || checkForPositionSensorTimeout() || !validateRTHSanityChecker()) { if (posControl.flags.estHeadingStatus == EST_NONE || checkForPositionSensorTimeout() || (previousState != NAV_STATE_WAYPOINT_REACHED && !validateRTHSanityChecker())) {
return NAV_FSM_EVENT_SWITCH_TO_EMERGENCY_LANDING; return NAV_FSM_EVENT_SWITCH_TO_EMERGENCY_LANDING;
} }
@ -1721,7 +1723,7 @@ static navigationFSMEvent_t navOnEnteringState_NAV_STATE_RTH_LANDING(navigationF
#ifdef USE_FW_AUTOLAND #ifdef USE_FW_AUTOLAND
if (STATE(AIRPLANE)) { if (STATE(AIRPLANE)) {
int8_t missionIdx = -1, shIdx = -1, missionFwLandConfigStartIdx = 8; int8_t missionIdx = -1, shIdx = -1, missionFwLandConfigStartIdx = 8, approachSettingIdx = -1;
#ifdef USE_MULTI_MISSION #ifdef USE_MULTI_MISSION
missionIdx = posControl.loadedMultiMissionIndex - 1; missionIdx = posControl.loadedMultiMissionIndex - 1;
#endif #endif
@ -1730,18 +1732,23 @@ static navigationFSMEvent_t navOnEnteringState_NAV_STATE_RTH_LANDING(navigationF
shIdx = posControl.safehomeState.index; shIdx = posControl.safehomeState.index;
missionFwLandConfigStartIdx = MAX_SAFE_HOMES; missionFwLandConfigStartIdx = MAX_SAFE_HOMES;
#endif #endif
if (!posControl.fwLandState.landAborted && (shIdx >= 0 || missionIdx >= 0) && (fwAutolandApproachConfig(shIdx)->landApproachHeading1 != 0 || fwAutolandApproachConfig(shIdx)->landApproachHeading2 != 0)) { if (previousState == NAV_STATE_WAYPOINT_REACHED && missionIdx >= 0) {
approachSettingIdx = missionFwLandConfigStartIdx + missionIdx;
} else if (shIdx >= 0) {
approachSettingIdx = shIdx;
}
if (!posControl.fwLandState.landAborted && approachSettingIdx >= 0 && (fwAutolandApproachConfig(approachSettingIdx)->landApproachHeading1 != 0 || fwAutolandApproachConfig(approachSettingIdx)->landApproachHeading2 != 0)) {
if (previousState == NAV_STATE_WAYPOINT_REACHED) { if (previousState == NAV_STATE_WAYPOINT_REACHED) {
posControl.fwLandState.landPos = posControl.activeWaypoint.pos; posControl.fwLandState.landPos = posControl.activeWaypoint.pos;
posControl.fwLandState.approachSettingIdx = missionFwLandConfigStartIdx + missionIdx;
posControl.fwLandState.landWp = true; posControl.fwLandState.landWp = true;
} else { } else {
posControl.fwLandState.landPos = posControl.safehomeState.nearestSafeHome; posControl.fwLandState.landPos = posControl.safehomeState.nearestSafeHome;
posControl.fwLandState.approachSettingIdx = shIdx;
posControl.fwLandState.landWp = false; posControl.fwLandState.landWp = false;
} }
posControl.fwLandState.approachSettingIdx = approachSettingIdx;
posControl.fwLandState.landAltAgl = fwAutolandApproachConfig(posControl.fwLandState.approachSettingIdx)->isSeaLevelRef ? fwAutolandApproachConfig(posControl.fwLandState.approachSettingIdx)->landAlt - GPS_home.alt : fwAutolandApproachConfig(posControl.fwLandState.approachSettingIdx)->landAlt; posControl.fwLandState.landAltAgl = fwAutolandApproachConfig(posControl.fwLandState.approachSettingIdx)->isSeaLevelRef ? fwAutolandApproachConfig(posControl.fwLandState.approachSettingIdx)->landAlt - GPS_home.alt : fwAutolandApproachConfig(posControl.fwLandState.approachSettingIdx)->landAlt;
posControl.fwLandState.landAproachAltAgl = fwAutolandApproachConfig(posControl.fwLandState.approachSettingIdx)->isSeaLevelRef ? fwAutolandApproachConfig(posControl.fwLandState.approachSettingIdx)->approachAlt - GPS_home.alt : fwAutolandApproachConfig(posControl.fwLandState.approachSettingIdx)->approachAlt; posControl.fwLandState.landAproachAltAgl = fwAutolandApproachConfig(posControl.fwLandState.approachSettingIdx)->isSeaLevelRef ? fwAutolandApproachConfig(posControl.fwLandState.approachSettingIdx)->approachAlt - GPS_home.alt : fwAutolandApproachConfig(posControl.fwLandState.approachSettingIdx)->approachAlt;
return NAV_FSM_EVENT_SWITCH_TO_NAV_STATE_FW_LANDING; return NAV_FSM_EVENT_SWITCH_TO_NAV_STATE_FW_LANDING;
@ -1813,6 +1820,12 @@ static navigationFSMEvent_t navOnEnteringState_NAV_STATE_WAYPOINT_INITIALIZE(nav
resetPositionController(); resetPositionController();
resetAltitudeController(false); // Make sure surface tracking is not enabled - WP uses global altitude, not AGL resetAltitudeController(false); // Make sure surface tracking is not enabled - WP uses global altitude, not AGL
#ifdef USE_FW_AUTOLAND
if (previousState != NAV_STATE_FW_LANDING_ABORT) {
posControl.fwLandState.landAborted = false;
}
#endif
if (posControl.activeWaypointIndex == posControl.startWpIndex || posControl.wpMissionRestart) { if (posControl.activeWaypointIndex == posControl.startWpIndex || posControl.wpMissionRestart) {
/* Use p3 as the volatile jump counter, allowing embedded, rearmed jumps /* Use p3 as the volatile jump counter, allowing embedded, rearmed jumps
Using p3 minimises the risk of saving an invalid counter if a mission is aborted */ Using p3 minimises the risk of saving an invalid counter if a mission is aborted */
@ -2022,11 +2035,20 @@ static navigationFSMEvent_t navOnEnteringState_NAV_STATE_WAYPOINT_RTH_LAND(navig
{ {
UNUSED(previousState); UNUSED(previousState);
#ifdef USE_FW_AUTOLAND
if (posControl.fwLandState.landAborted) {
return NAV_FSM_EVENT_SWITCH_TO_WAYPOINT_FINISHED;
}
#endif
const navigationFSMEvent_t landEvent = navOnEnteringState_NAV_STATE_RTH_LANDING(previousState); const navigationFSMEvent_t landEvent = navOnEnteringState_NAV_STATE_RTH_LANDING(previousState);
#ifdef USE_FW_AUTOLAND
if (landEvent == NAV_FSM_EVENT_SWITCH_TO_NAV_STATE_FW_LANDING) { if (landEvent == NAV_FSM_EVENT_SWITCH_TO_NAV_STATE_FW_LANDING) {
return NAV_FSM_EVENT_SWITCH_TO_NAV_STATE_FW_LANDING; return NAV_FSM_EVENT_SWITCH_TO_NAV_STATE_FW_LANDING;
} else if (landEvent == NAV_FSM_EVENT_SWITCH_TO_RTH_HOVER_ABOVE_HOME) { } else
#endif
if (landEvent == NAV_FSM_EVENT_SWITCH_TO_RTH_HOVER_ABOVE_HOME) {
return NAV_FSM_EVENT_SWITCH_TO_WAYPOINT_FINISHED; return NAV_FSM_EVENT_SWITCH_TO_WAYPOINT_FINISHED;
} else if (landEvent == NAV_FSM_EVENT_SUCCESS) { } else if (landEvent == NAV_FSM_EVENT_SUCCESS) {
// Landing controller returned success - invoke RTH finishing state and finish the waypoint // Landing controller returned success - invoke RTH finishing state and finish the waypoint
@ -2356,7 +2378,7 @@ static navigationFSMEvent_t navOnEnteringState_NAV_STATE_FW_LANDING_APPROACH(nav
if (isLandingDetected()) { if (isLandingDetected()) {
posControl.fwLandState.landState = FW_AUTOLAND_STATE_IDLE; posControl.fwLandState.landState = FW_AUTOLAND_STATE_IDLE;
disarm(DISARM_LANDING); //disarm(DISARM_LANDING);
return NAV_FSM_EVENT_SWITCH_TO_IDLE; return NAV_FSM_EVENT_SWITCH_TO_IDLE;
} }
@ -2400,14 +2422,14 @@ static navigationFSMEvent_t navOnEnteringState_NAV_STATE_FW_LANDING_GLIDE(naviga
return NAV_FSM_EVENT_SWITCH_TO_NAV_STATE_FW_LANDING_ABORT; return NAV_FSM_EVENT_SWITCH_TO_NAV_STATE_FW_LANDING_ABORT;
} }
if (getLandAltitude() <= posControl.fwLandState.landAltAgl + navFwAutolandConfig()->flareAltitude) { if (getHwRangefinderStatus() == HW_SENSOR_OK && getLandAltitude() <= posControl.fwLandState.landAltAgl + navFwAutolandConfig()->flareAltitude) {
posControl.fwLandState.landState = FW_AUTOLAND_STATE_FLARE; posControl.fwLandState.landState = FW_AUTOLAND_STATE_FLARE;
return NAV_FSM_EVENT_SUCCESS; return NAV_FSM_EVENT_SUCCESS;
} }
if (isLandingDetected()) { if (isLandingDetected()) {
posControl.fwLandState.landState = FW_AUTOLAND_STATE_IDLE; posControl.fwLandState.landState = FW_AUTOLAND_STATE_IDLE;
disarm(DISARM_LANDING); //disarm(DISARM_LANDING);
return NAV_FSM_EVENT_SWITCH_TO_IDLE; return NAV_FSM_EVENT_SWITCH_TO_IDLE;
} }
@ -2421,7 +2443,7 @@ static navigationFSMEvent_t navOnEnteringState_NAV_STATE_FW_LANDING_FLARE(naviga
if (isLandingDetected()) { if (isLandingDetected()) {
posControl.fwLandState.landState = FW_AUTOLAND_STATE_IDLE; posControl.fwLandState.landState = FW_AUTOLAND_STATE_IDLE;
disarm(DISARM_LANDING); //disarm(DISARM_LANDING);
return NAV_FSM_EVENT_SUCCESS; return NAV_FSM_EVENT_SUCCESS;
} }
setDesiredPosition(NULL, posControl.cruise.course, NAV_POS_UPDATE_HEADING); setDesiredPosition(NULL, posControl.cruise.course, NAV_POS_UPDATE_HEADING);
@ -3016,7 +3038,7 @@ void setHomePosition(const fpVector3_t * pos, int32_t heading, navSetWaypointFla
updateDesiredRTHAltitude(); updateDesiredRTHAltitude();
// Reset RTH sanity checker for new home position if RTH active // Reset RTH sanity checker for new home position if RTH active
if (FLIGHT_MODE(NAV_RTH_MODE)) { if (FLIGHT_MODE(NAV_RTH_MODE) || FLIGHT_MODE(NAV_FW_AUTOLAND) ) {
initializeRTHSanityChecker(); initializeRTHSanityChecker();
} }
@ -3138,7 +3160,7 @@ void updateHomePosition(void)
static bool isHomeResetAllowed = false; static bool isHomeResetAllowed = false;
// If pilot so desires he may reset home position to current position // If pilot so desires he may reset home position to current position
if (IS_RC_MODE_ACTIVE(BOXHOMERESET)) { if (IS_RC_MODE_ACTIVE(BOXHOMERESET)) {
if (isHomeResetAllowed && !FLIGHT_MODE(FAILSAFE_MODE) && !FLIGHT_MODE(NAV_RTH_MODE) && !FLIGHT_MODE(NAV_WP_MODE) && (posControl.flags.estPosStatus >= EST_USABLE)) { if (isHomeResetAllowed && !FLIGHT_MODE(FAILSAFE_MODE) && !FLIGHT_MODE(NAV_RTH_MODE) && !FLIGHT_MODE(NAV_FW_AUTOLAND) && !FLIGHT_MODE(NAV_WP_MODE) && (posControl.flags.estPosStatus >= EST_USABLE)) {
homeUpdateFlags = 0; homeUpdateFlags = 0;
homeUpdateFlags = STATE(GPS_FIX_HOME) ? (NAV_POS_UPDATE_XY | NAV_POS_UPDATE_HEADING) : (NAV_POS_UPDATE_XY | NAV_POS_UPDATE_Z | NAV_POS_UPDATE_HEADING); homeUpdateFlags = STATE(GPS_FIX_HOME) ? (NAV_POS_UPDATE_XY | NAV_POS_UPDATE_HEADING) : (NAV_POS_UPDATE_XY | NAV_POS_UPDATE_Z | NAV_POS_UPDATE_HEADING);
setHome = true; setHome = true;
@ -3243,7 +3265,7 @@ static bool rthAltControlStickOverrideCheck(unsigned axis)
suspendTracking = false; suspendTracking = false;
} }
if (navConfig()->general.flags.rth_trackback_mode == RTH_TRACKBACK_OFF || FLIGHT_MODE(NAV_RTH_MODE) || !ARMING_FLAG(ARMED) || suspendTracking) { if (navConfig()->general.flags.rth_trackback_mode == RTH_TRACKBACK_OFF || FLIGHT_MODE(NAV_RTH_MODE) || FLIGHT_MODE(NAV_FW_AUTOLAND) || !ARMING_FLAG(ARMED) || suspendTracking) {
return; return;
} }
@ -4061,6 +4083,7 @@ bool isNavHoldPositionActive(void)
// Also hold position during emergency landing if position valid // Also hold position during emergency landing if position valid
return (FLIGHT_MODE(NAV_RTH_MODE) && !posControl.flags.rthTrackbackActive) || return (FLIGHT_MODE(NAV_RTH_MODE) && !posControl.flags.rthTrackbackActive) ||
FLIGHT_MODE(NAV_POSHOLD_MODE) || FLIGHT_MODE(NAV_POSHOLD_MODE) ||
(posControl.navState == NAV_STATE_FW_LANDING_CLIMB_TO_LOITER || posControl.navState == NAV_STATE_FW_LANDING_LOITER) ||
navigationIsExecutingAnEmergencyLanding(); navigationIsExecutingAnEmergencyLanding();
} }
@ -4100,7 +4123,9 @@ bool isWaypointNavTrackingActive(void)
// is set from current position not previous WP. Works for WP Restart intermediate WP as well as first mission WP. // is set from current position not previous WP. Works for WP Restart intermediate WP as well as first mission WP.
// (NAV_WP_MODE flag isn't set until WP initialisation is finished, i.e. after calculateAndSetActiveWaypoint called) // (NAV_WP_MODE flag isn't set until WP initialisation is finished, i.e. after calculateAndSetActiveWaypoint called)
return FLIGHT_MODE(NAV_WP_MODE) || (posControl.flags.rthTrackbackActive && posControl.activeRthTBPointIndex != posControl.rthTBLastSavedIndex); return FLIGHT_MODE(NAV_WP_MODE)
|| posControl.navState == NAV_STATE_FW_LANDING_APPROACH
|| (posControl.flags.rthTrackbackActive && posControl.activeRthTBPointIndex != posControl.rthTBLastSavedIndex);
} }
/*----------------------------------------------------------- /*-----------------------------------------------------------
@ -4169,7 +4194,7 @@ void applyWaypointNavigationAndAltitudeHold(void)
posControl.flags.verticalPositionDataConsumed = false; posControl.flags.verticalPositionDataConsumed = false;
#ifdef USE_FW_AUTOLAND #ifdef USE_FW_AUTOLAND
if (!isFwLandInProgess()) { if (!FLIGHT_MODE(NAV_FW_AUTOLAND)) {
posControl.fwLandState.landState = FW_AUTOLAND_STATE_IDLE; posControl.fwLandState.landState = FW_AUTOLAND_STATE_IDLE;
} }
#endif #endif
@ -4210,7 +4235,7 @@ void applyWaypointNavigationAndAltitudeHold(void)
void switchNavigationFlightModes(void) void switchNavigationFlightModes(void)
{ {
const flightModeFlags_e enabledNavFlightModes = navGetMappedFlightModes(posControl.navState); const flightModeFlags_e enabledNavFlightModes = navGetMappedFlightModes(posControl.navState);
const flightModeFlags_e disabledFlightModes = (NAV_ALTHOLD_MODE | NAV_RTH_MODE | NAV_POSHOLD_MODE | NAV_WP_MODE | NAV_LAUNCH_MODE | NAV_COURSE_HOLD_MODE) & (~enabledNavFlightModes); const flightModeFlags_e disabledFlightModes = (NAV_ALTHOLD_MODE | NAV_RTH_MODE | NAV_FW_AUTOLAND | NAV_POSHOLD_MODE | NAV_WP_MODE | NAV_LAUNCH_MODE | NAV_COURSE_HOLD_MODE) & (~enabledNavFlightModes);
DISABLE_FLIGHT_MODE(disabledFlightModes); DISABLE_FLIGHT_MODE(disabledFlightModes);
ENABLE_FLIGHT_MODE(enabledNavFlightModes); ENABLE_FLIGHT_MODE(enabledNavFlightModes);
} }
@ -4899,7 +4924,7 @@ void abortForcedRTH(void)
rthState_e getStateOfForcedRTH(void) rthState_e getStateOfForcedRTH(void)
{ {
/* If forced RTH activated and in AUTO_RTH or EMERG state */ /* If forced RTH activated and in AUTO_RTH or EMERG state */
if (posControl.flags.forcedRTHActivated && (navGetStateFlags(posControl.navState) & (NAV_AUTO_RTH | NAV_CTL_EMERG | NAV_MIXERAT))) { if (posControl.flags.forcedRTHActivated && ((navGetStateFlags(posControl.navState) & (NAV_AUTO_RTH | NAV_CTL_EMERG | NAV_MIXERAT)) || FLIGHT_MODE(NAV_FW_AUTOLAND))) {
if (posControl.navState == NAV_STATE_RTH_FINISHED || posControl.navState == NAV_STATE_EMERGENCY_LANDING_FINISHED) { if (posControl.navState == NAV_STATE_RTH_FINISHED || posControl.navState == NAV_STATE_EMERGENCY_LANDING_FINISHED) {
return RTH_HAS_LANDED; return RTH_HAS_LANDED;
} }
@ -4981,6 +5006,12 @@ bool navigationIsFlyingAutonomousMode(void)
bool navigationRTHAllowsLanding(void) bool navigationRTHAllowsLanding(void)
{ {
#ifdef USE_FW_AUTOLAND
if (posControl.fwLandState.landAborted) {
return false;
}
#endif
// WP mission RTH landing setting // WP mission RTH landing setting
if (isWaypointMissionRTHActive() && isWaypointMissionValid()) { if (isWaypointMissionRTHActive() && isWaypointMissionValid()) {
return posControl.waypointList[posControl.startWpIndex + posControl.waypointCount - 1].p1 > 0; return posControl.waypointList[posControl.startWpIndex + posControl.waypointCount - 1].p1 > 0;
@ -5138,15 +5169,6 @@ void resetFwAutolandApproach(int8_t idx)
} }
} }
bool isFwLandInProgess(void)
{
return posControl.navState == NAV_STATE_FW_LANDING_CLIMB_TO_LOITER
|| posControl.navState == NAV_STATE_FW_LANDING_LOITER
|| posControl.navState == NAV_STATE_FW_LANDING_APPROACH
|| posControl.navState == NAV_STATE_FW_LANDING_GLIDE
|| posControl.navState == NAV_STATE_FW_LANDING_FLARE;
}
bool canFwLandCanceld(void) bool canFwLandCanceld(void)
{ {
return posControl.navState == NAV_STATE_FW_LANDING_CLIMB_TO_LOITER return posControl.navState == NAV_STATE_FW_LANDING_CLIMB_TO_LOITER

View file

@ -693,7 +693,6 @@ uint8_t getActiveWpNumber(void);
int32_t navigationGetHomeHeading(void); int32_t navigationGetHomeHeading(void);
#ifdef USE_FW_AUTOLAND #ifdef USE_FW_AUTOLAND
bool isFwLandInProgess(void);
bool canFwLandCanceld(void); bool canFwLandCanceld(void);
#endif #endif

View file

@ -271,7 +271,7 @@ static int8_t loiterDirection(void) {
static void calculateVirtualPositionTarget_FW(float trackingPeriod) static void calculateVirtualPositionTarget_FW(float trackingPeriod)
{ {
if (FLIGHT_MODE(NAV_COURSE_HOLD_MODE)) { if (FLIGHT_MODE(NAV_COURSE_HOLD_MODE) || posControl.navState == NAV_STATE_FW_LANDING_GLIDE || posControl.navState == NAV_STATE_FW_LANDING_FLARE) {
return; return;
} }
@ -405,7 +405,7 @@ static void updatePositionHeadingController_FW(timeUs_t currentTimeUs, timeDelta
static bool forceTurnDirection = false; static bool forceTurnDirection = false;
int32_t virtualTargetBearing; int32_t virtualTargetBearing;
if (FLIGHT_MODE(NAV_COURSE_HOLD_MODE)) { if (FLIGHT_MODE(NAV_COURSE_HOLD_MODE) || posControl.navState == NAV_STATE_FW_LANDING_GLIDE || posControl.navState == NAV_STATE_FW_LANDING_FLARE) {
virtualTargetBearing = posControl.desiredState.yaw; virtualTargetBearing = posControl.desiredState.yaw;
} else { } else {
// We have virtual position target, calculate heading error // We have virtual position target, calculate heading error
@ -643,11 +643,7 @@ void applyFixedWingPitchRollThrottleController(navigationFSMStateFlags_t navStat
uint16_t correctedThrottleValue = constrain(currentBatteryProfile->nav.fw.cruise_throttle + throttleCorrection, currentBatteryProfile->nav.fw.min_throttle, currentBatteryProfile->nav.fw.max_throttle); uint16_t correctedThrottleValue = constrain(currentBatteryProfile->nav.fw.cruise_throttle + throttleCorrection, currentBatteryProfile->nav.fw.min_throttle, currentBatteryProfile->nav.fw.max_throttle);
// Manual throttle increase // Manual throttle increase
#ifdef USE_FW_AUTOLAND if (navConfig()->fw.allow_manual_thr_increase && !FLIGHT_MODE(FAILSAFE_MODE) && !FLIGHT_MODE(NAV_FW_AUTOLAND)) {
if (navConfig()->fw.allow_manual_thr_increase && !FLIGHT_MODE(FAILSAFE_MODE) && !isFwLandInProgess()) {
#else
if (navConfig()->fw.allow_manual_thr_increase && !FLIGHT_MODE(FAILSAFE_MODE)) {
#endif
if (rcCommand[THROTTLE] < PWM_RANGE_MIN + (PWM_RANGE_MAX - PWM_RANGE_MIN) * 0.95){ if (rcCommand[THROTTLE] < PWM_RANGE_MIN + (PWM_RANGE_MAX - PWM_RANGE_MIN) * 0.95){
correctedThrottleValue += MAX(0, rcCommand[THROTTLE] - currentBatteryProfile->nav.fw.cruise_throttle); correctedThrottleValue += MAX(0, rcCommand[THROTTLE] - currentBatteryProfile->nav.fw.cruise_throttle);
} else { } else {
@ -665,7 +661,6 @@ void applyFixedWingPitchRollThrottleController(navigationFSMStateFlags_t navStat
// Advanced autoland // Advanced autoland
if (posControl.navState == NAV_STATE_FW_LANDING_GLIDE || posControl.navState == NAV_STATE_FW_LANDING_FLARE || STATE(LANDING_DETECTED)) { if (posControl.navState == NAV_STATE_FW_LANDING_GLIDE || posControl.navState == NAV_STATE_FW_LANDING_FLARE || STATE(LANDING_DETECTED)) {
// Set motor to min. throttle and stop it when MOTOR_STOP feature is enabled // Set motor to min. throttle and stop it when MOTOR_STOP feature is enabled
rcCommand[THROTTLE] = getThrottleIdleValue();
ENABLE_STATE(NAV_MOTOR_STOP_OR_IDLE); ENABLE_STATE(NAV_MOTOR_STOP_OR_IDLE);
if (posControl.navState == NAV_STATE_FW_LANDING_GLIDE) { if (posControl.navState == NAV_STATE_FW_LANDING_GLIDE) {
@ -727,6 +722,7 @@ bool isFixedWingLandingDetected(void)
// Basic condition to start looking for landing // Basic condition to start looking for landing
bool startCondition = (navGetCurrentStateFlags() & (NAV_CTL_LAND | NAV_CTL_EMERG)) bool startCondition = (navGetCurrentStateFlags() & (NAV_CTL_LAND | NAV_CTL_EMERG))
|| FLIGHT_MODE(FAILSAFE_MODE) || FLIGHT_MODE(FAILSAFE_MODE)
|| FLIGHT_MODE(NAV_FW_AUTOLAND)
|| (!navigationIsControllingThrottle() && throttleStickIsLow()); || (!navigationIsControllingThrottle() && throttleStickIsLow());
if (!startCondition || posControl.flags.resetLandingDetector) { if (!startCondition || posControl.flags.resetLandingDetector) {

View file

@ -746,7 +746,7 @@ static int logicConditionGetFlightOperandValue(int operand) {
case LOGIC_CONDITION_OPERAND_FLIGHT_IS_LANDING: // 0/1 case LOGIC_CONDITION_OPERAND_FLIGHT_IS_LANDING: // 0/1
#ifdef USE_FW_AUTOLAND #ifdef USE_FW_AUTOLAND
return ((navGetCurrentStateFlags() & NAV_CTL_LAND) || isFwLandInProgess()) ? 1 : 0; return ((navGetCurrentStateFlags() & NAV_CTL_LAND) || FLIGHT_MODE(NAV_FW_AUTOLAND)) ? 1 : 0;
#else #else
return ((navGetCurrentStateFlags() & NAV_CTL_LAND)) ? 1 : 0; return ((navGetCurrentStateFlags() & NAV_CTL_LAND)) ? 1 : 0;
#endif #endif

View file

@ -371,6 +371,11 @@ static void crsfFrameFlightMode(sbuf_t *dst)
} else if (FLIGHT_MODE(ANGLEHOLD_MODE)) { } else if (FLIGHT_MODE(ANGLEHOLD_MODE)) {
flightMode = "ANGH"; flightMode = "ANGH";
} }
#ifdef USE_FW_AUTOLAND
} else if (FLIGHT_MODE(NAV_FW_AUTOLAND)) {
flightMode = "LAND"
}
#endif
#ifdef USE_GPS #ifdef USE_GPS
} else if (feature(FEATURE_GPS) && navConfig()->general.flags.extra_arming_safety && (!STATE(GPS_FIX) || !STATE(GPS_FIX_HOME))) { } else if (feature(FEATURE_GPS) && navConfig()->general.flags.extra_arming_safety && (!STATE(GPS_FIX) || !STATE(GPS_FIX_HOME))) {
flightMode = "WAIT"; // Waiting for GPS lock flightMode = "WAIT"; // Waiting for GPS lock

View file

@ -71,6 +71,7 @@
#include "sensors/gyro.h" #include "sensors/gyro.h"
#include "sensors/sensors.h" #include "sensors/sensors.h"
#include "sensors/pitotmeter.h" #include "sensors/pitotmeter.h"
#include "sensors/diagnostics.h"
#include "telemetry/ltm.h" #include "telemetry/ltm.h"
#include "telemetry/telemetry.h" #include "telemetry/telemetry.h"
@ -178,6 +179,10 @@ void ltm_sframe(sbuf_t *dst)
lt_flightmode = LTM_MODE_ANGLE; lt_flightmode = LTM_MODE_ANGLE;
else if (FLIGHT_MODE(HORIZON_MODE)) else if (FLIGHT_MODE(HORIZON_MODE))
lt_flightmode = LTM_MODE_HORIZON; lt_flightmode = LTM_MODE_HORIZON;
#ifdef USE_FW_AUTOLAND
else if (FLIGHT_MODE(NAV_FW_AUTOLAND))
lt_flightmode = LTM_MODE_LAND;
#endif
else else
lt_flightmode = LTM_MODE_RATE; // Rate mode lt_flightmode = LTM_MODE_RATE; // Rate mode