00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00037 #include <stdlib.h>
00038
00039 #include <qpOASES/QProblemB.hpp>
00040
00041
00042 #ifdef __cplusplus
00043 extern "C" {
00044 #endif
00045
00046
00047 #define S_FUNCTION_NAME qpOASES_QProblemB
00048 #define S_FUNCTION_LEVEL 2
00050 #define MDL_START
00052 #include "simstruc.h"
00053
00054
00055
00056 #define SAMPLINGTIME 0.1
00057 #define NCONTROLINPUTS 2
00058 #define NWSR 10
00061 static void mdlInitializeSizes (SimStruct *S)
00062 {
00063 int nU = NCONTROLINPUTS;
00064
00065
00066 ssSetNumContStates(S, 0);
00067 ssSetNumDiscStates(S, 0);
00068
00069
00070 if ( !ssSetNumInputPorts(S, 4) )
00071 return;
00072
00073
00074 if ( !ssSetNumOutputPorts(S, 4) )
00075 return;
00076
00077
00078 ssSetInputPortVectorDimension(S, 0, DYNAMICALLY_SIZED);
00079 ssSetInputPortVectorDimension(S, 1, DYNAMICALLY_SIZED);
00080 ssSetInputPortVectorDimension(S, 2, DYNAMICALLY_SIZED);
00081 ssSetInputPortVectorDimension(S, 3, DYNAMICALLY_SIZED);
00082
00083
00084 ssSetOutputPortVectorDimension(S, 0, 1 );
00085 ssSetOutputPortVectorDimension(S, 1, nU );
00086 ssSetOutputPortVectorDimension(S, 2, 1 );
00087 ssSetOutputPortVectorDimension(S, 3, 1 );
00088
00089
00090 ssSetInputPortDirectFeedThrough(S, 0, 1);
00091 ssSetInputPortDirectFeedThrough(S, 1, 1);
00092 ssSetInputPortDirectFeedThrough(S, 2, 1);
00093 ssSetInputPortDirectFeedThrough(S, 3, 1);
00094
00095
00096 ssSetNumSampleTimes(S, 1);
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109 ssSetNumPWork(S, 6);
00110 }
00111
00112
00113 #if defined(MATLAB_MEX_FILE)
00114
00115 #define MDL_SET_INPUT_PORT_DIMENSION_INFO
00116 #define MDL_SET_OUTPUT_PORT_DIMENSION_INFO
00117
00118 static void mdlSetInputPortDimensionInfo(SimStruct *S, int_T port, const DimsInfo_T *dimsInfo)
00119 {
00120 if ( !ssSetInputPortDimensionInfo(S, port, dimsInfo) )
00121 return;
00122 }
00123
00124 static void mdlSetOutputPortDimensionInfo(SimStruct *S, int_T port, const DimsInfo_T *dimsInfo)
00125 {
00126 if ( !ssSetOutputPortDimensionInfo(S, port, dimsInfo) )
00127 return;
00128 }
00129
00130 #endif
00131
00132
00133 static void mdlInitializeSampleTimes(SimStruct *S)
00134 {
00135 ssSetSampleTime(S, 0, SAMPLINGTIME);
00136 ssSetOffsetTime(S, 0, 0.0);
00137 }
00138
00139
00140 static void mdlStart(SimStruct *S)
00141 {
00142 #ifndef __DSPACE__
00143 using namespace qpOASES;
00144 #endif
00145
00146 int nU = NCONTROLINPUTS;
00147 int size_H, size_g, size_lb, size_ub;
00148 int nV;
00149
00150 QProblemB* problem;
00151 real_t* count;
00152
00153
00154
00155 size_H = ssGetInputPortWidth(S, 0);
00156 size_g = ssGetInputPortWidth(S, 1);
00157 size_lb = ssGetInputPortWidth(S, 2);
00158 size_ub = ssGetInputPortWidth(S, 3);
00159
00160
00161
00162 nV = size_g;
00163
00164 if ( nV == 0 )
00165 {
00166 #ifndef __DSPACE__
00167 mexErrMsgTxt( "ERROR (qpOASES): Dimension mismatch!" );
00168 #endif
00169 return;
00170 }
00171
00172 if ( size_H != nV*nV )
00173 {
00174 #ifndef __DSPACE__
00175 mexErrMsgTxt( "ERROR (qpOASES): Dimension mismatch!" );
00176 #endif
00177 return;
00178 }
00179
00180 if ( nU > nV )
00181 {
00182 #ifndef __DSPACE__
00183 mexErrMsgTxt( "ERROR (qpOASES): Dimension mismatch!" );
00184 #endif
00185 return;
00186 }
00187
00188 if ( size_lb != nV )
00189 {
00190 #ifndef __DSPACE__
00191 mexErrMsgTxt( "ERROR (qpOASES): Dimension mismatch!" );
00192 #endif
00193 return;
00194 }
00195
00196 if ( size_ub != nV )
00197 {
00198 #ifndef __DSPACE__
00199 mexErrMsgTxt( "ERROR (qpOASES): Dimension mismatch!" );
00200 #endif
00201 return;
00202 }
00203
00204
00205
00206 problem = new QProblemB( nV );
00207 if ( problem == 0 )
00208 {
00209 #ifndef __DSPACE__
00210 mexErrMsgTxt( "ERROR (qpOASES): Unable to create QProblemB object!" );
00211 #endif
00212 return;
00213 }
00214
00215 #ifndef __DEBUG__
00216 problem->setPrintLevel( PL_LOW );
00217 #endif
00218 #ifdef __SUPPRESSANYOUTPUT__
00219 problem->setPrintLevel( PL_NONE );
00220 #endif
00221 #ifdef __DSPACE__
00222 problem->setPrintLevel( PL_NONE );
00223 #endif
00224
00225 ssGetPWork(S)[0] = (void *) problem;
00226
00227
00228 ssGetPWork(S)[1] = (void *) calloc( size_H, sizeof(real_t) );
00229 ssGetPWork(S)[2] = (void *) calloc( size_g, sizeof(real_t) );
00230 ssGetPWork(S)[3] = (void *) calloc( size_lb, sizeof(real_t) );
00231 ssGetPWork(S)[4] = (void *) calloc( size_ub, sizeof(real_t) );
00232 ssGetPWork(S)[5] = (void *) calloc( 1, sizeof(real_t) );
00233
00234
00235 count = (real_t *) ssGetPWork(S)[5];
00236 count[0] = 0.0;
00237 }
00238
00239
00240 static void mdlOutputs(SimStruct *S, int_T tid)
00241 {
00242 #ifndef __DSPACE__
00243 using namespace qpOASES;
00244 #endif
00245
00246 int i;
00247 int nV, status;
00248
00249 int nWSR = NWSR;
00250 int nU = NCONTROLINPUTS;
00251
00252 InputRealPtrsType in_H, in_g, in_lb, in_ub;
00253
00254 QProblemB* problem;
00255 real_t *H, *g, *lb, *ub, *count;
00256
00257 real_t *xOpt;
00258
00259 real_T *out_objVal, *out_xOpt, *out_status, *out_nWSR;
00260
00261
00262
00263 in_H = ssGetInputPortRealSignalPtrs(S, 0);
00264 in_g = ssGetInputPortRealSignalPtrs(S, 1);
00265 in_lb = ssGetInputPortRealSignalPtrs(S, 2);
00266 in_ub = ssGetInputPortRealSignalPtrs(S, 3);
00267
00268
00269 problem = (QProblemB *) ssGetPWork(S)[0];
00270
00271 H = (real_t *) ssGetPWork(S)[1];
00272 g = (real_t *) ssGetPWork(S)[2];
00273 lb = (real_t *) ssGetPWork(S)[3];
00274 ub = (real_t *) ssGetPWork(S)[4];
00275
00276 count = (real_t *) ssGetPWork(S)[5];
00277
00278
00279
00280 nV = ssGetInputPortWidth(S, 1);
00281
00282 for ( i=0; i<nV*nV; ++i )
00283 H[i] = (*in_H)[i];
00284
00285 for ( i=0; i<nV; ++i )
00286 {
00287 g[i] = (*in_g)[i];
00288 lb[i] = (*in_lb)[i];
00289 ub[i] = (*in_ub)[i];
00290 }
00291
00292 xOpt = new real_t[nV];
00293
00294 if ( count[0] == 0 )
00295 {
00296
00297 status = problem->init( H,g,lb,ub, nWSR,0 );
00298 ssGetPWork(S)[0] = ( void* ) problem;
00299 problem->getPrimalSolution( xOpt );
00300 }
00301 else
00302 {
00303
00304 status = problem->hotstart( g,lb,ub, nWSR,0 );
00305 if ( ( status != SUCCESSFUL_RETURN ) && ( status != RET_MAX_NWSR_REACHED ) )
00306 {
00307
00308 problem->reset( );
00309 problem->init( H,g,lb,ub, nWSR,0 );
00310 }
00311 else
00312 {
00313
00314 problem->getPrimalSolution( xOpt );
00315 }
00316 }
00317
00318
00319 out_objVal = ssGetOutputPortRealSignal(S, 0);
00320 out_xOpt = ssGetOutputPortRealSignal(S, 1);
00321 out_status = ssGetOutputPortRealSignal(S, 2);
00322 out_nWSR = ssGetOutputPortRealSignal(S, 3);
00323
00324 out_objVal[0] = ((real_T) problem->getObjVal( ));
00325
00326 for ( i=0; i<nU; ++i )
00327 out_xOpt[i] = ((real_T) xOpt[i]);
00328
00329 switch ( status )
00330 {
00331 case SUCCESSFUL_RETURN:
00332 out_status[0] = 0.0;
00333 break;
00334
00335 case RET_MAX_NWSR_REACHED:
00336 out_status[0] = 1.0;
00337 break;
00338
00339 case RET_INIT_FAILED_INFEASIBILITY:
00340 case RET_HOTSTART_STOPPED_INFEASIBILITY:
00341 out_status[0] = -2.0;
00342 break;
00343
00344 case RET_INIT_FAILED_UNBOUNDEDNESS:
00345 case RET_HOTSTART_STOPPED_UNBOUNDEDNESS:
00346 out_status[0] = -3.0;
00347 break;
00348
00349 default:
00350 out_status[0] = -1.0;
00351 break;
00352 }
00353
00354 out_nWSR[0] = ((real_T) nWSR);
00355
00356
00357 count[0] = count[0] + 1;
00358
00359 delete[] xOpt;
00360 }
00361
00362
00363 static void mdlTerminate(SimStruct *S)
00364 {
00365 #ifndef __DSPACE__
00366 using namespace qpOASES;
00367 #endif
00368
00369
00370 getGlobalMessageHandler( )->reset( );
00371
00372 int i;
00373 for ( i=0; i<6; ++i )
00374 {
00375 if ( ssGetPWork(S)[i] != 0 )
00376 free( ssGetPWork(S)[i] );
00377 }
00378 }
00379
00380
00381 #ifdef MATLAB_MEX_FILE
00382 #include "simulink.c"
00383 #else
00384 #include "cg_sfun.h"
00385 #endif
00386
00387
00388 #ifdef __cplusplus
00389 }
00390 #endif
00391
00392
00393
00394
00395