external interface to simulink
TRANSCRIPT
1
EXTERNAL INTERFACE TO SIMULINK
by
Robert M. Edwards
Summer Faculty
US Nuclear Regulatory Commission
August 22, 2003
Contents:
1. Introduction ………………………………………………………………………………1
2. Execution of a SIMULINK model from the MATLAB command line……………….2
3. Execution of a SIMULINK model from a C Program…………………………………8
4. Execution of a SIMULINK model from FORTRAN…………………………………...9
5. Execution of a SIMULINK model from the Modular Modeling System (MMS)…….9
6. Execution of a SIMULINK model from TRACE……………………………………..14
7. Conclusion ………………………………………………………………………………21
Appendix A: simulink_demo.m script file ……………………………………………22
Appendix B: eng_simulink_demo.c program listing…………………………………24
Appendix C: FORTRAN eng_simulink_demo.f ……………………………………..27
1. Introduction:
SIMULINK, a MATLAB option, provides a high-level block-programming language for
dynamic simulation of systems of ordinary differential equations, discrete-time models, and hybrid
continuous-time and discrete-time systems. Extensive control related blocks and the State Flow
option are available to represent complex analog, digital and hybrid control systems. A standard
feature of MATLAB is its capability to be called from an external program, and compatibility is
provided for several C compilers and the Compaq Visual FORTRAN compiler version 6.6. The
MATLAB documentation provides and describes elementary examples of how to call MATLAB
from a program and to execute command line operations. Full control of a SIMULINK model is
available from the MATLAB command line.
The MATLAB external interface provides procedures for a program to put data into the
MATLAB workspace, execute commands, and retrieve MATLAB results back to the program
workspace. This document provides the additional examples of how to execute a SIMULINK model
from a program and how to preserve SIMULINK state information for repeated execution of the
model over an extended start-and-stop cycle spanning an indefinite period of accumulated simulation
time. The ultimate example at the end of this report demonstrates a FORTRAN interface to both
SIMULINK and the TRAC/RELAP Enhanced Computational Engine (TRACE). This ultimate
example demonstrates the feasibility of developing a detailed control systems model in SIMULINK
and interfacing it with a detailed systems model of a plant.
2
2. Execution of a SIMULINK model from the MATLAB command line
SIMULINK models may be executed from the MATLAB command line, and SIMULINK has
the useful feature of making the states of the model available at the end of a simulation and can
receive initial states that override any initial values in the SIMULINK model diagram. The
MATLAB command to execute a SIMULINK simulation is sim, and its online help is listed below:
SIM Simulate a Simulink model
SIM('model') will simulate your Simulink model using all simulation
parameter dialog settings including Workspace I/O options.
The SIM command also takes the following parameters. By default
time, state, and output are saved to the specified left hand side
arguments unless OPTIONS overrides this. If there are no left hand side
arguments, then the simulation parameters dialog Workspace I/O settings
are used to specify what data to log.
[T,X,Y] = SIM('model',TIMESPAN,OPTIONS,UT)
[T,X,Y1,...,Yn] = SIM('model',TIMESPAN,OPTIONS,UT)
T : Returned time vector.
X : Returned state in matrix or structure format.
The state matrix contains continuous states followed by
discrete states.
Y : Returned output in matrix or structure format.
For block diagram models this contains all root-level
outport blocks.
Y1,...,Yn : Can only be specified for block diagram models, where n
must be the number of root-level outport blocks. Each
outport will be returned in the Y1,...,Yn variables.
'model' : Name of a block diagram model.
TIMESPAN : One of:
TFinal,
[TStart TFinal], or
[TStart OutputTimes TFinal].
OutputTimes are time points which will be returned in
T, but in general T will include additional time points.
OPTIONS : Optional simulation parameters. This is a structure
created with SIMSET using name value pairs.
UT : Optional extern input. UT = [T, U1, ... Un]
where T = [t1, ..., tm]' or UT is a string containing a
function u=UT(t) evaluated at each time step. For
table inputs, the input to the model is interpolated
from UT.
Specifying any right hand side argument to SIM as the empty matrix, [],
will cause the default for the argument to be used.
Only the first parameter is required. All defaults will be taken from the
block diagram, including unspecified options. Any optional arguments
specified will override the settings in the block diagram.
See also SLDEBUG, SIMSET.
Overloaded methods
help idmodel/sim.m
3
The simset command is used to override the simulation parameters and initial states defined in
the block diagram model. The simset command without any arguments returns the available settings,
and their formats, that can be set:
Solver: [ 'VariableStepDiscrete' |
'ode45' | 'ode23' | 'ode113' | 'ode15s' | 'ode23s' |
'FixedStepDiscrete' |
'ode5' | 'ode4' | 'ode3' | 'ode2' | 'ode1' ]
RelTol: [ positive scalar {1e-3} ]
AbsTol: [ positive scalar {1e-6} ]
Refine: [ positive integer {1} ]
MaxStep: [ positive scalar {auto} ]
MinStep: [ [positive scalar, nonnegative integer] {auto} ]
InitialStep: [ positive scalar {auto} ]
MaxOrder: [ 1 | 2 | 3 | 4 | {5} ]
FixedStep: [ positive scalar {auto} ]
OutputPoints: [ {'specified'} | 'all' ]
OutputVariables: [ {'txy'} | 'tx' | 'ty' | 'xy' | 't' | 'x' | 'y' ]
SaveFormat: [ {'Array'} | 'Structure' | 'StructureWithTime']
MaxDataPoints: [ non-negative integer {0} ]
Decimation: [ positive integer {1} ]
InitialState: [ vector {[]} ]
FinalStateName: [ string {''} ]
Trace: [ comma separated list of 'minstep', 'siminfo', 'compile',
'compilestats' {''}]
SrcWorkspace: [ {'base'} | 'current' | 'parent' ]
DstWorkspace: [ 'base' | {'current'} | 'parent' ]
ZeroCross: [ {'on'} | 'off' ]
To insure that a model’s states are saved, the following simset commands will create an
OPTIONS variable NEWOPT for use with the sim command of a simulation named test.mdl:
OPTIONS=simget('test'); %get the models default options and show what
%needs to be modified.
NEWOPT=simset(OPTIONS,'MaxDataPoints',0); %change to unlimited data points
NEWOPT=simset(NEWOPT,'OutputVariables','txy'); %add states to workspace I/O
NEWOPT=simset(NEWOPT,'FinalStateName','xFinal'); %add states to workspace I/O
NEWOPT=simset(NEWOPT,'InitialState',[]); %go with the original states
NEWOPT=simset(NEWOPT,'FixedStep','auto'); %choose variable step integration
NEWOPT=simset(NEWOPT,'Solver','ode45'); %choose good integration algo.
And when it is time to begin copying the final states of a simulation interval back to the initial
states of an extended simulation interval, the NEWOPT option is set as follows:
NEWOPT=simset(NEWOPT,'InitialState',xFinal); %pass along initial state
The simulink_demo.m script file demonstrates MATLAB commands to an elementary
SIMULINK model named test.mdl. The m-file is listed in Appendix A. All files are in the
rxbiglib/engine directory (d:\rxbiglib\engine on Roman’s windows 2000 machine.)
With the MATLAB working directory set to the location of these files, the script is invoked by
simply typing the name of the file. The script includes pauses for the user to study the commands
and comments as the script proceeds. The test.mdl SIMULINK model is shown in Figure 1:
4
Figure 1: SIMULINK model test.mdl.
The model test has two states, the outputs of two simple analog integrators. The second
integrator is contained within the Subsystem block to demonstrate that the SIMULINK model can be
of arbitrary depth complexity. The top level diagram shows one input variable (In1), which must be
defined by the UT argument in the call to sim. Two output variables (Out1 and Out2) are indicated
in Figure 1 and are returned in the Y argument of sim. Ultimately, the inputs can represent the
response from an external systems code such as TRACE or the MMS, and the outputs can represent
the control algorithm response to manipulate control variables in the systems code. In this first
example m-file the input is simply sin(t), where t is the simulation time. The output of the first
integrator is sin(t)+1 and becomes the input to the second integrator. The second integrator thus
monotonically increases, and its state value must be preserved when the SIMULINK model is started
and stopped sequentially over the full length of an extended simulation-time interval. Although not
shown in Figure 1, the system states at each integration time step are returned in the X argument of
sim, and the times at each integration time step are returned in the T argument. The states at the end
of the simulation run are also returned in the variable name xFinal as requested by the simset option
settings in NEWOPT.
The simulink_demo.m script file first demonstrates a full 100 second simulation from time 0 to
time 100 and generates two plots presented in Figures 2 and 3.
The script file next demonstrates how to divide up the SIMULINK simulation into 100 one-
second simulations, where data exchanges could occur with a systems code. At the end of each one-
second time step, the script takes the final states at the end of the previous interval and passes them
on as initial states for the next interval. All the data from the 100 one-second simulations is
accumulated and plotted for comparison with the full 100 second simulation as shown in Figures 4
and 5.
Figures 4 and 5 actually show a somewhat smoother response than a single 100 second
simulation because the variable step integration algorithm (arbitrarily selected) is forced to hit the one
second intervals in the 100 one-second simulations. The script file then reruns the 100 second
5
simulation with a maximum time step of 0.1 second to demonstrate that it too can have a somewhat
better representation of the sinusoidal input and responses as shown in Figures 6 and 7.
0 10 20 30 40 50 60 70 80 90 1000
20
40
60
80
100
120the states integral(u) and double integral(u)
Figure 2 above contains the two states, and Figure 3 below contains the two outputs.
0 10 20 30 40 50 60 70 80 90 100-20
0
20
40
60
80
100
120the outputs u and integral(u)
6
0 10 20 30 40 50 60 70 80 90 100-20
0
20
40
60
80
100
120the states integral(u) and double integral(u)
Figure 4 above and Figure 5 below demonstrate that the state memory of a previous interval is
properly transferred to the next interval.
0 10 20 30 40 50 60 70 80 90 100-20
0
20
40
60
80
100
120the outputs u and integral(u)
7
0 10 20 30 40 50 60 70 80 90 1000
20
40
60
80
100
120the states integral(u) and double integral(u) (small steps)
Figure 6 above and Figure 7 below demonstrate that a smoother 100 second simulation can be
achieved with a limit on maximum time step size.
0 10 20 30 40 50 60 70 80 90 100-20
0
20
40
60
80
100
120the outputs u and integral(u) (small steps)
8
3. Execution of a SIMULINK model from a C Program
The eng_simulink_demo.c (and corresponding .exe) file demonstrate the same operation as the
script file except that it is done externally from the C program. A listing is provided in Appendix B.
Once a compiler is selected with the mex –setup command, the executable is created with the
MATLAB mex command (for an lcc compiler):
mex –f lccengmatopts.bat eng_simulink_demo.c
The command must be executed while in the rxbiglib/engine directory. The executable is
operated from the windows START/RUN menu. The program presents intermediate MATLAB
results using the windows message box feature which requires the user to click ok to continue (these
are like pauses). The message box feature is an important debugging tool to ensure that MATLAB
commands are correct. Unlike entering commands to a MATLAB command window, one does not
see the MATLAB response without the use of a message box.
The eng_simulink_demo program does the 100 one-second simulations similarly to the
simulink_demo script file. It includes the demonstration of how to put local C variables into the
inputs of the SIMULINK program. It also demonstrates how to retrieve MATLAB environment
variables back to the C program for processing. The ultimate response of the eng_simulink_demo
program produces the same plots shown in Figure 8 to demonstrate that it has performed just like the
script file, preserving state information across 100 one-second simulations:
0 10 20 30 40 50 60 70 80 90 100-20
0
20
40
60
80
100
120the outputs u and integral(u)
Figure 8 Results from the C program demonstrating preservation of state information over 100 one-
second simulations.
9
The eng_simulink_demo.c program contains a conditional compilation based on the definition
(or lack of definition) of the string BOBS. BOBS must be defined for MATLAB release 13
compatibility and the location of the rxbiglib/engine directory. BOBS must not be defined for release
12 compatibility and the location of rxbiglib/engine on Roman’s win2k machine. One can examine
the listing to see the differences between release 12 and 13 calls to MATLAB C library functions.
4. Execution of a SIMULINK model from FORTRAN
The standalone FORTRAN code that parallels the C code version is listed in Appendix C for
MATLAB release 13. A version for MATLAB release 12 would have to modify commands similarly
to the conditional compilation in the C program of Appendix B. (The best way to perform such a
conversion is to examine the coding of the MATLAB supplied FORTRAN example fengdemo.f that
is supplied with each MATLAB release in the MATLAB\extern\examples\eng_mat directory.) The
FORTRAN example executes the same sequence of external SIMULINK functions that the C
example executes. The Compaq digital FORTRAN compiler (version 6.6) is required. The
MATLAB mex –setup command is used to select the compiler, and once selected, the command to
build the executable is:
mex –f df60engmatopts.bat eng_simulink_demo.f
5. Execution of a SIMULINK model from the Modular Modeling System (MMS)
In addition to Penn State’s control research using SIMULINK and MATLAB, substantial
research has used the Modular Modeling System, MMS (originated by EPRI, and subsequently
handled by B&W, Framatome, and now nHance Technologies.) The MMS provides an extensive
library of power plant components that are based on lumped-parameter models in contrast to TRACE
distributed parameter modeling. An MMS systems model is integrated with the Advanced
Continuous Simulation Language, which has built in facilities to schedule execution of discrete time
controllers at regular intervals. The standalone SIMULINK FORTRAN example was carved up and
placed in an example MMS model’s initial, discrete, and terminal sections. In this first example, the
functions of the standalone example are “joined” at the hip with the MMS model’s execution. A next
example, could pull a PI controller out of the MMS model and demonstrate its implementation in
SIMULINK. A TMI MMS primary system model was used in David Werkheiser’s MS thesis where
he implemented a portion of the B&W integrated control system (ICS) centered around the rod
control system, all within MMS. This model can be expanded with more BOP components suitable
for testing a complete ICS implemented in SIMULINK.
In principal, the same detailed digital-control algorithms and logics implemented in SIMULINK
could be tested with either TRACE or MMS. MMS may be more suitable for normal operational
transients whereas TRACE would have an advantage for study of control algorithm performance
leading to or during severe upset or accident conditions.
One aspect of TRACE execution that should be noted is that it is not routinely used to integrate
a model at a fixed execution frequency that would be representative of the needs to communicate
with a digital controller, e.g., 10 hz sampling for example. While, the maximum time step can be
readily limited to 0.1 seconds, special consideration to even-out the time steps to hit “even” 0.1
second intervals is required. Without this special consideration, simulation time might proceed, for
10
example: 0.0, 0.05, 0.15, 0.22, 0.32, etc. Special consideration is needed to even out the TRACE
execution to communicate results at the required communication intervals of a digital controller; e.g.,
0, 0.1, 0.2, 0.3, 0.4, etc. The ACSL language employed by the MMS specifically addresses the
execution of discrete blocks at prescribed intervals and automatically adjusts the integration of the
continuous time model to hit required communication intervals.
An MMS/ACSL template file, modified to include external code in the initial, discrete and
terminal section is given below:
! include 'macfile.inc' ! comment out if no user-defined macros
Initial
include 'initfile.inc' ! comment out if no initialization at start command End ! of Initial
Dynamic
Constant tstop = 0.0, cint = 1.0
Termt (t.ge.tstop, '**** t>=tstop ****')
Derivative
Algorithm ialgder = 3 ! Euler
Nsteps nstpder = 10 ! initial time step = cint/nstpder
Maxterval maxtder = 100.0
Minterval mintder = 1.d-9
begin("noutil1")
!--------------------------------------------------------------------------------------------------
!model components are inserted here
!-------------------------------------------------------------------------------------------------- integer count
Constant count = 0
Procedural (= count)
count = count + 1
End ! of count procedural
finish()
End ! of Derivative
include 'discrbl.inc' ! uncomment if discrete blocks End ! of Dynamic
Terminal
include 'term.inc' ! uncomment if terminal calculations End ! of Terminal
End ! of Program.
The bolded items indicate places where ACSL Language code is inserted by the MMS model
builder. The MMS model builder inserts the code for a systems model in the
DYNAMIC/DERIVATIVE section of the template at “model components are inserted here”. An
MMS model definition can be created in a GUI interface as shown, for example, in Figure 9, and the
resulting code would be placed as indicated in the template.
11
Figure 9: Example of an MMS GUI for defining a systems model.
12
The carved-up SIMULINK FORTRAN example is placed through the indicated include
statements in the template. The carved-up FORTRAN contained in the include files are listed below:
'initfile.inc’ operations performed once at initialization integer engOpen, engGetVariable, mxCreateDoubleMatrix
integer mxGetPr
integer ep, TT, D, dummy
double precision time(11,2),data(2)
character*801 mbuffer
integer engPutVariable, engEvalString, engClose, engOutputBuffer
integer temp, status
CONSTANT time=0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0,...
1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0
Procedural
ep=engOpen('MATLAB')
dummy=engEvalString(ep, 'cd c:/users/rxbiglib/engine') .ne.0)
dummy=engEvalString(ep,'OPTIONS=simget(''test'');')
dummy=engEvalString(ep,'NEWOPT=simset(OPTIONS,''MaxDataPoints'',0);')
dummy=engEvalString(ep,'NEWOPT=simset(NEWOPT,''OutputVariables'',''txy'');')
dummy=engEvalString(ep,'NEWOPT=simset(NEWOPT,''FinalStateName'',''xFinal'');')
dummy=engEvalString(ep,'NEWOPT=simset(NEWOPT,''InitialState'',[]);')
dummy=engEvalString(ep,'NEWOPT=simset(NEWOPT,''FixedStep'',''auto'');')
dummy=engEvalString(ep,'NEWOPT=simset(NEWOPT,''Solver'',''ode45'')')
! first run the original model with its embedded initial states to the
! first 1 second interval.
!
! Create a variable from our time data 11 rows by 2 columns
!
INTEGER ik
TT = mxCreateDoubleMatrix(11, 2, 0)
do 20 iK=1,11
! /*note that FORTRAN Arrays follow MATLAB row-column syntax*/
20.. time(iK,2)=sin(time(ik,1))
call mxCopyReal8ToPtr(time, mxGetPr(TT), 22)
!
! Place the variable TT into the MATLAB workspace with name UTsubset
!
dummy=engPutVariable(ep, 'UTsubset', TT) .ne. 0)
!=======================================================================
! Run the simulation for 1 second with its built in initial conditions */
!==================================================
dummy=engEvalString(ep, '[tsubset,xsubset,ysubset]=sim(''test'',...
[0 1],NEWOPT,UTsubset);')
! initialze MATLAB arrays to hold the transient data
dummy=engEvalString(ep, 't=tsubset;x=xsubset;y=ysubset;')
end !Procedual
13
'discrbl.inc' Operations performed at even intervals of 1 second DISCRETE DEMO
INTERVAL myDT=1.0
!
! NOW, loop through the remaining time, at each interval,
! but copy the final states of each interval to the initial states of the
! next
!
PROCEDURAL
if(T.GT.0) THEN
dummy=engEvalString(ep,'NEWOPT=simset(NEWOPT,''InitialState'',xFinal);')
dummy=engEvalString(ep,'UTsubset=[UTsubset(:,1)+1 sin(UTsubset(:,1)+1)]')
dummy=engEvalString(ep,'[tsubset,xsubset,ysubset]=.sim(''test'',[UTsubset(1,1) …
UTsubset(11,1)],NEWOPT,UTsubset);')
dummy=engEvalString(ep,'t=[t;tsubset];x=[x;xsubset];y=[y;ysubset];');
endif
END !PROCEDURAL
END !DISCRETE
'term.inc' Operations performed at the end of the simulation PROCEDURAL
dummy=engEvalString(ep, 'figure (3);plot(t,x);grid;...
title(''the states integral(u) and double integral(u)'')')
dummy=engEvalString(ep, 'figure (4);plot(t,y);grid;...
title(''the outputs u and integral(u)'')')
! an example of pulling data out of the matlab space for consumption locally
!
! D = engGetVariable(ep, 'xFinal')
! /*release 13 format */
! call mxCopyPtrToReal8(mxGetPr(D), data, 2)
!
! call mxDestroyArray(TT)
! call mxDestroyArray(D)
! status = engClose(ep)
!
if (status .ne. 0) then
! write(6,*) 'engClose failed'
! stop
endif
END ! of procedural
14
6. Execution of a SIMULINK model from TRACE
This example modifies the TRACE example2a of its External Control Interface (ECI) documentation.
Example 2a demonstrates how an external FORTRAN program participates in a TRACE simulation. On
Roman’s computer, all files are rooted in the c:\trace directory. The interaction of TRACE and the control
example is specified in the tasklist file in the trace\example2a directory. The example program name is
control and is implemented with Compaq Digital Fortran, whose project is contained in the c:\trace\control
directory. A simple TRACE model of a heat exchanger is provided and the external control example reads the
value of time at each time step, calculates a flow ramp for one side of the heat exchanger, and deposits the
flow calculation into the TRACE simulation. The flow ramp is from 0 to 4252.18 in 20 seconds.
The control example was modified to additionally obtain a pressure variable, influenced by the
manipulated flow variable, and to execute a SIMULINK model of a PI control algorithm. The pressure
response to the flow ramp settles to 1.5534E7 and is shown in Figure 10, below:
0 20 40 60 80 100 120 140 1601.52
1.525
1.53
1.535
1.54
1.545
1.55
1.555x 10
7 pressure
Figure 10. TRACE ECI example2a response to flow ramp.
The SIMULINK PI control algorithm, shown below in Figure 11, contains a pressure setpoint, receives
the TRACE pressure as input 1, and computes a flow response to regulate TRACE pressure to the setpoint.
Figure 11. SIMULINK model trace_test interfaced to TRACE
15
It was found that the PI algorithm could not handle the regulation to setpoint problem by itself.
However, the use of the PI algorithm’s output as an additive signal to the flow ramp was successful. The flow
and pressure responses with the SIMULINK interface are shown below in Figures 12 and 13:
0 20 40 60 80 100 120 140 160 1800
1000
2000
3000
4000
5000
6000total flow and flow contribution of the controller
flow
flowPI
Figure 12. SIMULINK additive flow signal flowPI and total flow.
0 20 40 60 80 100 120 140 160 1801.52
1.53
1.54
1.55
1.56
1.57
1.58x 10
7 pressure
Figure 13. SIMULINK-TRACE pressure regulation response to setpoint.
16
There is considerable “ring” in the PI controller output and pressure response at the beginning of the
transient, shown below in Figures 14 and 15, which probably interferes with the ability of the PI controller to
handle the pressure regulation from 0 flow conditions.
-1 0 1 2 3 4
300
400
500
600
700
800
900
1000
total flow and flow contribution of the controller
flow
flowPI
Figure 14. SIMULINK-TRACE flow response from 0 to 4 seconds.
-0.5 0 0.5 1 1.5 2 2.5 3 3.5 4 4.5
1.525
1.53
1.535
1.54
1.545
1.55
1.555
1.56
1.565
1.57
x 107 pressure
Figure 15. SIMULINK-TRACE pressure response from 0 to 4 seconds.
17
Pressure regulation is not the important aspect of this demonstration of an interface between TRACE
and SIMULINK. The example demonstrates that a SIMULINK program can be started and stopped
sequentially from an external FORTRAN program while retaining its memory of its previous states. In this
example, the SIMULINK state is the output of integral mode of the controller.
The modifications to the TRACE control example occur at five points in the coding: 1) the declaration
section, 2) an initialization section, 3) the definition of variables to be communicated with TRACE, 4)
simulation section, and 5) at the conclusion of the simulation. The listing of the entire control.f90 program is
best viewed or printed from within Microsoft Visual Studio.
The inserted code for the declaration section is listed below. The pressure variable was added to the
existing Real (sdk) declaration line. Unlike the standalone eng_simulink_demo.f program, it was found that
FORTRAN 90 requires the explicit definition of the interface to subroutines and functions used in the
MATLAB libraries.
REAL(sdk), TARGET :: flow, time, pressure
!===============================================================
!
integer*4 ep, T, UT, D, dummy, temp, status
character*601 buffer
DOUBLE PRECISION matdata, lasttime, lastpressure, UTlocal(2,2)
DOUBLE PRECISION flowPI
INTERFACE
FUNCTION engopen (C)
Integer*4 engopen
Character*(*) C
end function engopen
FUNCTION engEvalString (I,C)
Integer*4 engEvalString
Integer*4 I
Character*(*) C
end function engEvalString
FUNCTION engOutputBuffer (I,C)
Integer*4 engOutputBuffer
Integer*4 I
Character*(*) C
end function engOutputBuffer
FUNCTION mxCreateDoubleMatrix(I1, I2, I3)
Integer*4 mxCreateDoubleMatrix
Integer*4 I1,I2,I3
end function mxCreateDoubleMatrix
SUBROUTINE mxCopyReal8ToPtr(D, I1, I2)
Integer*4 I1,I2
Double Precision D
end subroutine mxCopyReal8ToPtr
FUNCTION engPutVariable(I1, C, I2)
Integer*4 engPutVariable
Integer*4 I1,I2
Character*(*) C
end function engPutVariable
FUNCTION mxGetPr(I)
Integer*4 mxGetPr
Integer*4 I
end function mxGetPr
FUNCTION engGetVariable(I,C)
Integer*4 engGetVariable
Integer*4 I
Character*(*) C
18
end function engGetVariable
SUBROUTINE mxCopyPtrToReal8(I1, D, I2)
Integer*4 I1,I2
Double Precision D
end subroutine mxCopyPtrToReal8
SUBROUTINE mxDestroyArray(I)
Integer*4 I
end Subroutine mxDestroyArray
FUNCTION engClose(I)
Integer*4 engClose
Integer*4 I
end function engClose
END INTERFACE
The inserted code for the initialization section, just after the existing call to ExTransfer(‘Init’) , is
entered before the simulation begins and is listed below. The occurrences of print and read dialogues occur in
the child command window and are examples of how to debug MATLAB command sequences in this
environment.
CALL ExtTransfer('Init')
!===============================================================
!=========================================Initialization section
!
ep = engOpen('matlab')
!
if (ep .eq. 0) then
write(6,*) 'Can''t start MATLAB engine'
STOP
endif
dummy=engOutputBuffer(ep, buffer)
!
dummy=engEvalString(ep,'cd c:/users/rxbiglib/engine')
dummy=engEvalString(ep, 'pwd')
print *, buffer
print *, 'Type any number to continue'
read(*,*) temp
!
! Create pointers to MATLAB matricies' structures for copying
! FORTRAN data into MATLAB workspace
!
T = mxCreateDoubleMatrix(1, 1, 0)
D = mxCreateDoubleMatrix(1, 1, 0)
UT= mxCreateDoubleMatrix(2, 2, 0)
!
!Initialize MATLAB arrays to collect times and flows and pressures
!
dummy=engEvalString(ep, 't=[];flow=[];pressure=[];flowPI=[];')
!
!Initialize SIMULINK model trace_test simulation parameters
!
dummy=engEvalString(ep, 'OPTIONS=simget(''trace_test'');')
dummy=engEvalString(ep, 'NEWOPT=simset(OPTIONS,''MaxDataPoints'',0);')
dummy=engEvalString(ep, 'NEWOPT=simset(NEWOPT,''OutputVariables'',''txy'');')
dummy=engEvalString(ep, 'NEWOPT=simset(NEWOPT,''FinalStateName'',''xFinal'');')
dummy=engEvalString(ep, 'NEWOPT=simset(NEWOPT,''InitialState'',[]);')
dummy=engEvalString(ep, 'NEWOPT=simset(NEWOPT,''FixedStep'',''auto'');')
dummy=engEvalString(ep, 'NEWOPT=simset(NEWOPT,''Solver'',''ode45'')')
print *, buffer
print *, 'Type any number to continue'
read(*,*) temp
!
! Initialize the last time the simulink program called.
19
lasttime=0.0
The inserted code for the definition of variables to be communicated with TRACE is contained in the
SetMissing subroutine. Examination of the TRACE input deck is needed to identify variables of interest to a
control program through the call to IsMissing.
aptr => pressure
CALL IsMissing('fluid','OldTime',2, 'pn','index',1,0,0,aptr)
The inserted code for the simulation section of the MassFlow subroutine, which is entered at each time
step, is listed below. This example has been programmed to build a pressure input table to linearly ramp the
pressure signal to the SIMULINK program over the last computational interval of TRACE from lasttime to the
current time. Strictly speaking, an analog control system providing a feedback signal to TRACE should
be integrated with the model equations. A SIMULINK model of a digital control system could sample and
hold its inputs and compute outputs for the next interval of a TRACE simulation. A digital controller would
execute at a fixed interval; e.g., every tenth of a second. A hopefully second order effect for possible
consideration of large distributed digital control systems is that, unlike operation with a systems simulation
code, not all process variables will arrive simultaneously, nor will all the outputs be applied at the same point
in time.
! call SIMULINK trace_test to compute new flow rate
!
! setup input table with the previous pressure and current pressure and
! put into matlab space under the name UTsubset
!
if(time.le.0.0) then
lastpressure=pressure
lasttime=time
endif
UTlocal(1,1)=lasttime
UTlocal(2,1)=time
UTlocal(1,2)=lastpressure
UTlocal(2,2)=pressure
call mxCopyReal8ToPtr(UTlocal(1,1), mxGetPr(UT), 4)
dummy=engPutVariable(ep, 'UTsubset', UT)
if(time.le.0.0) then dummy=engEvalString(ep, '[tsubset,xsubset,ysubset]=sim(''trace_test'',[0 0],NEWOPT,UTsubset);')
dummy=engEvalString(ep, 'ysubset')
print *, 'The output at time',time
print *, buffer
print *, 'Type any number to continue'
read(*,*) temp
else
dummy=engEvalString(ep, 'NEWOPT=simset(NEWOPT,''InitialState'',xFinal);') dummy=engEvalString(ep, '[tsubset,xsubset,ysubset]=sim(''trace_test'',[UTsubset(1,1) UTsubset(2,1)],NEWOPT,UTsubset);')
endif
!
! get the last output flow to pass into TRACE for the next interval
!
dummy=engEvalString(ep, 'lastoutput=ysubset(length(ysubset));')
D = engGetVariable(ep, 'lastoutput')
call mxCopyPtrToReal8(mxGetPr(D), flowPI, 1)
lasttime=time
lastpressure=pressure
flow = 4252.18_sdk*MIN(1.0_sdk, 0.05_sdk*time)+ flowPI
!
! put time and flow into MATLAB workspace and accummulate
! data for plot at the end
!
call mxCopyReal8ToPtr(time, mxGetPr(T), 1)
dummy=engPutVariable(ep, 'traceT', T)
call mxCopyReal8ToPtr(flow, mxGetPr(T), 1)
20
dummy=engPutVariable(ep, 'traceF', T)
call mxCopyReal8ToPtr(Pressure, mxGetPr(T), 1)
dummy=engPutVariable(ep, 'traceP', T)
dummy=engEvalString(ep,'t=[t;traceT];flow=[flow;traceF];pressure=[pressure;traceP];')
dummy=engEvalString(ep,'flowPI=[flowPI;lastoutput];')
Finally, the code inserted at the conclusion of the TRACE simulation after the ENDDO TimeStepLoop
statement, generates MATLAB plots of the results:
ENDDO TimeStepLoop
!=============================================================================
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! end of job processing
dummy=engEvalString(ep,'figure(1);plot(t,flow,t,flowPI,''-.'');')
dummy=engEvalString(ep,'title(''total flow and flow contribution of the controller'');grid')
dummy=engEvalString(ep,'legend(''flow'',''flowPI'');')
dummy=engEvalString(ep,'figure(2);plot(t,pressure);title(''pressure'');grid')
if(dummy.ne.0) then
print *, buffer
print *, 'plot failed enter any number to continue'
read(*,*) temp
endif
!
! an example of pulling data of the matlab space for consumption locally
!
dummy=engEvalString(ep,'lenT=length(t)')
D = engGetVariable(ep, 'lenT')
! /*release 13 format */
call mxCopyPtrToReal8(mxGetPr(D), matdata, 1)
!
print *, 'number of data points, LOOK at the plots'
print *, matdata
print *, 'Type any number to continue'
read (*,*) temp
!
call mxDestroyArray(T)
call mxDestroyArray(D)
status = engClose(ep)
if (status .ne. 0) then
write(6,*) 'engClose failed'
print *, 'Type any number to continue'
read (*,*) temp
endif
Operational notes for Roman’s computer:
Although Roman doesn’t yet have visual studio and Compaq FORTRAN, a control executable was built
for his version of MATLAB release 12, where it has been modified for the path to his rxbiglib on his d: drive.
The control.f90 had to be modified for release 12 on Roman’s machine, and is in the file
c:\trace\control\control.f90 file. The release 13 version code, presented above, is contained in the file
c:\trace\control\control_matlab6p5.f90 file. The gains, and other programming, of the
d:\rxbiglib\engine\trace_test.mdl can still be modified as long as the basic input/output structure at the top
level diagram is not changed. Operation on Roman’s computer is as follows: Open up two command
windows (from programs/accessories menu). In one command window:
cd c:\trace
.\bin\driver
In the other command window:
cd c:\trace\example2a
..\bin\trace
21
When the control program is started, a third command window (a child window) is
automatically created. Enter a number to the debugging outputs as they occur in this child window.
When you enter 1 to the last output, the figures and MATLAB command window will disappear.
The variables are accessible for additional processing and plots while the MATLAB command
window is open.
7. CONCLUSION
These series of external interface to SIMULINK examples demonstrate the feasibility of
constructing detailed models of control systems in the high-level block-programming language of
SIMULINK with all of its associated options, such as State Flow. The SIMULINK models of a
control system can be interfaced to systems codes such as TRACE or the MMS.
Things to watch for in expanded SIMULINK control applications are as follows:
1. The use of transport delay and memory blocks are often used in digital control systems
to “remember” the last value of a particular signal. These blocks require initial values.
If SIMULINK creates a discrete-time state for these blocks, then the coding of the
examples in this report should allow preservation of this state information. SIMULINK
lumps all the continuous-time and discrete-time states in its state vector. If SIMULINK
does not create discrete-time states for these blocks, then the external program can
remember the last outputs of these blocks and reset the initial values at the beginning of
the next simulation interval.
2. The “states” described by the State Flow option do not appear to be treated as discrete-
time states, but rather as “machine” states. Additional handshaking by the external
program may be required to remember the last machine state and restore them at the
beginning of a new simulation interval.
22
APPENDIX A: simulink_demo.m script file % demo script file for calling a simulink block diagram sequentially
% while changing the inputs while preserving the state of the system.
% (Should be able to do the same programming sequence externally from
% Fortran or c)
%
% start in the directory with the model test.mdl that has the default
% simulationparameters, which are changed as necessary.
%
echo on;
OPTIONS=simget('test'); %get the models default options and show what
%needs to be modified.
NEWOPT=simset(OPTIONS,'MaxDataPoints',0); %change to unlimited data points
NEWOPT=simset(NEWOPT,'OutputVariables','txy'); %add states to workspace I/O
NEWOPT=simset(NEWOPT,'FinalStateName','xFinal'); %add states to workspace I/O
NEWOPT=simset(NEWOPT,'InitialState',[]); %go with the original states
NEWOPT=simset(NEWOPT,'FixedStep','auto'); %choose variable step
integration
NEWOPT=simset(NEWOPT,'Solver','ode45'); %choose good integration algo.
UTt=[0:0.1:100]; %setup a 1000 time points for an input vector
UT=[UTt' sin(UTt')]; %and create a sinusoidal input pattern
pause %now run the full simulation from 0 to 100 seconds
[t,x,y]=sim('test',[0 100],NEWOPT,UT);
figure (1);plot(t,x);grid;title('the states integral(u) and double integral(u)')
figure (2);plot(t,y);grid;title('the outputs u and integral(u)')
xFinal %the final states
% look at the scope block in the simulink model to see why the
% double integral(u) monotonically increases
pause %=======================================================================
% NOW, lets divide up the simulation into 100 equal
% parts that might be representative of the needs of an
% external progam to call and interact with the inputs
% at each step; but in this demo we're going to use the
% same ultimate input pattern to demonstrate retention
% of previous state information.
%
% first run the original model with its embedded initial states to the
% first 1 second interval.
%
UTsubset=[];
for k=1:10
UTsubset=[UTsubset;UT(k,:)];
echo off
end
echo on
[tsubset,xsubset,ysubset]=sim('test',[0 1],NEWOPT,UTsubset);
xFinal
pause
% NOW, loop through the remaining time points, but copy the final states to
% the initial states of each remaining interval
t=tsubset;x=xsubset;y=ysubset; %prepare to concantate interval outputs
for k=1:99
NEWOPT=simset(NEWOPT,'InitialState',xFinal); %pass along initial state
UTsubset=[];
for m=1:10
UTsubset=[UTsubset;UT(m+k*10,:)]; %the next 10 inputs
end
23
[tsubset,xsubset,ysubset]=sim('test',[k k+1],NEWOPT,UTsubset);
t=[t;tsubset];x=[x;xsubset];y=[y;ysubset]; %accummulate proof
echo off
end
echo on
xFinal
pause
figure (3);plot(t,x);grid;title('the states integral(u) and double integral(u)')
figure (4);plot(t,y);grid;title('the outputs u and integral(u)')
xFinal %the final states
% look at the scope block in the simulink model to see the last
% second of the interval
pause %=======================================================================
%
% NOW comparing figures 1 and 3 AND 2 with 4 there seems to be a a bit
% more "ragedness" to the full job. Want proof? Change the test.mdl
% simulation parameters to fixed step RK with a step size of 0.1 second.
NEWOPT=simset(NEWOPT,'InitialState',[]); %restore the original states
NEWOPT=simset(NEWOPT,'FixedStep',0.1); %choose tiny fixed step
NEWOPT=simset(NEWOPT,'Solver','ode5'); %choose good integration also.
[t,x,y]=sim('test',[0 100],NEWOPT,UT);
figure (5);plot(t,x);grid;title('the states integral(u) and double integral(u)
(small steps)')
figure (6);plot(t,y);grid;title('the outputs u and integral(u) (small steps)')
echo off
24
APPENDIX B. eng_simulink_demo.c program listing /*
* eng_simulink_demo.c
*
* This example implements the simulink_demo.m file demonstration of how to call
* SIMULINK from the MATLAB command line and splitting the simulation up to allow
* for potentially time varying inputs that may depend, for example, TRACE
* Simulation results. The outputs of the SIMULINK model may be routed to TRACE
* to optain the response of the plant.
*
* Modifies the engwindemo.c provided by MATLAB: Copyright 1984-2000 The MathWorks, Inc.
*/
/* $Revision: 1.8 $ */
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "engine.h"
#include "math.h"
/* ============== MUST CHOOSE PLATFORM BY EDITING THE FOLLOWING LINE */
#define BOBS /* comment this line out for Roman's release 12 on his computer */
static double Areal[6] = { 1, 2, 3, 4, 5, 6 };
int PASCAL WinMain (HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpszCmdLine,
int nCmdShow)
{
Engine *ep;
mxArray *T = NULL, *a = NULL, *d = NULL;
char buffer[801];
double *Dreal, *Dimag;
double time[2][11] = { 0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1, 1,2,3,4,5,6,7,8,9,10,11 };
double tbeg;
int i;
/*
* Start the MATLAB engine
*/
if (!(ep = engOpen(NULL))) {
MessageBox ((HWND)NULL, (LPSTR)"Can't start MATLAB engine",
(LPSTR) "Engwindemo.c", MB_OK);
exit(-1);
}
/*
* PART I
*
* first get into the right directory, bring up the simulation and
* set the simulation parameters the way we want them
*/
/*
* Use engOutputBuffer to capture MATLAB output
*/
engOutputBuffer(ep, buffer, 800);
/*
* the evaluate string returns the result into the
* output buffer.
*/
#ifdef BOBS
engEvalString(ep, "cd c:/users/rxbiglib/engine");/*this is the path for bob's notebook computer*/
#else
engEvalString(ep, "cd d:/rxbiglib/engine"); /*this is the path for roman's win2kmachine */
#endif
engEvalString(ep, "pwd");
MessageBox ((HWND)NULL, (LPSTR)buffer, (LPSTR) "MATLAB - cd", MB_OK); /*std windows library*/
engEvalString(ep, "OPTIONS=simget('test')");
engEvalString(ep, "NEWOPT=simset(OPTIONS,'MaxDataPoints',0);");
engEvalString(ep, "NEWOPT=simset(NEWOPT,'OutputVariables','txy');");
engEvalString(ep, "NEWOPT=simset(NEWOPT,'FinalStateName','xFinal');");
25
engEvalString(ep, "NEWOPT=simset(NEWOPT,'InitialState',[]);");
engEvalString(ep, "NEWOPT=simset(NEWOPT,'FixedStep','auto');");
engEvalString(ep, "NEWOPT=simset(NEWOPT,'Solver','ode45')");
MessageBox ((HWND)NULL, (LPSTR)buffer, (LPSTR) "MATLAB - NEWOPT", MB_OK);
/*
% NOW, lets divide up the simulation into 100 additional equal
% parts that might be representative of the needs of an
% external progam to call and interact with the inputs
% at each step; but in this demo we're going to use the
% same ultimate input pattern as simulink_demo.m
% to demonstrate retention of previous state information.
%
% first run the original model with its embedded initial states to the
% first 1 second interval.
%
*/
/*
* Create a variable from our time data
*/
T = mxCreateDoubleMatrix(11, 2, mxREAL); /* 11 rows by 2 columns*/
i=0;
while(i<11) { /*note that it is best to think of C arrays as */
time[1][i]=sin(time[0][i]); /*reversed notation of MATLAB, the first index */
i++; /*is the column, second index is the row!!! */
} /*and if you look back at the initialization */
/*you will see that columns fill first !! */
memcpy((char *) mxGetPr(T), (char *) time, 22*sizeof(double)); /* std C routine */
#ifndef BOBS
mxSetName(T, "UTsubset"); /*this is the release 12 format (not release13)*/
engPutArray(ep, T);
#else
engPutVariable(ep, "UTsubset", T); /*release 13 incorporates name in the call */
#endif
/*========================================================================================*/
engEvalString(ep, "UTsubset");
MessageBox ((HWND)NULL, (LPSTR)buffer, (LPSTR) "first UTsubset", MB_OK);
/* Run the simulation for 1 second with its built in initial conditions */
engEvalString(ep, "[tsubset,xsubset,ysubset]=sim('test',[0 1],NEWOPT,UTsubset);");
engEvalString(ep, "xFinal");
MessageBox ((HWND)NULL, (LPSTR)buffer, (LPSTR) "states at 1 sec", MB_OK);
/*
% NOW, loop through the remaining time 99 seconds, one second at a time,
% but copy the final states of each intervaql to the initial states of the
% next
%
*/
engEvalString(ep, "t=tsubset;x=xsubset;y=ysubset;"); /*initialze MATLAB arrays */
tbeg=1; /*to collect data from all 100 sec*/
while(tbeg<100)
{
engEvalString(ep, "NEWOPT=simset(NEWOPT,'InitialState',xFinal);"); /*last final to initial
of next */
engEvalString(ep, "UTsubset=[UTsubset(:,1)+1 sin(UTsubset(:,1)+1)]"); /*modify input for next
interval*/
engEvalString(ep, "[tsubset,xsubset,ysubset]=sim('test',[UTsubset(1,1)
UTsubset(11,1)],NEWOPT,UTsubset);");
engEvalString(ep, "t=[t;tsubset];x=[x;xsubset];y=[y;ysubset];"); /*accummulate results
*/
tbeg=tbeg+1;
}
engEvalString(ep, "figure (3);plot(t,x);grid;title('the states integral(u) and double
integral(u)')");
engEvalString(ep, "figure (4);plot(t,y);grid;title('the outputs u and integral(u)')");
/* an example of pulling data of the matlab space for consumption in c programming
*/
#ifndef BOBS
d = engGetArray(ep, "xFinal"); /*release 12 format */
#else
d = engGetVariable(ep, "xFinal"); /*release 13 format */
#endif
26
if (d == NULL) {
MessageBox ((HWND)NULL, (LPSTR)"Get Array Failed", (LPSTR)"Engwindemo.c", MB_OK);
}
else {
Dreal = mxGetPr(d); /* yes MATLAB variables can be complex */
Dimag = mxGetPi(d);
if (Dimag)
sprintf(buffer,"imaginary final output???????: %g+%gi",Dreal[0],Dimag[0]);
else
sprintf(buffer,"final outputs: %g,%g",Dreal[0],Dreal[1]);
MessageBox ((HWND)NULL, (LPSTR)buffer, (LPSTR)"states at 100 sec", MB_OK);
mxDestroyArray(d);
}
engEvalString(ep, "whos"); /*list out variables in the workspace, just for fun*/
MessageBox ((HWND)NULL, (LPSTR)buffer, (LPSTR) "MATLAB - whos", MB_OK);
/*
* We're done! Free memory, close MATLAB engine and exit.
*/
mxDestroyArray(T);
engClose(ep);
return(0);
}
27
APPENDIX C. FORTRAN eng_simulink_demo.f C
C This example implements the simulink_demo.m file demonstration of how to call
C SIMULINK from the MATLAB command line and splitting the simulation up to allow
C for potentially time varying inputs that may depend, for example, TRACE
C Simulation results. The outputs of the SIMULINK model may be routed to TRACE
C to optain the response of the plant.
C
C Modifies the fengdemo.f MATLAB Example Copyright 1984-2000 The MathWorks, Inc.
C======================================================================
C $Revision: 1.9 $
program main
C-----------------------------------------------------------------------
C (pointer) Replace integer by integer*8 on the DEC Alpha
C 64-bit platform
C
integer engOpen, engGetVariable, mxCreateDoubleMatrix
integer mxGetPr
integer ep, T, D, dummy
C----------------------------------------------------------------------
C
C Other variable declarations here
double precision time(11,2),data(2)
character*801 buffer
integer engPutVariable, engEvalString, engClose, engOutputBuffer
integer temp, status
data time / 0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0,
1 1,2,3,4,5,6,7,8,9,10,11/
C
ep = engOpen('matlab ')
C
if (ep .eq. 0) then
write(6,*) 'Can''t start MATLAB engine'
stop
endif
dummy=engOutputBuffer(ep, buffer)
C
if (engEvalString(ep, 'cd c:/users/rxbiglib/engine') .ne.0) then
write(6,*) 'engEvalString failed on cd'
stop
endif
dummy=engEvalString(ep, 'pwd')
print *, buffer
print *, 'Type any number to continue'
read(*,*) temp
dummy=engEvalString(ep, 'OPTIONS=simget(''test'');')
C=======================================================================column 73
dummy=engEvalString(ep, 'NEWOPT=simset(OPTIONS,''MaxDataPoints'',0 silly old 72
column limitation
1);')
dummy=engEvalString(ep, 'NEWOPT=simset(NEWOPT,''OutputVariables'',
1''txy'');')
dummy=engEvalString(ep, 'NEWOPT=simset(NEWOPT,''FinalStateName'','
1'xFinal'');')
dummy=engEvalString(ep, 'NEWOPT=simset(NEWOPT,''InitialState'',[])
1;')
dummy=engEvalString(ep, 'NEWOPT=simset(NEWOPT,''FixedStep'',''auto
1'');')
dummy=engEvalString(ep, 'NEWOPT=simset(NEWOPT,''Solver'',''ode45''
1)')
print *, buffer
print *, 'Type any number to continue'
read(*,*) temp
C=======================================================================column 73
28
C NOW, lets divide up the simulation into 100 additional equal
C parts that might be representative of the needs of an
C external progam to call and interact with the inputs
C at each step; but in this demo we're going to use the
C same ultimate input pattern as simulink_demo.m
C to demonstrate retention of previous state information.
C
C first run the original model with its embedded initial states to the
C first 1 second interval.
C
C Create a variable from our time data 11 rows by 2 columns
C
T = mxCreateDoubleMatrix(11, 2, 0)
do 20 i=1,11
C /*note that FORTRAN Arrays follow MATLAB row-column syntax*/
20 time(i,2)=sin(time(i,1))
call mxCopyReal8ToPtr(time, mxGetPr(T), 22)
C
C Place the variable T into the MATLAB workspace with name UTsubset
C
if (engPutVariable(ep, 'UTsubset', T) .ne. 0) then
C /*release 13 incorporates name in the call */
write(6,*) 'engPutVariable failed'
print *, 'Type any number to continue'
read(*,*) temp
stop
endif
dummy=engEvalString(ep, 'UTsubset')
print *, buffer
print *, 'Type any number to continue'
read(*,*) temp
C====================================================================================
C Run the simulation for 1 second with its built in initial conditions */
C=======================================================================column 73
dummy=engEvalString(ep, '[tsubset,xsubset,ysubset]=sim(''test'',[0
1 1],NEWOPT,UTsubset);')
dummy=engEvalString(ep, 'xFinal')
print *, 'The states after 1 second'
print *, buffer
print *, 'Type any number to continue'
read(*,*) temp
C
C NOW, loop through the remaining time 99 seconds, one second at a time,
C but copy the final states of each intervaql to the initial states of the
C next
C
C
dummy=engEvalString(ep, 't=tsubset;x=xsubset;y=ysubset;')
C /*initialze MATLAB arrays */
DO 100 I=1,99
dummy=engEvalString(ep, 'NEWOPT=simset(NEWOPT,''InitialState'',x
1Final);')
dummy=engEvalString(ep, 'UTsubset=[UTsubset(:,1)+1 sin(UTsubset(
1:,1)+1)]')
dummy=engEvalString(ep, '[tsubset,xsubset,ysubset]=sim(''test'',
1[UTsubset(1,1) UTsubset(11,1)],NEWOPT,UTsubset);')
dummy=engEvalString(ep, 't=[t;tsubset];x=[x;xsubset];y=[y;ysubse
1t];')
100 CONTINUE
dummy=engEvalString(ep, 'figure (3);plot(t,x);grid;title(''the sta
1tes integral(u) and double integral(u)'')')
dummy=engEvalString(ep, 'figure (4);plot(t,y);grid;title(''the out
1puts u and integral(u)'')')
C an example of pulling data of the matlab space for consumption in c programming
29
C
D = engGetVariable(ep, 'xFinal')
C /*release 13 format */
call mxCopyPtrToReal8(mxGetPr(D), data, 2)
C========================================================================================
print *, 'the final states in FORTRAN, LOOK at the plots'
print *, data
print *, 'Type any number to continue'
read (*,*) temp
C
call mxDestroyArray(T)
call mxDestroyArray(D)
status = engClose(ep)
C
if (status .ne. 0) then
write(6,*) 'engClose failed'
stop
endif
C
stop
end
30