qpOASES_e_QProblemB.c
Go to the documentation of this file.
1 /*
2  * This file is part of qpOASES.
3  *
4  * qpOASES -- An Implementation of the Online Active Set Strategy.
5  * Copyright (C) 2007-2015 by Hans Joachim Ferreau, Andreas Potschka,
6  * Christian Kirches et al. All rights reserved.
7  *
8  * qpOASES is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * qpOASES is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16  * See the GNU Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with qpOASES; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  *
22  */
23 
24 
37 #include <stdlib.h>
38 
39 #include <qpOASES_e.h>
41 
42 
43 #ifdef __cplusplus
44 extern "C" {
45 #endif
46 
47 
48 #define S_FUNCTION_NAME qpOASES_e_QProblemB
49 #define S_FUNCTION_LEVEL 2
51 #define MDL_START
53 #include "simstruc.h"
54 
55 
56 /* SETTINGS */
57 #define SAMPLINGTIME -1
58 #define NCONTROLINPUTS 2
59 #define MAXITER 100
60 #define HESSIANTYPE HST_UNKNOWN
64 static void mdlInitializeSizes (SimStruct *S) /* Init sizes array */
65 {
66  int nU = NCONTROLINPUTS;
67 
68  /* Specify the number of continuous and discrete states */
69  ssSetNumContStates(S, 0);
70  ssSetNumDiscStates(S, 0);
71 
72  /* Specify the number of parameters */
73  ssSetNumSFcnParams(S, 1); /* H */
74  if ( ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S) )
75  return;
76 
77  /* Specify the number of intput ports */
78  if ( !ssSetNumInputPorts(S, 3) )
79  return;
80 
81  /* Specify the number of output ports */
82  if ( !ssSetNumOutputPorts(S, 4) )
83  return;
84 
85  /* Specify dimension information for the input ports */
86  ssSetInputPortVectorDimension(S, 0, DYNAMICALLY_SIZED); /* g */
87  ssSetInputPortVectorDimension(S, 1, DYNAMICALLY_SIZED); /* lb */
88  ssSetInputPortVectorDimension(S, 2, DYNAMICALLY_SIZED); /* ub */
89 
90  /* Specify dimension information for the output ports */
91  ssSetOutputPortVectorDimension(S, 0, nU ); /* uOpt */
92  ssSetOutputPortVectorDimension(S, 1, 1 ); /* fval */
93  ssSetOutputPortVectorDimension(S, 2, 1 ); /* exitflag */
94  ssSetOutputPortVectorDimension(S, 3, 1 ); /* iter */
95 
96  /* Specify the direct feedthrough status */
97  ssSetInputPortDirectFeedThrough(S, 0, 1);
98  ssSetInputPortDirectFeedThrough(S, 1, 1);
99  ssSetInputPortDirectFeedThrough(S, 2, 1);
100 
101  /* One sample time */
102  ssSetNumSampleTimes(S, 1);
103 
104  /* global variables:
105  * 0: problem
106  * 1: H
107  * 2: g
108  * 3: lb
109  * 4: ub
110  */
111 
112  /* Specify the size of the block's pointer work vector */
113  ssSetNumPWork(S, 5);
114 }
115 
116 
117 #if defined(MATLAB_MEX_FILE)
118 
119 #define MDL_SET_INPUT_PORT_DIMENSION_INFO
120 #define MDL_SET_OUTPUT_PORT_DIMENSION_INFO
121 
122 static void mdlSetInputPortDimensionInfo(SimStruct *S, int_T port, const DimsInfo_T *dimsInfo)
123 {
124  if ( !ssSetInputPortDimensionInfo(S, port, dimsInfo) )
125  return;
126 }
127 
128 static void mdlSetOutputPortDimensionInfo(SimStruct *S, int_T port, const DimsInfo_T *dimsInfo)
129 {
130  if ( !ssSetOutputPortDimensionInfo(S, port, dimsInfo) )
131  return;
132 }
133 
134 #endif
135 
136 
137 static void mdlInitializeSampleTimes(SimStruct *S)
138 {
139  ssSetSampleTime(S, 0, SAMPLINGTIME);
140  ssSetOffsetTime(S, 0, 0.0);
141 }
142 
143 
144 static void mdlStart(SimStruct *S)
145 {
147 
148  int nU = NCONTROLINPUTS;
149  int size_g, size_lb, size_ub;
150  int size_H, nRows_H, nCols_H;
151  int nV;
152 
153  static QProblemB problem;
154  static Options problemOptions;
155  real_t* count;
156 
157 
158  /* get block inputs dimensions */
159  const mxArray* in_H = ssGetSFcnParam(S, 0);
160 
161  if ( mxIsEmpty(in_H) == 1 )
162  {
163  if ( ( HESSIANTYPE != HST_ZERO ) && ( HESSIANTYPE != HST_IDENTITY ) )
164  {
165  #ifndef __SUPPRESSANYOUTPUT__
166  mexErrMsgTxt( "ERROR (qpOASES): Hessian can only be empty if type is set to HST_ZERO or HST_IDENTITY!" );
167  #endif
168  return;
169  }
170 
171  nRows_H = 0;
172  nCols_H = 0;
173  size_H = 0;
174  }
175  else
176  {
177  nRows_H = (int)mxGetM(in_H);
178  nCols_H = (int)mxGetN(in_H);
179  size_H = nRows_H * nCols_H;
180  }
181 
182  size_g = ssGetInputPortWidth(S, 0);
183  size_lb = ssGetInputPortWidth(S, 1);
184  size_ub = ssGetInputPortWidth(S, 2);
185 
186 
187  /* dimension checks */
188  nV = size_g;
189 
190  if ( MAXITER < 0 )
191  {
192  #ifndef __SUPPRESSANYOUTPUT__
193  mexErrMsgTxt( "ERROR (qpOASES): Maximum number of iterations must not be negative!" );
194  #endif
195  return;
196  }
197 
198  if ( nV <= 0 )
199  {
200  #ifndef __SUPPRESSANYOUTPUT__
201  mexErrMsgTxt( "ERROR (qpOASES): Dimension mismatch!" );
202  #endif
203  return;
204  }
205 
206  if ( ( size_H != nV*nV ) && ( size_H != 0 ) )
207  {
208  #ifndef __SUPPRESSANYOUTPUT__
209  mexErrMsgTxt( "ERROR (qpOASES): Dimension mismatch in H!" );
210  #endif
211  return;
212  }
213 
214  if ( nRows_H != nCols_H )
215  {
216  #ifndef __SUPPRESSANYOUTPUT__
217  mexErrMsgTxt( "ERROR (qpOASES): Hessian matrix must be square matrix!" );
218  #endif
219  return;
220  }
221 
222  if ( ( nU < 1 ) || ( nU > nV ) )
223  {
224  #ifndef __SUPPRESSANYOUTPUT__
225  mexErrMsgTxt( "ERROR (qpOASES): Invalid number of control inputs!" );
226  #endif
227  return;
228  }
229 
230  if ( ( size_lb != nV ) && ( size_lb != 0 ) )
231  {
232  #ifndef __SUPPRESSANYOUTPUT__
233  mexErrMsgTxt( "ERROR (qpOASES): Dimension mismatch in lb!" );
234  #endif
235  return;
236  }
237 
238  if ( ( size_ub != nV ) && ( size_ub != 0 ) )
239  {
240  #ifndef __SUPPRESSANYOUTPUT__
241  mexErrMsgTxt( "ERROR (qpOASES): Dimension mismatch in ub!" );
242  #endif
243  return;
244  }
245 
246 
247  /* allocate QProblemB object */
248  QProblemBCON( &problem,nV,HESSIANTYPE );
249 
250  Options_setToMPC( &problemOptions );
251  QProblemB_setOptions( &problem,problemOptions );
252  #ifndef __DEBUG__
253  QProblemB_setPrintLevel( &problem,PL_LOW );
254  #endif
255  #ifdef __SUPPRESSANYOUTPUT__
256  QProblemB_setPrintLevel( &problem,PL_NONE );
257  #endif
258 
259  ssGetPWork(S)[0] = (void*)(&problem);
260 
261  /* allocate memory for QP data ... */
262  if ( size_H > 0 )
263  ssGetPWork(S)[1] = (void *) calloc( size_H, sizeof(real_t) ); /* H */
264  else
265  ssGetPWork(S)[1] = 0;
266 
267  ssGetPWork(S)[2] = (void *) calloc( size_g, sizeof(real_t) ); /* g */
268 
269  if ( size_lb > 0 )
270  ssGetPWork(S)[3] = (void *) calloc( size_lb, sizeof(real_t) ); /* lb */
271  else
272  ssGetPWork(S)[3] = 0;
273 
274  if ( size_ub > 0 )
275  ssGetPWork(S)[4] = (void *) calloc( size_ub, sizeof(real_t) ); /* ub */
276  else
277  ssGetPWork(S)[4] = 0;
278 }
279 
280 
281 static void mdlOutputs(SimStruct *S, int_T tid)
282 {
284 
285  int i;
286  int nV;
287  returnValue status;
288 
289  int nWSR = MAXITER;
290  int nU = NCONTROLINPUTS;
291 
292  InputRealPtrsType in_g, in_lb, in_ub;
293 
294  QProblemB* problem;
295  real_t *H, *g, *lb, *ub;
296 
297  real_t xOpt[NVMAX];
298 
299  real_T *out_uOpt, *out_objVal, *out_status, *out_nWSR;
300 
301  int nWSR_retry;
302 
303 
304  /* get pointers to block inputs ... */
305  const mxArray* in_H = ssGetSFcnParam(S, 0);
306  in_g = ssGetInputPortRealSignalPtrs(S, 0);
307  in_lb = ssGetInputPortRealSignalPtrs(S, 1);
308  in_ub = ssGetInputPortRealSignalPtrs(S, 2);
309 
310  /* ... and to the QP data */
311  problem = (QProblemB*)(ssGetPWork(S)[0]);
312 
313  H = (real_t*)(ssGetPWork(S)[1]);
314  g = (real_t*)(ssGetPWork(S)[2]);
315  lb = (real_t*)(ssGetPWork(S)[3]);
316  ub = (real_t*)(ssGetPWork(S)[4]);
317 
318 
319  /* setup QP data */
320  nV = ssGetInputPortWidth(S, 1); /* nV = size_g */
321 
322  if ( H != 0 )
323  {
324  /* no conversion from FORTRAN to C as Hessian is symmetric! */
325  for ( i=0; i<nV*nV; ++i )
326  H[i] = (mxGetPr(in_H))[i];
327  }
328 
329  for ( i=0; i<nV; ++i )
330  g[i] = (*in_g)[i];
331 
332  if ( lb != 0 )
333  {
334  for ( i=0; i<nV; ++i )
335  lb[i] = (*in_lb)[i];
336  }
337 
338  if ( ub != 0 )
339  {
340  for ( i=0; i<nV; ++i )
341  ub[i] = (*in_ub)[i];
342  }
343 
344  if ( QProblemB_getCount( problem ) == 0 )
345  {
346  /* initialise and solve first QP */
347  status = QProblemB_init( problem,H,g,lb,ub, &nWSR,0 );
348  QProblemB_getPrimalSolution( problem,xOpt );
349  }
350  else
351  {
352  /* solve neighbouring QP using hotstart technique */
353  status = QProblemB_hotstart( problem,g,lb,ub, &nWSR,0 );
354  if ( ( status != SUCCESSFUL_RETURN ) && ( status != RET_MAX_NWSR_REACHED ) )
355  {
356  /* if an error occurs, reset problem data structures ... */
357  QProblemB_reset( problem );
358 
359  /* ... and initialise/solve again with remaining number of iterations. */
360  nWSR_retry = MAXITER - nWSR;
361  status = QProblemB_init( problem,H,g,lb,ub, &nWSR_retry,0 );
362  nWSR += nWSR_retry;
363  }
364 
365  /* obtain optimal solution */
366  QProblemB_getPrimalSolution( problem,xOpt );
367  }
368 
369  /* generate block output: status information ... */
370  out_uOpt = ssGetOutputPortRealSignal(S, 0);
371  out_objVal = ssGetOutputPortRealSignal(S, 1);
372  out_status = ssGetOutputPortRealSignal(S, 2);
373  out_nWSR = ssGetOutputPortRealSignal(S, 3);
374 
375  for ( i=0; i<nU; ++i )
376  out_uOpt[i] = (real_T)(xOpt[i]);
377 
378  out_objVal[0] = (real_T)(QProblemB_getObjVal( problem ));
379  out_status[0] = (real_t)(qpOASES_getSimpleStatus( status,BT_FALSE ));
380  out_nWSR[0] = (real_T)(nWSR);
381 
382  removeNaNs( out_uOpt,nU );
383  removeInfs( out_uOpt,nU );
384  removeNaNs( out_objVal,1 );
385  removeInfs( out_objVal,1 );
386 }
387 
388 
389 static void mdlTerminate(SimStruct *S)
390 {
392 
393  int i;
394 
395  /* reset global message handler */
397 
398  for ( i=1; i<5; ++i )
399  {
400  if ( ssGetPWork(S)[i] != 0 )
401  free( ssGetPWork(S)[i] );
402  }
403 }
404 
405 
406 #ifdef MATLAB_MEX_FILE
407 #include "simulink.c"
408 #else
409 #include "cg_sfun.h"
410 #endif
411 
412 
413 #ifdef __cplusplus
414 }
415 #endif
416 
417 
418 /*
419  * end of file
420  */
void QProblemBCON(QProblemB *_THIS, int _nV, HessianType _hessianType)
Definition: QProblemB.c:45
static void mdlInitializeSampleTimes(SimStruct *S)
#define NCONTROLINPUTS
Implements the online active set strategy for box-constrained QPs.
returnValue QProblemB_reset(QProblemB *_THIS)
Definition: QProblemB.c:153
#define HESSIANTYPE
int qpOASES_getSimpleStatus(returnValue returnvalue, BooleanType doPrintStatus)
Definition: Utils.c:882
Allows to pass back messages to the calling function.
real_t QProblemB_getObjVal(QProblemB *_THIS)
Definition: QProblemB.c:807
#define HST_IDENTITY
#define PL_NONE
returnValue MessageHandling_reset(MessageHandling *_THIS)
#define SAMPLINGTIME
static void mdlOutputs(SimStruct *S, int_T tid)
static void mdlTerminate(SimStruct *S)
static void mdlStart(SimStruct *S)
int_t QProblemB_hotstart(const real_t *const g, const real_t *const lb, const real_t *const ub, int_t *const nWSR, real_t *const cputime, real_t *const x, real_t *const y, real_t *const obj, int_t *const status)
Provides a generic way to set and pass user-specified options.
Definition: options.hpp:65
#define MAXITER
#define PL_LOW
returnValue QProblemB_setPrintLevel(QProblemB *_THIS, PrintLevel _printlevel)
Definition: QProblemB.c:930
static returnValue QProblemB_setOptions(QProblemB *_THIS, Options _options)
Definition: QProblemB.h:1299
returnValue Options_setToMPC(Options *_THIS)
Definition: Options.c:214
MessageHandling * qpOASES_getGlobalMessageHandler()
returnValue QProblemB_getPrimalSolution(QProblemB *_THIS, real_t *const xOpt)
Definition: QProblemB.c:880
int_t QProblemB_init(const real_t *const H, const real_t *const g, const real_t *const lb, const real_t *const ub, int_t *const nWSR, real_t *const cputime, const qpOASES_Options *const options, real_t *const x, real_t *const y, real_t *const obj, int_t *const status)
#define HST_ZERO
static unsigned int QProblemB_getCount(QProblemB *_THIS)
Definition: QProblemB.h:1325
#define BT_FALSE
Definition: acado_types.hpp:49
double real_t
Definition: AD_test.c:10


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