Sie sind auf Seite 1von 25

Mechanical Simulation Technical Memo

912 North Main, Suite 210, Ann Arbor MI, 48104, USA
Phone: 734 668-2930 • Fax: 734 668-2877 • Email:

Extending a VS Solver: A Steer Control Example

Introduction .................................................................................................................... 1
An Example Model Extension ....................................................................................... 2
Existing Model Documentation............................................................................ 2
The Steering Controller Definition....................................................................... 3
Programming the Steer Controller with VS Commands ................................................ 4
The VS Commands............................................................................................... 4
Running the Extended Model ............................................................................... 5
Extending the Model with a Programming Language: Overview.................................. 7
Extending the Model with Visual Basic (VB)................................................................ 8
The VB Program................................................................................................... 8
Running the VB Program ..................................................................................... 11
Extending the Model with MATLAB ............................................................................ 13
The MATLAB M File .......................................................................................... 13
Running the VB Program ..................................................................................... 17
Extending the Model with ANSI C ................................................................................ 19
Setting up the external code with external_setdef ................................................ 19
Defining external calculations with external_calc................................................ 21
Adding more information to an echo file with external_echo .............................. 22
Handling more information from input parsfiles with external_scan................... 23
Running the extended model ................................................................................ 24
Summary ........................................................................................................................ 25

This technical memo shows by example how a VehicleSim (VS) vehicle model is extended to
include an alternative steering controller. The original memo from January 2007 has been updated
to match revisions made during the release of CarSim 7.1 and to include examples in three
programming languages (Visual Basic, MATLAB, and C).

The VS solver has a math model with “native” equations that simulate the response of a vehicle
to driver controls while traveling on a 3D road surface. The VS solver can be extended to handle
custom controllers and alternate component models using an external simulation environment
such as Simulink. However there are three other general methods that can also be used to extend
the model:
1. Equations can be added at runtime using VS commands.
2. Equations can be written in a programming language and combined with the capabilities
of the VS solver using the VS application program interface (API) and the exchange of
import and output arrays of variables.

July 9, 2008 1 / 25
3. Equations can be written in custom C routines and new variables can be defined in C and
installed using the VS API.
This memo extends the model using these three methods.
VS commands are described in the VehicleSim Math Models: Solver Program Reference Manual
(the VS Solver Manual) and require no additional software beyond a product from Mechanical
Simulation such as CarSim. The other three versions use methods described in The VehicleSim
API: Accessing and Extending VehicleSim Solver Programs (the VS API Manual).

An Example Model Extension

A simple steering control will be based on a “preview point” in front of the vehicle and its
relationship to the road centerline. If the point is not on target, a steering wheel angle is calculated
that is proportional to the lateral distance between the point and the target lateral position. Figure
1 shows the point represented with an arrow in front of the vehicle. The intended location is the
center of the right-hand lane. The arrow is a little to the left of the target line, and therefore the
the vehicle steering wheel should be turned to the right.

Figure 1. Vehicle with a preview point for a simple steering controller.

Existing Model Documentation

The full list of available import variables for a VS model is available in two readme files: one for
viewing with a text editor, and one for viewing as a spreadsheet. The list can be viewed quickly in
either format by using the View button in the lower-right corner of the Run Control screen of a
product such as CarSim.
Browsing the readme file for any of the vehicle models in CarSim or TruckSim shows that they
all include steering wheel angle as a variable that can be imported.

2 / 25
The default settings for all of the import variables are that they be ignored. The setting for the
steering wheel can be changed easily by using the library screen I/O Channels: Import to
activate the steering wheel import variable. This can also be accomplished by providing a line of
text in a file that will be read as input to the model:
Although the native equations in the VS solver include the effect of the imported steer, they do
not define the angle. (After all, the whole purpose of the imported steer is to replace or modify the
value already available in the native equations of the model.)
The output variables available in a VS model are contained in readme files similar to those that
list the available import files. (The readme file for outputs can also be viewed using the View
button on the Run Control screen.) Reading through the list of available variables shows that
there are many X and Y coordinates, for points such as the origin of the sprung mass coordinate
system, the vehicle center of gravity (CG), etc. A preview point for a new steering controller can
be based on any of the existing X and Y coordinate pairs. In this example, the X and Y
coordinates of the vehicle CG will be used.

The Steering Controller Definition

The desired steer angle will be:
LAT_TRACK is the target lateral position relative to the road centerline,
ROAD_L is a function available in VS solvers (see the VS Solver Manual) that gives the
lateral distance of a point defined by X and Y coordinates relative to the road centerline,
XPREVIEW and YPREVIEW are X and Y coordinates of a point in front of the vehicle, and
GAIN_STEER_CTRL is a constant used to scale the steering wheel angle.
The X and Y coordinates of the preview point are:
XCG_TM and YCG_TM are the X and Y coordinates of the center of mass of the entire vehicle,
as listed in the readme file for available outputs,
YAW is the yaw angle for the vehicle, as listed in the readme file for available outputs, and
L_FORWARD is the distance the preview point lies in front of the vehicle mass center.
The controller calculation is potentially complicated at the start of the run because not all of the
output variables have been calculated yet. To maintain simplicity, the steering wheel angle will be
defined as 0 prior to the start. One way to accomplish this is with equation:

3 / 25
Programming the Steer Controller with VS Commands
This section describes how the steer controller is added to the math model using VS commands.

The VS Commands
In reviewing the equations needed to calculate steering wheel angle, we see that they involve four
existing output variables (T, XCG_TM, YCG_TM, and YAW), two new variables (XPREVIEW and
YPREVIEW ), and three new constants (LAT_TRACK, GAIN_STEER_CTRL, and L_FORWARD). The
new variables XPREVIEW and YPREVIEW that are used to calculate the steering would also be
helpful if available for plotting, and for animating to show the preview point (see Figure 1).
Listing 1 shows a complete set of VS commands for adding the necessary variables and
equations. (The line numbers do not exist in the actual file; they are shown to support the
following discussion.)
Listing 1. VS Commands for the simple steering control.
1. ! Simple Steer Controller

