pid_controller.cpp
Go to the documentation of this file.
1 /*********************************************************************
2  *
3  * Software License Agreement
4  *
5  * Copyright (c) 2020,
6  * TU Dortmund - Institute of Control Theory and Systems Engineering.
7  * All rights reserved.
8  *
9  * This program is free software: you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation, either version 3 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program. If not, see <https://www.gnu.org/licenses/>.
21  *
22  * Authors: Christoph Rösmann
23  *********************************************************************/
24 
26 #include <corbo-core/console.h>
27 
28 #include <algorithm>
29 
30 namespace corbo {
31 
33 
34 bool PidController::step(const ControllerInterface::StateVector& x, ReferenceTrajectoryInterface& xref, ReferenceTrajectoryInterface& uref,
35  const Duration& dt, const Time& t, TimeSeries::Ptr u_sequence, TimeSeries::Ptr x_sequence,
36  SignalTargetInterface* signal_target, ReferenceTrajectoryInterface* sref, ReferenceTrajectoryInterface* xinit,
37  ReferenceTrajectoryInterface* uinit, const std::string& ns)
38 {
39  assert(x.rows() == xref.getDimension() && "Dimension mismatch in controller: current state x and reference");
40 
42  xref.getReference(t, yref);
43 
44  if (yref.rows() != _num_parallel_pid)
45  {
46  PRINT_WARNING("PidController number of parallel PID controllers does not match dimension of the state vector.");
47  return false;
48  }
49  if (uref.getDimension() != _num_parallel_pid)
50  {
51  PRINT_WARNING("PidController: number of parallel PID controllers does not match number of required control inputs");
52  return false;
53  }
54 
55  assert(_num_parallel_pid == _p_error.size());
56  assert(_num_parallel_pid == _i_error.size());
57  assert(_num_parallel_pid == _d_error.size());
58 
59  ControlVector u;
60 
61  for (int i = 0; i < _num_parallel_pid; ++i)
62  {
63  double p_error_last = _p_error[i];
64 
65  _p_error[i] = yref[i] - x[i];
66  _d_error[i] = dt.toSec() > 0 ? (_p_error[i] - p_error_last) / dt.toSec() : 0.0;
67  _i_error[i] += dt.toSec() * _p_error[i];
68 
69  u.resize(_num_parallel_pid);
70  u[i] = _p_gain * _p_error[i] + _i_gain * _i_error[i] + _d_gain * _d_error[i];
71 
72  if (signal_target && _publish_error)
73  {
74  signal_target->sendMeasurement(ns + "controller/error/p", t.toSec(), _p_error);
75  signal_target->sendMeasurement(ns + "controller/error/i", t.toSec(), _i_error);
76  signal_target->sendMeasurement(ns + "controller/error/d", t.toSec(), _d_error);
77  }
78  }
79 
80  u_sequence->clear();
81  x_sequence->clear();
82  u_sequence->add(0.0, u);
83  x_sequence->add(0.0, x);
84 
85  return true;
86 }
87 
88 void PidController::getAvailableSignals(SignalTargetInterface& signal_target, const std::string& ns) const
89 {
90  if (_publish_error)
91  {
92  signal_target.registerMeasurement(ns + "controller/error/p", _num_parallel_pid);
93  signal_target.registerMeasurement(ns + "controller/error/i", _num_parallel_pid);
94  signal_target.registerMeasurement(ns + "controller/error/d", _num_parallel_pid);
95  }
96 }
97 
99 {
100  std::fill(_p_error.begin(), _p_error.end(), 0.0);
101  std::fill(_d_error.begin(), _d_error.end(), 0.0);
102  std::fill(_i_error.begin(), _i_error.end(), 0.0);
103 }
104 
105 #ifdef MESSAGE_SUPPORT
106 void PidController::toMessage(corbo::messages::Controller& message) const
107 {
108  message.mutable_pid_controller()->set_p_gain(_p_gain);
109  message.mutable_pid_controller()->set_i_gain(_i_gain);
110  message.mutable_pid_controller()->set_d_gain(_d_gain);
111 
112  message.mutable_pid_controller()->set_num_parallel_pid(_num_parallel_pid);
113 
114  message.mutable_pid_controller()->set_publish_error(_publish_error);
115 }
116 
117 void PidController::fromMessage(const corbo::messages::Controller& message, std::stringstream* issues)
118 {
119  _p_gain = message.pid_controller().p_gain();
120  _i_gain = message.pid_controller().i_gain();
121  _d_gain = message.pid_controller().d_gain();
122 
123  setNumParallelPid(message.pid_controller().num_parallel_pid());
124 
125  _publish_error = message.pid_controller().publish_error();
126 }
127 #endif
128 
129 } // namespace corbo
corbo::PidController::_num_parallel_pid
int _num_parallel_pid
Definition: pid_controller.h:165
PRINT_WARNING
#define PRINT_WARNING(msg)
Print msg-stream.
Definition: console.h:145
corbo
Definition: communication/include/corbo-communication/utilities.h:37
corbo::PidController::getAvailableSignals
void getAvailableSignals(SignalTargetInterface &signal_target, const std::string &ns="") const override
Retrieve available signals from the controller.
Definition: pid_controller.cpp:110
corbo::PidController::_i_error
std::vector< double > _i_error
Definition: pid_controller.h:161
console.h
corbo::PidController::_p_error
std::vector< double > _p_error
Definition: pid_controller.h:160
corbo::ControllerInterface::ControlVector
Eigen::VectorXd ControlVector
Definition: controller_interface.h:108
x
Scalar * x
Definition: level1_cplx_impl.h:89
corbo::PidController::_i_gain
double _i_gain
Definition: pid_controller.h:156
corbo::PidController::reset
void reset() override
Reset internal controller state and caches.
Definition: pid_controller.cpp:120
pid_controller.h
corbo::ReferenceTrajectoryInterface::OutputVector
Eigen::VectorXd OutputVector
Definition: reference_trajectory.h:108
corbo::ControllerInterface::StateVector
Eigen::VectorXd StateVector
Definition: controller_interface.h:107
corbo::PidController::PidController
PidController()
Definition: pid_controller.cpp:54
corbo::TimeSeries::Ptr
std::shared_ptr< TimeSeries > Ptr
Definition: time_series.h:108
corbo::PidController::_d_error
std::vector< double > _d_error
Definition: pid_controller.h:162
corbo::PidController::_d_gain
double _d_gain
Definition: pid_controller.h:157
corbo::PidController::step
bool step(const StateVector &x, ReferenceTrajectoryInterface &xref, ReferenceTrajectoryInterface &uref, const Duration &dt, const Time &t, TimeSeries::Ptr u_sequence, TimeSeries::Ptr x_sequence, SignalTargetInterface *signal_target=nullptr, ReferenceTrajectoryInterface *sref=nullptr, ReferenceTrajectoryInterface *xinit=nullptr, ReferenceTrajectoryInterface *uinit=nullptr, const std::string &ns="") override
Definition: pid_controller.cpp:56
corbo::PidController::setNumParallelPid
void setNumParallelPid(int num_parallel_pid)
Definition: pid_controller.h:121
corbo::PidController::_publish_error
bool _publish_error
Definition: pid_controller.h:167
corbo::PidController::_p_gain
double _p_gain
Definition: pid_controller.h:155


control_box_rst
Author(s): Christoph Rösmann
autogenerated on Wed Mar 2 2022 00:06:03