ToFile from SImulink read into C++ standalone program

7 views (last 30 days)
Looking for sample C or C++ code that will successfully extract MATFILE data created by Simulink's "To File" block. It is time series data, apparently. The sample reader program, matdgns.c, does identify that a single variable, called "ans", is in the MATFILE but I am unable to get the values out into an ordinary C array. "mxGetNumberOfDimensions" indicates "2" which suggests that data is present. Also, the file is 193K bytes, which also indicates that there is data present. However, mxIsEmpty(arr) is returning TRUE.

Answers (4)

James Tursa
James Tursa on 9 Aug 2018
Edited: James Tursa on 10 Aug 2018
Time series objects are classdef OOP objects. To get at the underlying data in them, you will need to use the mxGetProperty API function. This, unfortunately, will produce a deep data copy. If your data is large you might want to explore using the mxGetPropertyPtr function from the FEX. E.g.,
/* Echo timeseries Time and Data values to the screen */
#include "mex.h"
#include <string.h>
int mxIsTimeSeries(const mxArray *mx)
{
int result = 0;
if( mx ) {
result = strcmp(mxGetClassName(mx),"timeseries") == 0;
}
return result;
}
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
mxArray *Time, *Data;
double *t, *d;
int i, n;
if( nrhs && mxIsTimeSeries(prhs[0]) ) {
Time = mxGetProperty(prhs[0],0,"Time"); /* makes deep data copy */
if( Time ) {
t = mxGetPr(Time);
n = mxGetNumberOfElements(Time);
for( i=0; i<n; i++ ) {
mexPrintf("t[%d] = %f\n",i,t[i]);
}
mxDestroyArray(Time);
}
Data = mxGetProperty(prhs[0],0,"Data"); /* makes deep data copy */
if( Data ) {
d = mxGetPr(Data);
n = mxGetNumberOfElements(Data);
for( i=0; i<n; i++ ) {
mexPrintf("d[%d] = %f\n",i,d[i]);
}
mxDestroyArray(Data);
}
}
}
* EDIT *
Try this for standalone code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "matrix.h"
#include "mat.h"
int mxIsTimeSeries(const mxArray *mx)
{
int result = 0;
if( mx ) {
result = strcmp(mxGetClassName(mx),"timeseries") == 0;
}
return result;
}
int main(int argc, char **argv)
{
MATFile *pmat;
int i, n;
mxArray *pa, *Time, *Data;
double *t, *d;
/* If no input argument, do nothing */
if (argc == 0 ) return 0;
/* Open the mat file */
pmat = matOpen(argv[0], "r");
if (pmat == NULL) {
printf("Error opening file %s\n", argv[0]);
return 1;
}
/* Read the desired variable */
pa = matGetVariable(pmat,"ans");
if (pa == NULL) {
printf("Error reading variable 'ans'\n");
matClose(pmat);
return 1;
}
/* Check to see if it is a timseries object */
if( !mxIsTimeSeries(pa) ) {
printf("Error variable 'ans' is not a timeseries object\n");
mxDestroyArray(pa);
matClose(pmat);
return 1;
}
/* Process the data */
Time = mxGetProperty(pa,0,"Time");
if( Time ) {
t = mxGetPr(Time);
n = mxGetNumberOfElements(Time);
for( i=0; i<n; i++ ) {
printf("t[%d] = %f\n",i,t[i]);
}
mxDestroyArray(Time);
} else {
printf("Error variable 'ans' does not have a 'Time' property\n");
}
Data = mxGetProperty(pa,0,"Data");
if( Data ) {
d = mxGetPr(Data);
n = mxGetNumberOfElements(Data);
for( i=0; i<n; i++ ) {
printf("d[%d] = %f\n",i,d[i]);
}
mxDestroyArray(Data);
} else {
printf("Error variable 'ans' does not have a 'Data' property\n");
}
/* Done */
mxDestroyArray(pa);
if (matClose(pmat) != 0) {
printf("Error closing file %s\n",argv[0]);
return 1;
}
printf("Done\n");
return 0;
}
  7 Comments
James Tursa
James Tursa on 10 Aug 2018
I think the simplest thing for you to do is to use the matdgns.c file as the starting point for your code. Use everything in the code except the "Diagnose array pa" section. Replace that code with this:
mxArray *Time, *Data;
double *t, *d;
int n;
:
/*
* Diagnose array pa
*/
Time = mxGetProperty(pa,0,"Time");
t = mxGetPr(Time);
Data = mxGetProperty(pa,0,"Data");
d = mxGetPr(Data);
n = mxGetNumberOfElements(Time);
:
/* insert code here to use t and d vector data */
:
mxDestroyArray(Data);
mxDestroyArray(Time);
mxDestroyArray(pa);
Elliott Rachlin
Elliott Rachlin on 10 Aug 2018
Time and Data are coming back from mxGetProperty as NULL. Can you load the file I sent and see what named properties are actually present?

Sign in to comment.


Elliott Rachlin
Elliott Rachlin on 9 Aug 2018
Where can I copy or email the sample file? By the way, I will be on travel Friday and Monday, so if I go silent, that is the reason. It won't be because I've lost interest in pursuing this.

Elliott Rachlin
Elliott Rachlin on 10 Aug 2018
File attached.
  2 Comments
Elliott Rachlin
Elliott Rachlin on 10 Aug 2018
Time and Data are coming back from mxGetProperty as NULL. Can you load the file I sent and see what named properties are actually present?
James Tursa
James Tursa on 10 Aug 2018
I loaded the mat file into MATLAB and saw data there, but have not put together a C program to read it. I can do that tomorrow.

Sign in to comment.


Elliott Rachlin
Elliott Rachlin on 10 Aug 2018
OK, thanks very much. As I mentioned earlier, I will be on business travel Friday and Monday, returning Tuesday.
  21 Comments
Elliott Rachlin
Elliott Rachlin on 20 Aug 2018
Are you still there and thinking about my issue? IT has been a while since I've heard from you.

Sign in to comment.

Categories

Find more on Write C Functions Callable from MATLAB (MEX Files) in Help Center and File Exchange

Tags

Products


Release

R2017b

Community Treasure Hunt

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

Start Hunting!