2. ! Define new units for control parameter

3. define_units deg/m 57.29577951

4. ! Define 3 new parameters

5. define_variable L_FORWARD 20; units = m ! View point distance (parameter)
6. define_variable LAT_TRACK -1.6; units = m ! distance to driver's left
7. define_variable GAIN_STEER_CTRL 10; units = deg/m ! Control gain (parameter)

8. ! Define 2 new outputs

9. define_output Xpreview = XCG_TM + L_FORWARD*cos(YAW); units = m ;
10. define_output Ypreview = YCG_TM + L_FORWARD*sin(YAW); units = m ;

11. ! Define extra variable for steer control

12. define_variable steer_ctrl

13. !Add equation to define imported steering wheel angle

14. eq_in steer_ctrl = (LAT_TRACK - road_l(Xpreview, Ypreview))*GAIN_STEER_CTRL ;
15. eq_in IMP_STEER_SW = IF_GT_0_THEN(t - tstart, steer_ctrl, 0);

16. ! Activate steering import

17. IMP_STEER_SW replace 0
18. !
19. ! Define detailed output titles
20. set_output_long_name Xpreview X coord. of driver look-point
21. set_output_long_name Ypreview Y coord. of driver look-point
22. set_output_generic Xpreview X coordinate
23. set_output_generic Ypreview Y coordinate
24. set_output_component Xpreview Driver look-point
25. set_output_component Ypreview Driver look-point

The three new constants are added in lines 5 - 7 and the new dynamic variables are defined as
outputs in lines 9 and 10, using the definitions from equations 3 and 4.
Note that the VS commands allow the units to be specified. Every parameter, import, and output
variable in a VS model has associated units. As described in the VS Solver Manual, conversions

4 / 25
are made automatically between user units shown for input and output files, and internal
dynamical units used for internal calculations. For example, steering wheel angle has user units of
degrees, and internal units of radians. Any input angles are divided by 57.29577951 to convert
from degrees to radians. For output, the angles are multiplied by 57.29577951 to convert from
radians to degrees.
Existing user units are shown in the readme files and the echo files generated with each run.

Note The internal units are generally SI, and by definition require no scale factors
for internal calculations. There is a parameter OPT_ECHO_ALL_UNITS that
can be set to show everything about the current units system in the echo file,
including all of the scale factors that relate user units to internal units.

Most of the new variables and parameters that will be introduced for this example will have units
of length. The commands in the listing specify meters, because meters are used for most of the
road geometry. The exception is the constant GAIN_STEER_CTRL, which should have units of
steer per unit of lateral distance: deg/m.
If the run is made without the command from line 3, an error message appears saying the units
“deg/m” are not installed. To allow the use of “deg/m,” the DEFINE_UNITS command on line 3 is
used to install everything the solver needs to know about the new units: the printed name is
“deg/m” and the scale factor is 57.29577951. After the new units are installed they can be
specified with the keyword “DEG/M” (not case sensitive), as shown in line 7.
Line 12 adds an intermediate variable for the steering wheel angle, and lines 14 and 15 provide
equations 2 and 5. Line 17 activates the imported steering wheel angle with a copy of equation 1.
At this point (line 17), the steering controller is fully defined and the additional X and Y output
coordinates are available for plotting and animation. Lines 20 - 25 in the listing could be
considered optional. They provide labeling information to allow nice plot labeling with the two
new variables.
The VS commands are shown in the echo files generated by the solver programs when runs are
made. Most commands appear at the end of the file, as shown in the excerpt in Listing 2. The
printed version in the echo file is not necessarily identical in appearance to the original
commands (see Listing 1), but it has the same meaning and will give identical results if used in
future runs. One difference is that all variables are shown in upper case, regardless of how they
were provided as input. Another difference is that some of the commands are broken up into
multiple commands when printed. For example, the commands to add output variables for the X
and Y coordinates of the preview point included equations. In the echo file shown in Listing 2,
the same information is provided in two commands: one to introduce the variable and one to add
an equation for calculating new values at each time step.
Whenever the units system of the VS solver is modified (e.g., adding the new units “deg/m”), a
set of commands appears at the top of the echo file to fully specify the units system as it was
modified in the run.

Running the Extended Model

The commands from the listing can be placed anywhere in the VehicleSim database where they
would be passed to the math model when it reads inputs for a new run. The screen Models: Self-
Contained Solvers provides a convenient location for model extensions such as this example.

5 / 25
(Another convenient location is the Generic VS Commands screen.) Figure 2 shows the linked
dataset with the commands form Listing 1. Note that is also links to a dataset for showing the red
arrow at the previous point, as seen in Figure 1.

Listing 2. Excerpts of echo file, showing VS commands for steering example.

DEFINE_UNITS deg/m 57.2958

DEFINE_OUTPUT Xpreview = 0; UNITS = m;
SET_OUTPUT_LONG_NAME XPREVIEW X coordinate of driver look-poin;
DEFINE_OUTPUT Ypreview = 0; UNITS = m;
SET_OUTPUT_LONG_NAME YPREVIEW Y coordinate of driver look-poin;



! Each event is defined with the name of an output variable that is monitored, a
! comparison '<' or '>', a threshold equation, and a pathname with input data to
! read to restart the run if the threshold is reached. If no pathname is
! specified, the run is stopped.

IMP_STEER_SW REPLACE 0 ! #1. Steering wheel angle (deg)


6 / 25
Figure 2. Appearance of the VS commands on a Models library screen.

Figure 3. Linking to VS commands in the Models: Self-Contained Solvers library.

