Compiling MapleSim Code for Simulation in VisSim

1 Introduction MapleSim generates ANSI C code from any model. The code contains the differential equations that describe the model dynamics, and a solver. Moreover, the code is royalty-free, and can be used in any simulation tool (or development project) that accepts external code.

VisSim is a signal-flow simulation tool with strength in embedded systems programming, real-time and OPC. This document will describe the steps required to

• Generate C code from a MapleSim model of a DC Motor. The C code will contain a solver. • Implement the C code in a simulation DLL for VisSim. VisSim provides a DLL Wizard that sets up a Visual Studio C project for a simulation DLL. MapleSim code will be copied into this project. After a few modifications, the project will be compiled to a DLL.

The DLL can then be used as a block in a VisSim simulation.

The techniques demonstrated in this document can used to implement MapleSim code in any other environment.

MapleSim’s royalty -free C code can be implemented in other modeling environment s, such as VisSim

MapleSim’s C code can also be used in

2 API for the Maplesim Code The C code generated by MapleSim contains four significant functions.

• SolverSetup(t0, *ic, *u, *p, *y, h, *S) • SolverStep(*u, *S) where SolverStep is EulerStep, RK2Step, RK3Step or RK4Step • SolverUpdate(*u, *p, first, internal, *S) • SolverOutputs(*y, *S) u are the inputs, p are subsystem parameters (i.e. variables defined in a subsystem mask), ic are the initial conditions, y are the outputs, t0 is the initial time, and h is the time step. S corresponds to a C structure that contains the current value of the state variables, and some other information.

When MapleSim code is implemented in a third-party simulation tool (for example, LabVIEW), the functions are evaluated in this order

1. SolverSetup() is executed once at the start of the simulation 2. SolverStep () integrates the differential equations over one time step 3. SolverUpdate() and SolverOutputs() write the outputs to y 4. The simulation tool then returns to step 2

3 Tools Used • MapleSim 5 • MapleSim model: DCMotorVisSim.msim • Visual Studio 2010 Professional • VisSim 8 (with the VisSim DLL Wizard) • Windows 7 64 bit • A text editor like TextPad (recommended but not essential)

4 Generate Code for the MapleSim DC Motor model Open DCMotorVisSim.msim (a DC Motor model)

This is the subsystem

The subsystem has one input (voltage applied to motor) and one output (angular velocity of the rotational shaft).

We will

• generate code for the subsystem (one input, and one output) • copy the code into a VisSim DLL Wizard project in VisSim, and make some modifications • compile the code and run the resulting DLL in VisSim

Go to View > Attachments and select Code Generation template.

Click Create Attachment

You’re now in

Select the DC Motor Subsystem

Click Load Selected Subsystem

Note the values of the Input Ports, Output ports and Parameters

Scroll down to Step 3: C Code Generation Options . Under Solver Options , select RK4 (although for this model any solver will be sufficient).

Scroll to Step 4 and click Generate C Code

You should see your code generated in Step 5: View C Code . This is the code we will need to integrate into the VisSim DLL Wizard.

Copy all of this code into a text editor and save it.. The screenshot below uses Textpad, but you can use Notepad instead.

5 Prepare the Visual Studio Project using the VisSim DLL Wizard Load Visual Studio and start a new project using the VisSim Add-on DLL Wizard as the template.

Note the name in the screengrab below – MapleSimMotor

In the following window, click Next

In the next window, specify a name for the Base Function Name and Block Name

Note the names given in the screengrab below

In the next screen, add one input and one output, naming them both. Click Next .

In the next screen, check Want Custom Data Types . Select Double for both inputs and outputs from the drop-down menu. Click Next

In the next screen, change nothing. Click Next

In the next screen, specify names for the VisSim menu the block will appear in. Note the names below. Click Finish

Now we’re in the primary Visual Studio environment. Make sure you can see vsi.cpp in the main code window

Go to Project>Properties and select VC++ Directories.

Add c:\VisSim80\Vsdk\INCLUDE to the Include Directories

Add c:\VisSim80\Vsdk\LIB to the Directories

Click Apply

Double-click on StdAfx.h in the Solution Explorer so you see the code in the main window. You should see the following code near the top

Replace 0x0400 and 0x0410 with 0x0503 so you see this:

6 Copy the Code Generated by MapleSim into Visual Studio Double click on vsi.cpp in the Code Explorer so you see the code in the main window. In addition, load the MapleSim generated code into a text editor

We will now copy and paste MapleSim code into vsi.cipp (between HWND vsmHWnd; and #define MapleSimMotor_INFO_STR "IFs" )

From the MapleSim code, copy the following code into the clipboard

Paste this code into vsi.cpp, just above HWND vsmHWnd;

Write this code into vsi.cpp to just above HWND vsmHWnd; double baserate = 1.000000e-03; baserate defines the rate at which the model runs (and must match the VisSim simulation time).

Write this code into vsi.cpp to just above HWND vsmHWnd; static SolverStruct S;

Write the following function prototypes just above HWND vsmHWnd; static void SolverUpdate( double *u, double *p, long first, long internal , SolverStruct *S); static void SolverOutputs( double *y, SolverStruct *S); static void RK4Step( double *u, SolverStruct *S); static void SolverSetup( double t0, double *ic, double *u, double *p, double *y, double h, SolverStruct *S); static void SolverError(SolverStruct *S, char *errmsg);

The code we’ve just inserted into vsi.cpp should look like this

From the MapleSim code, copy the following functions, and paste them into the bottom of vsi.cpp, just before final brace.

In SolverUpdate(), comment out inpfn(S->w[0],u); so it looks like this

In SolverError(), comment out if(S->err==-1) kv->error(S->buf);so that it looks like

In SolverSetup(), add the following code:

S->w=( double *)malloc((1+2*NEQ+NPAR+NDFA+NEVT)* sizeof (double ));

SolveSetup() should now look like this

Now we need to change the simulation step function in VisSim. The existing function should look like this.

We will add calls to the code generated by MapleSim. Modify the simulation step function so it looks like this.

7 Compile the Code In Visual Studio, select Build>Build Solution . With some luck, you won’t have any errors.

You should find a dll in the Debug folder of the Visual Studio Project (MapleSimMotor.dll in the screengrab below)

8 Run the DLL in VisSim In VisSim, go to Edit>Preferences>Addons

Add a reference to MapleSimMotor.dll

Click OK . You should now see a new menu in VisSim, with a reference to the block we’ve just compiled

You can now use the DC Motor block in VisSim (make sure the simulation time step is equal to the base rate in the MapleSim code).

For example, see the VisSim model below

For the same input, the original MapleSim model and the VisSim version should give the same results.