Libbarrett  1.2.4
include/barrett/systems/detail/pid_controller-inl.h
00001 /*
00002         Copyright 2009, 2010 Barrett Technology <support@barrett.com>
00003 
00004         This file is part of libbarrett.
00005 
00006         This version of libbarrett is free software: you can redistribute it
00007         and/or modify it under the terms of the GNU General Public License as
00008         published by the Free Software Foundation, either version 3 of the
00009         License, or (at your option) any later version.
00010 
00011         This version of libbarrett is distributed in the hope that it will be
00012         useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
00013         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014         GNU General Public License for more details.
00015 
00016         You should have received a copy of the GNU General Public License along
00017         with this version of libbarrett.  If not, see
00018         <http://www.gnu.org/licenses/>.
00019 
00020         Further, non-binding information about licensing is available at:
00021         <http://wiki.barrett.com/libbarrett/wiki/LicenseNotes>
00022 */
00023 
00024 /*
00025  * pid_controller-inl.h
00026  *
00027  *  Created on: Oct 20, 2009
00028  *      Author: dc
00029  */
00030 
00031 
00032 #include <cassert>
00033 
00034 #include <libconfig.h++>
00035 
00036 #include <barrett/math/utils.h>
00037 #include <barrett/thread/abstract/mutex.h>
00038 
00039 
00040 namespace barrett {
00041 namespace systems {
00042 
00043 
00044 template<typename InputType, typename OutputType, typename MathTraits>
00045 PIDController<InputType, OutputType, MathTraits>::PIDController(const std::string& sysName) :
00046         Controller<InputType, OutputType>(sysName),
00047         T_s(0.0), error(0.0), error_1(0.0), intError(0.0), intErrorLimit(0.0),
00048         kp(0.0), ki(0.0), kd(0.0), controlSignal(0.0), controlSignalLimit(0.0)
00049 {
00050         getSamplePeriodFromEM();
00051 }
00052 
00053 template<typename InputType, typename OutputType, typename MathTraits>
00054 PIDController<InputType, OutputType, MathTraits>::PIDController(
00055                 const libconfig::Setting& setting, const std::string& sysName) :
00056         Controller<InputType, OutputType>(sysName),
00057         T_s(0.0), error(0.0), error_1(0.0), intError(0.0), intErrorLimit(0.0),
00058         kp(0.0), ki(0.0), kd(0.0), controlSignal(0.0), controlSignalLimit(0.0)
00059 {
00060         getSamplePeriodFromEM();
00061         setFromConfig(setting);
00062 }
00063 
00064 template<typename InputType, typename OutputType, typename MathTraits>
00065 void PIDController<InputType, OutputType, MathTraits>::setFromConfig(const libconfig::Setting& setting)
00066 {
00067         if (setting.exists("kp")) {
00068                 setKp(unitless_type(setting["kp"]));
00069         } else {
00070                 setKp(unitless_type(0.0));
00071         }
00072         if (setting.exists("ki")) {
00073                 setKi(unitless_type(setting["ki"]));
00074         } else {
00075                 setKi(unitless_type(0.0));
00076         }
00077         if (setting.exists("kd")) {
00078                 setKd(unitless_type(setting["kd"]));
00079         } else {
00080                 setKd(unitless_type(0.0));
00081         }
00082         if (setting.exists("integrator_limit")) {
00083                 setIntegratorLimit(unitless_type(setting["integrator_limit"]));
00084         } else {
00085                 setIntegratorLimit(unitless_type(0.0));
00086         }
00087         if (setting.exists("control_signal_limit")) {
00088                 setControlSignalLimit(unitless_type(setting["control_signal_limit"]));
00089         } else {
00090                 setControlSignalLimit(unitless_type(0.0));
00091         }
00092 }
00093 
00094 template<typename InputType, typename OutputType, typename MathTraits>
00095 void PIDController<InputType, OutputType, MathTraits>::setSamplePeriod(double timeStep)
00096 {
00097         T_s = timeStep;
00098 }
00099 
00100 template<typename InputType, typename OutputType, typename MathTraits>
00101 void PIDController<InputType, OutputType, MathTraits>::setKp(const unitless_type& proportionalGains)
00102 {
00103         kp = proportionalGains;
00104 }
00105 
00106 template<typename InputType, typename OutputType, typename MathTraits>
00107 void PIDController<InputType, OutputType, MathTraits>::setKi(const unitless_type& integralGains)
00108 {
00109         ki = integralGains;
00110 }
00111 
00112 template<typename InputType, typename OutputType, typename MathTraits>
00113 void PIDController<InputType, OutputType, MathTraits>::setKd(const unitless_type& derivitiveGains)
00114 {
00115         kd = derivitiveGains;
00116 }
00117 
00118 template<typename InputType, typename OutputType, typename MathTraits>
00119 void PIDController<InputType, OutputType, MathTraits>::setIntegratorState(
00120                 const unitless_type& integratorState)
00121 {
00122         // intError is written and read in operate(), so it needs to be locked.
00123         BARRETT_SCOPED_LOCK(this->getEmMutex());
00124         intError = integratorState;
00125 }
00126 
00127 template<typename InputType, typename OutputType, typename MathTraits>
00128 void PIDController<InputType, OutputType, MathTraits>::setIntegratorLimit(
00129                 const unitless_type& intSaturations)
00130 {
00131         intErrorLimit = intSaturations;
00132 }
00133 
00134 template<typename InputType, typename OutputType, typename MathTraits>
00135 void PIDController<InputType, OutputType, MathTraits>::setControlSignalLimit(
00136                 const unitless_type& csSaturations)
00137 {
00138         controlSignalLimit = csSaturations;
00139 }
00140 
00141 
00142 template<typename InputType, typename OutputType, typename MathTraits>
00143 inline void PIDController<InputType, OutputType, MathTraits>::resetIntegrator()
00144 {
00145         setIntegratorState(unitless_type(0.0));
00146 }
00147 
00148 
00149 template<typename InputType, typename OutputType, typename MathTraits>
00150 void PIDController<InputType, OutputType, MathTraits>::operate()
00151 {
00152         typedef MathTraits MT;
00153 
00154         error = MT::sub(this->referenceInput.getValue(), this->feedbackInput.getValue());
00155 
00156         intError = MT::add(intError, MT::mult(ki, MT::mult(T_s, error_1)));
00157         if (intErrorLimit != MT::zero()) {
00158                 intError = math::saturate(intError, intErrorLimit);
00159         }
00160 
00161         controlSignal = MT::add(MT::mult(kp, error),
00162                                                         MT::add(intError,
00163                                                                 MT::mult(kd, MT::div(MT::sub(error, error_1), T_s))));
00164         if (controlSignalLimit != MT::zero()) {
00165                 controlSignal = math::saturate(controlSignal, controlSignalLimit);
00166         }
00167 
00168         error_1 = error;
00169 
00170         this->controlOutputValue->setData(&controlSignal);
00171 }
00172 
00173 
00174 template<typename InputType, typename OutputType, typename MathTraits>
00175 void PIDController<InputType, OutputType, MathTraits>::getSamplePeriodFromEM()
00176 {
00177         if (this->hasExecutionManager()) {
00178                 assert(this->getExecutionManager()->getPeriod() > 0.0);
00179                 setSamplePeriod(this->getExecutionManager()->getPeriod());
00180         } else {
00181                 setSamplePeriod(0.0);
00182         }
00183 }
00184 
00185 
00186 }
00187 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Defines