qpOASES_QProblemB.cpp
Go to the documentation of this file.
00001 /*
00002  *      This file is part of qpOASES.
00003  *
00004  *      qpOASES -- An Implementation of the Online Active Set Strategy.
00005  *      Copyright (C) 2007-2011 by Hans Joachim Ferreau, Andreas Potschka,
00006  *      Christian Kirches et al. All rights reserved.
00007  *
00008  *      qpOASES is free software; you can redistribute it and/or
00009  *      modify it under the terms of the GNU Lesser General Public
00010  *      License as published by the Free Software Foundation; either
00011  *      version 2.1 of the License, or (at your option) any later version.
00012  *
00013  *      qpOASES is distributed in the hope that it will be useful,
00014  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00016  *      See the GNU Lesser General Public License for more details.
00017  *
00018  *      You should have received a copy of the GNU Lesser General Public
00019  *      License along with qpOASES; if not, write to the Free Software
00020  *      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
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 /* SETTINGS: */
00056 #define SAMPLINGTIME    0.1                                             
00057 #define NCONTROLINPUTS  2                                               
00058 #define NWSR            10                                              
00061 static void mdlInitializeSizes (SimStruct *S)   /* Init sizes array */
00062 {
00063         int nU = NCONTROLINPUTS;
00064 
00065         /* Specify the number of continuous and discrete states */
00066         ssSetNumContStates(S, 0);
00067         ssSetNumDiscStates(S, 0);
00068 
00069         /* Specify the number of intput ports */
00070         if ( !ssSetNumInputPorts(S, 4) )
00071                 return;
00072 
00073         /* Specify the number of output ports */
00074         if ( !ssSetNumOutputPorts(S, 4) )
00075                 return;
00076 
00077         /* Specify dimension information for the input ports */
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         /* Specify dimension information for the output ports */
00084         ssSetOutputPortVectorDimension(S, 0, 1 );
00085         ssSetOutputPortVectorDimension(S, 1, nU );
00086         ssSetOutputPortVectorDimension(S, 2, 1 );
00087         ssSetOutputPortVectorDimension(S, 3, 1 );
00088 
00089         /* Specify the direct feedthrough status */
00090         ssSetInputPortDirectFeedThrough(S, 0, 1);
00091         ssSetInputPortDirectFeedThrough(S, 1, 1);
00092         ssSetInputPortDirectFeedThrough(S, 2, 1);
00093         ssSetInputPortDirectFeedThrough(S, 3, 1);
00094 
00095         /* One sample time */
00096         ssSetNumSampleTimes(S, 1);
00097 
00098 
00099         /* global variables:
00100      * 0: problem
00101      * 1: H
00102      * 2: g
00103      * 3: lb
00104      * 4: ub
00105      * 5: count
00106      */
00107 
00108         /* Specify the size of the block's pointer work vector */
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         /* get block inputs dimensions */
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         /* dimension checks */
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         /* allocate QProblemB object */
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         /* allocate memory for QP data ... */
00228         ssGetPWork(S)[1] = (void *) calloc( size_H, sizeof(real_t) );   /* H */
00229         ssGetPWork(S)[2] = (void *) calloc( size_g, sizeof(real_t) );   /* g */
00230         ssGetPWork(S)[3] = (void *) calloc( size_lb, sizeof(real_t) );  /* lb */
00231         ssGetPWork(S)[4] = (void *) calloc( size_ub, sizeof(real_t) );  /* ub */
00232         ssGetPWork(S)[5] = (void *) calloc( 1, sizeof(real_t) );                /* count */
00233 
00234         /* reset counter */
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         /* get pointers to block inputs ... */
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         /* ... and to the QP data */
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         /* setup QP data */
00280         nV = ssGetInputPortWidth(S, 1); /* nV = size_g */
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                 /* initialise and solve first QP */
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                 /* solve neighbouring QP using hotstart technique */
00304                 status = problem->hotstart( g,lb,ub, nWSR,0 );
00305                 if ( ( status != SUCCESSFUL_RETURN ) && ( status != RET_MAX_NWSR_REACHED ) )
00306                 {
00307                         /* if an error occurs, reset problem data structures and initialise again */
00308                         problem->reset( );
00309                         problem->init( H,g,lb,ub, nWSR,0 );
00310                 }
00311                 else
00312                 {
00313                 /* otherwise obtain optimal solution */
00314                 problem->getPrimalSolution( xOpt );
00315                 }
00316         }
00317 
00318         /* generate block output: status information ... */
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         /* increase counter */
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         /* reset global message handler */
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  *      end of file
00395  */


acado
Author(s): Milan Vukov, Rien Quirynen
autogenerated on Thu Aug 27 2015 11:59:50