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