Simulating C MEX S-Function causes crash

38 visualizaciones (últimos 30 días)
hanssar
hanssar el 13 de Nov. de 2014
Respondida: Nits el 5 de Jun. de 2019
Hello, when i try to simulate my C mex S-Function Matlab/Simulink crashes caused by Fatal Execusion:
"Error ... while executing C MEX S-Function 'sfun_test',(mdlOutputs), at time 0.0."
I don't get an error when compiling the C mex S-Function.
A short explanation: I use an external program(Motive OptiTrack) to stream data via Network(Location and Orientation data of rigid bodies). The S-Function is used to convert this data. I want to make the Regulation in Simulink and then i want to use Simulink Coder to get a RTWT.
I tried several things, but i couldn't find my mistake.
I also made a MATLAB S-Function and it works very well, but creating the TLC-File seems to be very difficult.
if true
#define S_FUNCTION_NAME sfun_c_test
#define S_FUNCTION_LEVEL 2
#include "simstruc.h"
//
#ifdef WIN32
# pragma warning( disable : 4996 )
# define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#endif
#include <cstring> // For memset.
#include <windows.h>
#include <winsock.h>
#include "resource.h"
#include <tchar.h>
// NatNet SDK 2.7
#include "NatNetTypes.h" // NatNet data & Rigid Body DataDiscription
#include "NatNetClient.h" // Initialize Client
#include "natutils.h" // Convert quaternion to Euler angles
#pragma comment(lib, "NatNetLib")
NatNetClient* theClient = new NatNetClient;
/*====================*
* S-function methods *
*====================*/
static void mdlInitializeSizes(SimStruct *S)
{
int_T nInputPorts = 0; /* number of input ports */
int_T nOutputPorts = 1; /* number of output ports */
int_T needsInput = 0; /* direct feed through */
int_T inputPortIdx = 0;
int_T outputPortIdx = 0;
ssSetNumSFcnParams(S, 0); /* Number of expected parameters */
if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) {
/* Return if number of expected != number of actual parameters */
return;
}
ssSetNumContStates(S, 0);
ssSetNumDiscStates(S, 0);
// Output
if (!ssSetNumOutputPorts(S, nOutputPorts)) return;
if(!ssSetOutputPortDimensionInfo(S,outputPortIdx,DYNAMIC_DIMENSION)) return;
ssSetOutputPortWidth(S, 0, 1);
// Sample Time
ssSetNumSampleTimes(S, 1);
// Work vectors
ssSetNumRWork( S, 0); /* real work vector elements */
ssSetNumIWork( S, 0); /* integer work vector elements*/
ssSetNumPWork( S, 0); /* pointer work vector elements*/
ssSetNumModes( S, 0); /* mode work vector elements */
ssSetNumNonsampledZCs( S, 0); /* nonsampled zero crossings */
ssSetSimStateCompliance(S, USE_DEFAULT_SIM_STATE);
ssSetOptions(S, 0);
} /* end mdlInitializeSizes */
//
static void mdlInitializeSampleTimes(SimStruct *S)
{
double sampleTime = 0.01;
ssSetSampleTime(S, 0, sampleTime);
ssSetOffsetTime(S, 0, 0.0);
} /* end mdlInitializeSampleTimes */
//
#define MDL_START
#if defined(MDL_START)
static void mdlStart(SimStruct *S)
{
// NatNet server IP address.
char szIPAddress[30] = {127,0,0,1};
char szServerIPAddress[30] = {127,0,0,1};
theClient->Initialize(szIPAddress, szServerIPAddress);
}
#endif /* MDL_START */
//
static void mdlOutputs(SimStruct *S, int_T tid)
{
real_T *y = ssGetOutputPortRealSignal(S,0);
sFrameOfMocapData* pData = theClient->GetLastFrameOfData();
y[0] = pData->iFrame;
}
//
static void mdlTerminate(SimStruct *S)
{
theClient->Uninitialize();
}
/*=============================*
* 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
end

Respuestas (4)

Titus Edelhofer
Titus Edelhofer el 13 de Nov. de 2014
Hi,
I'm not sure why you added the line
if(!ssSetOutputPortDimensionInfo(S,outputPortIdx,DYNAMIC_DIMENSION)) return;
As far as I understand you don't have dynamic dimensions but a fixed width of one. Esp. since you have no inport. Unless you are sure why you need it, I'd suggest to remove.
Second: what happens if your replace
sFrameOfMocapData* pData = theClient->GetLastFrameOfData();
y[0] = pData->iFrame;
by
y[0] = 42;
just to see if it's "Simulink's fault" or a problem with the NatNetClient.
Titus
Titus

hanssar
hanssar el 13 de Nov. de 2014
Then it works. I recognized earlier that "sFrameOfMocapData* pData = theClient->GetLastFrameOfData();" might be the problem. Maybe the inclusion of the NatNetLib is wrong? In my Matlab s-function i use a .dll and there it works fine.
  2 comentarios
Or Hirshfeld
Or Hirshfeld el 25 de Feb. de 2015
did you found a way to overcome this problem?
Or Hirshfeld
Or Hirshfeld el 6 de Mzo. de 2015
.I got an answer from Matlab support that you cannot use NatNet dll in Real-Time because it's use .Net Libraries. In The end did you succeed to solve it using NATNET dll or in other way like loading the API dll (NPTrackingTools)

Iniciar sesión para comentar.


Or Hirshfeld
Or Hirshfeld el 17 de Dic. de 2014
Editada: Or Hirshfeld el 17 de Dic. de 2014
What about trying to work with simpler option by incorporating c code in matlab function block. Also instead of using NatNet you can use Motive API.
Or Hirshfeld
אור הירשפלד

Nits
Nits el 5 de Jun. de 2019
Hello all,
I need to create interface between Simulink to Motive. I already succeed to interface between Matlab and Motive through NatNet, I reviewed the sample available with NatNet SDK to do so but I'm having trouble to migrate it to Simulink. Can anyone please guide me for the same?
Thanks in advance.
Regards
Nitin

Categorías

Más información sobre Block and Blockset Authoring en Help Center y File Exchange.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by