This diagram models the Lorentz's system defined by the following set of equations :
In the current Scicos version, the following flowchart shows a top-down view of the main parts of the modeler/simulator :
A more detailed flowchart of the Scicos hybrid dynamical systems toolbox is shown in figure 3.
Figure 4 displays the current Scicos code generation implementation.
In the editor, the C code generation can be achievied through a super-block or an complete top-level diagram. The various steps of code generation are not visible by the user. Finally, the generated codes are automatically compiled and dynamically linked inside Scicos and ScicosLab.
Note that some restrictions still exist concerning the name of the block :
Note that some restrictions still exist concerning the name of the path :
The libraries must have file extensions ".dll" for the windows operating systems (OS), and ".so" for the Linux OS. The generator will then automatically look at for static libraries with file extensions ".lib" for Windows OSs and ".a" for Linux OS.
If that lastest files are not found, the GUI send a message to the user and the generation is aborted.
The use of the field entries 'Other files to link with (if any)' and 'Additional compiler flag(s)' in the main GUI
of the code generation can be sometimes difficult and boring when the diagram is composed of lot of user's blocks
that need many external libraries.
In Scicos, the global variable %scicos_libs can be used to inform external libraries from the
ScicosLab prompt just before launching the Scicos editor. The global variable %scicos_cflags is used as a compiler flag.
Typically it can be used in a 'loader.sce' script file that is in charge of loading user's function like interfacing functions
and computational functions.
An example of use of such a script is given below :
099 ... 0100 if MSDOS then 0101 libnam = ['mylib1.dll','mylib2.dll'] 0102 else 0103 libnam = ['mylib1.so','mylib2.so'] 0104 end 0105 0106 if %scicos_libs<>[] then 0107 for i=1:size(libnam,2) 0108 if find(libnam(i)==%scicos_libs)==[] then 0109 %scicos_libs=[%scicos_libs,libnam(i)] 0110 end 0111 end 0112 else 0113 %scicos_libs=libnam 0114 end 0115 0116 if ~MSDOS then %scicos_cflags=[%scicos_cflags,'-lstdc++']; end 0117...
When this variables are informed, the code generator of Scicos will automatically use it during the link and compile processes.
The dialog parameter 'Other files to link with (if any)' of the main GUI will be then set with the contents of %scicos_libs
and the dialog parameter 'Additional compiler flag(s)' with the content of the variable %scicos_cflags.
Finally, one can say that when the user generates a new block with the code generation, then the output library of the new block
will be automatically added at the end of the %scicos_libs content. That behaviour is for users that use the generated
block inside other blocks or diagram to be generated.
Files | Description |
Rdnom.c | Scicos computational function |
Rdnom_c.sci | Scicos interfacing function |
Rdnom_standalone.c | Standalone code |
Rdnom_act_sens_events.c | Actuators/sensors routines (shell/files) |
Rdnom_void_io.c | Actuators/sensors routines (generic C structure) |
Rdnom_params.dat | Parameters standalone file (``little endian binary'') |
IntRdnom_sci.c | ScicosLab/standalone interfacing function |
Makefile_Rdnom (lcc.mak/mak) | Makefile for the computational function and the standalone codes |
Makefile_intRdnom (lcc.mak/mak) | Makefile for the ScicosLab/standalone interfacing function |
Rdnom_loader.sce | ScicosLab script to reload the generated code inside ScicosLab |
The code generation of Scicos generates both a computational function and a standalone code. In the generation process, when the user choose to generate the standalone code, it is automatically compiled and dynamically linked in the ScicosLab environment. Then the standalone code can be used by the way of a ScicosLab interfacing function which is also generated, compiled and dynamically linked in the same time than the standalone code. The ScicosLab interfacing function is a C function and is automatically added to the list of the ScicosLab functions with the help of the function addinter.
For a generated code called 'Rdnom', such a function will have the following calling sequence in ScicosLab for an entire diagram generation :
and the following calling sequence for a super-block code generation :
The output signals are scilab structures composed by two fields : time and values. After have running the interfacing function, on can compute, e.g., an output signal :
-->out1=Discrete_KalmanFilter() out1 = values: [15000x3 constant] time: [15000x1 constant]
The field values contains the data stored during the simulation. If input/output
signals are scalar, then the size of the value field will be [n,1] with n the n
calls for the sensor/actuator. If the input/output signals are vector of size m, then
the size for values will be [n,m]. The size for time is always [n,1]. For each rows,
the event dates of the call are recorded.
To extract or enclose data from or in signal structure one can use the scilab functions
sig2data or data2sig.
Note that for the time being, inputs are not considered like signals structure. The
in1,in2...,inX variables can only be set with vectors (for scalar sensors) or
with matrices (for vectorial sensors). The number of rows for the input correspond to
the number of call of the sensor routines. If the number of calls are more that the
number of rows, then the generic routine for sensor stops the reading at the last row.
When the ScicosLab interfacing function of the standalone code is launched, all the
simulation is running from the time 0 to the time tf. The value of the final simulation
time is in fact written in the default binary data file, but it can be overloaded by
the use of the optional right hand side argument tf.
For the entire diagram generation case, the default parameters data file is normally in the path where codes have been generated. This file is named, for example, 'Rdnom_params.dat' and is written in binary little endian format. The lastest optional right hand side argument fil allows to specify another path and name for that parameters file.
The code generation of Scicos generates a ScicosLab loader.sce script that can be used
to reload the generated codes in another ScicosLab session. The script is generated in
the default path where the codes have been generated and is named, for a block
called 'Rdnom', Rdnom_loader.sce.
This script successively :
Then after running this script from the ScicosLab prompt with the exec
command, with, e.g., the command :
->exec('Rdnom_loader.sce');,
the new generated Scicos block can be added to a diagram by the help of the item Add new block in the menu Edit of the Scicos editor, and the standalone simulation function can be run from the ScicosLab prompt with the ScicosLab interfacing function calling sequence.
When generating the codes, the standalone can be compiled as an executable. This executable can be run
in a shell and the compilation is possible via Makefiles generated in the target path. This Makefiles
are called, for example, Makefile_Rdnom for a Linux OS and Makefile_Rdnom.mak for a Windows OS.
Under Linux OS, the standalone executable can be obtained with the following command line :
alan@fiboue:~/scicoslab/Rdnom$ make -f Makefile_Rdnom standaloneand under Windows OS,
c:\scicoslab\Rdnom> nmake /f Makefile_Rdnom standalone
Note that to run the standalone in Windows OS, the standard ScicosLab libraries (dlls in the SCI/bin directory)
and the external libraries defined by the user must be avialable in the path where the standalone executable
is called.
The standalone executable is always called standalone (or standalone.exe for Windows).
When it is called without argument, the standalone simulation is run and interacts with the shell
concerning data of actuators/sensors.
Require outputs of sensor number 1 time is: 0.000000 sizes of the sensor output is: 1,1 type of the sensor output is: 10 (double) Please set the sensor output values y(0,0) :If the sensors are for vector or matrix then each element must be typed.
Actuator: time=0.000000, u(0,0) of actuator 1 is -0.878222 Actuator: time=0.000000, u(1,0) of actuator 1 is -0.702345 Actuator: time=0.000000, u(2,0) of actuator 1 is -0.783668 Actuator: time=0.001000, u(0,0) of actuator 1 is -0.878222 Actuator: time=0.001000, u(1,0) of actuator 1 is -0.702345 Actuator: time=0.001000, u(2,0) of actuator 1 is -0.783668The subroutines that correspond to the sensor/actuator are in the file called Rdnom_act_sens_events.c. For actuators, the routine is called Rdnom_actuator and for sensors, the routine is called Rdnom_sensor. That subroutines are considered like generic routines and the user of the standalone executable can easily modify it.
void Rdnom_actuator(flag,nport,nevprt,t,u,nu1,nu2,ut,typout,outptr) /* * To be customized for standalone execution * flag : specifies the action to be done * nport : specifies the index of the super-block * regular input (The input ports are numbered * from the top to the bottom ) * nevprt : indicates if an activation had been received * 0 = no activation * 1 = activation * t : the current time value * u : the vector inputs value * nu1 : the input size 1 * nu2 : the input size 2 * ut : the input type * typout : learn mode (0 from terminal,1 from input file) * outptr : pointer to out data * typout=0, outptr not used * typout=1, outptr contains the output file name */ int *flag,*nevprt,*nport; int *nu1,*nu2,*ut; int typout; void *outptr; double *t; void *u;The calling sequence of the Rdnom_sensor is :
void Rdnom_sensor(flag,nport,nevprt,t,y,ny1,ny2,yt,typin,inptr) /* * To be customized for standalone execution * flag : specifies the action to be done * nport : specifies the index of the super-block * regular input (The input ports are numbered * from the top to the bottom ) * nevprt: indicates if an activation had been received * 0 = no activation * 1 = activation * t : the current time value * y : the vector outputs value * ny1 : the output size 1 * ny2 : the output size 2 * yt : the output type * typin : learn mode (0 from terminal,1 from input file) * inptr : pointer to out data * typin=0, inptr not used * typin=1, inptr contains the input file name */ int *flag,*nevprt,*nport; int *ny1,*ny2,*yt; int typin; void *inptr; double *t; void *y;
All of options of the standalone executable can be viewed by using the inline help with the option -h.
When the user has chosen to generate codes for an complete diagram the following options are available :
alan@fiboue:~/scicoslab/Rdnom$./standalone -h Usage: ./standalone [-h] [-v] [-i arg] [-o arg] [-d arg] [-t arg] Options : -h for the help -v for printing the Scicos Version -i for input file name, by default is Terminal -o for output file name, by default is Terminal -t for the final time, by default is 1.500000e+01 -p for input parameters file name, by default is Rdnom_params.dat
alan@fiboue:~/scicoslab/Rdnom$./standalone -h Usage: ./standalone [-h] [-v] [-i arg] [-o arg] [-d arg] [-t arg] [-e arg] [-s arg] Options : -h for the help -v for printing the Scicos Version -i for input file name, by default is Terminal -o for output file name, by default is Terminal -d for the clock period, by default is 0.1 -t for the final time, by default is 30 -e for the solvers step size, by default is 0.001 -s integer parameter for select the numerical solver : 1 for Euler's method 2 for Heun's method 3 (default value) for the Fourth-Order Runge-Kutta (RK4) Formula
The standalone executables can be used with the command line parameters -i
and -o to specify input/output files for the sensors/actuators instead of
using the terminal.
To specify output file(s) for the actuator(s), one can use
alan@fiboue:~/scicoslab/Rdnom$./standalone -o out.txt
alan@fiboue:~/scicoslab/Rdnom$ cat out_1.txt | more 0.000000 -0.878222 -0.702345 -0.783668 0.001000 -0.878222 -0.702345 -0.783668 0.002000 -0.878222 -0.702345 -0.783668 0.003000 -0.878222 -0.702345 -0.783668 0.004000 -0.878222 -0.702345 -0.783668 ....
In the standalone code, a function named 'Rdnom_sim' is the entry point for the simulation function. It can be called and interfaced with external routines. In the main function of the standalone file 'Rdnom_standalone.c' and in the ScicosLab interfacing function file 'intRdnom_sci.c', the standalone simulation function is called like that :
ierr = Rdnom_sim(params,typin,inptr,typout,outptr);The first argument is a structure with the following definition :
typedef struct { char *filen; double tf; } params_struct;
The file 'Rdnom_void_io.c' allows to use the standalone simulation function with generic interfaces for actuator/sensor.
void Rdnom_actuator(flag,nport,nevprt,t,u,nu1,nu2,ut,typout,outptr) int *flag,*nevprt,*nport; int *nu1,*nu2,*ut; int typout; void *outptr; double *t; void *u;
void Rdnom_sensor(flag,nport,nevprt,t,y,ny1,ny2,yt,typin,inptr) int *flag,*nevprt,*nport; int *ny1,*ny2,*yt; int typin; void *inptr; double *t; void *y;
typedef struct { int typ; /* data type */ int ndims; /* number of dims */ int ndata; /* number of data */ int *dims; /* size of data (length ndims) */ double *time; /* date of data (length ndata) */ void *data; /* data (length ndata*prod(dims)) */ } scicos_inout;
When the code generation is used for an entire diagram a parameter file is generated to contain some data in binary format. This file is called, for example, Rdnom_params.dat. It is written in little endian format.
The map can also be accessible via a Xml file which is generated in the directory and is called Rdnom_params.xml. For i.e, the content of this file for the Scicos demo RLC_circuit.cosf is
<?xml version="1.0" encoding="ISO-8859-1"?> <ScicosParam Name="RLC_circuit" version="scicos4.4"> <ScicosVar name="tf" dim1="1" dim2="1" typ="10"/> <ScicosVar name="ttol" dim1="1" dim2="1" typ="10"/> <ScicosVar name="deltat" dim1="1" dim2="1" typ="10"/> <ScicosVar name="rtol" dim1="1" dim2="1" typ="10"/> <ScicosVar name="atol" dim1="1" dim2="1" typ="10"/> <ScicosVar name="hmax" dim1="1" dim2="1" typ="10"/> <ScicosVar name="rpar_1" dim1="1" dim2="1" typ="10"/> <ScicosVar name="rpar_2" dim1="7" dim2="1" typ="10"/> <ScicosVar name="rpar_3" dim1="6" dim2="1" typ="10"/> <ScicosVar name="ipar_2" dim1="12" dim2="1" typ="84"/> <ScicosVar name="ipar_3" dim1="10" dim2="1" typ="84"/> <ScicosVar name="x" dim1="3" dim2="1" typ="10"/> <ScicosVar name="outtb_1" dim1="1" dim2="1" typ="10"/> <ScicosVar name="outtb_2" dim1="1" dim2="1" typ="10"/> </ScicosParam>
For each variable, the size and the type is given. One then can use an Xml parser, to read and write data in the parameters file.
The ScicosLab functions getscicosparam and setscicosparam can be used from the ScicosLab
prompt to read and write data in the parameters file provided by the Scicos generation. It use the
Xml file to know how is it written.
For i.e, for the Scicos demo RLC_circuit.cosf :
Step 1 - Do the code generation.
-->load SCI/macros/scicos/lib; -->exec(SCI+'/demos/scicos/Electrical/RLC_circuit.cosf',-1); -->[ok,scs_m,%cpr] = scicos_codegeneration(scs_m,list(1));
Step 2 - Run the standalone generated code with default values.
-->[out1,out2]=RLC_circuit(); -->scf(1);plot(out1.time,out1.values);
Step 3 - Load the parameters enclosed in the paramaters file in a ScicosLab list.
-->curdir=getcwd(); -->[dt,data] = getscicosparam(curdir+'/RLC_circuit/RLC_circuit_params.dat');
Step 4 - Change parameter values.
-->dt(1) ans = column 1 to 9 !SicosParam tf ttol deltat rtol atol hmax rpar_1 rpar_2 ! column 10 to 15 !rpar_3 ipar_2 ipar_3 x outtb_1 outtb_2 ! -->dt.tf=1;
Step 5 - Save the parameters list in the parameters file.
-->ok=setscicosparam(dt,curdir+'/RLC_circuit/RLC_circuit_params.dat');
Step 6 - Re-Run the standalone generated code with new parameters values.
-->[out1,out2]=RLC_circuit(); -->scf(2);plot(out1.time,out1.values);