25#include "absl/strings/str_cat.h"
39 const double input_limit,
40 const double input_rate_limit) {
44 AERROR <<
"MRAC: model build failed; will work as a unity compensator. The "
45 "reference_model building status: "
47 <<
"; The adaption_model building status: "
65 double state_bounded = 0.0;
89 double control_unbounded =
187 const double Epsilon = 0.000001;
191 const auto error_msg = absl::StrCat(
192 "mrac controller error: reference model time-constant parameter: ",
194 "and natural frequency parameter: ",
196 " in configuration file are not reasonable with respect to the "
197 "reference model order: ",
200 return Status(ErrorCode::CONTROL_INIT_ERROR, error_msg);
211 const int p_size = mrac_conf.adaption_matrix_p_size();
212 const int x_size = mrac_conf.adaption_state_gain_size();
213 const int aw_size = mrac_conf.anti_windup_compensation_gain_size();
216 const auto error_msg = absl::StrCat(
217 "mrac controller error: adaption matrix p element number: ", p_size,
218 ", state gain number: ", x_size,
219 ", and anti-windup compensation gain number: ", aw_size,
220 " in configuration file do not match the model number: ",
model_order_);
222 return Status(ErrorCode::CONTROL_INIT_ERROR, error_msg);
244 const auto error_msg =
245 absl::StrCat(
"mrac controller error: reference model order ",
248 return Status(ErrorCode::CONTROL_INIT_ERROR, error_msg);
264 const auto error_msg =
265 absl::StrCat(
"mrac controller error: adaption model order ",
268 return Status(ErrorCode::CONTROL_INIT_ERROR, error_msg);
276 const std::string error_msg =
277 "Solution of the algebraic Lyapunov equation is not symmetric positive "
280 return Status(ErrorCode::CONTROL_INIT_ERROR, error_msg);
286 const Matrix matrix_p)
const {
287 Matrix matrix_q = -matrix_p * matrix_a - matrix_a.transpose() * matrix_p;
288 Eigen::LLT<Matrix> llt_matrix_q(matrix_q);
291 return (matrix_q.isApprox(matrix_q.transpose()) &&
292 llt_matrix_q.info() != Eigen::NumericalIssue);
296 const double rise_time_estimate =
298 const double settling_time_estimate =
305 (rise_time_estimate >=
ts_ || settling_time_estimate >=
ts_)) {
306 const double tau_estimate = (rise_time_estimate >=
ts_)
307 ? rise_time_estimate / 2.2
308 : settling_time_estimate / 4.0;
310 matrix_a_estimate(0, 0) = -1.0 / tau_estimate;
311 matrix_b_estimate(0, 0) = 1.0 / tau_estimate;
314 matrix_b_estimate(0, 0);
322 (matrix_a_clamping(0, 0) - matrix_a_estimate(0, 0)) /
323 matrix_b_estimate(0, 0);
325 matrix_b_clamping(0, 0) / matrix_b_estimate(0, 0);
328 (rise_time_estimate >=
ts_ && settling_time_estimate >=
ts_)) {
329 const double wn_estimate = 1.8 / rise_time_estimate;
330 const double zeta_estimate =
331 4.6 / (rise_time_estimate * settling_time_estimate);
332 matrix_a_estimate(0, 1) = 1.0;
333 matrix_a_estimate(1, 0) = -wn_estimate * wn_estimate;
334 matrix_a_estimate(1, 1) = -2 * zeta_estimate * wn_estimate;
335 matrix_b_estimate(1, 0) = wn_estimate * wn_estimate;
337 (common::math::PseudoInverse<double, 2, 1>(matrix_b_estimate) *
341 (common::math::PseudoInverse<double, 2, 1>(matrix_b_estimate) *
345 AWARN <<
"No pre-known actuation dynamics; the initial states of the "
346 "adaptive gains are set as zeros";
364 0.5 *
ts_ * gain_adp *
365 (state_adp.col(0) * (state_error.col(0).transpose() +
367 state_adp.col(1) * (state_error.col(1).transpose() +
373 const double previous_command) {
375 offset_windup(0, 0) =
381 offset_windup(1, 0) =
394 const double previous_output,
double *output) {
416 *output = output_unbounded;
424 const Matrix &state_reference_init) {
426 state_reference_init.cols() != 1) {
427 AWARN <<
"failed to set the initial reference states, due to the given "
429 << state_reference_init.
rows() <<
" x " << state_reference_init.cols()
438 state_action_init.cols() != 1) {
439 AWARN <<
"failed to set the initial action states, due to the given "
441 << state_action_init.
rows() <<
" x " << state_action_init.cols()
453 const Matrix &gain_state_adaption_init) {
455 gain_state_adaption_init.cols() != 1) {
456 AWARN <<
"failed to set the initial state adaption gains, due to the given "
458 << gain_state_adaption_init.
rows() <<
" x "
459 << gain_state_adaption_init.cols()
467 const double gain_input_adaption_init) {
472 const double gain_nonlinear_adaption_init) {
477 if (ratio_state < 0.0) {
478 AWARN <<
"failed to set the state adaption rate, due to new ratio < 0; the "
479 "current ratio is still: "
487 if (ratio_input < 0.0) {
488 AWARN <<
"failed to set the input adaption rate, due to new ratio < 0; the "
489 "current ratio is still: "
497 if (ratio_nonlinear < 0.0) {
498 AWARN <<
"failed to set the nonlinear adaption rate, due to new ratio < 0; "
499 "the current ratio is still: "
A general class to denote the return status of an API call.
bool ok() const
check whether the return status is OK.
static Status OK()
generate a success status.
void SetInitialNonlinearAdaptionGain(const double gain_nonlinear_adaption_init)
set initial value of nonlinear adaption gain for mrac control
void ResetStates()
reset internal states for mrac controller
bool adaption_clamping_enabled
void SetInitialCommand(const double command_init)
set initial command (desired input)
common::Status BuildReferenceModel()
build mrac (1st or 2nd) order reference model in the discrete-time form, with the bilinear transform ...
Eigen::MatrixXd compensation_anti_windup_
double gamma_ratio_nonlinear_
bool reference_model_enabled_
common::Status BuildAdaptionModel()
build mrac (1st or 2nd) order adaptive dynamic model in the discrete-time form
void SetInitialActionState(const Eigen::MatrixXd &state_action_init)
set initial values for state components in actual actuator dynamics
common::Status SetAdaptionModel(const MracConf &mrac_conf)
state adaptive gain, desired adaptive gain and nonlinear-component adaptive gain
Eigen::MatrixXd matrix_a_reference_
int saturation_status_control_
void SetInputAdaptionRate(const double ratio_input)
set convergence ratio for input components in adaptive dynamics
Eigen::MatrixXd gamma_nonlinear_adaption_
void EstimateInitialGains(const common::LatencyParam &latency_param)
estimate the initial states of the adaptive gains via known actuation dynamics approximation
double InputAdaptionRate() const
get convergence ratio for input components in adaptive dynamics
Eigen::MatrixXd gain_input_adaption_
double NonlinearAdaptionRate() const
get convergence ratio for nonlinear components in adaptive dynamics
void SetNonlinearAdaptionRate(const double ratio_nonlinear)
set convergence ratio for nonlinear components in adaptive dynamics
Eigen::MatrixXd gamma_input_adaption_
double bound_command_rate_
Eigen::MatrixXd gain_state_clamping_
Eigen::MatrixXd CurrentInputAdaptionGain() const
get current input adaptive gain for mrac control
Eigen::MatrixXd state_action_
void SetInitialInputAdaptionGain(const double gain_input_adaption_init)
set initial value of input adaption gain for mrac control
int saturation_status_reference_
Eigen::MatrixXd gain_state_adaption_init_
bool adaption_model_enabled_
virtual double Control(const double command, const Eigen::MatrixXd state, const double input_limit, const double input_rate_limit)
compute control value based on the original command
void Init(const MracConf &mrac_conf, const common::LatencyParam &latency_param, const double dt)
initialize mrac controller
int ReferenceSaturationStatus() const
get saturation status for reference system
Eigen::MatrixXd matrix_b_adaption_
void ResetGains()
reset adaptive gains for mrac controller
double gamma_ratio_state_
void UpdateAdaption(Eigen::MatrixXd *law_adp, const Eigen::MatrixXd state_adp, const Eigen::MatrixXd gain_adp)
execute the adaption interation with respect to the designed law in discrete-time form,...
Eigen::MatrixXd gain_input_clamping_
double gamma_ratio_input_
void Reset()
reset all the variables (including all the states, gains and externally-setting control parameters) f...
Eigen::MatrixXd CurrentNonlinearAdaptionGain() const
get current nonlinear adaptive gain for mrac control
Eigen::MatrixXd gain_input_adaption_init_
Eigen::MatrixXd gain_nonlinear_adaption_
common::Status SetReferenceModel(const MracConf &mrac_conf)
time constant, natural frequency and damping ratio
Eigen::MatrixXd gain_anti_windup_
void AntiWindupCompensation(const double control_command, const double previous_command)
calculate the anti-windup compensation with respect to the integral windup issue
Eigen::MatrixXd matrix_b_reference_
Eigen::MatrixXd gain_nonlinear_adaption_init_
Eigen::MatrixXd gain_state_adaption_
int ControlSaturationStatus() const
get saturation status for control system
Eigen::MatrixXd matrix_p_adaption_
Eigen::MatrixXd input_desired_
void SetInitialReferenceState(const Eigen::MatrixXd &state_reference_init)
set initial values for state components in reference model dynamics
double StateAdaptionRate() const
get convergence ratio for state components in adaptive dynamics
void SetStateAdaptionRate(const double ratio_state)
set convergence ratio for state components in adaptive dynamics
int BoundOutput(const double output_unbounded, const double previous_output, double *output_bounded)
bound the system output with the given bound and change-rate bound
bool CheckLyapunovPD(const Eigen::MatrixXd matrix_a, const Eigen::MatrixXd matrix_p) const
check if the solution of the algebraic Lyapunov Equation is symmetric positive definite
void SetInitialStateAdaptionGain(const Eigen::MatrixXd &gain_state_adaption_init)
set initial values of state adaption gains for mrac control
Eigen::MatrixXd CurrentReferenceState() const
get current state for reference system
Eigen::MatrixXd state_reference_
Eigen::MatrixXd gamma_state_adaption_
Eigen::MatrixXd CurrentStateAdaptionGain() const
get current state adaptive gain for mrac control
Eigen::MatrixXd gain_nonlinear_clamping_
void UpdateReference()
execute the reference state interation with respect to the designed inputs in discrete-time form,...
Defines some useful matrix operations.
optional double dead_time
optional double settling_time
optional double rise_time
optional double adaption_nonlinear_gain
optional int32 mrac_model_order
optional double reference_damping_ratio
repeated double adaption_matrix_p
optional double reference_natural_frequency
optional double reference_time_constant
optional double clamping_time_constant
optional double adaption_desired_gain
repeated double adaption_state_gain
repeated double anti_windup_compensation_gain
optional double mrac_saturation_level