1 /* Siconos is a program dedicated to modeling, simulation and control 2 * of non smooth dynamical systems. 3 * 4 * Copyright 2021 INRIA. 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 19 /*! \file CommonSMC.hpp 20 \brief General interface to define a sliding mode actuator 21 */ 22 23 #ifndef CommonSMC_H 24 #define CommonSMC_H 25 26 #include "Actuator.hpp" 27 #include "SiconosAlgebraTypeDef.hpp" 28 #include "SiconosFwd.hpp" 29 30 #include <relay_cst.h> 31 32 class CommonSMC : public Actuator 33 { 34 private: 35 /** serialization hooks */ 36 ACCEPT_SERIALIZATION(CommonSMC); 37 38 protected: 39 /** default constructor */ CommonSMC()40 CommonSMC() {}; 41 42 /** index for saving data */ 43 unsigned int _indx; 44 45 /** name of the plugin to add a term to the sliding variable; useful when doing trajectory tracking */ 46 std::string _plugineName; 47 48 /** name of the plugin to compute \f$y = h(x, ...)\f$ for the nonlinear case*/ 49 std::string _pluginhName; 50 51 /** name of the plugin to compute \f$\nabla_x h\f$ for the nonlinear case*/ 52 std::string _pluginJachxName; 53 54 /** name of the plugin to compute \f$\nabla_\lambda h\f$ for the nonlinear case*/ 55 std::string _pluginJachlambdaName; 56 57 /** name of the plugin to compute \f$\nabla_\lambda g\f$ for the nonlinear case*/ 58 std::string _pluginJacglambdaName; 59 60 /** the vector defining the linear contribution of the state to the sliding variable (\f$ \sigma = Cx \f$) */ 61 SP::SimpleMatrix _Csurface; 62 63 /** matrix describing the influence of \f$lambda\f$ on \f$\sigma\f$ */ 64 SP::SimpleMatrix _D; 65 66 /** scalar multiplying Sign; \f$ u^s = - \alpha Sign \f$ */ 67 double _alpha; 68 69 /** the Relation for the Controller */ 70 SP::FirstOrderR _relationSMC; 71 72 /** Interaction for the control */ 73 SP::Interaction _interactionSMC; 74 75 /** easy access to lambda */ 76 SP::SiconosVector _lambda; 77 78 /** Relay solver type */ 79 int _numericsSolverId; 80 81 /** Numerical precision expected for the Relay solver */ 82 double _precision; 83 84 /** the nsds for the controller */ 85 SP::NonSmoothDynamicalSystem _nsdsSMC; 86 87 /** the DynamicalSystem for the controller */ 88 SP::FirstOrderNonLinearDS _DS_SMC; // XXX replace this by FirstOrderDS 89 90 /** the TimeDiscretisation for the controller */ 91 SP::TimeDiscretisation _td; 92 93 /** Simulation for the controller */ 94 SP::TimeStepping _simulationSMC; 95 96 /** Integrator for the controller */ 97 SP::OneStepIntegrator _integratorSMC; 98 99 /** Theta for the controller */ 100 double _thetaSMC; 101 102 /** OneStepNsProblem for the controller */ 103 SP::LinearOSNS _OSNSPB_SMC; 104 105 /** SP::EventsManager of the SMC Simulation */ 106 SP::EventsManager _eventsManager; 107 108 /** SP::NonSmoothLaw for computing the control law */ 109 SP::NonSmoothLaw _nsLawSMC; 110 111 /** inverse of CB */ 112 SP::SimpleMatrix _invCB; 113 114 /** Store \f$u^{eq}\f$ */ 115 SP::SiconosVector _ueq; 116 117 /** Store \f$u^s\f$ */ 118 SP::SiconosVector _us; 119 120 /** Do not use the state-continuous equivaluent control \f$u^{eq}\f$ */ 121 bool _noUeq; 122 123 /** If true perform the computation of the residus in the Newton loop if needed */ 124 bool _computeResidus; 125 126 /** Compute the equivalent part of the control \f$u^{eq}\f$. 127 * The method used here is to discretize the continuous-time 128 * formula using a theta method 129 */ 130 void computeUeq(); 131 132 public: 133 134 /**General constructor 135 * \param type the type of the SMC Actuator 136 * \param sensor the ControlSensor feeding the Actuator 137 */ CommonSMC(unsigned int type,SP::ControlSensor sensor)138 CommonSMC(unsigned int type, SP::ControlSensor sensor): Actuator(type, sensor), 139 _indx(0), _alpha(1.0), _numericsSolverId(SICONOS_RELAY_AVI_CAOFERRIS), _precision(1e-8), 140 _thetaSMC(0.5), _noUeq(false), _computeResidus(true) {} 141 142 /** Constructor for dynamics affine in control 143 * \param type the type of the SMC Actuator 144 * \param sensor the ControlSensor feeding the Actuator 145 * \param B the matrix multiplying the control input 146 * \param D the saturation matrix (optional) 147 */ CommonSMC(unsigned int type,SP::ControlSensor sensor,SP::SimpleMatrix B,SP::SimpleMatrix D=std::shared_ptr<SimpleMatrix> ())148 CommonSMC(unsigned int type, SP::ControlSensor sensor, SP::SimpleMatrix B, SP::SimpleMatrix D = std::shared_ptr<SimpleMatrix>()): 149 Actuator(type, sensor, B), _indx(0), _D(D), _alpha(1.0), _numericsSolverId(SICONOS_RELAY_AVI_CAOFERRIS), 150 _precision(1e-8), _thetaSMC(0.5), _noUeq(false), _computeResidus(true) {} 151 152 153 /** Compute the new control law at each event 154 */ 155 virtual void actuate() = 0; 156 157 /** Initialization 158 * \param nsds current nonsmooth dynamical system 159 * \param s current simulation setup 160 */ 161 virtual void initialize(const NonSmoothDynamicalSystem& nsds, const Simulation& s); 162 163 164 void sete(const std::string& plugin); 165 void seth(const std::string& plugin); 166 void setJachx(const std::string& plugin); 167 void setJachlambda(const std::string& plugin); 168 void setg(const std::string& plugin); 169 void setJacgx(const std::string& plugin); 170 void setJacglambda(const std::string& plugin); 171 172 /** Set Csurface 173 * \param Csurface a SP::SimpleMatrix containing the new value for _Csurface 174 */ 175 void setCsurface(SP::SimpleMatrix Csurface); 176 177 /** Set _D to pointer newPtr 178 * \param newSat a SP::SimpleMatrix containing the new value for _D 179 */ 180 void setSaturationMatrix(SP::SimpleMatrix newSat); 181 182 /** Set _alpha 183 * \param alpha the new value for _alpha 184 */ setAlpha(double alpha)185 inline void setAlpha(double alpha) { _alpha = alpha; }; 186 187 /** get _lambda 188 * \return a pointer to _lambda 189 */ lambda() const190 inline SP::SiconosVector lambda() const 191 { 192 return _lambda; 193 }; 194 195 /** Set the solver 196 * \param numericsSolverId the solver for the relay 197 */ setSolver(const int numericsSolverId)198 inline void setSolver(const int numericsSolverId) 199 { 200 _numericsSolverId = numericsSolverId; 201 }; 202 203 /** Set the precision 204 * \param newPrecision a double 205 */ setPrecision(double newPrecision)206 inline void setPrecision(double newPrecision) 207 { 208 _precision = newPrecision; 209 }; 210 211 /** Get the OneStepNSProblem problem associated with the controller. This is useful to 212 * gain access to the data given to the solver in Numerics 213 * \return a reference to the LinearOSNS problem 214 */ relay()215 inline const LinearOSNS& relay() 216 { 217 return * _OSNSPB_SMC; 218 }; 219 220 /** get \f$u^{eq}\f$ 221 * \return a reference to _ueq 222 */ ueq()223 inline SiconosVector& ueq() 224 { 225 return *_ueq; 226 }; 227 228 /** get \f$u^{s}\f$ 229 * \return a reference to _us 230 */ 231 us()232 inline SiconosVector& us() 233 { 234 return *_us; 235 }; 236 237 /** Set _theta, used in some discretization method for \f$u^{eq}\f$ 238 * \param newTheta the new value for _thetaSMC 239 */ 240 setTheta(double newTheta)241 inline void setTheta(double newTheta) 242 { 243 _thetaSMC = newTheta; 244 }; 245 246 /** Disable (or enable) the use of the state-continuous control \f$u^{eq}\f$ 247 * \param b disable the use of Ueq if true 248 */ noUeq(bool b)249 inline void noUeq(bool b) 250 { 251 _noUeq = b; 252 }; 253 254 /** Disable (or enable) the computation of the residus on the Newton loop. 255 * This has an incidence only if the Relation is nonlinear 256 * \param b disable the computation of the residus 257 */ setComputeResidus(bool b)258 inline void setComputeResidus(bool b) 259 { 260 _computeResidus = b; 261 }; 262 263 /** This is derived in child classes if they need to copy the TimeDiscretisation 264 * associated with this Sensor 265 * \param td the TimeDiscretisation for this Sensor 266 */ 267 virtual void setTimeDiscretisation(const TimeDiscretisation& td); 268 269 /** Set the DynamicalSystem used to compute the control law. 270 * This is useful when we have a Nonlinear problem and we need to compute 271 * the control law with an approximate model, or when the dynamics are 272 * quite different. 273 * \param ds the DynamicalSystem to be used in the Controller 274 */ setDS(SP::FirstOrderNonLinearDS ds)275 void setDS(SP::FirstOrderNonLinearDS ds) // XXX replace this by FirstOrderDS 276 { 277 _DS_SMC = ds; 278 }; 279 280 /** get the NSDS used in the SMC 281 * \return the NSDS used in the SMC 282 */ getInternalNSDS() const283 virtual SP::NonSmoothDynamicalSystem getInternalNSDS() const { return _nsdsSMC; }; 284 285 /** get the Integrator used in the SMC 286 * \return the Integrator used in the SMC 287 */ getInternalOSI() const288 OneStepIntegrator& getInternalOSI() const { return *_integratorSMC; }; 289 290 }; 291 #endif 292