Figure 3 shows how this dataset is linked to the Run Control screen.

Extending the Model with a Programming Language: Overview

The same steering control will be programmed several languages in the following sections of this
memo. In each case, a short program will load the VS solver DLL and make the run. The vehicle
Yaw and X and Y coordinates will be exported, a VS API equivalent of the ROAD_L function
will be used to determine the lateral tracking of the preview point, and a steering wheel angle will
be computed for use in the vehicle model. In addition, the X and Y coordinates of the preview

7 / 25
point will be sent to the VS solver in order to put the coordinate in the output file for the animator
to show the red arrow as seen in Figure 1.
In normal operation, the top-level input file for the VS solver is a simfile (with the default name
simfile) that contains pathnames for the input parsfile for the solver, plus names of output files
to be generated by the solver, plus the pathname for the solver DLL. (Details of this process are
presented in the VS Solver Manual.) The normal way to load a VS solver DLL is by first reading
simfile to get the pathname for the DLL, then loading the DLL, then getting access to the VS API
functions from the DLL, and finally, using the VS API functions to make the run. Details of this
process are covered in the VS API Manual and are summarized here as four steps.
1. Load. The DLL is loaded using a pathname read from a simfile and the VS API functions
are located.
2. Initialize. The VS solver reads input data from a parsfile whose pathname is also
obtained from the simfile, and then initializes the internal math model.
3. Run. The run is made with a simple loop in which the VS solver integrates the equations
of motion.
4. Terminate. The run terminates and the DLL is unloaded.

Extending the Model with Visual Basic (VB)

Running a VS solver from a program written in VB is fairly easy, and this example shows the
process. The example VB program can be modified as might be needed for customized
It should be noted that integration of the code from VB with the internal workings of the VS
solver DLL is limited in comparison to the extensions that are possible in ANSI C. However, it is
indeed possible to make simple extensions to the model and run the VB program from the Run
Control screen, as will be shown for the example steering controller.

The VB Program
The process of loading and running the solver from VB requires that some of the information
must be set manually (hard-coded). Listing 3 shows how the name of the DLL and six of the VS
API function names are declared in VB. If more VS functions will be used, they should be
declared in the same style.
Note that the name of the DLL appears in every Declare statement. If running with a VS solver
with a different name, then lines 6, 9, 10, 11, 13, and 15 would be modified to use the alternative
Variables needed to run any VS math model are declared in lines 17 – 19. Additional variables
used to implement the steering controller are declared in lines 20 and 21.
Next, the program reads a simfile to get the location of the DLL file (lines 24 – 39).

8 / 25
Listing 3. Visual Basic code for loading a VS solver.
1. Imports System.IO

2. Module Steer_Control

3. ' Declare the VS API functions that will be used to make a run.
4. ' The name of the DLL is hard-coded here; change to match the DLL of interest,
5. ' e.g. i_i.dll, i_s.dll etc.

6. Declare Sub vs_read_configuration Lib "i_i.dll" _

7. (ByVal Simfile As String, ByRef n_imp As Integer, ByRef n_exp As Integer, _
8. ByRef tstart As Double, ByRef tstop As Double, ByRef tstep As Double)
9. Declare Function vs_error_occurred Lib "i_i.dll" () As Integer
10. Declare Function vs_get_output_message Lib "i_i.dll" () As String
11. Declare Function vs_integrate_io Lib "i_i.dll" _
12. (ByVal t As Double, ByRef import As Double, ByRef export As Double) As Integer
13. Declare Function vs_road_l Lib "i_i.dll" _
14. (ByVal sXprevAs As Double, ByVal Ypreview As Double) As Double
15. Declare Sub vs_terminate Lib "i_i.dll" (ByVal t As Double, ByVal func As Integer)

16. Sub Main()

17. Dim n_import, n_export, status, ibarg, print_interval, i, j As Integer
18. Dim SIMFILE, strBuff, DLL_Dir, VS_Msg As String
19. Dim t_start, t_stop, t_step, t_current, D2R As Double
20. Dim Lfwd, GainStr, LatTrack, ImpStr As Double
21. Dim Xpreview, Ypreview, Xcg, Ycg, Yaw, road_l As Double

22. D2R = 3.1415926 / 180

23. ' Get full pathname for simfile

24. SIMFILE = Directory.GetCurrentDirectory() + "\simfile"

25. ' Open simfile to get DLL folder location

