Hello Everybody,
I am trying to implement the nlopt.dll in a Simulink C-Code S-Function - but
it would not compile.
I have already used nlopt to be called from Matlab (after mex-ing it) and I
managed the tutorial example in C (Visual Studio 2010). I am not a
professional to C-Code, so I have problems implementing it in a C-Code
S-Function. Maybe someone has done this already or could give me an idea?
I have copied the declarations from the tutorial into the corresponding
S-Function Blocks (as best as I knew) and have put the objective and the
constraint function in separate c-files; I don`t know, if this is working. I
get a couple of error messages, when I compile these three c-files (linking
it to the nlopt.lib file), kind of error C2146, error C2065, error C2109,
error C2059 and so on.
Any ideas or helping tips are very much appreciated.
Thanks in advanced!
Bettina Kutschera
//=========================================================================
//Standard defines and includes
//=========================================================================
#define S_FUNCTION_NAME mysfunction3
#define S_FUNCTION_LEVEL 2
#include <simstruc.h>
#include "nlopt.h" //NLOPT is a Library not a stand alone program. ""
um in lokalen Ordernpfaden zu suchen. <> sucht in Systemordnerpfaden.
#include "math.h"
#include "stdlib.h"
//=========================================================================
//Parameters, Constants, Global Variables etc.
//=========================================================================
extern __declspec(dllimport) void nlopt(nlopt_opt opt, double x);
typedef struct {double a, b;} my_constraint_data;
extern real_T myfunc(unsigned n, const real_T *x, real_T *grad, void
*my_func_data);
extern real_T myconstraint(unsigned n, const real_T *x, real_T *grad, void
*data);
//=========================================================================
//S-function methods
//=========================================================================
//Function: mdlInitializeSizes ============================================
//Abstract: The sizes information is used to determine the S-function
//block's characteristics (number of inputs, outputs, states, etc.).
static void mdlInitializeSizes(SimStruct *S)
{
ssSetNumSFcnParams(S, 0); /* Number of S-function prameters */
ssSetNumContStates(S, 0); /* Number of continuous states */
ssSetNumDiscStates(S, 0); /* Number of discrete states */
//Inputs General Definition------------------------------------------------
if (!ssSetNumInputPorts(S, 0)) return; //Number of inputs
//Outputs General Definition-----------------------------------------------
if (!ssSetNumOutputPorts(S, 2)) return; //Number of outputs
ssSetOutputPortWidth(S, 0, 2); //"Name" (SimStruct, Index,
Width)
ssSetOutputPortVectorDimension(S, 0,2);
ssSetOutputPortDataType(S, 0, SS_DOUBLE); //float (32bit) = real_T
ssSetOutputPortWidth(S, 1, 1); //"Name" (SimStruct, Index,
Width)
ssSetOutputPortDataType(S, 1, SS_DOUBLE); //float (32bit) = real_T
//Set Sample Time----------------------------------------------------------
ssSetNumSampleTimes(S, 1); //Specify the number of sample
times that an S-Function block has
}
//Function: mdlInitializeSampleTimes ======================================
//Abstract: This function is used to specify the sample time(s) for your
//S-function. You must register the same number of sample times as
// specified in ssSetNumSampleTimes.
static void mdlInitializeSampleTimes(SimStruct *S)
{
ssSetSampleTime(S, 0, INHERITED_SAMPLE_TIME);
ssSetOffsetTime(S, 0, 0);
}
//Initialize---------------------------------------------------------------
#define MDL_INITIALIZE_CONDITIONS //Change to #undef to remove function
#if defined(MDL_INITIALIZE_CONDITIONS)
static void mdlInitializeConditions(SimStruct *S)
{
//Initial states are placed in state vectors ssGetContStates(S) or
ssGetDiscStates(S)
}
#endif //MDL_INITIALIZE_CONDITIONS
//Initalize----------------------------------------------------------------
#define MDL_START //Change to #undef to remove function
#if defined(MDL_START)
static void mdlStart(SimStruct *S)
{
//If you have states that should be initialized once, do it here.
typedef struct {double a, b;} my_constraint_data;
double lb[2] = {-HUGE_VAL,0}; //lower bounds
nlopt_opt opt;
opt = nlopt_create(NLOPT_LN_COBYLA,2); //algorithm and
dimensionality
nlopt_set_lower_bounds(opt, lb);
nlopt_set_min_objective(opt, myfunc, NULL);
my_constraint_data data[2] = {{2,0}, {-1,1}};
nlopt_add_inequality_constraint(opt, myconstraint, &data[0], 1e-8);
nlopt_add_inequality_constraint(opt, myconstraint, &data[1], 1e-8);
nlopt_set_xtol_rel(opt, 1e-4);
double x[2] = {1.234, 5.678};
double minf;
}
#endif //MDL_START
//Function: mdlOutputs ====================================================
//Abstract: In this function, you compute the outputs of your S-function
//block. Generally outputs are placed in the output vector(s),
ssGetOutputPortSignal.
static void mdlOutputs(SimStruct *S, int_T tid)
{
//Variables: input data----------------------------------------------------
//Variables: output data---------------------------------------------------
real_T *y0 = ssGetOutputPortRealSignal(S,0);
real_T *y1 = ssGetOutputPortRealSignal(S,1);
y0[0] = 5;
y0[1] = 1;
if (nlopt_optimize(opt, x, &minf) >= 0)
*y1 = minf;
//Update-------------------------------------------------------------------
#define MDL_UPDATE /* Change to #undef to remove function */
#if defined(MDL_UPDATE)
//Function: mdlUpdate
//Abstract: This function is called once for every major integration time step.
//Discrete states are typically updated here, but this function is useful
//for performing any tasks that should only take place once per integration
step.
static void mdlUpdate(SimStruct *S, int_T tid)
{
}
#endif // MDL_UPDATE
/* Function: mdlTerminate =====================================================
* Abstract:
* In this function, you should perform any actions that are necessary
* at the termination of a simulation. For example, if memory was
* allocated in mdlStart, this is the place to free it.
*/
static void mdlTerminate(SimStruct *S){
UNUSED_ARG(S); /* unused input argument */
}
//=========================================================================
//Required S-function trailer
//=========================================================================
#ifdef MATLAB_MEX_FILE /* Is this file being compiled as a MEX-file? */
#include "simulink.c" /* MEX-file interface mechanism */
#else
#include "cg_sfun.h" /* Code generation registration function */
#endif
double myfunc(unsigned n, const double *x, double *grad, void *my_func_data)
/*Definition der Funktion myfunc*/
{
if (grad)
{
grad[0] = 0.0;
grad[1] = 0.5 / sqrt(x[1]);
}
return sqrt(x[1]);
}
typedef struct {double a, b;} my_constraint_data;
double myconstraint(unsigned n, const double *x, double *grad, void *data)
{
my_constraint_data *d = (my_constraint_data *) data;
double a = d->a, b = d->b;
if (grad)
{
grad[0] = 3*a*(a*x[0]+b)*(a*x[0]+b);
grad[1] = -1.0;
}
return ((a*x[0]+b)*(a*x[0]+b)*(a*x[0]+b)-x[1]);
}_______________________________________________
NLopt-discuss mailing list
[email protected]
http://ab-initio.mit.edu/cgi-bin/mailman/listinfo/nlopt-discuss