EEROS  1.0.0.0
API for the EEROS Real-Time Robotics Framework
Gain.hpp
Go to the documentation of this file.
1 #ifndef ORG_EEROS_CONTROL_GAIN_HPP_
2 #define ORG_EEROS_CONTROL_GAIN_HPP_
3 
5 #include <type_traits>
6 
7 
8 namespace eeros {
9  namespace control {
10 
31  template <typename Tout = double, typename Tgain = double, bool elementWise = false>
32  class Gain : public Block1i1o<Tout> {
33 
34  public:
41  Gain() : Gain(1.0) {}
42 
43 
52  Gain(Tgain c) : Gain(c, 1.0, -1.0) { // 1.0 and -1.0 are temp values only.
53  resetMinMaxGain<Tgain>(); // set limits to smallest/largest value.
54  }
55 
56 
67  Gain(Tgain c, Tgain maxGain, Tgain minGain) {
68  gain = c;
69  this->maxGain = maxGain;
70  this->minGain = minGain;
71  targetGain = gain;
72  gainDiff = 0;
73  }
74 
75 
94  virtual void run() {
95  if(smoothChange) {
96  if(gain < targetGain) {
97  gain += gainDiff;
98  if(gain > targetGain) { // overshoot case.
99  gain = targetGain;
100  }
101  }
102 
103  if(gain > targetGain) {
104  gain -= gainDiff;
105  if(gain < targetGain) {
106  gain = targetGain;
107  }
108  }
109  }
110 
111  if(gain > maxGain) { // if diff will cause gain to be too large.
112  gain = maxGain;
113  }
114 
115  if(gain < minGain) {
116  gain = minGain;
117  }
118 
119  if(enabled) {
120  this->out.getSignal().setValue(calculateResults<Tout>(this->in.getSignal().getValue()));
121  } else {
122  this->out.getSignal().setValue(this->in.getSignal().getValue());
123  }
124  this->out.getSignal().setTimestamp(this->in.getSignal().getTimestamp());
125  }
126 
127 
138  virtual void enable() {
139  enabled = true;
140  }
141 
142 
153  virtual void disable() {
154  enabled = false;
155  }
156 
157 
171  virtual void enableSmoothChange(bool enable) {
173  }
174 
175 
185  virtual void setGain(Tgain c) {
186  if(c <= maxGain && c >= minGain) {
187  if(smoothChange) {
188  targetGain = c;
189  }else {
190  gain = c;
191  }
192  }
193  }
194 
195 
201  virtual void setMaxGain(Tgain maxGain) {
202  this->maxGain = maxGain;
203  }
204 
205 
211  virtual void setMinGain(Tgain minGain) {
212  this->minGain = minGain;
213  }
214 
215 
221  virtual void setGainDiff(Tgain gainDiff) {
222  this->gainDiff = gainDiff;
223  }
224 
225 
226  /*
227  * Friend operator overload to give the operator overload outside
228  * the class access to the private fields.
229  */
230  template <typename Xout, typename Xgain>
231  friend std::ostream& operator<<(std::ostream& os, Gain<Xout,Xgain>& gain);
232 
233 
234  protected:
235  Tgain gain;
236  Tgain maxGain;
237  Tgain minGain;
238  Tgain targetGain;
239  Tgain gainDiff;
240  bool enabled{true};
241  bool smoothChange{false};
242 
243 
244  private:
245  template <typename S>
246  typename std::enable_if<!elementWise,S>::type calculateResults(S value) {
247  return gain * value;
248  }
249 
250 
251  template <typename S>
252  typename std::enable_if<elementWise,S>::type calculateResults(S value) {
253  return value.multiplyElementWise(gain);
254  }
255 
256 
257  template <typename S>
258  typename std::enable_if<std::is_integral<S>::value>::type resetMinMaxGain() {
259  minGain = std::numeric_limits<int32_t>::min();
260  maxGain = std::numeric_limits<int32_t>::max();
261  }
262 
263 
264  template <typename S>
265  typename std::enable_if<std::is_floating_point<S>::value>::type resetMinMaxGain() {
266  minGain = std::numeric_limits<double>::lowest();
267  maxGain = std::numeric_limits<double>::max();
268  }
269 
270 
271  template <typename S>
272  typename std::enable_if<!std::is_arithmetic<S>::value && std::is_integral<typename S::value_type>::value>::type resetMinMaxGain() {
273  minGain.fill(std::numeric_limits<int32_t>::min());
274  maxGain.fill(std::numeric_limits<int32_t>::max());
275  }
276 
277 
278  template <typename S>
279  typename std::enable_if<!std::is_arithmetic<S>::value && std::is_floating_point<typename S::value_type>::value>::type resetMinMaxGain() {
280  minGain.fill(std::numeric_limits<double>::lowest());
281  maxGain.fill(std::numeric_limits<double>::max());
282  }
283  };
284 
285 
291  template <typename Tout, typename Tgain>
292  std::ostream& operator<<(std::ostream& os, Gain<Tout,Tgain>& gain) {
293  os << "Block Gain: '" << gain.getName() << "' is enabled=" << gain.enabled << ", gain=" << gain.gain << ", ";
294  os << "smoothChange=" << gain.smoothChange << ", minGain=" << gain.minGain << ", maxGain=" << gain.maxGain << ", ";
295  os << "targetGain=" << gain.targetGain << ", gainDiff=" << gain.gainDiff;
296  }
297  };
298 };
299 
300 #endif /* ORG_EEROS_CONTROL_GAIN_HPP_ */
Tgain targetGain
Definition: Gain.hpp:238
bool enabled
Definition: Gain.hpp:240
virtual void setGainDiff(Tgain gainDiff)
Definition: Gain.hpp:221
virtual Signal< T > & getSignal()
Definition: Output.hpp:16
virtual T getValue() const
Definition: Signal.hpp:49
virtual void disable()
Definition: Gain.hpp:153
Tgain maxGain
Definition: Gain.hpp:236
Gain(Tgain c, Tgain maxGain, Tgain minGain)
Definition: Gain.hpp:67
Gain(Tgain c)
Definition: Gain.hpp:52
Input< Tout > in
Definition: Block1i1o.hpp:27
virtual void run()
Definition: Gain.hpp:94
virtual void setGain(Tgain c)
Definition: Gain.hpp:185
Definition: Config.hpp:14
Tgain gain
Definition: Gain.hpp:235
Output< Tout > out
Definition: Block1i1o.hpp:28
virtual void setValue(T newValue)
Definition: Signal.hpp:53
virtual void enable()
Definition: Gain.hpp:138
virtual void setTimestamp(timestamp_t newTimestamp)
Definition: Signal.hpp:66
Tgain minGain
Definition: Gain.hpp:237
Definition: Block1i1o.hpp:12
virtual Signal< T > & getSignal()
Definition: Input.hpp:38
virtual void setMinGain(Tgain minGain)
Definition: Gain.hpp:211
virtual timestamp_t getTimestamp() const
Definition: Signal.hpp:62
Tgain gainDiff
Definition: Gain.hpp:239
virtual void setMaxGain(Tgain maxGain)
Definition: Gain.hpp:201
Gain()
Definition: Gain.hpp:41
Definition: Gain.hpp:32
bool smoothChange
Definition: Gain.hpp:241
virtual void enableSmoothChange(bool enable)
Definition: Gain.hpp:171