qpOASES-3.0beta/interfaces/simulink/qpOASES_QProblemB.cpp
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-2011 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/QProblemB.hpp>
40 
41 
42 #ifdef __cplusplus
43 extern "C" {
44 #endif
45 
46 
47 #define S_FUNCTION_NAME qpOASES_QProblemB
48 #define S_FUNCTION_LEVEL 2
50 #define MDL_START
52 #include "simstruc.h"
53 
54 
55 /* SETTINGS: */
56 #define SAMPLINGTIME 0.1
57 #define NCONTROLINPUTS 2
58 #define NWSR 10
61 static void mdlInitializeSizes (SimStruct *S) /* Init sizes array */
62 {
63  int nU = NCONTROLINPUTS;
64 
65  /* Specify the number of continuous and discrete states */
66  ssSetNumContStates(S, 0);
67  ssSetNumDiscStates(S, 0);
68 
69  /* Specify the number of intput ports */
70  if ( !ssSetNumInputPorts(S, 4) )
71  return;
72 
73  /* Specify the number of output ports */
74  if ( !ssSetNumOutputPorts(S, 4) )
75  return;
76 
77  /* Specify dimension information for the input ports */
78  ssSetInputPortVectorDimension(S, 0, DYNAMICALLY_SIZED);
79  ssSetInputPortVectorDimension(S, 1, DYNAMICALLY_SIZED);
80  ssSetInputPortVectorDimension(S, 2, DYNAMICALLY_SIZED);
81  ssSetInputPortVectorDimension(S, 3, DYNAMICALLY_SIZED);
82 
83  /* Specify dimension information for the output ports */
84  ssSetOutputPortVectorDimension(S, 0, 1 );
85  ssSetOutputPortVectorDimension(S, 1, nU );
86  ssSetOutputPortVectorDimension(S, 2, 1 );
87  ssSetOutputPortVectorDimension(S, 3, 1 );
88 
89  /* Specify the direct feedthrough status */
90  ssSetInputPortDirectFeedThrough(S, 0, 1);
91  ssSetInputPortDirectFeedThrough(S, 1, 1);
92  ssSetInputPortDirectFeedThrough(S, 2, 1);
93  ssSetInputPortDirectFeedThrough(S, 3, 1);
94 
95  /* One sample time */
96  ssSetNumSampleTimes(S, 1);
97 
98 
99  /* global variables:
100  * 0: problem
101  * 1: H
102  * 2: g
103  * 3: lb
104  * 4: ub
105  * 5: count
106  */
107 
108  /* Specify the size of the block's pointer work vector */
109  ssSetNumPWork(S, 6);
110 }
111 
112 
113 #if defined(MATLAB_MEX_FILE)
114 
115 #define MDL_SET_INPUT_PORT_DIMENSION_INFO
116 #define MDL_SET_OUTPUT_PORT_DIMENSION_INFO
117 
118 static void mdlSetInputPortDimensionInfo(SimStruct *S, int_T port, const DimsInfo_T *dimsInfo)
119 {
120  if ( !ssSetInputPortDimensionInfo(S, port, dimsInfo) )
121  return;
122 }
123 
124 static void mdlSetOutputPortDimensionInfo(SimStruct *S, int_T port, const DimsInfo_T *dimsInfo)
125 {
126  if ( !ssSetOutputPortDimensionInfo(S, port, dimsInfo) )
127  return;
128 }
129 
130 #endif
131 
132 
133 static void mdlInitializeSampleTimes(SimStruct *S)
134 {
135  ssSetSampleTime(S, 0, SAMPLINGTIME);
136  ssSetOffsetTime(S, 0, 0.0);
137 }
138 
139 
140 static void mdlStart(SimStruct *S)
141 {
142  #ifndef __DSPACE__
143  using namespace qpOASES;
144  #endif
145 
146  int nU = NCONTROLINPUTS;
147  int size_H, size_g, size_lb, size_ub;
148  int nV;
149 
150  QProblemB* problem;
151  real_t* count;
152 
153 
154  /* get block inputs dimensions */
155  size_H = ssGetInputPortWidth(S, 0);
156  size_g = ssGetInputPortWidth(S, 1);
157  size_lb = ssGetInputPortWidth(S, 2);
158  size_ub = ssGetInputPortWidth(S, 3);
159 
160 
161  /* dimension checks */
162  nV = size_g;
163 
164  if ( nV == 0 )
165  {
166  #ifndef __DSPACE__
167  mexErrMsgTxt( "ERROR (qpOASES): Dimension mismatch!" );
168  #endif
169  return;
170  }
171 
172  if ( size_H != nV*nV )
173  {
174  #ifndef __DSPACE__
175  mexErrMsgTxt( "ERROR (qpOASES): Dimension mismatch!" );
176  #endif
177  return;
178  }
179 
180  if ( nU > nV )
181  {
182  #ifndef __DSPACE__
183  mexErrMsgTxt( "ERROR (qpOASES): Dimension mismatch!" );
184  #endif
185  return;
186  }
187 
188  if ( size_lb != nV )
189  {
190  #ifndef __DSPACE__
191  mexErrMsgTxt( "ERROR (qpOASES): Dimension mismatch!" );
192  #endif
193  return;
194  }
195 
196  if ( size_ub != nV )
197  {
198  #ifndef __DSPACE__
199  mexErrMsgTxt( "ERROR (qpOASES): Dimension mismatch!" );
200  #endif
201  return;
202  }
203 
204 
205  /* allocate QProblemB object */
206  problem = new QProblemB( nV );
207  if ( problem == 0 )
208  {
209  #ifndef __DSPACE__
210  mexErrMsgTxt( "ERROR (qpOASES): Unable to create QProblemB object!" );
211  #endif
212  return;
213  }
214 
215  #ifndef __DEBUG__
216  problem->setPrintLevel( PL_LOW );
217  #endif
218  #ifdef __SUPPRESSANYOUTPUT__
219  problem->setPrintLevel( PL_NONE );
220  #endif
221  #ifdef __DSPACE__
222  problem->setPrintLevel( PL_NONE );
223  #endif
224 
225  ssGetPWork(S)[0] = (void *) problem;
226 
227  /* allocate memory for QP data ... */
228  ssGetPWork(S)[1] = (void *) calloc( size_H, sizeof(real_t) ); /* H */
229  ssGetPWork(S)[2] = (void *) calloc( size_g, sizeof(real_t) ); /* g */
230  ssGetPWork(S)[3] = (void *) calloc( size_lb, sizeof(real_t) ); /* lb */
231  ssGetPWork(S)[4] = (void *) calloc( size_ub, sizeof(real_t) ); /* ub */
232  ssGetPWork(S)[5] = (void *) calloc( 1, sizeof(real_t) ); /* count */
233 
234  /* reset counter */
235  count = (real_t *) ssGetPWork(S)[5];
236  count[0] = 0.0;
237 }
238 
239 
240 static void mdlOutputs(SimStruct *S, int_T tid)
241 {
242  #ifndef __DSPACE__
243  using namespace qpOASES;
244  #endif
245 
246  int i;
247  int nV, status;
248 
249  int nWSR = NWSR;
250  int nU = NCONTROLINPUTS;
251 
252  InputRealPtrsType in_H, in_g, in_lb, in_ub;
253 
254  QProblemB* problem;
255  real_t *H, *g, *lb, *ub, *count;
256 
257  real_t *xOpt;
258 
259  real_T *out_objVal, *out_xOpt, *out_status, *out_nWSR;
260 
261 
262  /* get pointers to block inputs ... */
263  in_H = ssGetInputPortRealSignalPtrs(S, 0);
264  in_g = ssGetInputPortRealSignalPtrs(S, 1);
265  in_lb = ssGetInputPortRealSignalPtrs(S, 2);
266  in_ub = ssGetInputPortRealSignalPtrs(S, 3);
267 
268  /* ... and to the QP data */
269  problem = (QProblemB *) ssGetPWork(S)[0];
270 
271  H = (real_t *) ssGetPWork(S)[1];
272  g = (real_t *) ssGetPWork(S)[2];
273  lb = (real_t *) ssGetPWork(S)[3];
274  ub = (real_t *) ssGetPWork(S)[4];
275 
276  count = (real_t *) ssGetPWork(S)[5];
277 
278 
279  /* setup QP data */
280  nV = ssGetInputPortWidth(S, 1); /* nV = size_g */
281 
282  for ( i=0; i<nV*nV; ++i )
283  H[i] = (*in_H)[i];
284 
285  for ( i=0; i<nV; ++i )
286  {
287  g[i] = (*in_g)[i];
288  lb[i] = (*in_lb)[i];
289  ub[i] = (*in_ub)[i];
290  }
291 
292  xOpt = new real_t[nV];
293 
294  if ( count[0] == 0 )
295  {
296  /* initialise and solve first QP */
297  status = problem->init( H,g,lb,ub, nWSR,0 );
298  ssGetPWork(S)[0] = ( void* ) problem;
299  problem->getPrimalSolution( xOpt );
300  }
301  else
302  {
303  /* solve neighbouring QP using hotstart technique */
304  status = problem->hotstart( g,lb,ub, nWSR,0 );
305  if ( ( status != SUCCESSFUL_RETURN ) && ( status != RET_MAX_NWSR_REACHED ) )
306  {
307  /* if an error occurs, reset problem data structures and initialise again */
308  problem->reset( );
309  problem->init( H,g,lb,ub, nWSR,0 );
310  }
311  else
312  {
313  /* otherwise obtain optimal solution */
314  problem->getPrimalSolution( xOpt );
315  }
316  }
317 
318  /* generate block output: status information ... */
319  out_objVal = ssGetOutputPortRealSignal(S, 0);
320  out_xOpt = ssGetOutputPortRealSignal(S, 1);
321  out_status = ssGetOutputPortRealSignal(S, 2);
322  out_nWSR = ssGetOutputPortRealSignal(S, 3);
323 
324  out_objVal[0] = ((real_T) problem->getObjVal( ));
325 
326  for ( i=0; i<nU; ++i )
327  out_xOpt[i] = ((real_T) xOpt[i]);
328 
329  switch ( status )
330  {
331  case SUCCESSFUL_RETURN:
332  out_status[0] = 0.0;
333  break;
334 
336  out_status[0] = 1.0;
337  break;
338 
341  out_status[0] = -2.0;
342  break;
343 
346  out_status[0] = -3.0;
347  break;
348 
349  default:
350  out_status[0] = -1.0;
351  break;
352  }
353 
354  out_nWSR[0] = ((real_T) nWSR);
355 
356  /* increase counter */
357  count[0] = count[0] + 1;
358 
359  delete[] xOpt;
360 }
361 
362 
363 static void mdlTerminate(SimStruct *S)
364 {
365  #ifndef __DSPACE__
366  using namespace qpOASES;
367  #endif
368 
369  /* reset global message handler */
371 
372  int i;
373  for ( i=0; i<6; ++i )
374  {
375  if ( ssGetPWork(S)[i] != 0 )
376  free( ssGetPWork(S)[i] );
377  }
378 }
379 
380 
381 #ifdef MATLAB_MEX_FILE
382 #include "simulink.c"
383 #else
384 #include "cg_sfun.h"
385 #endif
386 
387 
388 #ifdef __cplusplus
389 }
390 #endif
391 
392 
393 /*
394  * end of file
395  */
Implements the online active set strategy for box-constrained QPs.
returnValue init(const real_t *const _H, const real_t *const _g, const real_t *const _lb, const real_t *const _ub, int &nWSR, const real_t *const yOpt=0, real_t *const cputime=0)
#define PL_NONE
returnValue hotstart(const real_t *const g_new, const real_t *const lb_new, const real_t *const ub_new, int &nWSR, real_t *const cputime)
#define PL_LOW
double real_t
Definition: AD_test.c:10


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