export_exact_hessian_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 
34 
36 
37 using namespace std;
38 
40  const std::string& _commonHeaderName
41  ) : ExportGaussNewtonQpDunes( _userInteraction,_commonHeaderName )
42 {}
43 
45 {
46  LOG( LVL_DEBUG ) << "Solver: setup initialization... " << endl;
48 
49  //
50  // Add QP initialization call to the initialization
51  //
52  initialize << "for( ret = 0; ret < ACADO_N*(ACADO_NX+ACADO_NU)*(ACADO_NX+ACADO_NU)+ACADO_NX*ACADO_NX; ret++ ) acadoWorkspace.qpH[ret] = 1.0;\n"; // TODO: this is added because of a bug in qpDUNES !!
53  ExportFunction initializeQpDunes( "initializeQpDunes" );
55  << "ret = (int)initializeQpDunes();\n"
56  << "if ((return_t)ret != QPDUNES_OK) return ret;\n";
57 
58  cleanup.setup( "cleanupSolver" );
59  ExportFunction cleanupQpDunes( "cleanupQpDunes" );
60  cleanup.addFunctionCall( cleanupQpDunes );
61  LOG( LVL_DEBUG ) << "done!" << endl;
62 
63  LOG( LVL_DEBUG ) << "Solver: setup setupVariables... " << endl;
65  LOG( LVL_DEBUG ) << "done!" << endl;
66 
67  LOG( LVL_DEBUG ) << "Solver: setup setupSimulation... " << endl;
69  LOG( LVL_DEBUG ) << "done!" << endl;
70 
71  LOG( LVL_DEBUG ) << "Solver: setup setupObjectiveEvaluation... " << endl;
73  LOG( LVL_DEBUG ) << "done!" << endl;
74 
75  LOG( LVL_DEBUG ) << "Solver: setup setupConstraintsEvaluation... " << endl;
77  LOG( LVL_DEBUG ) << "done!" << endl;
78 
79  LOG( LVL_DEBUG ) << "Solver: setup hessian regularization... " << endl;
81  LOG( LVL_DEBUG ) << "done!" << endl;
82 
83  LOG( LVL_DEBUG ) << "Solver: setup Evaluation... " << endl;
85  LOG( LVL_DEBUG ) << "done!" << endl;
86 
87  LOG( LVL_DEBUG ) << "Solver: setup setupAuxiliaryFunctions... " << endl;
89  LOG( LVL_DEBUG ) << "done!" << endl;
90 
91  return SUCCESSFUL_RETURN;
92 }
93 
95  ) const
96 {
98 
99  declarations.addDeclaration( regularization );
100 
101  return SUCCESSFUL_RETURN;
102 }
103 
105  )
106 {
108  code.addStatement( *qpInterface );
109 
110  code.addLinebreak( 2 );
111  code.addStatement( "/******************************************************************************/\n" );
112  code.addStatement( "/* */\n" );
113  code.addStatement( "/* ACADO code generation */\n" );
114  code.addStatement( "/* */\n" );
115  code.addStatement( "/******************************************************************************/\n" );
116  code.addLinebreak( 2 );
117 
118  int useOMP;
119  get(CG_USE_OPENMP, useOMP);
120  if ( useOMP )
121  {
122  code.addDeclaration( state );
123  }
124 
126 
129  code.addFunction( setObjQ1Q2 );
130  code.addFunction( setObjR1R2 );
131  code.addFunction( setObjQN1QN2 );
132  code.addFunction( setStageH );
133  code.addFunction( setStagef );
135 
137 
139 
140  for (unsigned i = 0; i < evaluatePointConstraints.size(); ++i)
141  {
142  if (evaluatePointConstraints[ i ] == 0)
143  continue;
145  }
146 
147  code.addFunction( setStagePac );
149 
150  code.addFunction( acc );
151 
152  code.addFunction( preparation );
153  code.addFunction( feedback );
154 
155  code.addFunction( initialize );
157  code.addFunction( shiftStates );
158  code.addFunction( shiftControls );
159  code.addFunction( getKKT );
160  code.addFunction( getObjective );
161 
162  code.addFunction( cleanup );
163  code.addFunction( shiftQpData );
164 
165  return SUCCESSFUL_RETURN;
166 }
167 
168 //
169 // PROTECTED FUNCTIONS:
170 //
171 
173 {
174  evaluateObjective.setup("evaluateObjective");
175 
176  //
177  // A loop the evaluates objective and corresponding gradients
178  //
179  ExportIndex runObj( "runObj" );
180  ExportForLoop loopObjective( runObj, 0, N );
181 
182  evaluateObjective.addIndex( runObj );
183 
184  // Interface variable to qpDUNES
185  qpH.setup("qpH", N * (NX + NU) * (NX + NU) + NX * NX, 1, REAL, ACADO_WORKSPACE); // --> to be used only after regularization to pass to qpDUNES
186  qpg.setup("qpG", N * (NX + NU) + NX, 1, REAL, ACADO_WORKSPACE);
187 
188  // LM regularization preparation
189 
190  ExportVariable evLmX = zeros<double>(NX, NX);
191  ExportVariable evLmU = zeros<double>(NU, NU);
192 
193  if (levenbergMarquardt > 0.0)
194  {
195  DMatrix lmX = eye<double>( NX );
196  lmX *= levenbergMarquardt;
197 
198  DMatrix lmU = eye<double>( NU );
199  lmU *= levenbergMarquardt;
200 
201  evLmX = lmX;
202  evLmU = lmU;
203  }
204 
205  ExportVariable stagef;
206  stagef.setup("stagef", NX + NU, 1, REAL, ACADO_LOCAL);
207 
208  ExportVariable stageH;
209  stageH.setup("stageH", NX + NU, NX + NU, REAL, ACADO_LOCAL);
210 
211  if( evaluateStageCost.getFunctionDim() > 0 ) {
212  loopObjective.addStatement( objValueIn.getCols(0, getNX()) == x.getRow( runObj ) );
213  loopObjective.addStatement( objValueIn.getCols(NX, NX + NU) == u.getRow( runObj ) );
214  loopObjective.addStatement( objValueIn.getCols(NX + NU, NX + NU + NOD) == od.getRow( runObj ) );
215  loopObjective.addLinebreak( );
216 
217  // Evaluate the objective function
219  loopObjective.addLinebreak( );
220 
221  ExportVariable tmpFxx, tmpFxu, tmpFuu;
222  tmpFxx.setup("tmpFxx", NX, NX, REAL, ACADO_LOCAL);
223  tmpFxu.setup("tmpFxu", NX, NU, REAL, ACADO_LOCAL);
224  tmpFuu.setup("tmpFuu", NU, NU, REAL, ACADO_LOCAL);
225 
226  setStageH.setup("addObjTerm", tmpFxx, tmpFxu, tmpFuu, stageH);
227  setStageH.addStatement( stageH.getSubMatrix(0,NX,0,NX) += tmpFxx + evLmX );
228  setStageH.addStatement( stageH.getSubMatrix(0,NX,NX,NX+NU) += tmpFxu );
229  setStageH.addStatement( stageH.getSubMatrix(NX,NX+NU,0,NX) += tmpFxu.getTranspose() );
230  setStageH.addStatement( stageH.getSubMatrix(NX,NX+NU,NX,NX+NU) += tmpFuu + evLmU );
231 
232  loopObjective.addFunctionCall(
233  setStageH, objValueOut.getAddress(0, 1+NX+NU), objValueOut.getAddress(0, 1+NX+NU+NX*NX),
234  objValueOut.getAddress(0, 1+NX+NU+NX*(NX+NU)), objS.getAddress(runObj*(NX+NU), 0) );
235 
236  ExportVariable tmpDF;
237  tmpDF.setup("tmpDF", NX+NU, 1, REAL, ACADO_LOCAL);
238  setStagef.setup("addObjLinearTerm", tmpDF, stagef);
239  setStagef.addStatement( stagef == tmpDF.getRows(0,NX+NU) );
240 
241  loopObjective.addFunctionCall(
242  setStagef, objValueOut.getAddress(0, 1), qpg.getAddress(runObj * (NX+NU)) );
243 
244  loopObjective.addLinebreak( );
245  }
246  else {
247  if(levenbergMarquardt > 0.0) {
248  setStageH.setup("addObjTerm", stageH);
249  setStageH.addStatement( stageH.getSubMatrix(0,NX,0,NX) += evLmX );
250  setStageH.addStatement( stageH.getSubMatrix(NX,NX+NU,NX,NX+NU) += evLmU );
251 
252  loopObjective.addFunctionCall( setStageH, objS.getAddress(runObj*(NX+NU), 0) );
253  }
254  DMatrix D(NX+NU,1); D.setAll(0);
255  loopObjective.addStatement( qpg.getRows(runObj*(NX+NU), runObj*(NX+NU)+NX+NU) == D );
256  }
257 
258  evaluateObjective.addStatement( loopObjective );
259 
260  //
261  // Evaluate the quadratic Mayer term
262  //
266 
267  // Evaluate the objective function, last node.
270 
272  evaluateObjective.addStatement( qpg.getRows(N * NX, (N + 1) * NX) == objValueOut.getCols(1,1+NX).getTranspose() );
273 
275  }
276  else {
277  if(levenbergMarquardt > 0.0) {
279  }
280  else {
281  DMatrix hess(NX,NX); hess.setAll(0);
283  }
284 
285  DMatrix Dx(NX,1); Dx.setAll(0);
286  evaluateObjective.addStatement( qpg.getRows(N*NX, (N+1)*NX) == Dx );
287  }
288 
289  return SUCCESSFUL_RETURN;
290 }
291 
293 {
294  string moduleName;
295  get(CG_MODULE_NAME, moduleName);
296 
297  ExportVariable block( "hessian_block", NX+NU, NX+NU );
298  regularization = ExportFunction( "regularize", block );
299  regularization.doc( "EVD-based regularization of a Hessian block." );
301 
302  regularizeHessian.setup( "regularizeHessian" );
303  regularizeHessian.doc( "Regularization procedure of the computed exact Hessian." );
304 
305  ExportIndex oInd;
306  regularizeHessian.acquire( oInd );
307 
308  ExportForLoop loopObjective(oInd, 0, N);
309  loopObjective.addFunctionCall( regularization, objS.getAddress(oInd*(NX+NU),0) );
310  for( uint row = 0; row < NX+NU; row++ ) {
311  loopObjective.addStatement( qpH.getRows((oInd*(NX+NU)+row)*(NX+NU),(oInd*(NX+NU)+row+1)*(NX+NU)) == objS.getRow(oInd*(NX+NU)+row).getTranspose() );
312  }
313  regularizeHessian.addStatement( loopObjective );
314 
316 
317  return SUCCESSFUL_RETURN;
318 }
319 
#define LOG(level)
Just define a handy macro for getting the logger.
Lowest level, the debug level.
virtual returnValue setupHessianRegularization(void)
ExportVariable getRow(const ExportIndex &idx) const
ExportVariable objS
ExportFunction shiftStates
virtual returnValue getFunctionDeclarations(ExportStatementBlock &declarations) const
A class for export of an OCP solver using sparse QP solver qpDUNES.
ExportVariable getTranspose() const
ExportVariable & setup(const std::string &_name, uint _nRows=1, uint _nCols=1, ExportType _type=REAL, ExportStruct _dataStruct=ACADO_LOCAL, bool _callItByValue=false, const std::string &_prefix=std::string())
uint getNX() const
Allows to pass back messages to the calling function.
virtual returnValue getCode(ExportStatementBlock &code)
Block< Derived > block(Index startRow, Index startCol, Index blockRows, Index blockCols)
Definition: BlockMethods.h:56
BEGIN_NAMESPACE_ACADO typedef unsigned int uint
Definition: acado_types.hpp:42
void setAll(const T &_value)
Definition: matrix.hpp:141
Allows to export code of a for-loop.
#define CLOSE_NAMESPACE_ACADO
ExportVariable state
ExportVariable getSubMatrix(const ExportIndex &rowIdx1, const ExportIndex &rowIdx2, const ExportIndex &colIdx1, const ExportIndex &colIdx2) const
virtual returnValue setupConstraintsEvaluation(void)
Defines a scalar-valued index variable to be used for exporting code.
ExportAcadoFunction evaluateStageCost
ExportAcadoFunction evaluateTerminalCost
ExportFunction regularization
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)
std::shared_ptr< ExportQpDunesInterface > qpInterface
virtual returnValue setupInitialization()
ExportFunction modelSimulation
virtual ExportFunction & doc(const std::string &_doc)
ExportVariable getCols(const ExportIndex &idx1, const ExportIndex &idx2) const
ExportFunction getObjective
ExportVariable makeRowVector() const
ExportVariable objValueIn
ExportFunction initializeNodes
virtual returnValue setupSimulation(void)
std::vector< std::shared_ptr< ExportAcadoFunction > > evaluatePointConstraints
Encapsulates all user interaction for setting options, logging data and plotting results.
Allows to export code of an arbitrary function.
ExportFunction shiftControls
returnValue addStatement(const ExportStatement &_statement)
returnValue addLinebreak(uint num=1)
ExportAcadoFunction evaluatePathConstraints
RowXpr row(Index i)
Definition: BlockMethods.h:725
virtual ExportFunction & acquire(ExportIndex &obj)
ExportVariable objSEndTerm
ExportVariable getRows(const ExportIndex &idx1, const ExportIndex &idx2) const
returnValue addDeclaration(const ExportVariable &_data, ExportStruct _dataStruct=ACADO_ANY)
returnValue setupAuxiliaryFunctions()
ExportExactHessianQpDunes(UserInteraction *_userInteraction=0, const std::string &_commonHeaderName="")
#define BEGIN_NAMESPACE_ACADO
returnValue addFunction(const ExportFunction &_function)
virtual returnValue getFunctionDeclarations(ExportStatementBlock &declarations) const
Allows to export code for a block of statements.
ExportFunction initialize
ExportArgument getAddress(const ExportIndex &_rowIdx, const ExportIndex &_colIdx=emptyConstExportIndex) const
ExportVariable objValueOut
ExportFunction & addIndex(const ExportIndex &_index)
ExportFunction regularizeHessian
Defines a matrix-valued variable to be used for exporting code.
virtual returnValue setupObjectiveEvaluation(void)
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


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