Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

Thread Subject:
JMatLink and MatLab

Subject: JMatLink and MatLab

From: Lucas

Date: 7 Jun, 2012 15:10:08

Message: 1 of 14

Hello, my name is Lucas Keaton. I’m currently working on a project where we use JMatLink to interface from Eclipse/Java to MatLab. Using a simple model with a few Inport and Outports, I use engEvalString to set data to our Inport blocks and I can run the simulation and get the data from the Outport block using engGetScalar (I do believe). But our copy of MatLab is on our work network and when we run some test on our model it takes a long time to open everything up. Since it opens and closes MatLab/Simulink with every test it takes up a lot of time.

I want to connect Eclipse/Java to MatLab via a socket and pass and run the model that way. I’ve searched all over the internet but no one knows how to set data to an Inport block in Simulink. When I ran it with a Inport block data type of Int32 I got a data type mismatch error. It showed a model with a ground type, a function block, and a Outport, so I didn’t know if it used another model to interface with our model or not.

http://i239.photobucket.com/albums/ff88/Yuipu/Error.png

I seen in JMatLink.c it calls the engEvalString found in MatLabs libeng.dll. So I don’t know if it’s the JMatLink code or the code in libeng.dll that’s actually setting the data to the Inport block.

I know the Inport block is suppose to get it data from something being passed in, like into a subsystem, but the models that I’m working with all start and end with Inport blocks. So any help into this matter would be appreciated. I know it can be done, just need to figure out how. Thanks for your time.

Lucas

Subject: JMatLink and MatLab

From: Phil Goddard

Date: 7 Jun, 2012 18:21:08

Message: 2 of 14

It's not really clear what you have working and what you don't.

