export_gauss_newton_block_qpdunes.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of ACADO Toolkit.
3  *
4  * ACADO Toolkit -- A Toolkit for Automatic Control and Dynamic Optimization.
5  * Copyright (C) 2008-2014 by Boris Houska, Hans Joachim Ferreau,
6  * Milan Vukov, Rien Quirynen, KU Leuven.
7  * Developed within the Optimization in Engineering Center (OPTEC)
8  * under supervision of Moritz Diehl. All rights reserved.
9  *
10  * ACADO Toolkit is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public
12  * License as published by the Free Software Foundation; either
13  * version 3 of the License, or (at your option) any later version.
14  *
15  * ACADO Toolkit is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  * Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public
21  * License along with ACADO Toolkit; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23  *
24  */
25 
33 
34 using namespace std;
35 
37 
39  const std::string& _commonHeaderName
40  ) : ExportGaussNewtonBlockCN2( _userInteraction,_commonHeaderName )
41 {}
42 
44 {
45 
47  if( status != SUCCESSFUL_RETURN ) return status;
48 
49  LOG( LVL_DEBUG ) << "Solver: setup extra initialization... " << endl;
50  //
51  // Add QP initialization call to the initialization
52  //
53  stringstream ss;
54  ss.str( string() );
55  ss << "for( ret = 0; ret < " << getNumberOfBlocks()*getNumBlockVariables()*getNumBlockVariables()+NX*NX << "; ret++ ) acadoWorkspace.qpH[ret] += 1e-8;\n"; // TODO: this is added because of a bug in qpDUNES !!
56  initialize << ss.str();
57  initialize << "ret = (int)initializeQpDunes();\n"
58  << "if ((return_t)ret != QPDUNES_OK) return ret;\n";
59 
60  cleanup.setup( "cleanupSolver" );
61  ExportFunction cleanupQpDunes( "cleanupQpDunes" );
62  cleanupQpDunes.setName( "cleanupQpDunes" );
63  cleanup.addFunctionCall( cleanupQpDunes );
64  LOG( LVL_DEBUG ) << "done!" << endl;
65 
66  return SUCCESSFUL_RETURN;
67 }
68 
70  )
71 {
73  code.addStatement( *qpInterface );
74 
75  code.addFunction( cleanup );
76  code.addFunction( shiftQpData );
77 
79 
80  return ExportGaussNewtonCN2::getCode( code );
81 }
82 
84 {
86  //
87  // Preparation phase
88  //
90 
91  preparation.setup( "preparationStep" );
92  preparation.doc( "Preparation step of the RTI scheme." );
93  ExportVariable retSim("ret", 1, 1, INT, ACADO_LOCAL, true);
94  retSim.setDoc("Status of the integration module. =0: OK, otherwise the error code.");
95  preparation.setReturnValue(retSim, false);
96  ExportIndex index("index");
97  preparation.addIndex( index );
98 
99  preparation << retSim.getFullName() << " = " << modelSimulation.getName() << "();\n";
100 
104 
106  preparation << (Dy -= y) << (DyN -= yN);
108 
109  ExportForLoop condensePrepLoop( index, 0, getNumberOfBlocks() );
110  condensePrepLoop.addFunctionCall( condensePrep, index );
111  preparation.addStatement( condensePrepLoop );
112 
114  if( levenbergMarquardt > ZERO_EPS ) {
115  for( uint i = 0; i < NX; i++ ) {
117  }
118  }
120 
122  int variableObjS;
123  get(CG_USE_VARIABLE_WEIGHTING_MATRIX, variableObjS);
124  ExportVariable SlxCall =
125  objSlx.isGiven() == true || variableObjS == false ? objSlx : objSlx.getRows(N * NX, (N + 1) * NX);
128 
129  stringstream prep;
130  prep << retSim.getName() << " = prepareQpDunes( );" << endl;
131  preparation << prep.str();
133 
135  //
136  // Feedback phase
137  //
139 
140  ExportVariable tmp("tmp", 1, 1, INT, ACADO_LOCAL, true);
141  tmp.setDoc( "Status code of the qpOASES QP solver." );
142 
143  feedback.setup("feedbackStep");
144  feedback.doc( "Feedback/estimation step of the RTI scheme." );
145  feedback.setReturnValue( tmp );
146  feedback.addIndex( index );
147 
148  if (initialStateFixed() == true)
149  {
151  feedback.addStatement( qpUb0.getCols(0, NX) == qpLb0.getCols(0, NX) );
152  }
153  else
154  {
156  }
158 
159  stringstream s;
160  s << tmp.getName() << " = solveQpDunes( );" << endl;
161  feedback << s.str();
163 
164  ExportForLoop expandLoop( index, 0, getNumberOfBlocks() );
165  expandLoop.addFunctionCall( expand, index );
166  feedback.addStatement( expandLoop );
167 
169 
171  //
172  // Shifting of QP data
173  //
175 
176  stringstream ss;
177  shiftQpData.setup( "shiftQpData" );
178  ss.str( string() );
179  ss << "qpDUNES_shiftLambda( &qpData );" << endl
180  << "qpDUNES_shiftIntervals( &qpData );" << endl;
181  shiftQpData.addStatement( ss.str().c_str() );
182 
184  //
185  // Setup evaluation of the KKT tolerance
186  //
188  ExportVariable kkt("kkt", 1, 1, REAL, ACADO_LOCAL, true);
189  ExportVariable prd("prd", 1, 1, REAL, ACADO_LOCAL, true);
190  ExportIndex index2( "index2" );
191 
192  getKKT.setup( "getKKT" );
193  getKKT.doc( "Get the KKT tolerance of the current iterate." );
194  kkt.setDoc( "KKT tolerance." );
195  getKKT.setReturnValue( kkt );
196  // getKKT.addVariable( prd );
197  getKKT.addIndex( index );
198  getKKT.addIndex( index2 );
199 
200  getKKT.addStatement( kkt == (g ^ xVars) );
201  getKKT << kkt.getFullName() << " = fabs( " << kkt.getFullName() << " );\n";
202 
203  ExportForLoop lamLoop(index, 0, getNumberOfBlocks() * NX);
204  lamLoop << kkt.getFullName() << "+= fabs( " << qpc.get(index, 0) << " * " << qpLambda.get(index, 0) << ");\n";
205  getKKT.addStatement( lamLoop );
206 
207  /*
208 
209  lambda are the multipliers of the coupling constraints
210  i.e. lambda_i for x_{i+1} = A * x_i + B * u_i + c
211  mu correspond to the bounds
212  in the fashion
213  mu = mu_0 … mu_N
214  i.e. major ordering by the stages
215  within each stage i
216  i.e. within mu_i
217  we have the minor ordering( I drop the i here)
218  lb z_0, ub z_0, lb z_1, ub z_1, … lb z_nZ, ub z_nZ
219  where z are the stage variables in the ordering z = [x u]
220  signs are positive if active, zero if inactive
221 
222  */
223 
224  if ( getNumComplexConstraints() )
225  {
227  "KKT Tolerance with affine stage constraints is under development");
228  return SUCCESSFUL_RETURN;
229  }
230 
231  if (initialStateFixed() == true)
232  {
233  for (unsigned el = 0; el < getNumBlockVariables(); ++el)
234  {
235  getKKT << kkt.getFullName() << " += fabs("
236  << qpLb0.get(0, el) << " * " << qpMu.get(2 * el + 0, 0) << ");\n";
237  getKKT << kkt.getFullName() << " += fabs("
238  << qpUb0.get(0, el) << " * " << qpMu.get(2 * el + 1, 0) << ");\n";
239  }
240  }
241 
242  ExportForLoop bndLoop(index, initialStateFixed() ? 1 : 0, getNumberOfBlocks());
243  ExportForLoop bndInLoop(index2, 0, getNumBlockVariables());
244  bndInLoop << kkt.getFullName() << " += fabs("
245  << lb.get(index * getNumBlockVariables() + index2, 0) << " * " << qpMu.get(index * 2 * getNumBlockVariables() + 2 * index2 + 0, 0) << ");\n";
246  bndInLoop << kkt.getFullName() << " += fabs("
247  << ub.get(index * getNumBlockVariables() + index2, 0) << " * " << qpMu.get(index * 2 * getNumBlockVariables() + 2 * index2 + 1, 0) << ");\n";
248  bndLoop.addStatement( bndInLoop );
249  getKKT.addStatement( bndLoop );
250 
251  for (unsigned el = 0; el < NX; ++el)
252  {
253  getKKT << kkt.getFullName() << " += fabs("
254  << lb.get(getNumberOfBlocks() * getNumBlockVariables() + el, 0) << " * " << qpMu.get(2 * getNumberOfBlocks() * getNumBlockVariables() + 2 * el + 0, 0) << ");\n";
255  getKKT << kkt.getFullName() << " += fabs("
256  << ub.get(getNumberOfBlocks() * getNumBlockVariables() + el, 0) << " * " << qpMu.get(2 * getNumberOfBlocks() * getNumBlockVariables() + 2 * el + 1, 0) << ");\n";
257  }
258 
259  return SUCCESSFUL_RETURN;
260 }
261 
263 {
264  //
265  // Configure and export QP interface
266  //
267 
268  qpInterface = std::shared_ptr< ExportSplitQpDunesInterface >(new ExportSplitQpDunesInterface("", commonHeaderName));
269 
270  int maxNumQPiterations;
271  get(MAX_NUM_QP_ITERATIONS, maxNumQPiterations);
272 
273  // XXX If not specified, use default value
274  if ( maxNumQPiterations <= 0 )
275  maxNumQPiterations = getNumQPvars();
276 
277  int printLevel;
278  get(PRINTLEVEL, printLevel);
279 
280  if ( (PrintLevel)printLevel >= MEDIUM )
281  printLevel = 2;
282  else
283  printLevel = 0;
284 
285  qpInterface->configure(
286  maxNumQPiterations,
287  printLevel,
288  qpH.getFullName(),
289  g.getFullName(),
290  initialStateFixed() ? "0" : qpgN.getFullName(),
291  qpC.getFullName(),
292  qpc.getFullName(),
293  A.getFullName(),
294  initialStateFixed() ? qpLb0.getFullName() : "0",
295  initialStateFixed() ? qpUb0.getFullName() : "0",
296  lb.getFullName(),
297  ub.getFullName(),
298  lbA.getFullName(),
299  ubA.getFullName(),
300  xVars.getFullName(),
302  qpMu.getFullName(),
303  qpConDim,
304  initialStateFixed() ? "1" : "0",
305  diagonalH ? "1" : "0",
306  diagonalHN ? "1" : "0",
308  NX,
309  getBlockSize()*NU
310  );
311 
312  return SUCCESSFUL_RETURN;
313 }
314 
315 
std::shared_ptr< ExportSplitQpDunesInterface > qpInterface
#define LOG(level)
Just define a handy macro for getting the logger.
Lowest level, the debug level.
std::string getFullName() const
virtual bool isDefined() const
ExportFunction & setName(const std::string &_name)
Allows to pass back messages to the calling function.
ExportVariable getRow(const ExportIndex &idx) const
BEGIN_NAMESPACE_ACADO typedef unsigned int uint
Definition: acado_types.hpp:42
ExportGaussNewtonBlockQpDunes(UserInteraction *_userInteraction=0, const std::string &_commonHeaderName="")
Allows to export code of a for-loop.
ExportVariable objSlx
#define CLOSE_NAMESPACE_ACADO
ExportVariable getElement(const ExportIndex &rowIdx, const ExportIndex &colIdx) const
ExportVariable DyN
Defines a scalar-valued index variable to be used for exporting code.
An OCP solver based on the block N^2 condensing algorithm.
ExportVariable getRows(const ExportIndex &idx1, const ExportIndex &idx2) const
bool initialStateFixed() const
ExportFunction & setup(const std::string &_name="defaultFunctionName", const ExportArgument &_argument1=emptyConstExportArgument, const ExportArgument &_argument2=emptyConstExportArgument, const ExportArgument &_argument3=emptyConstExportArgument, const ExportArgument &_argument4=emptyConstExportArgument, const ExportArgument &_argument5=emptyConstExportArgument, const ExportArgument &_argument6=emptyConstExportArgument, const ExportArgument &_argument7=emptyConstExportArgument, const ExportArgument &_argument8=emptyConstExportArgument, const ExportArgument &_argument9=emptyConstExportArgument)
virtual returnValue setDoc(const std::string &_doc)
std::string commonHeaderName
ExportFunction modelSimulation
virtual ExportFunction & doc(const std::string &_doc)
printLevel
Definition: example1.py:55
bool isGiven(const ExportIndex &rowIdx, const ExportIndex &colIdx) const
ExportVariable getTranspose() const
ExportVariable QN2
ExportVariable QN1
Encapsulates all user interaction for setting options, logging data and plotting results.
Allows to export code of an arbitrary function.
returnValue addStatement(const ExportStatement &_statement)
PrintLevel
std::string getName() const
Definition: export_data.cpp:86
returnValue addLinebreak(uint num=1)
#define ACADOWARNINGTEXT(retval, text)
ExportFunction & setReturnValue(const ExportVariable &_functionReturnValue, bool _returnAsPointer=false)
unsigned getNumComplexConstraints(void)
std::string getName() const
#define BEGIN_NAMESPACE_ACADO
Interface generator for the qpDUNES QP solver.
const std::string get(const ExportIndex &rowIdx, const ExportIndex &colIdx) const
returnValue addFunction(const ExportFunction &_function)
virtual returnValue getCode(ExportStatementBlock &code)
virtual returnValue getCode(ExportStatementBlock &code)
ExportVariable getCols(const ExportIndex &idx1, const ExportIndex &idx2) const
Allows to export code for a block of statements.
ExportFunction initialize
const double ZERO_EPS
ExportFunction & addIndex(const ExportIndex &_index)
ExportFunction regularizeHessian
ExportVariable makeColVector() const
Defines a matrix-valued variable to be used for exporting code.
returnValue addFunctionCall(const std::string &_fName, const ExportArgument &_argument1=emptyConstExportArgument, const ExportArgument &_argument2=emptyConstExportArgument, const ExportArgument &_argument3=emptyConstExportArgument, const ExportArgument &_argument4=emptyConstExportArgument, const ExportArgument &_argument5=emptyConstExportArgument, const ExportArgument &_argument6=emptyConstExportArgument, const ExportArgument &_argument7=emptyConstExportArgument, const ExportArgument &_argument8=emptyConstExportArgument, const ExportArgument &_argument9=emptyConstExportArgument)


acado
Author(s): Milan Vukov, Rien Quirynen
autogenerated on Mon Feb 28 2022 21:31:53