26. FileOpen(1, SIMFILE, OpenMode.Input)
27. strBuff = "input string"
28. Do Until EOF(1)
29. Input(1, strBuff)
30. i = InStr(strBuff, "DLLFILE ")
31. If i = 1 Then
32. j = InStrRev(strBuff, "\")
33. DLL_Dir = Mid(strBuff, i + 8, j - i - 8)

34. ' Change current folder to DLL folder

35. ChDir(DLL_Dir)
36. Exit Do
37. End If
38. Loop
39. FileClose(1)

9 / 25
Listing 4. Initializing the math model and making the run from VB.
40. ' Call vs_read_configuration to read parsfile and initialize the VS solver.
41. ' Get no. of import/export variables, start time, stop time and time step.
42. vs_read_configuration(SIMFILE, n_import, n_export, t_start, t_stop, t_step)
43. VS_Msg = vs_get_output_message()
44. Console.WriteLine(VS_Msg)

45. ' Check if error occurred

46. status = vs_error_occurred()
47. Lfwd = 20.0
48. GainStr = 10 * D2R
49. LatTrack = -1.6
50. ImpStr = 0
51. print_interval = (t_stop - t_start) / t_step / 50
52. ibarg = print_interval
53. t_current = t_start

54. ' Create import and export arrays based on sizes from VS solver
55. Dim import(0 To n_import - 1) As Double
56. Dim export(0 To n_export - 1) As Double

57. 'Run integration loop

58. Do While (status = 0)

59. ' Call integration function

60. status = vs_integrate_io(t_current, import(0), export(0))

61. ' Get 3 variables that were exported from the VS solver
62. Xcg = export(0)
63. Ycg = export(1)
64. Yaw = export(2) * D2R
65. Xpreview = Xcg + Lfwd * Math.Cos(Yaw)
66. Ypreview = Ycg + Lfwd * Math.Sin(Yaw)
67. If t_current > t_start Then
68. road_l = vs_road_l(Xpreview, Ypreview)
69. ImpStr = GainStr * (LatTrack - road_l) / D2R
70. End If

71. ' Prepare 3 variables that are imported to the VS solver

72. import(0) = ImpStr
73. import(1) = Xpreview
74. import(2) = Ypreview
75. t_current = t_current + t_step

76. ' Update bar graph to show progress

77. If ibarg >= print_interval Then
78. Console.Write("=")
79. ibarg = 0
80. End If
81. ibarg = ibarg + 1
82. Loop

83. 'Terminate solver

84. vs_terminate(t_current, 0&)
85. End Sub
86. End Module

10 / 25
Listing 4 shows the remainder of the VB program. It continues by using the VS API function
vs_read_configuration (line 42) to handle the Initialize part of the simulation:
1. get the Parsfile name from SIMFILE,
2. read the parsfile to get values for all parameters of the math model,
3. initialize the math model, and
4. provide values for the number of import variables (n_import), export variables
(n_export), start time (t_start), stop time (t_stop), and time step (t_step).
Parameters used for the steering controller are given values in lines 47 – 49.
When running a VS solver from Visual Basic, arrays of import and export variables are used to
communicate between the VS solver and the calling program. The number of imports
(n_import) and exports (n_export) were obtained by vs_read_configuration (line
42) and are used in lines 55 and 56 to define arrays with the proper dimensions.
The main simulation loop starts with the Do While command (line 58) and continues to the
matching Loop statement on line 82. The VS solver updates the math model equations via the
function vs_integrate_io (line 60), and will continue as long as the function returns a value
of 0.
The three variables from the VS solver (X coordinate, Y coordinate, and Yaw) are exported using
the array export and are used to compute the X and Y coordinates of the previous point
(XPreview and Ypreview) and the steering wheel angle (ImpStr). The VS API function
vs_road_l is used in line 68 to compute the lateral distance to the road reference line at the
point defined with coordinates XPreview and Ypreview.
The three calculated variables are copied into the array import (lines 72 – 74) so they can be
sent to the math model at the next time step (line 60).
The simulation time is updated in line 75, in preparation for the next call to the function
vs_integrate_io (line 60).
The Do While loop stays in effect as long as the vs_integrate_io function returns 0.
When the run ends, the vs_terminate function (line 84) updates all open VS files and then
closes them.

Running the VB Program

In order for the arrays defined in the VB code to work with the VS solver, the solver must be set
up to activate the appropriate import and export variables. A dataset in the library Models: Self-
Contained Solvers can be used to specify the program compiled from the VB and also datasets
for import and export variables (see Figure 4). For this example:
· the external wrapper field specifies the EXE file generated by compiling the VB
program 1 ;
· one of the misc. links 3 is set to I/O Channels: Import dataset shown in Figure 5;
· another misc. link 4 is set to the I/O Channels: Export dataset shown in Figure 6.

11 / 25

Figure 4. Dataset for VS program that also specifies import and export variables.

Figure 5. Activation of three import variables provided by external program.

12 / 25
Figure 6. Activation of three output variables for use in external program.

Two of the import variables are passed through to the animator, to show a red arrow at the
preview point (see Figure 1). In order for the animator setup used for the example with VS
commands to also work for this VB example, two VS commands are used to introduce output
variables with the same names. The values for these variables are imported from the VB program
(see the commands 2 in Figure 4).

Extending the Model with MATLAB

VS solvers are ready to run from within MATLAB/Simulink as S-Functions, and many users
extend the models using Simulink. Alternatively, the solvers can be run directly from MATLAB
(without Simulink) by using the API. The general method for loading and running the VS solver
in MATLAB is the same as in VB.


Listing 5 shows the first part of a MATLAB file for running a VS solver. MATLAB is a little
more dynamic than VS, allowing the name of the DLL file (SolverPath) to be obtained from
the simfile (lines 11 - 30).
Next, the DLL is loaded (line 32, 33). The VS API functions are declared in another file
vs_api_def_m.h, that is named when loading the solver (line 33).
A few commands that are commented out (lines 36 and 37) can be enabled to view the available
VS API functions that were loaded.

13 / 25
Listing 5. Loading the VS solver DLL in MATLAB.
1. % Simple Steering control example to show you how to use an M-File script
2. % wrapper to work with a VS solver DLL

3. clc;
4. D2R = pi/180;
5. R2D = 180/pi;

6. % Check if last loaded library is still in memory. If so, unload it.

7. if libisloaded('vs_solver')
8. unloadlibrary('vs_solver');
9. end

10. % Open simfile

11. simfile = 'simfile';
12. SIMFILE = fopen(simfile, 'r');
13. if SIMFILE == -1
14. fprintf('\n Error: Can''t find out simfile.\n\n');
15. return;
16. end

17. % Scan simfile to get the pathname for the VS DLL

18. SolverPath = [];
19. while 1
20. tmpstr = fgetl(SIMFILE);
21. if tmpstr == -1 % File end
22. break;
23. end
24. if strncmpi(tmpstr, 'DLLFILE', 7)
25. [keyword SolverPath] = strtok(tmpstr);
26. SolverPath(1) = [];
27. break;
28. end
29. end
30. fclose(SIMFILE);

31. % Load solver DLL

32. [notfound, warnings] = ...
33. loadlibrary(SolverPath, 'vs_api_def_m.h', 'alias', 'vs_solver');
34. disp('The VS DLL is loaded.');

35. % Display function list in the DLL

36. %libfunctions('vs_solver', '-full');
37. %libfunctionsview('vs_solver');

Listing 6 shows the part of the MATLAB program that initializes the model. It uses the VS API
function vs_read_configuration (lines 46 - 48) to get the Parsfile name from simfile, read
the parsfile with all parameters for the math model, initialize the math model, and provide values
for the number of import variables (n_import), export variables (n_export), start time
(t_start), stop time (t_stop), and time step (t_step).
Some of the arguments to the VS API function vs_read_configuration are pointers, so
special pointer variables are declared (lines 39 – 43) to set up the function call.

14 / 25
Listing 6. Initializing the math model from MATLAB.
38. % Define pointer
39. p_nimp = libpointer('int32Ptr', 0);
40. p_nexp = libpointer('int32Ptr', 0);
41. p_start = libpointer('doublePtr', 0);
42. p_stop = libpointer('doublePtr', 0);
43. p_step = libpointer('doublePtr', 0);

44. % Read parsfile, get number of channels for import/export

45. % get start time, stop time and time step and initialization
46. [str n_import n_export t_start t_stop t_step] = ...
47. calllib('vs_solver', 'vs_read_configuration', ...
48. simfile, p_nimp, p_nexp, p_start, p_stop, p_step);

49. msg = calllib('vs_solver', 'vs_get_output_message');

50. disp(msg);
51. disp('Initialization is done.');
52. % Check if error occurred
53. status = calllib('vs_solver', 'vs_error_occurred');
54. if status
55. unloadlibrary('vs_solver');
56. return;
57. end

58. % Set import/export pointer

59. imports = zeros(1, n_import);
60. p_imp = libpointer('doublePtr', imports);
61. exports = zeros(1, n_export);
62. p_exp = libpointer('doublePtr', exports);

63. % extend model with new steer equations. Start with new parameters
64. Lfwd = 20.0; % preview distance
65. GainStr = 10*D2R; % control gain for steering wheel angle
66. LatTrack = -1.6; % target lateral position
67. ImpStr = 0; % steering to be imported into VS solver
68. t_current = t_start;
69. print_interval = (t_stop-t_start)/t_step/50;
70. ibarg = print_interval;

As was done for the VB program, arrays of import and export variables are used to communicate
between MATLAB and the VS solver. The number of imports (n_import) and exports
(n_export) obtained by vs_read_configuration are used in lines 59 and 61 to define
arrays with the proper dimensions. Pointers to those arrays are assigned to the variables p_imp
and p_exp (lines 60 and 62) for later use during the run.
The parameters for the steering controller are given values in lines 64 – 66, and the steering wheel
angle is set to 0 (line 67).
Listing 7 shows the rest of the MATLAB program.
The main simulation loop starts with the While statement (line 72) and continues to the
matching end statement on line 98. The VS solver updates the math model equations via the
function vs_integrate_io (line 75), and will continue as long as the function returns a value
of 0.

15 / 25
Listing 7. Running and terminating the VS solver from MATLAB.
71. % Start integration loop
72. while ~status
73. set(p_imp, 'Value', imports); % Assign import value to pointer

74. % Call integration function

75. status = calllib('vs_solver', 'vs_integrate_io', t_current, p_imp, p_exp);

76. % Get variables exported from VS solver

77. exports = get(p_exp, 'Value');

78. % Steering Controller variables

79. Xcg = exports(1);
80. Ycg = exports(2);
81. Yaw = exports(3)*D2R;
82. Xpreview = Xcg + Lfwd*cos(Yaw);
83. Ypreview = Ycg + Lfwd*sin(Yaw);
84. if t_current > t_start
85. road_l = calllib('vs_solver', 'vs_road_l', Xpreview, Ypreview);
86. ImpStr = GainStr*(LatTrack - road_l)*R2D;
87. end

88. % calculate values for 3 variables imported to VS solver

89. imports(1)= ImpStr;
90. imports(2)= Xpreview;
91. imports(3)= Ypreview;
92. t_current = t_current + t_step;
93. if ibarg >= print_interval
94. fprintf('=');
95. ibarg = 0;
96. end
97. ibarg = ibarg + 1;
98. end
99. fprintf('\n');

100. % Terminate solver

101. calllib('vs_solver', 'vs_terminate', t_current, []);
102. disp('Simulation has finished.');

103. % Unload solver DLL

104. unloadlibrary('vs_solver');

The three variables from the VS solver (X coordinate, Y coordinate, and Yaw) are exported using
the array exports and are used to compute the X and Y coordinates of the previous point
(XPreview and Ypreview) and the steering wheel angle (ImpStr). The VS API function
vs_road_l is used in line 85 to compute the lateral distance to the road reference line at the
point defined with coordinates XPreview and Ypreview.
The three calculated variables are copied into the array imports (lines 89 - 91) so they can be
sent to the math model.
Lines 93 – 97 are not technically necessary, but provide visual feedback that the simulation is
running by generating a bar graph with ‘=’ characters as the run proceeds. The VS command

16 / 25
vs_terminate causes the VS solver to clean up output files and free memory (line 101), and
the DLL is then unloaded (line 104).

Running the MATLAB Program

There are several ways to initiate a run using MATLAB. If the intent is to open MATLAB and
control the simulation from within MATLAB, then the VS browser should be set up to generate
the required simfile in the folder containing the MATLAB files. This information is normally
provided using the Models: Transfer to Local Windows Directory screen, as shown in Figure
7. This screen is very similar to the one used for setting up the VB example (Figure 4), with the
main difference being that a directory is specified 1 rather than a file name. As with the VS
example, link 3 is set to I/O Channels: Import dataset (see Figure 5), and another misc. link
4 is set to the I/O Channels: Export dataset (see Figure 6).

When the dataset from Figure 7 is specified on the Run Control screen, the active button is
Generate Files for This Run (see Figure 8). Clicking the button causes the browser to write a
new simfile in the specified directory ( 1 in Figure 7). When runs are made under the control of
MATLAB, all output files are written into the VS database so results can be viewed normally
with the VS animator and plotter.

Figure 7. Dataset to identify M-File directory and also specify import and export variables.

17 / 25
Figure 8. Appearance of Run Control screen for the MATLAB example.
Listing 8. Loading the DLL and making a run from C.
1. /* ----------------------------------------------------------------------------
2. Main program to run DLL with VS API.
3. ---------------------------------------------------------------------------- */
4. void main(int argc, char **argv)
5. {
7. double t;
8. char pathDLL[FILENAME_MAX], simfile[FILENAME_MAX]={"simfile"}, *printMsg;
9. int ibarg = 0;

10. // get simfile from argument list and load DLL

11. if (argc > 1) strcpy (simfile, &argv[1][0]);
12. if (vs_get_dll_path(simfile, pathDLL)) return;
13. vsDLL = LoadLibrary(pathDLL);
14. if (vs_get_api_basic(vsDLL, pathDLL)) return; // get basic functions
15. if (vs_get_api_extend(vsDLL, pathDLL)) return; // get model extension functions
16. if (vs_get_api_road(vsDLL, pathDLL)) return; // get road functions

17. printMsg = vs_get_output_message(); // pointer to text from DLL

18. // Initialize VS model

19. t = vs_setdef_and_read(simfile, external_setdef, external_scan);
20. vss_check_for_dll_error ();
21. vs_initialize (t, external_calc, external_echo);
22. vss_print_message (printMsg);
23. vss_check_for_dll_error ();

24. // Run. Each loop advances time one full step.

25. while (!vs_stop_run())
26. {
27. vs_integrate (&t, external_calc);
28. vss_check_for_dll_error ();
29. vs_bar_graph_update (&ibarg); // update bar graph?
30. vss_print_message (printMsg);
31. }

32. // Terminate
33. external_calc (t, VS_EXT_EQ_END);
34. vs_terminate (t, external_echo);
35. vss_print_message (printMsg);
36. vss_opt_pause ();
37. FreeLibrary (vsDLL);
38. return;
39. }

18 / 25
Extending the Model with ANSI C
The VS solver programs are written in ANSI C, and the VS API allows a tight connection
between the internal math model and external programming when the programming is done in C.
The parameters for the new steering controller will not only be used in externally programmed
equations, but they will be installed into the VS math model so new values can be set at runtime
using the same VS GUI and database. Also, the values for the parameters will be shown in the
echo files generated with each run.
Listing 8 shows the C program that scans the simfile and loads the DLL (lines 11 – 17), reads the
parsfile and initializes the model (lines 19 – 23), runs the simulation (lines 25 – 31), and
terminates the simulation (lines 33 – 38). (For more detail about this specific file, please see the
VS API Manual.)
Model extensions can be installed in four functions that are compiled along with the program
from Listing 8. These functions are passed as arguments to VS API functions in the code shown
in Listing 8: functions external_setdef and external_scan are made available to the
API function vs_setdef_and_read (line 19); function external_echo is provided to the
API functionss vs_initialize (line 21) and vs_terminate (line 34); and function
external_calc is provided to the API functions vs_initialize (line 21),
vs_integrate (line 27), and is also called directly in the main function (line 33).

Setting up the external code with external_setdef

Listing 9 shows some static variables that are shared by the four external functions.
Listing 10 shows the source code for external_setdef, the function that installs new variables
and links to the variables in the VS solver.

Listing 9. Required include statements and some shared static variables.

// VehicleSim header files and prototypes for these functions
#include "vs_deftypes.h" // VS types and definitions
#include "vs_api.h" // VS API structure definition
#include "external.h" // prototypes for the functions in this file

// define some static variables used for the controller

static vs_real sXprev, sYprev, // X and Y coordinates of a preview point
sLfwd, // length forward for preview (m)
sLatTrack, // Lateral offset for tracking target
sGainStr, // parameter for a control gain
*sXcg, *sYcg, *sYaw, // pointers to vehicle X, Y, and yaw
*sImpStr, // pointer to imported steering wheel angle
*sTstart; // pointer to start time
static int sUseExternal; // option to use external model.

19 / 25
Listing 10. Example function external_setdef.
1. /* ----------------------------------------------------------------------------
2. Set up variables for the model extension. For the steering controller,
3. define new units and parameters and set default values of the parameters
4. that will be used if nothing is specified at runtime.
5. ---------------------------------------------------------------------------- */
6. void external_setdef (void)
7. {
8. int idX, idY;
10. // set default values for parameters defined in this file
11. sUseExternal = 0;
12. sLfwd = 20.0;
13. sGainStr = 10.0*PI/180.0;
14. sLatTrack = -1.6;
16. // C version of VS command: define_units deg/m 57.29577951
17. vs_define_units ("deg/m", 180.0/PI);
19. // define two new parameters: L_FORWARD and LAT_ERR
20. vs_define_parameter ("L_FORWARD",
21. "Distance preview point is forward of vehicle CG",
22. &sLfwd, "M");
23. vs_define_parameter ("LAT_TRACK",
24. "Lateral offset (to driver's left) for target",
25. &sLatTrack, "M");
26. vs_define_parameter ("GAIN_STEER_CTRL",
27. "Control parameter: steering angle per meter of "
28. "lateral offset", &sGainStr, "DEG/M");
30. // define two new outputs using variables defined here
31. idX = vs_define_output ("Xpreview", "X coordinate of preview point",
32. &sXprev, "M");
33. idY = vs_define_output ("Ypreview", "Y coordinate of preview point",
34. &sYprev, "M");
36. // set labels and units for new output variables
37. vs_set_sym_attribute (idX, OUTVAR_GEN_NAME, "X coordinate");
38. vs_set_sym_attribute (idY, OUTVAR_GEN_NAME, "Y coordinate");
39. vs_set_sym_attribute (idX, OUTVAR_BODY_NAME, "Steer control look point");
40. vs_set_sym_attribute (idY, OUTVAR_BODY_NAME, "Steer control look point");
41. vs_set_sym_attribute (idX, OUTVAR_UNITS, "M");
42. vs_set_sym_attribute (idY, OUTVAR_UNITS, "M");
44. // get pointers to vehicle X, Y, yaw, and imported steering wheel angle
45. // that will be used in calculation made during the run
46. sXcg = vs_get_var_ptr("XCG_TM");
47. sYcg = vs_get_var_ptr("YCG_TM");
48. sYaw = vs_get_var_ptr("YAW");
49. sImpStr = vs_get_var_ptr("IMP_STEER_SW");
50. sTstart = vs_get_var_ptr("TSTART");
51. }

20 / 25
In addition to the constants and variables for the steering controller, a new variable will be used to
activate the controller: the integer sUseExternal. Lines 11-14 define the default values for
these four parameters (variables that remain constant during a run).
Line 17 has the C equivalent of the VS command DEFINE_UNITS, and installs the “deg/m” units
for the steering control gain. Note that the default value set for this gain in line 13 should be set
with internal units (rad/m).
Lines 20 - 28 define three new parameters. Although a single VS command is used to add any
kind of variable, the VS API has separate functions for defining parameters, import variables,
outputs, and other miscellaneous variables. Variables added with the vs_define_parameter
function are handled the same as native parameters when the solver reads a parsfile or generates
an echo file. Note that the function takes the pointer to the variable as an input. The installation is
such that when the keyword associated with the parameter is found in an input, the variable in the
external code is updated properly. For example, if the keyword L_FORWARD is used in an input
parsfile, the associated value is assigned to the variable sLfwd in the external code.
Lines 31 - 34 define two new output variables and also obtain ID numbers to the symbolic
structures created within the VS solver. Those ID numbers are used with attribute codes
(OUTVAR_GEN_NAME, OUTVAR_BODY_NAME, and OUTVAR_UNITS) in lines 37 - 42 to set names
for the new output variables. These function call serve the same purposes as the VS commands
Up to this point (line 42), all code in Listing 10 has involved defining attributes of new variables
that will be used in equations that will be added to the model. Lines 46 - 49 provide access to
variables that have always existed in the VS solver, based on their associated keywords. This
external code will work with any VS math model that has variables with the keywords shown:
XCG_TM, YCG_TM, YAW, and IMP_STEER_SW. (This includes any vehicle in CarSim or
TruckSim.) Note that the function vs_get_var_ptr returns a pointer to the internal variable.
Therefore, the local copies sXcg, sYcg, sYaw, sImpStr, and sTstart were defined as pointers
in Listing 9.

Defining external calculations with external_calc

Listing 11 shows the source code for external_calc, the function that performs most of the
calculations that extend the original model within the VS solver. This function has two
arguments: the first is the current simulation time, and the second is the location in the equations.
As noted in the comments (and in the VS API Manual), this function can be used in six places. In
the case of the steering controller, only one is needed: VS_EXT_EQ_IN. This is at the beginning
of each time step. Output variables are available from the previous time step, and imported
variables can be computed for use in the native equation built into the VS solver (in the DLL).
Lines 75 and 76 always compute the new output variables, whether or not the new steer control is
Lines 78 - 81 handle the imported steering wheel angle. If the flag sUseExternal is FALSE then the
steering is not touched. If the time is less than or equal to tstart, the steering is set to 0.
Otherwise, the steering is set using the point-follower control equation (line 81).

21 / 25
Listing 11. Example function external_calc.
52. /* ----------------------------------------------------------------------------
53. Perform calculations involving the model extensions. The function is called
54. from four places as indicated with the argument where, which can have the
56. and VS_EXT_EQ_END (defined in vs_deftypes.h).
57. ---------------------------------------------------------------------------- */
58. void external_calc (vs_real t, vs_ext_loc where)
59. {
60. switch (where)
61. {
62. // initialization after reading parsfile but before init
63. case VS_EXT_EQ_PRE_INIT:
64. break;
66. case VS_EXT_EQ_INIT: // initialization after reading parsfile
67. break;
69. case VS_EXT_EQ_INIT2: // initialization after calculating outputs
70. break;
72. case VS_EXT_EQ_IN: // calculations at the start of a time step
74. // calculate X and Y coordinates of preview point
75. sXprev = *sXcg + sLfwd*cos(*sYaw);
76. sYprev = *sYcg + sLfwd*sin(*sYaw);
78. if (!sUseExternal) ; // no effect if sUseExternal is FALSE
79. else if (t <= *sTstart) *sImpStr = 0.0; // no steering at the start
80. else // steer proportional to the lateral error
81. *sImpStr = sGainStr*(sLatTrack -vs_road_l(sXprev, sYprev));
83. break;
85. case VS_EXT_EQ_OUT: // calculate output variables at the end of a time step
86. break;
88. case VS_EXT_EQ_END: // calculations done at end of run
89. break;
90. }
91. }

Adding more information to an echo file with external_echo

Listing 12 shows the source code for external_echo, the function that can write more
information into an echo file.
When the VS solver writes an echo file, it will call this function in four places, identified with the
argument where. A VS API function vs_write_to_echo_file is used to send a string to the
DLL so the VS solver can in turn write the string to file.
In this example, we use two of the locations. First, additional text is written at the top of the echo
file to tell users that the run was made with an extended model (lines 106 - 108). Next, the value
of sUseExternal is written at the end of the block of system parameters in the echo file (lines
112 - 113).

22 / 25
Listing 12. Example function external_echo.
92. /* ----------------------------------------------------------------------------
93. Write information into the current output echo file using the VS API
94. function vs_write_to_echo_file. This function is called four times when
95. generating the echo file as indicated with the argument where, which can
97. VS_EXT_ECHO_END (defined in vs_deftypes.h).
98. ---------------------------------------------------------------------------- */
99. void external_echo (vs_ext_loc where)
100. {
101. static char buffer[200];
103. switch (where)
104. {
105. case VS_EXT_ECHO_TOP: // top of echo file
106. vs_write_to_echo_file (
107. "! This model was extended with custom C code to provide a point-follower\n"
108. "! steer controller.\n\n");
109. break;
111. case VS_EXT_ECHO_SYPARS: // end of system parameter section
112. vs_write_i_to_echo_file ("OPT_USE_EXT_STEER", sUseExternal,
113. "! Use steering controller defined with external C code");
114. break;
116. case VS_EXT_ECHO_PARS: // end of model parameter section
117. break;
119. case VS_EXT_ECHO_END: // end of echo file
120. break;
121. }
122. }

Listing 13 shows excerpts of the resulting echo file. Lines 5 and 6 identify the extension. Line 10
documents the state of sUseExternal.
In many cases, this function is not needed. (For this example, the function is used for an integer
variable sUseExternal that is included mainly to provide an excuse for showing how to use
external_echo and external_scan.) Note that the three variables added with the
vs_define_parameter function are automatically included in the list of parameters, appearing
in lines 15 - 17.

Handling more information from input parsfiles with external_scan

Listing 14 shows the source code for external_scan, the function that can help process the
information in an input parsfile. This capability is not needed for any variables added with
vs_define_parameter, vs_define_import, or vs_define_output. However, it can be
used to obtain information for other variables that are defined for use in the external functions. In
this example, it is used read a value for the variable sUseExternal.

23 / 25
Listing 13. Excerpts of an echo file that created with the help of external_echo.
2. ! CarSim 7- (VS Alpha 6)
3. ! Vehicle-suspension arrangement: i_i
4. ! Generated by VehicleSim 1.0 Alpha 6 on December 18, 2006

5. ! This model was extended with custom C code to provide a point-follower

6. ! steer controller.

7. TITLE Simple Driver Control (Road) #1 <* Custom Driver Model>

8. …
9. TSTOP 15 ! Stop when this time is reached (s)
10. OPT_USE_EXT_STEER 1 ! Use steering controller defined with external C code.

11. !-----------------------------------------------------------------------------
13. !-----------------------------------------------------------------------------
14. …
15. L_FORWARD 20 ! Distance preview point is forward of vehicle CG (m)
16. LAT_TRACK -1.6 ! Lateral offset (to driver's left) for target (m)
17. GAIN_STEER_CTRL 10 ! Control parameter: steering angle per meter of …

18. !-----------------------------------------------------------------------------
20. !-----------------------------------------------------------------------------
21. …

Listing 14. Example function external_scan.

/* ----------------------------------------------------------------------------
Scan a line read from the current input parsfile. Return TRUE if the keyword
is recognized, FALSE if not.

keyword -> string with current ALL CAPS keyword to be tested

buffer -> string with rest of line from parsfile.
---------------------------------------------------------------------------- */
vs_bool external_scan (char *keyword, char *buffer)
if (!strcmp(keyword, "OPT_USE_EXT_STEER"))
sUseExternal = atoi(buffer);
return TRUE;
return FALSE;

Running the extended model

To run with the extended model, it is necessary to specify that the compiled EXE program should
be launched, and also to activate the imported steering wheel angle. This can be done with a
dataset in the library Models: Self-Contained Solvers, as shown in Figure 9. In this case, the
external wrapper field is identifies the compiled C program 1 , and two lines of inputs are
provided to activate the imported steering wheel angle and external calculations 2 .

24 / 25

Figure 9. Specifying the compiled C program and activating the alternative steer control.
The variables from the external code are installed into the solver, and access to the variables
within the solver is handled using C pointers. Because variables can be shared directly between
the solver and the external code, the arrays of import and export variables used for the VB and
MATLAB examples are not needed here.

The purpose of this document was to show how a VS math model could be extended using four
methods. The example is a steering controller, in which the vehicle is steered in proportion to the
lateral distance between a preview point a fixed distance in front of the vehicle, and the target
path (a constant distance to the left or right of a road centerline).
The first approach uses VS commands and requires no additional software beyond a package
from Mechanical Simulation such as CarSim. To extend the model with VS commands:
1. Read through the detailed documentation (readme text files and echo files) to find the
existing import and output variables of interest. Also, review the echo file for any
existing parameters that would be used in equations you will add to the model.
2. Add variables to the model using VS commands such as DEFINE_VARIABLE,
DEFINE_OUTPUT, and others (see the VS Solver Manual).
3. Add equations to the model using VS commands such as EQ_IN, EQ_OUT,
EQ_DIFFERENTIAL, and others (see the VS Solver Manual).
4. Add extra information for user-friendliness, such as new units (e.g., “deg/m”) and labels
for output variables.
The other three methods use programming languages to calculate the steering wheel angle. With
MATLAB and Visual Basic (VB), the VS solver is loaded and run, and arrays are used to
communicate between the new program and the math model in the VS solver.
More options exist when the programming language is C. Example source code files provided
with VS products (CarSim, BikeSim, and TruckSim) can be modified to provide any extension
possible with VS commands. In addition, complex model equations can be provided and
integrated with the existing VS model. The example in this document showed how access is
provided to internal variables in the existing solver, to allow the external calculations to be made
with a mixture of existing model variables and new variables defined in the external code.

25 / 25