VS calls Matlab Engine method

VS calls Matlab Engine method

Friends who are interested in trajectory planning or c/matlab hybrid programming can pay attention to the two parts of the OTPL open source project code: https://github.com/libing403/OTPL and https://github.com/libing403/OTPL/tree /master/OTPL/TestDemo/MatlabEngineCode

The project is mainly developed on the basis of the theory of the following two books:

Trajectory Planning for Automatic Machines and Robots;

The NURBS Book


Matlab mainly faces the high-tech computing environment of scientific computing, visualization and interactive programming, but because the programs developed on the Matlab development platform cannot be separated from the Matlab operating environment, it is not flexible enough to deal with some practical application problems, while VC++ To a certain extent, it can make up for this deficiency. The c language is not convenient for data visualization, making it difficult to test and analyze the results of some programs that must be implemented in c language. Therefore, combining the two and sharing their strengths can provide more powerful technical support for scientific research and engineering development.

Configure VS project properties

The environment I am using is

x86

Windows 7 

VS2015

MATLAB R2016a (other versions are similar)

Make the following settings in the built VS project

1. Configuration Properties -> VC++ Directories -> Include Directories

Edited to: under the Matlab installation path...\extern\include;

2. Configuration properties -> VC++ directory -> library directory

Edited to: under the Matlab installation path...\extern\lib;

3. Configuration Properties -> Linker -> Input -> Additional Dependencies

Add: libeng.lib;libmx.lib;libmex.lib;libmat.lib (add the lib needed in the program here)

system environment variables

Add D:\MatLab\R2010a\bin\win64; to PATH to help VS find the dynamic link library provided by MATLAB.

Register MATLAB server : cmd, run in D:\MatLab\R2010a\bin directory

matlab \regserver

Sometimes it is registered during installation, and this command does not work.

Call matlab engine in VS

include header files

#include "engine.h"

Turn on the engine

Engine* pEng = NULL;
    if (!(pEng = engOpen(NULL)))
    {
        printf("Open matlab enging fail!");
        getchar();
        return -1;
    }

Common functions for setting/getting data to matlab workspace

int engPutVariable(Engine *ep, const char *name, const mxArray *pm)

Set the value of a variable array

mxArray *engGetVariable(Engine *ep, const char *name) gets a variable

int engEvalString(Engine* ep, const char* string) executes Matlab expression

shut down the engine

if(pEng)
    engClose(pEng);

Example

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<engine.h>
#define dataNum 100
int main()
{
    int ret = 0;
    Engine* eg = NULL;
    if (!(eg = engOpen(NULL)))
    {
        printf("Open matlab enging fail!");
        return 1;
    }
    double xtemp[dataNum] = { 0 };
    double ytemp[dataNum] = { 0 };
    for (int i = 0; i < dataNum; i++)
    {
        xtemp[i] = i * 2.0 * 3.1415926 / 100.0;
        ytemp[i] = sin(xtemp[i]);

    }
    mxArray *X = mxCreateDoubleMatrix(1, dataNum, mxREAL);//创建matlab存储数据的指针
    mxArray *Y = mxCreateDoubleMatrix(1, dataNum, mxREAL);

    memcpy(mxGetPr(X), xtemp, dataNum * sizeof(double)); //数据复制
    memcpy(mxGetPr(Y), ytemp, dataNum * sizeof(double));

    if ((ret = engPutVariable(eg, "X", X)) != 0)   //把数据传递到matlab工作空间,并命名为X
        printf("engPutVariable error:%d\n", ret);
    if ((ret = engPutVariable(eg, "Y", Y)) != 0)
        printf("engPutVariable error:%d\n", ret);
    engEvalString(eg, "plot(X,Y)");//运行绘图命令
    getchar();
    if(eg)
        engClose(eg);
    return 0;
}

The result of running the example is as follows

Write matlab command wrapper function

It can be seen from the above programming that calling matlab for drawing is also cumbersome, such as creating variables, copying memory data, running command expressions and a series of operations. In order to invoke the experience of running matlab commands like in matlab, you can encapsulate matlab commands into functions in C language. For example, the following is a wrapper around the plot command:

