RCAC C++
RCACCreator.hpp
Go to the documentation of this file.
1 #ifndef _RCACCREATOR_HPP_
2 #define _RCACCREATOR_HPP_
3 
4 #include "RCAC.hpp"
5 #include "RCACRLS.hpp"
6 #include "RCACGrad.hpp"
7 //#include <any>
8 
9 
10 //Name: Nima Mohseni
11 //Date: 1/20/2020
12 //Purpose: This file contains the implementation of the factory function to
13 //generate new RCAC versions
14 
22 //RCAC Types: define your RCAC typenames here
23 std::string useRLS = "RLS";
24 std::string useGrad = "Grad";
25 
34 //Factory Method (TODO: move to a separate class, fix memory leak)
35 template <typename T>
37  T &FLAGS,
38  rcacFilt &FILT,
39  std::string &rcacType
40 )
41 {
42  //Hack to get things working with templates
43  //std::any FLAGStemp(FLAGS);
44  void *FLAGStemp = (void*)&FLAGS;
45 
46  if (rcacType == useRLS)
47  {
48  //rcacRlsFlags FLAGSnew = std::any_cast<rcacRlsFlags>(FLAGStemp);
49  rcacRlsFlags *FLAGSnew = (rcacRlsFlags*)FLAGStemp;
50  return new RCACRLS(*FLAGSnew, FILT);
51  }
52  else if (rcacType == useGrad)
53  {
54  //rcacGradFlags FLAGSnew = std::any_cast<rcacGradFlags>(FLAGStemp);
55  rcacGradFlags *FLAGSnew = (rcacGradFlags*)FLAGStemp;
56  return new RCACGrad(*FLAGSnew, FILT);
57  }
58  else
59  {
60  std::cout << "Bad RCAC Type!" << "\n";
61  exit(EXIT_FAILURE);
62  }
63 }
64 
65 /*
66 template <>
67 RCAC* RCAC::init(
68  rcacRlsFlags &FLAGS,
69  rcacFilt &FILT,
70  std::string &rcacType
71 )
72 {
73  if (rcacType == useRLS)
74  {
75  return new RCACRLS(FLAGS, FILT);
76  }
77  {
78  std::cout << "Bad RCAC Type!" << "\n";
79  exit(EXIT_FAILURE);
80  }
81 }
82 
83 template <>
84 RCAC* RCAC::init(
85  rcacGradFlags &FLAGS,
86  rcacFilt &FILT,
87  std::string &rcacType
88 )
89 {
90  if (rcacType == useGrad)
91  {
92  return new RCACGrad(FLAGS, FILT);
93  }
94  {
95  std::cout << "Bad RCAC Type!" << "\n";
96  exit(EXIT_FAILURE);
97  }
98 }
99 */
100 
101 //load FILTmx into FILT struct, should not be used outside initSimulink
102 //mxArray must be in format
103 //[FILTNu'(:); FILTDu'(:); FILTNz'(:); FILTDz'(:)]
104 //Matrices must be transposed and then vectorized
105 rcacFilt initFiltSimulink(
106  int lz,
107  int ly,
108  int lu,
109  int Nc,
110  int filtorder,
111  double* &FILTmx
112 )
113 {
114  rcacFilt FILT;
115 
116  //load Gf numerator
117  int filtIndex = 0;
118  FILT.filtNu.resize(lz, lu*filtorder); //Tell eigen the matrix size
119  FILT.filtNu = Eigen::Map<Eigen::MatrixXd>(&FILTmx[filtIndex], (double)lz, (double)lu*filtorder);
120  for (int i = 0; i < (lz*lu*filtorder); i++)
121  {
122  //FILT.filtNu << FILTmx[filtIndex];
123  filtIndex++;
124  }
125 
126  //load Gf Denominator
127  FILT.filtDu.resize(lz, lz*(filtorder-1)); //Tell eigen the matrix size
128  FILT.filtDu = Eigen::Map<Eigen::MatrixXd>(&FILTmx[filtIndex], (double)lz, (double)lz*(filtorder-1));
129  for (int i = 0; i < (lz*lz*(filtorder-1)); i++)
130  {
131  //FILT.filtDu << FILTmx[filtIndex];
132  filtIndex++;
133  }
134 
135  //load Gf_z Numerator (never used?)
136  FILT.filtNz.resize(lz, lz); //Tell eigen the matrix size
137  FILT.filtNz = Eigen::Map<Eigen::MatrixXd>(&FILTmx[filtIndex], (double)lz, (double)lz);
138  for (int i = 0; i < (lz*lz); i++)
139  {
140  //FILT.filtNz << FILTmx[filtIndex];
141  filtIndex++;
142  }
143 
144  //load Gf_z Denominator (never used?)
145  FILT.filtDz.resize(lz, lz); //Tell eigen the matrix size
146  FILT.filtDz = Eigen::Map<Eigen::MatrixXd>(&FILTmx[filtIndex], (double)lz, (double)lz);
147  for (int i = 0; i < (lz*lz); i++)
148  {
149  //FILT.filtDz << FILTmx[filtIndex];
150  filtIndex++;
151  }
152 
153  return(FILT);
154 }
155 
168 //Function initSimulink, takes the array format of the RCAC variables from
169 //simulink and converts it to the struct format and returns a pointer to an RCAC
170 //object
171 //
172 //ITEGRATE ME:
173 //std::string msg = std::string("Aw snap: ");
174 //mexErrMsgTxt(msg.c_str());
175 //TODO: move filt outside of the if statement
177  double* &FLAGSmx,
178  double* &FILTmx,
179  std::string &rcacType
180 )
181 {
182  if (rcacType == useRLS)
183  {
184  //load FLAGSmx into flags struct
185  //mxArray must be in format
186  //[lz; ly; lu; Nc; filtorder; k_0; P0'(:); Ru'(:); Rz'(:); lambda; theta_0]
187  //Matrices must be transposed and then vectorized
188 
189  rcacRlsFlags FLAGS;
190  //load the first 6 variables
191  int flagsIndex = 0;
192  FLAGS.lz = FLAGSmx[flagsIndex]; flagsIndex++;
193  FLAGS.ly = FLAGSmx[flagsIndex]; flagsIndex++;
194  FLAGS.lu = FLAGSmx[flagsIndex]; flagsIndex++;
195  FLAGS.Nc = FLAGSmx[flagsIndex]; flagsIndex++;
196  FLAGS.filtorder = FLAGSmx[flagsIndex]; flagsIndex++;
197  FLAGS.k_0 = (int)FLAGSmx[flagsIndex]; flagsIndex++;
198 
199  //load P0
200  int ltheta = FLAGS.Nc*FLAGS.lu*(FLAGS.lu+FLAGS.ly);
201  FLAGS.P0.resize(ltheta, ltheta); //Tell eigen the matrix size
202  //TODO: fix this lazy indexing
203 
204  //assigning the array to a Eigen compatible matrix
205  FLAGS.P0 = Eigen::Map<Eigen::MatrixXd>(&FLAGSmx[flagsIndex], (double)ltheta, (double)ltheta);
206  for (int i = 0; i < pow(ltheta,2); i++)
207  {
208  //FLAGS.P0 << FLAGSmx[flagsIndex];
209  flagsIndex++;
210  }
211 
212  //load Ru
213  FLAGS.Ru.resize(FLAGS.lu, FLAGS.lu); //Tell eigen the matrix size
214  FLAGS.Ru = Eigen::Map<Eigen::MatrixXd>(&FLAGSmx[flagsIndex], (double)FLAGS.lu, (double)FLAGS.lu);
215  for (int i = 0; i < pow(FLAGS.lu,2); i++)
216  {
217  //FLAGS.Ru << FLAGSmx[flagsIndex];
218  flagsIndex++;
219  }
220 
221  //load Rz
222  FLAGS.Rz.resize(FLAGS.lz, FLAGS.lz); //Tell eigen the matrix size
223  FLAGS.Rz = Eigen::Map<Eigen::MatrixXd>(&FLAGSmx[flagsIndex], (double)FLAGS.lz, (double)FLAGS.lz);
224  for (int i = 0; i < pow(FLAGS.lz,2); i++)
225  {
226  //FLAGS.Rz << FLAGSmx[flagsIndex];
227  flagsIndex++;
228  }
229 
230  //load lambda
231  FLAGS.lambda = FLAGSmx[flagsIndex]; flagsIndex++;
232 
233  //load theta_0
234  FLAGS.theta_0.resize(ltheta); //Tell eigen the matrix size
235  FLAGS.theta_0 = Eigen::Map<Eigen::VectorXd>(&FLAGSmx[flagsIndex], (double)ltheta, 1);
236  for (int i = 0; i < ltheta; i++)
237  {
238  //FLAGS.theta_0 << FLAGSmx[flagsIndex];
239  flagsIndex++;
240  }
241 
242  rcacFilt FILT = initFiltSimulink(FLAGS.lz, FLAGS.ly, FLAGS.lu,
243  FLAGS.Nc, FLAGS.filtorder, FILTmx);
244 
245  //create RCACRLS
246  return new RCACRLS(FLAGS, FILT);
247  }
248  else if (rcacType == useGrad)
249  {
250  //load FLAGSmx into flags struct
251  //mxArray must be in format
252  //[lz; ly; lu; Nc; filtorder; k_0; alpha; theta_0]
253  //Matrices must be transposed and then vectorized
254 
255  rcacGradFlags FLAGS;
256  //load the first 6 variables
257  int flagsIndex = 0;
258  FLAGS.lz = FLAGSmx[flagsIndex]; flagsIndex++;
259  FLAGS.ly = FLAGSmx[flagsIndex]; flagsIndex++;
260  FLAGS.lu = FLAGSmx[flagsIndex]; flagsIndex++;
261  FLAGS.Nc = FLAGSmx[flagsIndex]; flagsIndex++;
262  FLAGS.filtorder = FLAGSmx[flagsIndex]; flagsIndex++;
263  FLAGS.k_0 = (int)FLAGSmx[flagsIndex]; flagsIndex++;
264 
265  //load the step size scaling
266  FLAGS.alpha = FLAGSmx[flagsIndex]; flagsIndex++;
267 
268  int ltheta = FLAGS.Nc*FLAGS.lu*(FLAGS.lu+FLAGS.ly);
269 
270  //load theta_0
271  FLAGS.theta_0.resize(ltheta); //Tell eigen the matrix size
272  FLAGS.theta_0 = Eigen::Map<Eigen::VectorXd>(&FLAGSmx[flagsIndex], (double)ltheta, 1);
273  for (int i = 0; i < ltheta; i++)
274  {
275  //FLAGS.theta_0 << FLAGSmx[flagsIndex];
276  flagsIndex++;
277  }
278 
279  rcacFilt FILT = initFiltSimulink(FLAGS.lz, FLAGS.ly, FLAGS.lu,
280  FLAGS.Nc, FLAGS.filtorder, FILTmx);
281 
282  //create RCACGrad
283  return new RCACGrad(FLAGS, FILT);
284 
285  }
286  else
287  {
288  std::cout << "Bad RCAC Type (Simulink)!" << "\n";
289  //throw(EXIT_FAILURE);
290  throw "Bad RCAC Type (Simulink)!";
291  }
292 }
293 
294 #endif
RCAC * initSimulink(double *&FLAGSmx, double *&FILTmx, std::string &rcacType)
Definition: RCACCreator.hpp:176
static RCAC * init(T &FLAGS, rcacFilt &FILT, std::string &whichRCAC)
Definition: RCACCreator.hpp:36
Definition: RCACRLS.hpp:55
Definition: RCACRLS.hpp:33
Definition: RCACGrad.hpp:48
Definition: RCAC.hpp:66
Definition: RCACGrad.hpp:28
Definition: RCAC.hpp:81