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.
ExportVariable getRow(const ExportIndex &idx) const
ExportFunction & setName(const std::string &_name)
ExportVariable getTranspose() const
bool initialStateFixed() const
bool isGiven(const ExportIndex &rowIdx, const ExportIndex &colIdx) const
Allows to pass back messages to the calling function.
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 getElement(const ExportIndex &rowIdx, const ExportIndex &colIdx) const
ExportVariable objSlx
#define CLOSE_NAMESPACE_ACADO
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.
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)
virtual bool isDefined() const
ExportVariable getCols(const ExportIndex &idx1, const ExportIndex &idx2) const
printLevel
Definition: example1.py:55
const std::string get(const ExportIndex &rowIdx, const ExportIndex &colIdx) 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 getFullName() const
returnValue addLinebreak(uint num=1)
#define ACADOWARNINGTEXT(retval, text)
ExportFunction & setReturnValue(const ExportVariable &_functionReturnValue, bool _returnAsPointer=false)
std::string getName() const
ExportVariable getRows(const ExportIndex &idx1, const ExportIndex &idx2) const
unsigned getNumComplexConstraints(void)
#define BEGIN_NAMESPACE_ACADO
Interface generator for the qpDUNES QP solver.
returnValue addFunction(const ExportFunction &_function)
virtual returnValue getCode(ExportStatementBlock &code)
virtual returnValue getCode(ExportStatementBlock &code)
Allows to export code for a block of statements.
ExportFunction initialize
const double ZERO_EPS
ExportFunction & addIndex(const ExportIndex &_index)
ExportFunction regularizeHessian
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)
ExportVariable makeColVector() const
std::string getName() const
Definition: export_data.cpp:86


acado
Author(s): Milan Vukov, Rien Quirynen
autogenerated on Mon Jun 10 2019 12:34:33