mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-05-21 11:47:34 +08:00
Separate takeoff and landing to individual fixed wing states for FW pos control (#19495)
This commit is contained in:
@@ -755,7 +755,23 @@ FixedwingPositionControl::set_control_mode_current(const hrt_abstime &now, bool
|
||||
|
||||
if (((_control_mode.flag_control_auto_enabled && _control_mode.flag_control_position_enabled) ||
|
||||
_control_mode.flag_control_offboard_enabled) && pos_sp_curr_valid) {
|
||||
_control_mode_current = FW_POSCTRL_MODE_AUTO;
|
||||
if (_pos_sp_triplet.current.type == position_setpoint_s::SETPOINT_TYPE_TAKEOFF) {
|
||||
// TAKEOFF: handle like a regular POSITION setpoint if already flying
|
||||
if (!in_takeoff_situation() && (_airspeed >= _param_fw_airspd_min.get() || !_airspeed_valid)) {
|
||||
// SETPOINT_TYPE_TAKEOFF -> SETPOINT_TYPE_POSITION
|
||||
_control_mode_current = FW_POSCTRL_MODE_AUTO;
|
||||
|
||||
} else {
|
||||
_control_mode_current = FW_POSCTRL_MODE_AUTO_TAKEOFF;
|
||||
}
|
||||
|
||||
} else if (_pos_sp_triplet.current.type == position_setpoint_s::SETPOINT_TYPE_LAND
|
||||
&& !_vehicle_status.in_transition_mode) {
|
||||
_control_mode_current = FW_POSCTRL_MODE_AUTO_LANDING;
|
||||
|
||||
} else {
|
||||
_control_mode_current = FW_POSCTRL_MODE_AUTO;
|
||||
}
|
||||
|
||||
} else if (_control_mode.flag_control_auto_enabled && _control_mode.flag_control_climb_rate_enabled
|
||||
&& pos_sp_curr_valid) {
|
||||
@@ -815,8 +831,9 @@ FixedwingPositionControl::control_auto(const hrt_abstime &now, const Vector2d &c
|
||||
const Vector2f &ground_speed, const position_setpoint_s &pos_sp_prev,
|
||||
const position_setpoint_s &pos_sp_curr, const position_setpoint_s &pos_sp_next)
|
||||
{
|
||||
const float dt = math::constrain((now - _control_position_last_called) * 1e-6f, 0.01f, 0.05f);
|
||||
_control_position_last_called = now;
|
||||
const float dt = math::constrain((now - _last_time_position_control_called) * 1e-6f, MIN_AUTO_TIMESTEP,
|
||||
MAX_AUTO_TIMESTEP);
|
||||
_last_time_position_control_called = now;
|
||||
|
||||
if (_param_fw_use_npfg.get()) {
|
||||
_npfg.setDt(dt);
|
||||
@@ -913,14 +930,6 @@ FixedwingPositionControl::control_auto(const hrt_abstime &now, const Vector2d &c
|
||||
case position_setpoint_s::SETPOINT_TYPE_LOITER:
|
||||
control_auto_loiter(now, dt, curr_pos, ground_speed, pos_sp_prev, current_sp, pos_sp_next);
|
||||
break;
|
||||
|
||||
case position_setpoint_s::SETPOINT_TYPE_LAND:
|
||||
control_auto_landing(now, dt, curr_pos, ground_speed, pos_sp_prev, current_sp);
|
||||
break;
|
||||
|
||||
case position_setpoint_s::SETPOINT_TYPE_TAKEOFF:
|
||||
control_auto_takeoff(now, dt, curr_pos, ground_speed, pos_sp_prev, current_sp);
|
||||
break;
|
||||
}
|
||||
|
||||
/* reset landing state */
|
||||
@@ -939,49 +948,17 @@ FixedwingPositionControl::control_auto(const hrt_abstime &now, const Vector2d &c
|
||||
}
|
||||
|
||||
/* Copy thrust output for publication, handle special cases */
|
||||
if (position_sp_type == position_setpoint_s::SETPOINT_TYPE_TAKEOFF && // launchdetector only available in auto
|
||||
_launch_detection_state != LAUNCHDETECTION_RES_DETECTED_ENABLEMOTORS &&
|
||||
!_runway_takeoff.runwayTakeoffEnabled()) {
|
||||
|
||||
/* making sure again that the correct thrust is used,
|
||||
* without depending on library calls for safety reasons.
|
||||
the pre-takeoff throttle and the idle throttle normally map to the same parameter. */
|
||||
_att_sp.thrust_body[0] = _param_fw_thr_idle.get();
|
||||
|
||||
} else if (position_sp_type == position_setpoint_s::SETPOINT_TYPE_TAKEOFF &&
|
||||
_runway_takeoff.runwayTakeoffEnabled()) {
|
||||
|
||||
_att_sp.thrust_body[0] = _runway_takeoff.getThrottle(now, get_tecs_thrust());
|
||||
|
||||
} else if (position_sp_type == position_setpoint_s::SETPOINT_TYPE_IDLE) {
|
||||
if (position_sp_type == position_setpoint_s::SETPOINT_TYPE_IDLE) {
|
||||
|
||||
_att_sp.thrust_body[0] = 0.0f;
|
||||
|
||||
} else {
|
||||
/* Copy thrust and pitch values from tecs */
|
||||
if (_landed) {
|
||||
// when we are landed state we want the motor to spin at idle speed
|
||||
_att_sp.thrust_body[0] = min(_param_fw_thr_idle.get(), 1.f);
|
||||
|
||||
} else {
|
||||
_att_sp.thrust_body[0] = get_tecs_thrust();
|
||||
}
|
||||
// when we are landed state we want the motor to spin at idle speed
|
||||
_att_sp.thrust_body[0] = (_landed) ? min(_param_fw_thr_idle.get(), 1.f) : get_tecs_thrust();
|
||||
}
|
||||
|
||||
// decide when to use pitch setpoint from TECS because in some cases pitch
|
||||
// setpoint is generated by other means
|
||||
bool use_tecs_pitch = true;
|
||||
|
||||
// auto runway takeoff
|
||||
use_tecs_pitch &= !(position_sp_type == position_setpoint_s::SETPOINT_TYPE_TAKEOFF &&
|
||||
(_launch_detection_state == LAUNCHDETECTION_RES_NONE || _runway_takeoff.runwayTakeoffEnabled()));
|
||||
|
||||
// flaring during landing
|
||||
use_tecs_pitch &= !(position_sp_type == position_setpoint_s::SETPOINT_TYPE_LAND && _land_noreturn_vertical);
|
||||
|
||||
if (use_tecs_pitch) {
|
||||
_att_sp.pitch_body = get_tecs_pitch();
|
||||
}
|
||||
/* Copy thrust and pitch values from tecs */
|
||||
_att_sp.pitch_body = get_tecs_pitch();
|
||||
|
||||
if (!_vehicle_status.in_transition_to_fw) {
|
||||
publishLocalPositionSetpoint(current_sp);
|
||||
@@ -1040,13 +1017,7 @@ FixedwingPositionControl::control_auto_descend(const hrt_abstime &now)
|
||||
_att_sp.roll_body = math::radians(_param_nav_gpsf_r.get()); // open loop loiter bank angle
|
||||
_att_sp.yaw_body = 0.f;
|
||||
|
||||
if (_landed) {
|
||||
_att_sp.thrust_body[0] = _param_fw_thr_min.get();
|
||||
|
||||
} else {
|
||||
_att_sp.thrust_body[0] = min(get_tecs_thrust(), _param_fw_thr_max.get());
|
||||
}
|
||||
|
||||
_att_sp.thrust_body[0] = (_landed) ? _param_fw_thr_min.get() : min(get_tecs_thrust(), _param_fw_thr_max.get());
|
||||
_att_sp.pitch_body = get_tecs_pitch();
|
||||
}
|
||||
|
||||
@@ -1441,9 +1412,20 @@ FixedwingPositionControl::control_auto_loiter(const hrt_abstime &now, const floa
|
||||
}
|
||||
|
||||
void
|
||||
FixedwingPositionControl::control_auto_takeoff(const hrt_abstime &now, const float dt, const Vector2d &curr_pos,
|
||||
FixedwingPositionControl::control_auto_takeoff(const hrt_abstime &now, const Vector2d &curr_pos,
|
||||
const Vector2f &ground_speed, const position_setpoint_s &pos_sp_prev, const position_setpoint_s &pos_sp_curr)
|
||||
{
|
||||
const float dt = math::constrain((now - _last_time_position_control_called) * 1e-6f, MIN_AUTO_TIMESTEP,
|
||||
MAX_AUTO_TIMESTEP);
|
||||
_last_time_position_control_called = now;
|
||||
|
||||
if (_param_fw_use_npfg.get()) {
|
||||
_npfg.setDt(dt);
|
||||
|
||||
} else {
|
||||
_l1_control.set_dt(dt);
|
||||
}
|
||||
|
||||
/* current waypoint (the one currently heading for) */
|
||||
Vector2d curr_wp(pos_sp_curr.lat, pos_sp_curr.lon);
|
||||
Vector2d prev_wp{0, 0}; /* previous waypoint */
|
||||
@@ -1642,12 +1624,49 @@ FixedwingPositionControl::control_auto_takeoff(const hrt_abstime &now, const flo
|
||||
_att_sp.pitch_body = radians(_takeoff_pitch_min.get());
|
||||
}
|
||||
}
|
||||
|
||||
if (_launch_detection_state != LAUNCHDETECTION_RES_DETECTED_ENABLEMOTORS && !_runway_takeoff.runwayTakeoffEnabled()) {
|
||||
|
||||
/* making sure again that the correct thrust is used,
|
||||
* without depending on library calls for safety reasons.
|
||||
the pre-takeoff throttle and the idle throttle normally map to the same parameter. */
|
||||
_att_sp.thrust_body[0] = _param_fw_thr_idle.get();
|
||||
|
||||
} else if (_runway_takeoff.runwayTakeoffEnabled()) {
|
||||
|
||||
_att_sp.thrust_body[0] = _runway_takeoff.getThrottle(now, get_tecs_thrust());
|
||||
|
||||
} else {
|
||||
/* Copy thrust and pitch values from tecs */
|
||||
// when we are landed state we want the motor to spin at idle speed
|
||||
_att_sp.thrust_body[0] = (_landed) ? min(_param_fw_thr_idle.get(), 1.f) : get_tecs_thrust();
|
||||
}
|
||||
|
||||
// only use TECS pitch setpoint if launch has not been detected and runway takeoff is not enabled
|
||||
if (!(_launch_detection_state == LAUNCHDETECTION_RES_NONE || _runway_takeoff.runwayTakeoffEnabled())) {
|
||||
_att_sp.pitch_body = get_tecs_pitch();
|
||||
}
|
||||
|
||||
if (!_vehicle_status.in_transition_to_fw) {
|
||||
publishLocalPositionSetpoint(pos_sp_curr);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
FixedwingPositionControl::control_auto_landing(const hrt_abstime &now, const float dt, const Vector2d &curr_pos,
|
||||
FixedwingPositionControl::control_auto_landing(const hrt_abstime &now, const Vector2d &curr_pos,
|
||||
const Vector2f &ground_speed, const position_setpoint_s &pos_sp_prev, const position_setpoint_s &pos_sp_curr)
|
||||
{
|
||||
const float dt = math::constrain((now - _last_time_position_control_called) * 1e-6f, MIN_AUTO_TIMESTEP,
|
||||
MAX_AUTO_TIMESTEP);
|
||||
_last_time_position_control_called = now;
|
||||
|
||||
if (_param_fw_use_npfg.get()) {
|
||||
_npfg.setDt(dt);
|
||||
|
||||
} else {
|
||||
_l1_control.set_dt(dt);
|
||||
}
|
||||
|
||||
/* current waypoint (the one currently heading for) */
|
||||
Vector2d curr_wp(pos_sp_curr.lat, pos_sp_curr.lon);
|
||||
Vector2d prev_wp{0, 0}; /* previous waypoint */
|
||||
@@ -1977,6 +1996,15 @@ FixedwingPositionControl::control_auto_landing(const hrt_abstime &now, const flo
|
||||
_param_fw_thr_cruise.get(),
|
||||
false,
|
||||
radians(_param_fw_p_lim_min.get()));
|
||||
_att_sp.pitch_body = get_tecs_pitch();
|
||||
}
|
||||
|
||||
/* Copy thrust and pitch values from tecs */
|
||||
// when we are landed state we want the motor to spin at idle speed
|
||||
_att_sp.thrust_body[0] = (_landed) ? min(_param_fw_thr_idle.get(), 1.f) : get_tecs_thrust();
|
||||
|
||||
if (!_vehicle_status.in_transition_to_fw) {
|
||||
publishLocalPositionSetpoint(pos_sp_curr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1985,7 +2013,7 @@ FixedwingPositionControl::control_manual_altitude(const hrt_abstime &now, const
|
||||
const Vector2f &ground_speed)
|
||||
{
|
||||
/* ALTITUDE CONTROL: pitch stick moves altitude setpoint, throttle stick sets airspeed */
|
||||
_control_position_last_called = now;
|
||||
_last_time_position_control_called = now;
|
||||
|
||||
/* Get demanded airspeed */
|
||||
float altctrl_airspeed = get_manual_airspeed_setpoint();
|
||||
@@ -2046,8 +2074,9 @@ void
|
||||
FixedwingPositionControl::control_manual_position(const hrt_abstime &now, const Vector2d &curr_pos,
|
||||
const Vector2f &ground_speed)
|
||||
{
|
||||
const float dt = math::constrain((now - _control_position_last_called) * 1e-6f, 0.01f, 0.05f);
|
||||
_control_position_last_called = now;
|
||||
const float dt = math::constrain((now - _last_time_position_control_called) * 1e-6f, MIN_AUTO_TIMESTEP,
|
||||
MAX_AUTO_TIMESTEP);
|
||||
_last_time_position_control_called = now;
|
||||
|
||||
// if we assume that user is taking off then help by demanding altitude setpoint well above ground
|
||||
// and set limit to pitch angle to prevent steering into ground
|
||||
@@ -2379,6 +2408,16 @@ FixedwingPositionControl::Run()
|
||||
break;
|
||||
}
|
||||
|
||||
case FW_POSCTRL_MODE_AUTO_LANDING: {
|
||||
control_auto_landing(_local_pos.timestamp, curr_pos, ground_speed, _pos_sp_triplet.previous, _pos_sp_triplet.current);
|
||||
break;
|
||||
}
|
||||
|
||||
case FW_POSCTRL_MODE_AUTO_TAKEOFF: {
|
||||
control_auto_takeoff(_local_pos.timestamp, curr_pos, ground_speed, _pos_sp_triplet.previous, _pos_sp_triplet.current);
|
||||
break;
|
||||
}
|
||||
|
||||
case FW_POSCTRL_MODE_MANUAL_POSITION: {
|
||||
control_manual_position(_local_pos.timestamp, curr_pos, ground_speed);
|
||||
break;
|
||||
@@ -2514,7 +2553,7 @@ FixedwingPositionControl::tecs_update_pitch_throttle(const hrt_abstime &now, flo
|
||||
bool climbout_mode, float climbout_pitch_min_rad,
|
||||
bool disable_underspeed_detection, float hgt_rate_sp)
|
||||
{
|
||||
const float dt = math::constrain((now - _last_tecs_update) * 1e-6f, 0.01f, 0.05f);
|
||||
const float dt = math::constrain((now - _last_tecs_update) * 1e-6f, MIN_AUTO_TIMESTEP, MAX_AUTO_TIMESTEP);
|
||||
_last_tecs_update = now;
|
||||
|
||||
// do not run TECS if we are not in air
|
||||
|
||||
@@ -120,6 +120,9 @@ static constexpr float ASPD_SP_SLEW_RATE = 1.f; // slew rate limit for airspeed
|
||||
static constexpr hrt_abstime T_WIND_EST_TIMEOUT =
|
||||
10_s; // time after which the wind estimate is disabled if no longer updating
|
||||
|
||||
static constexpr float MIN_AUTO_TIMESTEP = 0.01f; // minimum time step between auto control updates [s]
|
||||
static constexpr float MAX_AUTO_TIMESTEP = 0.05f; // maximum time step between auto control updates [s]
|
||||
|
||||
class FixedwingPositionControl final : public ModuleBase<FixedwingPositionControl>, public ModuleParams,
|
||||
public px4::WorkItem
|
||||
{
|
||||
@@ -195,7 +198,11 @@ private:
|
||||
position_setpoint_s _hdg_hold_prev_wp {}; ///< position where heading hold started
|
||||
position_setpoint_s _hdg_hold_curr_wp {}; ///< position to which heading hold flies
|
||||
|
||||
hrt_abstime _control_position_last_called{0}; ///< last call of control_position
|
||||
/**
|
||||
* @brief Last absolute time position control has been called [us]
|
||||
*
|
||||
*/
|
||||
hrt_abstime _last_time_position_control_called{0};
|
||||
|
||||
bool _landed{true};
|
||||
|
||||
@@ -279,6 +286,8 @@ private:
|
||||
FW_POSCTRL_MODE_AUTO,
|
||||
FW_POSCTRL_MODE_AUTO_ALTITUDE,
|
||||
FW_POSCTRL_MODE_AUTO_CLIMBRATE,
|
||||
FW_POSCTRL_MODE_AUTO_TAKEOFF,
|
||||
FW_POSCTRL_MODE_AUTO_LANDING,
|
||||
FW_POSCTRL_MODE_MANUAL_POSITION,
|
||||
FW_POSCTRL_MODE_MANUAL_ALTITUDE,
|
||||
FW_POSCTRL_MODE_OTHER
|
||||
@@ -358,11 +367,20 @@ private:
|
||||
void control_auto_velocity(const hrt_abstime &now, const float dt, const Vector2d &curr_pos,
|
||||
const Vector2f &ground_speed,
|
||||
const position_setpoint_s &pos_sp_prev, const position_setpoint_s &pos_sp_curr);
|
||||
void control_auto_takeoff(const hrt_abstime &now, const float dt, const Vector2d &curr_pos,
|
||||
|
||||
/**
|
||||
* @brief Vehicle control while in takeoff
|
||||
*
|
||||
* @param now Current system time [us]
|
||||
* @param curr_pos Current 2D local position vector of vehicle [m]
|
||||
* @param ground_speed Local 2D ground speed of vehicle [m/s]
|
||||
* @param pos_sp_prev previous position setpoint
|
||||
* @param pos_sp_curr current position setpoint
|
||||
*/
|
||||
void control_auto_takeoff(const hrt_abstime &now, const Vector2d &curr_pos,
|
||||
const Vector2f &ground_speed,
|
||||
const position_setpoint_s &pos_sp_prev,
|
||||
const position_setpoint_s &pos_sp_curr);
|
||||
void control_auto_landing(const hrt_abstime &now, const float dt, const Vector2d &curr_pos,
|
||||
const position_setpoint_s &pos_sp_prev, const position_setpoint_s &pos_sp_curr);
|
||||
void control_auto_landing(const hrt_abstime &now, const Vector2d &curr_pos,
|
||||
const Vector2f &ground_speed,
|
||||
const position_setpoint_s &pos_sp_prev,
|
||||
const position_setpoint_s &pos_sp_curr);
|
||||
@@ -373,8 +391,8 @@ private:
|
||||
float get_tecs_thrust();
|
||||
|
||||
float get_manual_airspeed_setpoint();
|
||||
float get_auto_airspeed_setpoint(const hrt_abstime &now, const float pos_sp_cru_airspeed,
|
||||
const Vector2f &ground_speed, float dt);
|
||||
float get_auto_airspeed_setpoint(const hrt_abstime &now, const float pos_sp_cru_airspeed, const Vector2f &ground_speed,
|
||||
float dt);
|
||||
|
||||
void reset_takeoff_state(bool force = false);
|
||||
void reset_landing_state();
|
||||
|
||||
Reference in New Issue
Block a user