int mat_plot(Engine *eg, double *x, double *y, int N, char *LineStyle, double LineWidth, double MarkerSize)
{
    int ret = 0;
    mxArray *X = mxCreateDoubleMatrix(1, N, mxREAL);
    mxArray *Y = mxCreateDoubleMatrix(1, N, mxREAL);
    mxArray *MS = mxCreateDoubleScalar(MarkerSize);
    memcpy(mxGetPr(X), x, N * sizeof(double));
    memcpy(mxGetPr(Y), y, N * sizeof(double));

    if ((ret = engPutVariable(eg, "X", X)) != 0)
        printf("engPutVariable error:%d\n", ret);
    if ((ret = engPutVariable(eg, "Y", Y)) != 0)
        printf("engPutVariable error:%d\n", ret);

    //gennerate the plot command
    char plotCommand[256] = "fig=plot(X,Y,'";
    //set line style and marker
    if (strlen(LineStyle) > 0)
        strncat(plotCommand, LineStyle, strlen(LineStyle));
    else
    {
        strncat(plotCommand, "-", strlen("-"));
    }
    strncat(plotCommand, "',", strlen(LineStyle));

    char temp[20] = "";
    //set line width
    if (LineWidth < 1.0)
        LineWidth = 1.0;
    strncat(plotCommand, "'LineWidth',", strlen("'LineWidth',"));
    memset(temp, 0, sizeof(temp));
    sprintf(temp, "%f,", LineWidth);
    strncat(plotCommand, temp, strlen(temp));

    //set marker size
    strncat(plotCommand, "'MarkerSize',", strlen("'MarkerSize',"));
    sprintf(temp, "%f", MarkerSize);
    strncat(plotCommand, temp, strlen(temp));
    strncat(plotCommand, ");", strlen(temp));

    //plot
    if ((ret = engEvalString(eg, plotCommand)) != 0)
    {
        printf("\nplot Command error:%s\n", plotCommand);
        return ret;
    }
    engEvalString(eg, "set(gcf,'color','w');");
    printf("plot Command ok:%s\n", plotCommand);
    //destroy mxArray,but they are still in matlab workspace
    mxDestroyArray(X);
    mxDestroyArray(Y);
    return 0;
}

In this way, it is much more convenient to use the matlab command. For example, I want to use the data calculated in the C language to draw a picture, and I can directly call the encapsulated function.

mat_plot(eg, xtemp, ytemp, dataNum, "-r", 1, 5);

The meaning of the above parameters

eg: pointer to the open matlab engine

xtemp: x coordinate data

ytemp: y-axis coordinate data

dataNum: the number of data

"-r": linetype, color (you can also set flags such as "-r*")

1: Line width

5: Marker size

This way you don't have to worry about how the data is passed to matlab and how the plot commands are run. If the encapsulation function is written better, it can be used more like in matlab, such as directly setting the line type and line width.

However, the commands of matlab are very large, and it is difficult to create a user-friendly, full-featured interface function library by only one person. Therefore, interested friends can contribute to this project. The project is stored on github: https://github.com/libing403/OTPL/tree/master/OTPL/TestDemo/MatlabEngineCode

To reference this interface function, you only need to include the two files MatlabEnginePlot.c and MatlabEnginePlot.h

As shown below

call file
Everyone noticed that this matlab command function encapsulation function library interface is only a part of the code of the OTPL (Open Trajectory Planning Library) open source project, which is mainly used to test the c algorithm library for trajectory planning.

summary

In the past, when testing the c algorithm, it was necessary to transfer the data derivative generated by c to matlab, and then plot it to see the effect. In this way, it is necessary to write a C language program and a matlab program for testing, and it is particularly troublesome to draw dynamic graphics. Now, by calling the matlab engine directly in c/c++ for data visualization, almost all commands of matlab can be called in the C language environment. If the matlab command is encapsulated, it is as convenient as drawing in matlab, which can greatly improve the development efficiency.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325433693&siteId=291194637