@@ -388,11 +388,9 @@ FixedWingModeManager::set_control_mode_current(const hrt_abstime &now)
388388 }
389389
390390 } else if ((_control_mode.flag_control_auto_enabled && _control_mode.flag_control_position_enabled )
391- && (_position_setpoint_current_valid
392- || _pos_sp_triplet.current .type == position_setpoint_s::SETPOINT_TYPE_IDLE)) {
391+ && _position_setpoint_current_valid) {
393392
394- // Enter this mode only if the current waypoint has valid 3D position setpoints or is of type IDLE.
395- // A setpoint of type IDLE can be published by Navigator without a valid position, and is handled here in FW_POSCTRL_MODE_AUTO.
393+ // Enter this mode only if the current waypoint has valid 3D position setpoints.
396394
397395 if (doing_backtransition) {
398396 _control_mode_current = FW_POSCTRL_MODE_TRANSITION_TO_HOVER_LINE_FOLLOW;
@@ -433,6 +431,28 @@ FixedWingModeManager::set_control_mode_current(const hrt_abstime &now)
433431 _control_mode_current = FW_POSCTRL_MODE_AUTO;
434432 }
435433
434+ } else if (_control_mode.flag_control_auto_enabled && _control_mode.flag_control_position_enabled
435+ && (_pos_sp_triplet.current .type == position_setpoint_s::SETPOINT_TYPE_IDLE)) {
436+
437+ // A setpoint of type IDLE can be published by Navigator without a valid position, and is handled here in FW_POSCTRL_MODE_AUTO.
438+ if (doing_backtransition) {
439+ _control_mode_current = FW_POSCTRL_MODE_TRANSITION_TO_HOVER_HEADING_HOLD;
440+
441+ } else {
442+ _control_mode_current = FW_POSCTRL_MODE_AUTO;
443+ }
444+
445+ } else if (_control_mode.flag_control_auto_enabled && _control_mode.flag_control_position_enabled
446+ && (_pos_sp_triplet.current .type == position_setpoint_s::SETPOINT_TYPE_LAND)) {
447+
448+ if (doing_backtransition) {
449+ _control_mode_current = FW_POSCTRL_MODE_TRANSITION_TO_HOVER_HEADING_HOLD;
450+
451+ } else {
452+ // Only circular landing are supported when LAND is sent without valid position
453+ _control_mode_current = FW_POSCTRL_MODE_AUTO_LANDING_CIRCULAR;
454+ }
455+
436456 } else if (_control_mode.flag_control_auto_enabled
437457 && _control_mode.flag_control_climb_rate_enabled
438458 && _control_mode.flag_armed // only enter this modes if armed, as pure failsafe modes
@@ -1594,19 +1614,24 @@ void
15941614FixedWingModeManager::control_auto_landing_circular (const hrt_abstime &now, const float control_interval,
15951615 const Vector2f &ground_speed, const position_setpoint_s &pos_sp_curr)
15961616{
1617+ if (_time_started_landing == 0 ) {
1618+ // save time at which we started landing and reset landing abort status
1619+ reset_landing_state ();
1620+ _time_started_landing = now;
1621+ }
1622+
15971623 const float airspeed_land = (_param_fw_lnd_airspd.get () > FLT_EPSILON) ? _param_fw_lnd_airspd.get () :
15981624 _param_fw_airspd_min.get ();
15991625
16001626 _ctrl_configuration_handler.setEnforceLowHeightCondition (true );
16011627
16021628
16031629 const Vector2f local_position{_local_pos.x , _local_pos.y };
1604- Vector2f local_landing_orbit_center = _global_local_proj_ref.project (pos_sp_curr.lat , pos_sp_curr.lon );
16051630
1606- if (_time_started_landing == 0 ) {
1607- // save time at which we started landing and reset landing abort status
1608- reset_landing_state ();
1609- _time_started_landing = now ;
1631+ if (!_local_landing_orbit_center. isAllFinite () ) {
1632+ _local_landing_orbit_center = _position_setpoint_current_valid
1633+ ? _global_local_proj_ref. project (pos_sp_curr. lat , pos_sp_curr. lon )
1634+ : local_position ;
16101635 }
16111636
16121637 const bool abort_on_terrain_timeout = checkLandingAbortBitMask (_param_fw_lnd_abort.get (),
@@ -1642,7 +1667,7 @@ FixedWingModeManager::control_auto_landing_circular(const hrt_abstime &now, cons
16421667 1 .0f );
16431668
16441669 /* lateral guidance first, because npfg will adjust the airspeed setpoint if necessary */
1645- const DirectionalGuidanceOutput sp = navigateLoiter (local_landing_orbit_center , local_position, loiter_radius,
1670+ const DirectionalGuidanceOutput sp = navigateLoiter (_local_landing_orbit_center , local_position, loiter_radius,
16461671 loiter_direction_ccw,
16471672 ground_speed, _wind_vel);
16481673 fixed_wing_lateral_setpoint_s fw_lateral_ctrl_sp{empty_lateral_control_setpoint};
@@ -1700,7 +1725,7 @@ FixedWingModeManager::control_auto_landing_circular(const hrt_abstime &now, cons
17001725 } else {
17011726
17021727 // follow the glide slope
1703- const DirectionalGuidanceOutput sp = navigateLoiter (local_landing_orbit_center , local_position, loiter_radius,
1728+ const DirectionalGuidanceOutput sp = navigateLoiter (_local_landing_orbit_center , local_position, loiter_radius,
17041729 loiter_direction_ccw,
17051730 ground_speed, _wind_vel);
17061731 fixed_wing_lateral_setpoint_s fw_lateral_ctrl_sp{empty_lateral_control_setpoint};
@@ -2285,6 +2310,7 @@ FixedWingModeManager::reset_landing_state()
22852310
22862311 _flare_states = FlareStates{};
22872312
2313+ _local_landing_orbit_center.setNaN ();
22882314 _lateral_touchdown_position_offset = 0 .0f ;
22892315
22902316 _last_time_terrain_alt_was_valid = 0 ;
@@ -2299,6 +2325,10 @@ FixedWingModeManager::reset_landing_state()
22992325
23002326float FixedWingModeManager::getMaxRollAngleNearGround (const float altitude, const float terrain_altitude) const
23012327{
2328+ if (!PX4_ISFINITE (altitude) || !PX4_ISFINITE (terrain_altitude)) {
2329+ return math::radians (_param_fw_r_lim.get ());
2330+ }
2331+
23022332 // we want the wings level when at the wing height above ground
23032333 const float height_above_ground = math::max (altitude - (terrain_altitude + _param_fw_wing_height.get ()), 0 .0f );
23042334
@@ -2424,7 +2454,7 @@ FixedWingModeManager::getLandingTerrainAltitudeEstimate(const hrt_abstime &now,
24242454
24252455 if (_local_pos.dist_bottom_valid ) {
24262456
2427- const float terrain_estimate = _local_pos. ref_alt + -_local_pos.z - _local_pos.dist_bottom ;
2457+ const float terrain_estimate = _reference_altitude + -_local_pos.z - _local_pos.dist_bottom ;
24282458 _last_valid_terrain_alt_estimate = terrain_estimate;
24292459 _last_time_terrain_alt_was_valid = now;
24302460
0 commit comments