/// @file AC_P_2D.cpp1/// @brief 2D P controller with output limiting, derivative constraint, and EEPROM-backed gain storage.23#include <AP_Math/AP_Math.h>4#include "AC_P_2D.h"56const AP_Param::GroupInfo AC_P_2D::var_info[] = {7// @Param: P8// @DisplayName: Proportional Gain9// @Description: Proportional gain that generates output based on the current error value10AP_GROUPINFO_FLAGS_DEFAULT_POINTER("P", 0, AC_P_2D, _kp, default_kp),11AP_GROUPEND12};1314// Constructor15AC_P_2D::AC_P_2D(float initial_p) :16default_kp(initial_p)17{18// load parameter values from eeprom19AP_Param::setup_object_defaults(this, var_info);20}2122// Computes the P controller output given a target and measurement.23// Applies position error clamping based on configured limits.24// Optionally constrains output slope using the sqrt_controller.25Vector2f AC_P_2D::update_all(Vector2p &target, const Vector2p &measurement)26{27// Compute vector error between target and measurement (NED frame)28_error = (target - measurement).tofloat();2930// Limit error vector length to prevent exceeding output constraints31if (is_positive(_error_max) && _error.limit_length(_error_max)) {32target = measurement + _error.topostype();33}3435// Use sqrt_controller to limit output and/or its derivative36return sqrt_controller(_error, _kp, _D1_max, 0.0);37}3839// Sets limits on output, output slope (D1), and output acceleration (D2).40// For position controllers: output = velocity, D1 = acceleration, D2 = jerk.41void AC_P_2D::set_limits(float output_max, float D_Out_max, float D2_Out_max)42{43// Reset all limits to zero before applying new ones44_D1_max = 0.0f;45_error_max = 0.0f;4647// Set first derivative (acceleration) limit if specified48if (is_positive(D_Out_max)) {49_D1_max = D_Out_max;50}5152// If second derivative (jerk) limit is specified, constrain velocity limit accordingly53if (is_positive(D2_Out_max) && is_positive(_kp)) {54// limit the first derivative so as not to exceed the second derivative55_D1_max = MIN(_D1_max, D2_Out_max / _kp);56}5758// Compute min/max allowable error from output limits59if (is_positive(output_max) && is_positive(_kp)) {60_error_max = inv_sqrt_controller(output_max, _kp, _D1_max);61}62}6364// Reduces the maximum allowable error after limit initialization.65// Intended to be called after set_limits().66void AC_P_2D::set_error_max(float error_max)67{68// Update _error_min if it's non-zero and the new value is more conservative69if (is_positive(error_max)) {70if (!is_zero(_error_max) ) {71_error_max = MIN(_error_max, error_max);72} else {73_error_max = error_max;74}75}76}777879