mxlib
c++ tools for analyzing astronomical data and other tasks by Jared R. Males. [git repo]
leakyIntegrator.hpp
Go to the documentation of this file.
1 /** \file leakyIntegrator.hpp
2  * \author Jared R. Males (jaredmales@gmail.com)
3  * \brief Declares and defines the leaky integrator controller class for AO control.
4  * \ingroup mxAO_sim_files
5  *
6  */
7 
8 #ifndef __leakyIntegrator_hpp__
9 #define __leakyIntegrator_hpp__
10 
11 namespace mx
12 {
13 namespace AO
14 {
15 namespace sim
16 {
17 
18 template<typename _realT>
19 struct wfMeasurement
20 {
21  typedef _realT realT;
22 
23  realT iterNo;
24 
25  typedef Eigen::Array< realT, Eigen::Dynamic, Eigen::Dynamic> commandT;
26 
27  commandT measurement;
28 };
29 
30 ///Implements the leaky integrator controller.
31 /**
32  * \tparam _realT is the floating point type for all calculations.
33  */
34 template<typename _realT>
36 {
37 
38 public:
39 
40  ///The real data type
41  typedef _realT realT;
42 
43  ///The wavefront data type
45 
46  ///The command type
47  typedef wfMeasurement<realT> commandT;
48 
49  ///The image type, used here as a general storage array
50  typedef Eigen::Array< realT, Eigen::Dynamic, Eigen::Dynamic> imageT;
51 
52  ///Default c'tor.
54 
55 protected:
56 
57  int _nModes; ///< The number of modes being filtered.
58 
59  bool _openLoop; ///< If true, then commands are not integrated.
60 
61  int _closingDelay; ///< If > 0, then the gains are ramped linearly up to this value. Default = 0.
62 
63  int _lowOrders; ///< If > 0, then this sets the maximum mode number which is filtered. All remaining modes are set to 0. Default = 0.
64 
65 
66  imageT _gains; ///< Column-vector of gains
67 
68  imageT _leaks; ///< Column-vector of leaks
69 
70  imageT _commands; ///< Column-vector past commands
71 
72 
73 
74 
75 public:
76 
77  int _lowOrderDelay;
78 
79  ///Allocate and initialize all state.
80  /**
81  * \returns 0 on success, a negative integer otherwise.
82  */
83  int initialize(int nModes /**< [in] the number of modes to be filtered */ );
84 
85  ///Get the number of modes
86  /** nModes is only set by calling initialize.
87  *
88  * \returns the current value of _nModes
89  */
90  int nModes();
91 
92  ///Set the _openLoop flag.
93  /** If _openLoop is true, then commands are not filtered.
94  *
95  * \returns 0 on success, a negative integer on error.
96  */
97  int openLoop(bool ol /**< The new value of _openLoop */ );
98 
99  ///Get the value of the _openLoop flag.
100  /**
101  * \returns the current value of _openLoop.
102  */
103  bool openLoop();
104 
105  ///Set _closingDelay.
106  /** If _closingDelay > 0, then the gains are ramped linearly up to this value.
107  *
108  * \returns 0 on success, a negative integer on error.
109  */
110  int closingDelay( int cd /**< The new value of _closingDelay */);
111 
112  ///Get the value of the _closingDelay.
113  /**
114  * \returns the current value of _closingDelay.
115  */
116  int closingDelay();
117 
118  ///Set _lowOrders.
119  /** If _lowOrders > 0, then this sets the maximum mode number which is filtered. All remaining modes are set to 0.
120  *
121  * \returns 0 on success, a negative integer on error.
122  */
123  int lowOrders( int lo /**< The new value of _lowOrders */);
124 
125  ///Get the value of the _lowOrders.
126  /**
127  * \returns the current value of _lowOrders.
128  */
129  int lowOrders();
130 
131  ///Get the gain for a single mode.
132  /** \returns the gain value if mode exists.
133  */
134  realT gain( int i /**< [in] the mode number*/);
135 
136  ///Set the gain for a single mode.
137  /**
138  * \returns 0 on success, negative number on error.
139  */
140  int gain( int i, ///< [in] the mode number
141  realT g ///< [in] the new gain value
142  );
143 
144  ///Set the gain for all modes to a single value
145  /**
146  * \returns 0 on success, negative number on error.
147  */
148  int gains(realT g /**< [in] the new gain value*/ );
149 
150  ///Set the gains for all modes, using a vector to specify each gain
151  /** The vector must be exactly as long as _nModes.
152  *
153  * \returns 0 on success, negative number on error.
154  */
155  int gains(const std::vector<realT> & vgains /**< [in] vector of gains.*/);
156 
157  ///Set the gains for all modes, using a file to specify each gain
158  /** The file format is a simple ASCII single column, with 1 gain per line.
159  * Must be exactly as long as _nModes.
160  *
161  * \returns 0 on success, negative number on error.
162  */
163  int gains(const std::string & ogainf /**< [in] the name of the file, full path */);
164 
165 
166  ///Set the leak for a single mode.
167  /**
168  * \returns 0 on success, negative number on error.
169  */
170  int leak( int i, ///< [in] the mode number
171  realT l ///< [in] the new leak value for this mode
172  );
173 
174  ///Set a leak for all modes.
175  /**
176  * \returns 0 on success, negative number on error.
177  */
178  int leaks( realT l /**< [in] the new leak value to set for all modes */ );
179 
180 
181  ///Allocate the provided command structures
182  /** Used by the calling system to allocate the commands being passed between components.
183  *
184  * \returns 0 on success, negative number on error.
185  */
186  int initMeasurements( commandT & filtAmps, ///< The structure to contain the filtered commands
187  commandT & rawAmps ///< The structure to contain the raw commands
188  );
189 
190 
191  ///Apply the leaky integrator
192  /**
193  * \returns 0 on success, negative number on error.
194  */
195  int filterCommands( commandT & filtAmps, ///< [out] the filtered commands
196  commandT & rawAmps, ///< [in] the raw commands
197  int iterNo ///< [in] The current iteration number
198  );
199 
200 
201 
202 };
203 
204 
205 template<typename realT>
207 {
208  _nModes = 0;
209 
210  _openLoop = false;
211 
212  _closingDelay = 0;
213 
214  _lowOrders = 0;
215  _lowOrderDelay = 0;
216 
217 }
218 
219 
220 
221 template<typename realT>
223 {
224  _nModes = nModes;
225 
226  _gains.resize(1,nModes);
227  _leaks.resize(1, nModes);
228  _commands.resize(1, nModes);
229 
230  _gains.setZero();
231 
232  _leaks.setZero();
233 
234  _commands.setZero();
235 
236  return 0;
237 
238 }
239 
240 template<typename realT>
242 {
243  return _nModes;
244 }
245 
246 template<typename realT>
248 {
249  _openLoop = ol;
250  return 0;
251 }
252 
253 template<typename realT>
255 {
256  return _openLoop;
257 }
258 
259 template<typename realT>
261 {
262  _closingDelay = cd;
263 
264  return 0;
265 }
266 
267 template<typename realT>
269 {
270  return _closingDelay;
271 }
272 
273 template<typename realT>
275 {
276  _lowOrders = lo;
277 
278  return 0;
279 }
280 
281 template<typename realT>
283 {
284  return _lowOrders;
285 }
286 
287 template<typename realT>
289 {
290  if(i < 0 || i >= _nModes)
291  {
292  mxError("leakyIntegrator::gain", MXE_INVALIDARG, "mode index out of range");
293  return 0; ///\retval 0 if the mode doesn't exist.
294  }
295 
296  return _gains(i);
297 }
298 
299 
300 template<typename realT>
302 {
303  if(i < 0 || i >= _nModes)
304  {
305  mxError("leakyIntegrator::gain", MXE_INVALIDARG, "mode index out of range");
306  return 0; ///\retval 0 if the mode doesn't exist.
307  }
308 
309  _gains(0,i) = g;
310 
311  return 0;
312 }
313 
314 template<typename realT>
316 {
317  for(int i=0;i<_gains.cols(); ++i)
318  {
319  _gains(0,i) = g;
320  }
321 
322  return 0;
323 }
324 
325 template<typename realT>
326 int leakyIntegrator<realT>::gains( const std::vector<realT> & gains )
327 {
328 
329  if( gains.size() != _gains.cols())
330  {
331  mxError("leakyIntegrator::gain", MXE_SIZEERR, "input gain vector not same size as number of modes");
332  return -1; ///\retval -1 on vector size mismatch
333  }
334 
335  for(int i=0;i<_gains.cols(); ++i)
336  {
337  _gains(0,i) = gains[i];
338  }
339 
340  return 0;
341 }
342 
343 template<typename realT>
344 int leakyIntegrator<realT>::gains( const std::string & ogainf )
345 {
346  std::ifstream fin;
347  fin.open(ogainf);
348 
349  if(!fin.good())
350  {
351  mxError("leakyIntegrator::gains", MXE_FILEOERR, "could not open gan file");
352  return -1; /// \retval -1 if file open fails
353  }
354 
355  std::string tmpstr;
356  realT g;
357  for(int i=0;i<_gains.cols();++i)
358  {
359  fin >> tmpstr;
360  g = mx::convertFromString<realT>(tmpstr);
361  gain(i, g);
362 
363  }
364 
365  return 0;
366 
367 }
368 
369 template<typename realT>
371 {
372  _leaks(0,i) = l;
373 }
374 
375 template<typename realT>
377 {
378  for(int i=0;i<_leaks.cols(); ++i) _leaks(0,i) = l;
379 
380  return 0;
381 }
382 
383 template<class realT>
385 {
386  filtAmps.measurement.resize(1, _nModes);
387  filtAmps.measurement.setZero();
388 
389  rawAmps.measurement.resize(1, _nModes);
390  rawAmps.measurement.setZero();
391 
392  return 0;
393 }
394 
395 template<class realT>
397  commandT & rawAmps,
398  int iterNo )
399 {
400  filtAmps.iterNo = rawAmps.iterNo;
401 
402  if(_openLoop)
403  {
404  filtAmps.measurement.setZero();
405  return 0;
406  }
407 
408  int topN = rawAmps.measurement.cols();
409 
410 
411 
412  realT gainF = 1.0;
413  realT HOgainF = 0.0;
414 
415  //leaks(0.01);
416 
417  if( iterNo < _closingDelay) gainF = ((realT) iterNo)/_closingDelay;
418 
419  //if( iterNo < 0.55*_closingDelay) leaks(0.1);
420 
421  if(_lowOrders > 0)
422  {
423  if( iterNo >= _closingDelay+_lowOrderDelay)
424  {
425  _lowOrders = 0;
426  }
427  else
428  {
429  topN = _lowOrders;
430 
431  if( iterNo >= _closingDelay )
432  {
433  HOgainF = ( (realT) (iterNo - _closingDelay) )/( _lowOrderDelay );
434 
435  }
436 
437  }
438  }
439 
440 
441  for(int i=0; i< topN; ++i)
442  {
443  if( std::isnan( rawAmps.measurement(0,i) ) || !std::isfinite(rawAmps.measurement(0,i))) rawAmps.measurement(0,i) = 0.0;
444 
445  _commands(0,i) = (1.0-_leaks(0,i))*_commands(0,i) + gainF*_gains(0,i)*rawAmps.measurement(0,i);
446 
447  filtAmps.measurement(0,i) = _commands(0,i);
448  }
449 
450  for(int i=topN; i< rawAmps.measurement.cols(); ++i)
451  {
452  if( std::isnan( rawAmps.measurement(0,i) ) || !std::isfinite(rawAmps.measurement(0,i))) rawAmps.measurement(0,i) = 0.0;
453 
454  _commands(0,i) = (1.0-_leaks(0,i))*_commands(0,i) + HOgainF*_gains(0,i)*rawAmps.measurement(0,i);
455 
456  filtAmps.measurement(0,i) = _commands(0,i);
457 
458  //filtAmps.measurement(0,i) = 0;
459  }
460 
461 
462  return 0;
463 
464 }
465 
466 
467 
468 } //namespace sim
469 } //namespace AO
470 } //namespace mx
471 
472 #endif //__leakyIntegrator_hpp__
Implements the leaky integrator controller.
imageT _gains
Column-vector of gains.
_realT realT
The real data type.
bool openLoop()
Get the value of the _openLoop flag.
wfMeasurement< realT > commandT
The command type.
int closingDelay()
Get the value of the _closingDelay.
wavefront< realT > wavefrontT
The wavefront data type.
int leaks(realT l)
Set a leak for all modes.
Eigen::Array< realT, Eigen::Dynamic, Eigen::Dynamic > imageT
The image type, used here as a general storage array.
imageT _leaks
Column-vector of leaks.
int filterCommands(commandT &filtAmps, commandT &rawAmps, int iterNo)
Apply the leaky integrator.
int initMeasurements(commandT &filtAmps, commandT &rawAmps)
Allocate the provided command structures.
int initialize(int nModes)
Allocate and initialize all state.
realT gain(int i)
Get the gain for a single mode.
int gains(realT g)
Set the gain for all modes to a single value.
int leak(int i, realT l)
Set the leak for a single mode.
int _nModes
The number of modes being filtered.
bool _openLoop
If true, then commands are not integrated.
imageT _commands
Column-vector past commands.
int _closingDelay
If > 0, then the gains are ramped linearly up to this value. Default = 0.
int lowOrders()
Get the value of the _lowOrders.
int nModes()
Get the number of modes.
int _lowOrders
If > 0, then this sets the maximum mode number which is filtered. All remaining modes are set to 0....
The mxlib c++ namespace.
Definition: mxError.hpp:107
Structure containing the phase and amplitude of a wavefront
Definition: wavefront.hpp:26