Your first paragraphs seems to indicate that you have things working, but it's slow, and you'd like to speed things up.
Your second paragraph seems to contradict the first in that you don't everything working.
(Note that nothing you have described would make an Inport suddenly change to a Ground block as in the picture you link to.
Either you are not running the model you think you are, or there's something in your code making the change.)

But I think the intiial problem comes down to "if you are sitting in front of MATLAB and have a Simulink model open, do you know how to pass data from MATLAB into the inports of the Simulink model?"
It sounds like the answer is no.

There's a brief description of how to do the above at
http://www.goddardconsulting.ca/simulink-interfacing-with-matlab.html

Once you figure that out then you "just" need to do the same thing using JMatLink.

But perhaps I've misunderstood your question.

Phil.

Subject: JMatLink and MatLab

From: Lucas

Date: 7 Jun, 2012 18:42:08

Message: 3 of 14

The first paragraph describes a method that works but it way too slow. Doing it through JMatLink also only allows for they variable type double, which didn't work for us. Since we have 100's of test cases doing it through JMatLink isn't going to work for us. That's why we're trying to do what it does, but through sockets.

Our models all begin with Inport block and end with Outport blocks. If we had an Inport Block called In1, using JMatLink, we'd use engEvalString(Engine *, "In1=10") and when we ran that Inport had the value of 10. Inports don't have a "data" or "value" field that you can set, so I didn't know how they did that. When I ran it with my Inport Block set to type Int32 it crashed with that picture I showed. So I didn't know if they got that Inport Block value set by using another model to give it, its value.

We get the models from another department and we need to be able to run them without changing anything in the model. That link you sent me, you have to change some of the model parameters. Using JMatLink we didn't need to do that, but it's slow and only accepts double types.

So what we really need to know is a work around for this problem. We know you can set Inport Blocks values and get Outport Block values also, we just can't figure out how it was done. Sorry if my first description was a little hard to understand, hopefully this clarifies things a little. Thanks.

Subject: JMatLink and MatLab

From: Phil Goddard

Date: 7 Jun, 2012 19:06:07

Message: 4 of 14

> That link you sent me, you have to change some of the model parameters.
> Using JMatLink we didn't need to do that, but it's slow and only accepts double
> types.

Yes, but the model changes will have already been made before your colleagues send you their model.
You won't have to make the changes.

Your description is still confusing (not the way you've described things but rather what you've described).
When running Simulink you do not poke data into an inport (called In1 in your example) by defining a MATLAB variable called In (In1=10 in your example).

As per the example on the link I gave, the model needs to be set up so that on the Simulation Parameters -> Input/Output Data tab the input box is given a MATLAB variable name.
(Your colleagues should already have done this.)
Then you need to define a 2 column matrix in MATLAB where the first column represent time points and the second represent the signal (which can change at the corresponding time points).
This is what you need to create (via JMatLink).

Once you've run the model, if it's set up to save data to the MATLAB workspace (described on the link, but something your colleagues should have done already) then signals terminating in an Outport will be saved to the MATLAB Workspace.
You need to get that data (via JMatLink).

> So what we really need to know is a work around for this problem. We know you can set Inport Blocks values and get Outport Block values also, we just can't figure out how it was done. Sorry if my first description was a little hard to understand, hopefully this clarifies things a little. Thanks.

I don't think it's doing what you think it is to get data into and out of the model.
(Obviously I don't have your set-up, and can only take your word on it, but it goes against everything I've ever seen in many many years of using Simulink.)

Phil.

Subject: JMatLink and MatLab

From: Lucas

Date: 7 Jun, 2012 19:38:08

Message: 5 of 14

JMatLink connects Java to MatLab/Simulink. If you had a model with 2 Inport blocks (In1and In2), a Sum/Add box and one Outport block (Out1). In java we’d set up the JMatLink engine, and use its function to talk to MatLab/Simulink. We use code like in Java:

JMatLinkPointer->engEvalString(Engine *, “In1=10”);
JMatLinkPointer->engEvalString(Engine *, “In2=10”);
Data = JMatLinkPointer->engGetScalar(Engine *, “Out1”);

And it worked as long as In1 and In2 were double types. We’re trying to create a tool that’ll run any model by using code, like the one above, from java. We can’t use JMatLink so we’re trying to code these ourselves. But no one knows how to do this. I don’t know what happened behind the scenes but they set our values. Out1 returned 20, and we’ve used it on several other simple models.

They could have opened the model, copied everything to a new model, did a replace_block on everything, got the data that way and got rid of the copied model. I just know it worked with Inport and Outports using the shown code from Java.

Subject: JMatLink and MatLab

From: Phil Goddard

Date: 7 Jun, 2012 20:56:07

Message: 6 of 14

Looking at the image/link from your previous post things become a little clearer.

Your models are not using Input ports.
For some reason, whoever is putting your models together is creating their own input blocks (and most likely output blocks) that comprise a ground block and a MATLAB Fcn block, and have then grouped those into a subsystem.
The inside of that subsystem is what is shown in your previous image.

In your case he MATLAB Fcn block uses the MATLAB variable In1, which your JMatLink code is defining in the MATLAB workspace and the block is using during the simulation.

That's a strange thing to do, but presumably they had a reason for not just simply using a Constant block.

But it does explain why you can't get anything other than 'double' data to work.
The output of the MATLAB Fcn block is picking up the same data type as its input, which in this case is a double (with value 0) from the Ground block.

I'd recommend you delete that whole subsystem and just replace it with a Constant block.
If the constant block is set to use the MATLAB variable In1 then it's output will be whatever the datatype of In1 is that you create with JMatLink.

Phil.

Subject: JMatLink and MatLab

From: Lucas

Date: 7 Jun, 2012 21:56:07

Message: 7 of 14

That picture that I posted was nothing that we created. It was something either generated by JMatLink or MathWorks (with their engEvalString function in libeng.dll). That's why I didn't know if they used another model, the one in the picture, to interface with ours. And if that's how they did it, then I'd be interested in how they did it.

But I can see how that's possible, but I can't see how they got the data back from the Outport. Right now I'm trying to get replace_block to work for the Inports on the top layer and I can switch them with Constant block and pass data in that way, but I have no idea on how they got the data out. If they used a model to pass in data to our model, I'd be interested in doing that, since you don't have to change the model at all for that. Just got to figure out how to get the data back if that's the case. Sorry for not being as clear as I could have been.

Subject: JMatLink and MatLab

From: Phil Goddard

Date: 7 Jun, 2012 22:30:10

Message: 8 of 14

engEvalString is doing nothing more than evaluating a string in the MATLAB engine.
In and of itself it is not making any changes to your model.

What other commands are you executing, i.e. the ones to run the simulation after putting data into the workspace?

Phil.

Subject: JMatLink and MatLab

From: Lucas

Date: 8 Jun, 2012 13:19:16

Message: 9 of 14

Ok, I was a little wrong with my last statement. When you set the data it stores it to a local variable array and doesnt set them until you set the models iteration count. Si it goes like this:

SetIterationCount("4")
    setValues()
        matlabEng.engEvalString ((Engine *)id,variable + " = [" + value + "]")
    matlabEng.engEvalString (id,"set_param('"+theModel+"', 'SimulationCommand','Start')");

Thats pretty much what made it ran. JMatLink uses a DLL, is open source, to do everything, but it did have some 'C' files in it. I found 3 functions that I thought might be in work here.

The First: Set the variable

JNIEXPORT jint JNICALL Java_jmatlink_CoreJMatLink_engEvalStringNATIVE
                        (JNIEnv *env, jobject obj, jlong enginePtr, jstring evalS_JNI)
{
    int retValI = 0;
    const char *evalS = (*env)->GetStringUTFChars(env, evalS_JNI, 0);
 
// evaluate expression in MATLAB
retValI = engEvalString((Engine *)enginePtr, evalS);

if (retValI != 0)
printf("engEvalStringNATIVE: return value !=0, some error\n");

    //printf("evalString %i",OpenB);

    (*env)->ReleaseStringUTFChars(env, evalS_JNI, evalS); // free memory

    return retValI;
}

The second: Convert data to matlab?

JNIEXPORT void JNICALL Java_jmatlink_CoreJMatLink_engPutVariableNATIVE
   (JNIEnv *env, jobject obj, jlong enginePtr, jstring arrayS_JNI, jobjectArray valueDD_JNI)
{

    int i;
    int j;
    mxArray *T = NULL;

    const char *arrayS;
    int rowCount;
    jobject colPtr;
    int colCount;
    double *tPtrR;
    jdouble *arrayElements;

    arrayS = (*env)->GetStringUTFChars(env, arrayS_JNI, 0);
    rowCount = (*env)->GetArrayLength(env, valueDD_JNI);
    colPtr = (*env)->GetObjectArrayElement(env, valueDD_JNI, 0);
    colCount = (*env)->GetArrayLength(env, colPtr);

    if (debugB) printf("engPutArray [][] %s %i %i\n", arrayS, rowCount, colCount);

    // create MATLAB array
    T = mxCreateDoubleMatrix(rowCount, colCount, mxREAL);
    
// get pointer on array
    tPtrR = mxGetPr(T);

// copy array elements from java to MATLAB
    for (i=0; i<rowCount; i++) {
        //printf("row %i\n",i);
        colPtr = (*env)->GetObjectArrayElement(env, valueDD_JNI, i);
        //printf("got colPtr %i\n",i);
        
        arrayElements = (*env)->GetDoubleArrayElements(env, colPtr, 0);

        for (j=0; j<colCount; j++) {
            //printf("col %i\n",j);
            tPtrR[i + j*rowCount] = arrayElements[j];
        }

        //?? (suggestion of Dan Cervelli 13.09.2002) because of memory leak?
        (*env)->ReleaseDoubleArrayElements(env, colPtr, arrayElements, 0);

    } // rows


// send array to MATLAB
    engPutVariable((Engine *)enginePtr, arrayS, T );

// free memory for array
    mxDestroyArray(T);

// free memory for String
    (*env)->ReleaseStringUTFChars(env, arrayS_JNI, arrayS);
}

The Third: Get data back

JNIEXPORT jdouble JNICALL Java_jmatlink_CoreJMatLink_engGetScalarNATIVE
                      (JNIEnv *env, jobject obj, jlong enginePtr, jstring scalarS_JNI)
{
    mxArray *arrayP;
    jdouble scalar;
    
    // get name of scalar
    const char *scalarS = (*env)->GetStringUTFChars(env, scalarS_JNI, 0);

    if (debugB) printf("native engGetScalar %s \n",scalarS);

// get variable from MATLAB
    arrayP = engGetVariable( (Engine *)enginePtr, scalarS);

    if (arrayP == NULL) {
        printf("Could not get scalar from MATLAB workspace.\n");
        (*env)->ReleaseStringUTFChars(env, scalarS_JNI, scalarS); // free memory
        return 0;
    }

// get scalar value from array
    scalar = mxGetScalar(arrayP);

// free memory
    mxDestroyArray(arrayP);
    (*env)->ReleaseStringUTFChars(env, scalarS_JNI, scalarS);
    
    return scalar;
}

I don't know what else is going on behind the scenes, but these were in the main 'C' file that came with the dll I recieved.

Subject: JMatLink and MatLab

From: Phil Goddard

Date: 8 Jun, 2012 16:24:07

Message: 10 of 14

There's nothing in this code that is changing the model.
It is simply putting data into the MATLAB Workspace and then executing the model.

In your TestInt32 model, are you sure that the "inport" block is really an Inport when you receive the model?
If you open it in Simulink (forget about JMatLink for the time being) and double click on the block, does it open a dialog that says it's an Inport, or does it open a subsystem containing the blocks from your previous jpg image?

Phil.

Subject: JMatLink and MatLab

From: Lucas

Date: 8 Jun, 2012 17:06:12

Message: 11 of 14

Yes, I'm possitive that it's an Inport block. I'd link another picture but I can't do it while I'm at work.

------------
| inport |----------
------------ | ------- -----------
|-------|+ |--------------|outport|
------------ | |+ | -----------
| inport |---------- -------
------------ Add

If I create a model that looks like this using 2 Inport (Simulink/Sources/Inport) and one Outport (Simulink/Sinks/Outport) with an add block, and run using JMatlink it works. If I set In1 to 5 and In2 to 10, Out1 is 15. The code that I pasted in is the only code that I can really see. So I don't know if anything else is going on, but I know block types and we are using Inport and Outports.

We have to use them because we run the model on a test stand and it has to be in that format. Were writing simulation software so we can test everything before we run it on the test stand, because that take a long time and costs a lot of money. So the models have to stay in the format and JMatLink was able to interface into them as long as the inports were double type.

Subject: JMatLink and MatLab

From: Lucas

Date: 8 Jun, 2012 17:36:31

Message: 12 of 14

The above message looked a lot better in here, but I found this image:

http://www.mathworks.com/help/toolbox/polyspace/modellink_ug/model.gif

And this is about JMatLink can work with. 2 Inports and 1 Outport.

Subject: JMatLink and MatLab

From: Malcolm Lidierth

Date: 8 Jun, 2012 18:29:08

Message: 13 of 14

An alternative might be Joshua Kaplan's MATLABcontrol which uses java to connect via TMW's own jmi.jar. Its well documented, actively developed, easy to use (and works).
See
http://code.google.com/p/matlabcontrol/

Subject: JMatLink and MatLab

From: Lucas

Date: 11 Jun, 2012 17:49:07

Message: 14 of 14

"Malcolm Lidierth" wrote in message <jqtg9j$nnh$1@newscl01ah.mathworks.com>...
> An alternative might be Joshua Kaplan's MATLABcontrol which uses java to connect via TMW's own jmi.jar. Its well documented, actively developed, easy to use (and works).
> See
> http://code.google.com/p/matlabcontrol/

I'm not interested in someone elses files. We wrote our own stuff that works, I was only interested in how JMatLink worked with Inports and Outports. From what I seen in the link you posted, it only told me what I know, and it doesn't work. Thanks though.

Tags for this Thread

What are tags?

A tag is like a keyword or category label associated with each thread. Tags make it easier for you to find threads of interest.

Anyone can tag a thread. Tags are public and visible to everyone.

Contact us