44 ModuleParams(nullptr),
45 WorkItem(MODULE_NAME,
px4::wq_configurations::att_pos_ctrl),
55 _roll_ctrl.set_max_rate(
radians(_param_fw_acro_x_max.get()));
70 PX4_ERR(
"vehicle attitude callback registration failed!");
88 _roll_ctrl.set_time_constant(_param_fw_r_tc.get());
89 _roll_ctrl.set_k_p(_param_fw_rr_p.get());
90 _roll_ctrl.set_k_i(_param_fw_rr_i.get());
91 _roll_ctrl.set_k_ff(_param_fw_rr_ff.get());
92 _roll_ctrl.set_integrator_max(_param_fw_rr_imax.get());
120 if (is_hovering || is_tailsitter_transition) {
140 if (fabsf(
_manual.
y) > _param_fw_ratt_th.get() || fabsf(
_manual.
x) > _param_fw_ratt_th.get()) {
153 -
radians(_param_fw_man_r_max.get()),
radians(_param_fw_man_r_max.get()));
157 -
radians(_param_fw_man_p_max.get()),
radians(_param_fw_man_p_max.get()));
233 int32_t vt_type = -1;
254 _landed = vehicle_land_detected.landed;
266 float airspeed = _param_fw_airspd_trim.get();
268 if ((_param_fw_arsp_mode.get() == 0) && airspeed_valid) {
278 airspeed = _param_fw_airspd_min.get();
289 const float airspeed_constrained =
constrain(airspeed, _param_fw_airspd_min.get(), _param_fw_airspd_max.get());
311 if (params_updated) {
322 static uint64_t last_run = 0;
331 float rollspeed = angular_velocity.xyz[0];
332 float pitchspeed = angular_velocity.xyz[1];
333 float yawspeed = angular_velocity.xyz[2];
355 R_adapted(0, 0) = R(0, 2);
356 R_adapted(1, 0) = R(1, 2);
357 R_adapted(2, 0) = R(2, 2);
360 R_adapted(0, 2) = R(0, 0);
361 R_adapted(1, 2) = R(1, 0);
362 R_adapted(2, 2) = R(2, 0);
365 R_adapted(0, 0) = -R_adapted(0, 0);
366 R_adapted(1, 0) = -R_adapted(1, 0);
367 R_adapted(2, 0) = -R_adapted(2, 0);
373 float helper = rollspeed;
374 rollspeed = -yawspeed;
421 float gspd_scaling_trim = (_param_fw_airspd_min.get() * 0.6f);
422 float groundspeed_scaler = gspd_scaling_trim / ((groundspeed < gspd_scaling_trim) ? gspd_scaling_trim : groundspeed);
426 _roll_ctrl.reset_integrator();
445 _roll_ctrl.reset_integrator();
453 control_input.
roll = euler_angles.
phi();
455 control_input.
yaw = euler_angles.
psi();
462 control_input.
airspeed_min = _param_fw_airspd_min.get();
463 control_input.
airspeed_max = _param_fw_airspd_max.get();
474 _roll_ctrl.set_max_rate(
radians(_param_fw_r_rmax.get()));
480 _roll_ctrl.set_max_rate(
radians(_param_fw_acro_x_max.get()));
490 float trim_roll = _param_trim_roll.get();
491 float trim_pitch = _param_trim_pitch.get();
492 float trim_yaw = _param_trim_yaw.get();
494 if (airspeed < _param_fw_airspd_trim.get()) {
495 trim_roll +=
gradual(airspeed, _param_fw_airspd_min.get(), _param_fw_airspd_trim.get(), _param_fw_dtrim_r_vmin.get(),
497 trim_pitch +=
gradual(airspeed, _param_fw_airspd_min.get(), _param_fw_airspd_trim.get(), _param_fw_dtrim_p_vmin.get(),
499 trim_yaw +=
gradual(airspeed, _param_fw_airspd_min.get(), _param_fw_airspd_trim.get(), _param_fw_dtrim_y_vmin.get(),
503 trim_roll +=
gradual(airspeed, _param_fw_airspd_trim.get(), _param_fw_airspd_max.get(), 0.0f,
504 _param_fw_dtrim_r_vmax.get());
505 trim_pitch +=
gradual(airspeed, _param_fw_airspd_trim.get(), _param_fw_airspd_max.get(), 0.0f,
506 _param_fw_dtrim_p_vmax.get());
507 trim_yaw +=
gradual(airspeed, _param_fw_airspd_trim.get(), _param_fw_airspd_max.get(), 0.0f,
508 _param_fw_dtrim_y_vmax.get());
518 _roll_ctrl.control_attitude(control_input);
529 float roll_u = _roll_ctrl.control_euler_rate(control_input);
530 _actuators.
control[actuator_controls_s::INDEX_ROLL] = (PX4_ISFINITE(roll_u)) ? roll_u + trim_roll : trim_roll;
532 if (!PX4_ISFINITE(roll_u)) {
533 _roll_ctrl.reset_integrator();
537 _actuators.
control[actuator_controls_s::INDEX_PITCH] = (PX4_ISFINITE(pitch_u)) ? pitch_u + trim_pitch : trim_pitch;
539 if (!PX4_ISFINITE(pitch_u)) {
552 _actuators.
control[actuator_controls_s::INDEX_YAW] = (PX4_ISFINITE(yaw_u)) ? yaw_u + trim_yaw : trim_yaw;
559 if (!PX4_ISFINITE(yaw_u)) {
569 if (_param_fw_bat_scale_en.get() &&
605 float roll_u = _roll_ctrl.control_bodyrate(control_input);
606 _actuators.
control[actuator_controls_s::INDEX_ROLL] = (PX4_ISFINITE(roll_u)) ? roll_u + trim_roll : trim_roll;
609 _actuators.
control[actuator_controls_s::INDEX_PITCH] = (PX4_ISFINITE(pitch_u)) ? pitch_u + trim_pitch : trim_pitch;
612 _actuators.
control[actuator_controls_s::INDEX_YAW] = (PX4_ISFINITE(yaw_u)) ? yaw_u + trim_yaw : trim_yaw;
630 _actuators.
control[actuator_controls_s::INDEX_YAW] += _param_fw_rll_to_yaw_ff.get()
667 float flap_control = 0.0f;
671 && fabsf(_param_fw_flaps_scl.get()) > 0.01
f) {
672 flap_control = 0.5f * (
_manual.
flaps + 1.0f) * _param_fw_flaps_scl.get();
675 && fabsf(_param_fw_flaps_scl.get()) > 0.01
f) {
678 case vehicle_attitude_setpoint_s::FLAPS_OFF:
682 case vehicle_attitude_setpoint_s::FLAPS_LAND:
683 flap_control = 1.0f * _param_fw_flaps_scl.get() * _param_fw_flaps_lnd_scl.get();
686 case vehicle_attitude_setpoint_s::FLAPS_TAKEOFF:
687 flap_control = 1.0f * _param_fw_flaps_scl.get() * _param_fw_flaps_to_scl.get();
701 float flaperon_control = 0.0f;
705 && fabsf(_param_fw_flaperon_scl.get()) > 0.01
f) {
707 flaperon_control = 0.5f * (
_manual.
aux2 + 1.0f) * _param_fw_flaperon_scl.get();
710 && fabsf(_param_fw_flaperon_scl.get()) > 0.01
f) {
713 flaperon_control = _param_fw_flaperon_scl.get();
716 flaperon_control = 0.0f;
734 _object.store(instance);
735 _task_id = task_id_is_work_queue;
737 if (instance->
init()) {
742 PX4_ERR(
"alloc failed");
746 _object.store(
nullptr);
767 PX4_WARN(
"%s\n", reason);
770 PRINT_MODULE_DESCRIPTION(
773 fw_att_control is the fixed wing attitude controller. 777 PRINT_MODULE_USAGE_COMMAND("start");
778 PRINT_MODULE_USAGE_NAME(
"fw_att_control",
"controller");
779 PRINT_MODULE_USAGE_DEFAULT_COMMANDS();
#define VEHICLE_TYPE_FIXED_WING
FixedwingAttitudeControl()
constexpr _Tp constrain(_Tp val, _Tp min_val, _Tp max_val)
static int task_spawn(int argc, char *argv[])
bool flag_control_offboard_enabled
void vehicle_rates_setpoint_poll()
vehicle_attitude_s _att
vehicle attitude setpoint
int print_status() override
bool flag_control_rates_enabled
void set_time_constant(float time_constant)
measure the time elapsed performing an event
void vehicle_status_poll()
bool flag_control_rattitude_enabled
uORB::Subscription _vehicle_status_sub
vehicle status subscription
bool flag_control_auto_enabled
bool update(void *dst)
Copy the struct if updated.
uORB::Subscription _vehicle_rates_sub
float pitch_rate_setpoint
__EXPORT int param_get(param_t param, void *val)
Copy the value of a parameter.
bool is_fixed_wing(const struct vehicle_status_s *current_status)
orb_id_t _actuators_id
pointer to correct actuator controls0 uORB metadata structure
bool flag_control_climb_rate_enabled
int main(int argc, char **argv)
manual_control_setpoint_s _manual
r/c channel data
uORB::Subscription _battery_status_sub
battery status subscription
ECL_YawController _yaw_ctrl
float get_airspeed_and_update_scaling()
actuator_controls_s _actuators
actuator control inputs
vehicle_control_mode_s _vcontrol_mode
vehicle control mode
orb_advert_t orb_advertise(const struct orb_metadata *meta, const void *data)
void set_max_rate(float max_rate)
perf_counter_t _loop_perf
loop performance counter
float control_bodyrate(const struct ECL_ControlData &ctl_data) override
vehicle_attitude_setpoint_s _att_sp
vehicle attitude setpoint
void vehicle_control_mode_poll()
uORB::SubscriptionData< airspeed_validated_s > _airspeed_validated_sub
float control_attitude(const struct ECL_ControlData &ctl_data) override
static int custom_command(int argc, char *argv[])
void set_max_rate_pos(float max_rate_pos)
uORB::Subscription _vcontrol_mode_sub
vehicle status subscription
const T gradual(const T &value, const T &x_low, const T &x_high, const T &y_low, const T &y_high)
ECL_PitchController _pitch_ctrl
uORB::PublicationMulti< rate_ctrl_status_s > _rate_ctrl_status_pub
rate controller status publication
#define ORB_ID(_name)
Generates a pointer to the uORB metadata structure for a given topic.
uORB::Subscription _rates_sp_sub
vehicle rates setpoint
bool publish(const T &data)
Publish the struct.
bool flag_control_manual_enabled
bool flag_control_termination_enabled
uORB::Publication< actuator_controls_s > _actuators_2_pub
actuator control group 1 setpoint (Airframe)
orb_id_t _attitude_setpoint_id
void perf_free(perf_counter_t handle)
Free a counter.
void vehicle_manual_poll()
bool pitch_reset_integral
uORB::Subscription _global_pos_sub
global position subscription
orb_advert_t _attitude_sp_pub
attitude setpoint point
float indicated_airspeed_m_s
constexpr T radians(T degrees)
Vector< float, 6 > f(float t, const Matrix< float, 6, 1 > &, const Matrix< float, 3, 1 > &)
float control_attitude(const struct ECL_ControlData &ctl_data) override
static hrt_abstime hrt_elapsed_time(const hrt_abstime *then)
Compute the delta between a timestamp taken in the past and now.
void set_k_ff(float k_ff)
void set_max_rate_neg(float max_rate_neg)
orb_advert_t _actuators_0_pub
actuator control group 0 setpoint
vehicle_status_s _vehicle_status
vehicle status
void perf_end(perf_counter_t handle)
End a performance event.
bool flag_control_attitude_enabled
uint64_t timestamp_sample
bool updated()
Check if there is a new update.
float control_attitude(const struct ECL_ControlData &ctl_data) override
float get_desired_bodyrate()
uORB::Publication< vehicle_rates_setpoint_s > _rate_sp_pub
rate setpoint publication
int orb_publish(const struct orb_metadata *meta, orb_advert_t handle, const void *data)
uORB::SubscriptionCallbackWorkItem _att_sub
vehicle attitude
void control_flaps(const float dt)
__EXPORT param_t param_find(const char *name)
Look up a parameter by name.
actuator_controls_s _actuators_airframe
actuator control inputs
float control_euler_rate(const struct ECL_ControlData &ctl_data) override
void set_bodyrate_setpoint(float rate)
constexpr _Tp max(_Tp a, _Tp b)
int parameters_update()
Update our local parameter cache.
vehicle_global_position_s _global_pos
global position
Quaternion< float > Quatf
void perf_print_counter(perf_counter_t handle)
Print one performance counter to stdout.
void unregisterCallback()
~FixedwingAttitudeControl() override
uORB::Subscription _vehicle_land_detected_sub
vehicle land detected subscription
float control_bodyrate(const struct ECL_ControlData &ctl_data) override
uORB::Subscription _att_sp_sub
vehicle attitude setpoint
bool update(void *dst)
Update the struct.
uORB::Subscription _manual_sub
notification of manual control updates
__EXPORT int fw_att_control_main(int argc, char *argv[])
vehicle_rates_setpoint_s _rates_sp
static int print_usage(const char *reason=nullptr)
uORB::Subscription _parameter_update_sub
notification of parameter updates
ECL_WheelController _wheel_ctrl
bool publish(const T &data)
Publish the struct.
float control_euler_rate(const struct ECL_ControlData &ctl_data) override
float control_bodyrate(const struct ECL_ControlData &ctl_data) override
void vehicle_attitude_setpoint_poll()
bool copy(void *dst)
Copy the struct.
void perf_begin(perf_counter_t handle)
Begin a performance event.
void set_integrator_max(float max)
__EXPORT hrt_abstime hrt_absolute_time(void)
Get absolute time in [us] (does not wrap).
void set_bodyrate_setpoint(float rate)
bool _flag_control_attitude_enabled_last
void vehicle_land_detected_poll()