add wiki to repository for github pages
15
docs/Deprecated-Features.md
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
List of features that have been deprecated.
|
||||||
|
|
||||||
|
### Trick Specific Units to Standard Units
|
||||||
|
|
||||||
|
Deprecated: 19
|
||||||
|
To be Removed: 21
|
||||||
|
|
||||||
|
This feature automatically converted Trick specific units to the standard unit names, e.g. "M" to "m" for meters. Trick 17 allowed the user to suppress warning messages Trick was doing this conversion. Trick 19 removes the option to suppress these warning messages. Trick 21 will remove the capability.
|
||||||
|
|
||||||
|
### TRICK_CPPC environment variable to specify c++ Compiler
|
||||||
|
|
||||||
|
Deprecated: 19
|
||||||
|
To be Removed: 21
|
||||||
|
|
||||||
|
Moving this environment variable to conform to the rest of the world. In 19 if TRICK_CPPC is found in the environment a warning is emitted and the variable is used. In 21, the variable will no longer be recognized.
|
1
docs/_Footer.md
Normal file
@ -0,0 +1 @@
|
|||||||
|
[Source Code](https://github.com/nasa/trick) - [[Wiki Home|Home]] - [[Install Guide]] - [[Tutorial]] - [[Documentation|Documentation-Home]] - [[Related Projects|Related-Projects]] - [[FAQ]] - [[How-To Guides|How‐To-Guides]]
|
14
docs/_Sidebar.md
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
## Quick Jump Menu
|
||||||
|
[Wiki Home](Home)<br>
|
||||||
|
[Install Guide](Install-Guide)<br>
|
||||||
|
[Tutorial](Tutorial)<br>
|
||||||
|
[Documentation](Documentation-Home)<br>
|
||||||
|
[Related Projects](Related-Projects)<br>
|
||||||
|
[FAQ](FAQ)<br>
|
||||||
|
[How-To Guides](How‐To-Guides)<br>
|
||||||
|
|
||||||
|
## Commonly Viewed Links
|
||||||
|
[Simulation Definition File](Simulation-Definition-File)<br>
|
||||||
|
[Input File](Input-File)<br>
|
||||||
|
[Input File Quick Reference](Input-File-Quick-Reference)<br>
|
||||||
|
[Deprecated Features](Deprecated-Features)<br>
|
1
docs/_config.yml
Normal file
@ -0,0 +1 @@
|
|||||||
|
markdown: GFM
|
61
docs/documentation/Documentation-Home.md
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
| [Home](Home) → Documentation Home |
|
||||||
|
|------------------------------------|
|
||||||
|
|
||||||
|
# User Guide
|
||||||
|
The user guide contains information pertinent to Trick users. These pages will help you create Trick simulations and understand how certain aspects of Trick function.
|
||||||
|
|
||||||
|
01. [Introduction](introduction/Introduction)
|
||||||
|
|
||||||
|
01. [Trick Install Guide](install_guide/Install-Guide)
|
||||||
|
|
||||||
|
01. [Building a Simulation](building_a_simulation/Building-a-Simulation)
|
||||||
|
01. [Model Source Code](building_a_simulation/Model-Source-Code)
|
||||||
|
01. [Environment Variables](building_a_simulation/Environment-Variables)
|
||||||
|
01. [Simulation Definition File (S_define)](building_a_simulation/Simulation-Definition-File)
|
||||||
|
01. [Making the Simulation](building_a_simulation/Making-the-Simulation)
|
||||||
|
01. [Trickified Project Libraries](building_a_simulation/Trickified-Project-Libraries)
|
||||||
|
|
||||||
|
01. [Running a Simulation](running_a_simulation/Running-a-Simulation)
|
||||||
|
01. [Input File](running_a_simulation/Input-File)
|
||||||
|
01. [Runtime GUIs](running_a_simulation/runtime_guis/Runtime-GUIs)
|
||||||
|
01. [Runtime Output](running_a_simulation/Runtime-Output)
|
||||||
|
|
||||||
|
01. [Data Products (DP)](data_products/Data-Products)
|
||||||
|
01. [DP Session File Format](data_products/DP-Session-File-Format)
|
||||||
|
01. [DP Product File Format](data_products/DP-Product-File-Format)
|
||||||
|
01. [Plot Printing](data_products/Plot-Printing)
|
||||||
|
01. [Data Products GUIs](data_products/Data-Products-GUIs)
|
||||||
|
|
||||||
|
01. [Simulation Capabilities](simulation_capabilities/Simulation-Capabilities)
|
||||||
|
01. [Executive Scheduler](simulation_capabilities/Executive-Scheduler)
|
||||||
|
01. [Input Processor](simulation_capabilities/Input-Processor)
|
||||||
|
01. [Just in Time C++ Input Processor](simulation_capabilities/JIT-Input-Processor)
|
||||||
|
01. [Event Manager](simulation_capabilities/Event-Manager)
|
||||||
|
01. [Realtime](simulation_capabilities/Realtime)
|
||||||
|
01. [Realtime Clock](simulation_capabilities/Realtime-Clock)
|
||||||
|
01. [Realtime Sleep Timer](simulation_capabilities/Realtime-Timer)
|
||||||
|
01. [Realtime Injector](simulation_capabilities/Realtime-Injector)
|
||||||
|
01. [Monte Carlo](simulation_capabilities/UserGuide-Monte-Carlo)
|
||||||
|
01. [Master Slave](simulation_capabilities/Master-Slave)
|
||||||
|
01. [Data Record](simulation_capabilities/Data-Record)
|
||||||
|
01. [Checkpoints](simulation_capabilities/Checkpoints)
|
||||||
|
01. [MemoryManager](simulation_capabilities/memory_manager/MemoryManager)
|
||||||
|
01. [Integrator](simulation_capabilities/Integrator)
|
||||||
|
01. [Frame Logging](simulation_capabilities/rame-Logging)
|
||||||
|
01. [Debug Pause](simulation_capabilities/Debug-Pause)
|
||||||
|
01. [Echo Jobs](simulation_capabilities/Echo-jobs)
|
||||||
|
01. [Variable Server](simulation_capabilities/Variable-Server)
|
||||||
|
01. [Status Message System](simulation_capabilities/Status-Message-System)
|
||||||
|
01. [Command Line Arguments](simulation_capabilities/Command-Line-Arguments)
|
||||||
|
01. [Environment](simulation_capabilities/Environment)
|
||||||
|
01. [Standard Template Library Checkpointing](simulation_capabilities/STL-Checkpointing)
|
||||||
|
01. [Threads](simulation_capabilities/Threads)
|
||||||
|
|
||||||
|
01. [Simulation Utilities](simulation_utilities/Simulation-Utilities)
|
||||||
|
01. [Trickcomm](simulation_utilities/Trickcomm)
|
||||||
|
01. [Math Utilities](simulation_utilities/Math-Utilities)
|
||||||
|
|
||||||
|
01. [Miscellaneous Trick Tools](miscellaneous_trick_tools/Miscellaneous-Trick-Tools)
|
||||||
|
01. [Python Variable Server Client](miscellaneous_trick_tools/Python-Variable-Server-Client)
|
||||||
|
|
||||||
|
01. [Software Requirements Specification](software_requirements_specification/SRS)
|
@ -0,0 +1,20 @@
|
|||||||
|
The building blocks of a basic Trick simulation are C/C++ structures/classes (models), a Python input file and a Trick simulation definition file (S_define). The S_define contains simulation objects which offer a way to turn the C/C++ function/methods into simulation jobs. Trick generates the necessary Python glue code which makes the C/C++ structures/classes accessible by the Python input file. The input file configures the simulation and is a command-line argument to the simulation executable.
|
||||||
|
|
||||||
|
... to be continued ...
|
||||||
|
|
||||||
|
1. As with any simulation development task, a Trick simulation development task begins with a system design. However, with Trick, the programmer does not have to start from scratch. Trick provides a time based cyclic executive, with a limited event capability, which schedules developer defined jobs (C subroutines) for execution based upon execution cycle frequencies and a multitude of different job classifications. This step can be viewed as fitting the developer’s "pieces" into the Trick "puzzle". The design time at this level should be relatively short, since we are talking about big pieces at this step in the development.
|
||||||
|
1. The next step involves source code development. The developer must design and implement the "jobs" which comprise the end-simulation. During source code development, the developer is required to adhere to stringent job interface (calling argument) specification guidelines, as well as a few in-code documentation guidelines. Otherwise, programming style is left to the developer. Math model source code design and implementation for a specific model is by far the most time consuming procedure in the entire simulation development scenario (excluding verification and validation). This is as it should be; i.e., simulations of the past often require abhorrent labor hours, not for math model development, but for executive and input and output mechanism development.
|
||||||
|
1. Next the developer must create a simulation definition file. The simulation definition file defines the source modules (jobs) and data structures used for a particular simulation. The simulation definition file contains the following information:
|
||||||
|
* global data structures, including types, versions, source code names, and default initialization data files,
|
||||||
|
* math model jobs (source code routines), including scheduled time intervals, version, calling argument specification (job interface) , and process specifier (for multi-process sim),
|
||||||
|
* model delineation (job groupings),
|
||||||
|
* state integration jobs and time intervals,
|
||||||
|
* specialized parameter collections,
|
||||||
|
* job dependencies for distributed process simulations.
|
||||||
|
1. With a complete simulation definition file, the developer invokes the Trick simulation Configuration Processor (CP). CP reads the simulation definition file and generates all simulation specific source code for the runtime executive, and all ASCII data base files for the user interface. CP also compiles the simulation specific source code and links in the object code libraries. Trick takes care of all executive, I/O, and file management chores that have traditionally given simulation developers fits in the past.
|
||||||
|
1. The developer may now create data product specification files, if data analysis is required. These files specify logged parameters to access, and display data in either plot or table format.
|
||||||
|
1. We now move into the simulation user domain (included in the developer’s domain). At this point the simulation is ready to operate. The user must first generate an input file.
|
||||||
|
1. The user now may execute one or more simulation runs.
|
||||||
|
1. During or after simulation execution the user may use the UI to post process simulation output data in either plot or tabular format.
|
||||||
|
|
||||||
|
[Continue to Model Source Code](Model-Source-Code)
|
@ -0,0 +1,133 @@
|
|||||||
|
Trick uses a list of variables for building sims e.g. TRICK_CFLAGS and TRICK_CXXFLAGS. Each variable has a default value that may be overridden by setting the value in the environment. Trick resolves these variables by a call to a function called "trick-gte". Type in "${TRICK_HOME}/bin/trick-gte" on the command line to see what the "Trick environment" is.
|
||||||
|
|
||||||
|
### Adding ${TRICK_HOME}/bin to PATH
|
||||||
|
|
||||||
|
${TRICK_HOME}/bin can be added to the PATH environment variable for convenience. It is not necessary for compiling or running sims but allows you to call Trick's functions without using the full path of Trick's executables.
|
||||||
|
|
||||||
|
```
|
||||||
|
# bash
|
||||||
|
PATH="${PATH}:/path/to/trick"
|
||||||
|
|
||||||
|
# [t]csh
|
||||||
|
setenv PATH "${PATH}:/path/to/trick"
|
||||||
|
```
|
||||||
|
|
||||||
|
### TRICK_CFLAGS and TRICK_CXXFLAGS
|
||||||
|
|
||||||
|
The contents of TRICK_CFLAGS is included on the command line with each C file compilation. Similarly, TRICK_CXXFLAGS is included for each C++ file. Each contain header file search directories, macro define variables, and compiler flags.
|
||||||
|
|
||||||
|
For building a simulation, a user must be proficient at tweaking TRICK_CFLAGS and TRICK_CXXFLAGS. There are a several ways to do this.
|
||||||
|
|
||||||
|
TRICK_CXXFLAGS works exactly like TRICK_CFLAGS.
|
||||||
|
|
||||||
|
Example 1: Add "-I/user/mooo/trick_models" to the environment variable. TRICK_CFLAGS is currently...
|
||||||
|
|
||||||
|
```
|
||||||
|
UNIX Prompt> echo $TRICK_CFLAGS
|
||||||
|
-Wall
|
||||||
|
```
|
||||||
|
|
||||||
|
Now we need to edit the shell startup file where TRICK_CFLAGS is defined.
|
||||||
|
|
||||||
|
Add the following line for bash.
|
||||||
|
|
||||||
|
```
|
||||||
|
TRICK_CFLAGS="$TRICK_CFLAGS -I/user/mooo/trick_models"
|
||||||
|
```
|
||||||
|
|
||||||
|
Add the following line for [t]csh.
|
||||||
|
|
||||||
|
```
|
||||||
|
setenv TRICK_CFLAGS "$TRICK_CFLAGS -I/user/mooo/trick_models"
|
||||||
|
```
|
||||||
|
|
||||||
|
Now source your shell startup file and voila!...
|
||||||
|
|
||||||
|
For bash:
|
||||||
|
```
|
||||||
|
UNIX Prompt> . ~/.bash_profile
|
||||||
|
UNIX Prompt> echo $TRICK_CFLAGS
|
||||||
|
-Wall -I/user/mooo/trick_models
|
||||||
|
```
|
||||||
|
|
||||||
|
For [t]csh:
|
||||||
|
```
|
||||||
|
UNIX Prompt> source ~/.cshrc
|
||||||
|
UNIX Prompt> echo $TRICK_CFLAGS
|
||||||
|
-Wall -I/user/mooo/trick_models
|
||||||
|
```
|
||||||
|
|
||||||
|
Example 2: Add "-I/user/mooo/trick_models" through the simulation S_overrides.mk file
|
||||||
|
|
||||||
|
We need to edit the S_overrides.mk file in the simulation to be built.
|
||||||
|
|
||||||
|
Add the following line.
|
||||||
|
|
||||||
|
```
|
||||||
|
TRICK_CFLAGS="$TRICK_CFLAGS -I/user/mooo/trick_models"
|
||||||
|
```
|
||||||
|
|
||||||
|
This will not show up in the current shell environment, but will be set for each command that the makefile executes.
|
||||||
|
|
||||||
|
### TRICK_CONVERT_SWIG_FLAGS
|
||||||
|
|
||||||
|
TRICK_CONVERT_SWIG_FLAGS contains flags sent to the convert_swig utility. Currently the flags only support "-s" which allows convert_swig to process STLs.
|
||||||
|
|
||||||
|
### TRICK_SWIG_FLAGS and TRICK_SWIG_CFLAGS
|
||||||
|
|
||||||
|
TRICK_SWIG_FLAGS are the options that are passed to SWIG (see the SWIG documentation). TRICK_SWIG_CFLAGS are the the options passed to the c/c++ compiler when compiling SWIG objects.
|
||||||
|
|
||||||
|
### TRICK_EXCLUDE
|
||||||
|
|
||||||
|
A colon separated list of directories to skip when processing files.
|
||||||
|
|
||||||
|
It is possible to instruct all CP functions to skip entire directories using the environment variable TRICK_EXCLUDE. Set this variable to a colon separated list of directories which you wish CP to bypass. All header files found in TRICK_EXCLUDE will not be processed. All source code files found in TRICK_EXCLUDE will not be compiled or linked into the simulation.
|
||||||
|
|
||||||
|
This feature is useful to bring in packages as a library.
|
||||||
|
|
||||||
|
### TRICK_FORCE_32BIT
|
||||||
|
|
||||||
|
To force Trick to compile in 32-bit on 64-bit systems, set the TRICK_FORCE_32BIT environment variable to 1. Setting this variable appends "-m32" automatically to TRICK_CFLAGS and TRICK_CXXFLAGS.
|
||||||
|
4.2.6 TRICK_HOST_CPU
|
||||||
|
|
||||||
|
Trick determines a system specific suffix to append to object code directory names. By default this is determined automatically by Trick. The user may override this by setting the TRICK_HOST_CPU environment variable.
|
||||||
|
|
||||||
|
### TRICK_ICG_EXCLUDE
|
||||||
|
|
||||||
|
A colon separated list of directories to skip when processing header files.
|
||||||
|
|
||||||
|
It is possible to instruct ICG to skip entire directories using the environment variable TRICK_ICG_EXCLUDE. Set this variable to a colon separated list of directories which you wish ICG to bypass. This is useful when there is code which you do not wish Trick to have any knowledge of (i.e. you don’t need any of the parameters recorded or input processable).
|
||||||
|
|
||||||
|
### TRICK_LDFLAGS
|
||||||
|
|
||||||
|
TRICK_LDFLAGS include linker flags. TRICK_LDFLAGS is used when linking the simulation executable. It is rare to set this variable.
|
||||||
|
|
||||||
|
### TRICK_SFLAGS
|
||||||
|
|
||||||
|
TRICK_SFLAGS includes header file search directories and macro define variables. TRICK_SFLAGS is used when parsing the S_define file.
|
||||||
|
|
||||||
|
### TRICK_USER_LINK_LIBS
|
||||||
|
|
||||||
|
Additional library and library directories to include when linking a simulation.
|
||||||
|
|
||||||
|
An example of adding a library search path, a library to be searched for, and a full path library.
|
||||||
|
|
||||||
|
bash
|
||||||
|
```
|
||||||
|
export TRICK_USER_LINK_LIBS="-L/full/path/to/libs -lfile1 /another/path/to/a/libfile2.a"
|
||||||
|
```
|
||||||
|
|
||||||
|
[t]csh
|
||||||
|
```
|
||||||
|
setenv TRICK_USER_LINK_LIBS "-L/full/path/to/libs -lfile1 /another/path/to/a/libfile2.a"
|
||||||
|
```
|
||||||
|
|
||||||
|
### MAKEFLAGS
|
||||||
|
|
||||||
|
MAKEFLAGS is not a Trick environment variable. It is used with the GNU make utility. Invoking make with the -j flag allows make to compile more than one file simultaneously. Dramatic speedups in compiling can be achieved when using multiple processors.
|
||||||
|
|
||||||
|
```
|
||||||
|
UNIX Prompt> setenv MAKEFLAGS –j10
|
||||||
|
```
|
||||||
|
|
||||||
|
[Continue to Simulation Definition File](Simulation-Definition-File)
|
@ -0,0 +1,112 @@
|
|||||||
|
### Simulation Compilation Environment Variables
|
||||||
|
|
||||||
|
The -Ipaths in TRICK_CFLAGS and TRICK_CXXFLAGS tell Trick where to find model source files. The flags also can contain compiler settings, for instance the -g flag is used for compiling in debug mode. See section Trick_Environment for more detail and information on variables for linking in external libraries, setting the compiler etc.
|
||||||
|
|
||||||
|
### Making the Simulation for the First Time.
|
||||||
|
|
||||||
|
Makefiles contain all of the rules for building the simulation. When a simulation is ready to be built for the very first time, the configuration processor script (CP) is executed in the simulation directory.
|
||||||
|
|
||||||
|
```
|
||||||
|
UNIX prompt> trick-CP
|
||||||
|
```
|
||||||
|
|
||||||
|
CP creates a small makefile and calls "make" to start the simulation build process. The small makefile is the same from simulation to simulation. It can even be copied from another simulation directory, skipping the CP step entirely. Once the small makefile is created, CP does not need to be run again, compilation can be accomplished by running "make".
|
||||||
|
|
||||||
|
When make is invoked, it calls CP to process the user-created S_define file. CP finds all source code related to the simulation, builds the code using a C/C++ compiler, and puts it all together to make one executable. CP also builds code generated from user source. This is done for model documentation, Python input, unit specifications, variable descriptions etc.
|
||||||
|
|
||||||
|
After the initial CP is run, when there are changes made to model source code or the S_define file, they are recompiled using make.
|
||||||
|
|
||||||
|
```
|
||||||
|
UNIX prompt> make
|
||||||
|
```
|
||||||
|
|
||||||
|
### How Trick Finds Simulation Source Code
|
||||||
|
|
||||||
|
Trick compiles all user model source code referenced in the S_define either through file inclusion or user supplied "library dependencies". Trick begins at the S_define and recursively follows code dependencies to create the entire source tree.
|
||||||
|
|
||||||
|
Header files are double pound "##" included in the S_define. Each header file is recursively parsed to determine all lower level header files on which the top level header is dependent on. Doing this for all double pound files yields the full list of header files.
|
||||||
|
|
||||||
|
Model source files are found through LIBRARY DEPENDENCIES specified in the Trick header comment at the top of the S_define and model source files. A recursive search is made beginning at the S_define, following all model source and header files. For details, see S_define_Library_Dependencies and Library_Dependencies.
|
||||||
|
|
||||||
|
Once the entire source tree is created, rules to compile all of these files are written to the makefile.
|
||||||
|
|
||||||
|
### Changing Simulation Compilation through Makefile Overrides
|
||||||
|
|
||||||
|
Sometimes a programmer may want Trick to pick up specific compiler flags or some special makefile rule for building a model or building the simulation. Trick allows the programmer to override the default Makefile rules with a facility we are calling "makefile overrides".
|
||||||
|
|
||||||
|
For overrides in model directories, a user can create a file called `makefile_overrides`. This file allows the user to augment or override rules in the main simulation `makefile`. `makefile_overrides` applies to all files in the directory in which it is located. Additionally, special treatment is afforded to directories specifically named `src`. In such directories, if no `makefile_overrides` exists, the parent directory is searched as well, and any `makefile_overrides` found there applies to the files in `src` in addition to the parent directory. Again, searching of the parent directory only occurs for directories named `src`, and the search does not extend beyond the immediate parent directory. This special treatment of `src` is a relic of the past, and you should prefer putting `makefile_overrides` in the same directory as the source files themselves.
|
||||||
|
|
||||||
|
Additional make-like syntax is available in `makefile_overrides` to apply changes to subsets of files. `objects:` will be replaced with all object files to be created from all source files in the directory. For instance,
|
||||||
|
|
||||||
|
```make
|
||||||
|
objects: TRICK_CXXFLAGS += -Wall
|
||||||
|
```
|
||||||
|
|
||||||
|
will cause all source files in the directory to be compiled with the additional flags. You can select a subset of files by extension by prepending `objects:` with the extension to affect:
|
||||||
|
|
||||||
|
```make
|
||||||
|
cpp_objects: TRICK_CXXFLAGS += -Wextra
|
||||||
|
```
|
||||||
|
will cause only files ending in `.cpp` to receive the additional flags.
|
||||||
|
|
||||||
|
Other possibilities are: ```c_objects``` , ```f_objects``` , ```l_objects``` , ```y_objects``` , ```C_objects``` , ```cc_objects``` , ```cxx_objects``` , and
|
||||||
|
```CPLUSPLUS_objects``` .
|
||||||
|
|
||||||
|
For overrides in sim directories, there is a sim specific overrides file called `S_overrides.mk`. If this file is present in the sim directory, it is included after the directory-specific overrides. The rules in this file are the last word in how things are going to compile.
|
||||||
|
|
||||||
|
#### Example Of How To Add a Pre-compiled Library to the Simulation
|
||||||
|
|
||||||
|
Go to simulation dir.
|
||||||
|
|
||||||
|
```
|
||||||
|
UNIX Prompt> cd /user/me/trick_sims/SIM_ball_L1
|
||||||
|
```
|
||||||
|
|
||||||
|
Edit a file called "S_overrides.mk". Append to the TRICK_USER_LINK_LIBS variable.
|
||||||
|
|
||||||
|
```
|
||||||
|
TRICK_USER_LINK_LIBS = -L/path/to/library -lmy_lib
|
||||||
|
```
|
||||||
|
#### Example Of How To Exclude a Directory from ICG during CP
|
||||||
|
|
||||||
|
Go to simulation dir.
|
||||||
|
|
||||||
|
```
|
||||||
|
UNIX Prompt> cd /user/me/trick_sims/SIM_ball_L1
|
||||||
|
```
|
||||||
|
|
||||||
|
Edit a file called "S_overrides.mk". Append to the TRICK_ICG_EXCLUDE variable.
|
||||||
|
|
||||||
|
TRICK_ICG_EXCLUDE += /path/to/exclude:/another/path/to/exclude
|
||||||
|
|
||||||
|
#### Example Of How To Exclude a Directory from most CP processing
|
||||||
|
|
||||||
|
Edit a file called "S_overrides.mk". Append to the TRICK_EXCLUDE variable.
|
||||||
|
|
||||||
|
```
|
||||||
|
TRICK_EXCLUDE += /path/to/exclude:/another/path/to/exclude
|
||||||
|
```
|
||||||
|
|
||||||
|
### Cleaning Up
|
||||||
|
|
||||||
|
There are several levels of clean.
|
||||||
|
|
||||||
|
```
|
||||||
|
UNIX Prompt> make clean
|
||||||
|
```
|
||||||
|
|
||||||
|
Clean tries to remove only object files directly related to the current simulation. It will remove all of the generated files in the simulation directory. Clean also selectively removes model object files used to link this simulation.
|
||||||
|
|
||||||
|
```
|
||||||
|
UNIX Prompt> make spotless
|
||||||
|
```
|
||||||
|
|
||||||
|
Spotless is less discriminate in the files it removes. In addition to all of the files that clean removes, spotless will remove complete model object directories where any file included in the simulation was found.
|
||||||
|
|
||||||
|
```
|
||||||
|
UNIX Prompt> make apocalypse
|
||||||
|
```
|
||||||
|
|
||||||
|
Apocalypse is a special case rule when simulation libraries are used to build a simulation. See section Simulation_Libraries for more information about. In addition to all of files that spotless removes, apocalypse will run the spotless rule on any simulation directory the current simulation includes.
|
||||||
|
|
||||||
|
[Continue to Trickified Project Libraries](Trickified-Project-Libraries)
|
567
docs/documentation/building_a_simulation/Model-Source-Code.md
Normal file
@ -0,0 +1,567 @@
|
|||||||
|
This section details the syntax for creating headers and source code that Trick can process.
|
||||||
|
|
||||||
|
It also details the operation of the Trick Interface Code Generator (ICG) that processes headers, and the Module Interface Specification Processor (MIS) that processes source code.
|
||||||
|
|
||||||
|
#### Programming Language Support
|
||||||
|
|
||||||
|
The majority of model source for simulations is written in C and C++ . Trick supports auto generating IO code to peek and poke C and C++ structures, classes, and enumerations. Trick also generates the necessary makefile rules to compile and link C and C++ model code into the simulation.
|
||||||
|
|
||||||
|
Models written in other languages may be included in the simulation. It is possible to include Fortran 77, Fortran 90, Ada, and/or Java code in the simulation. These models cannot be called directly from the Trick scheduler, but may be called through C language wrapper functions provided by the user that executes the other language calls.
|
||||||
|
|
||||||
|
#### C Header Files
|
||||||
|
|
||||||
|
Trick processes header files in order to auto generate IO source code for the simulation. IO source code is the heart of how Trick does its input processing. The following describes the syntax for a header file.
|
||||||
|
|
||||||
|
```C++
|
||||||
|
/* [TRICK_HEADER]
|
||||||
|
PURPOSE:
|
||||||
|
(Purpose statement.)
|
||||||
|
[LANGUAGE: (C++)]
|
||||||
|
[LIBRARY DEPENDENCY:
|
||||||
|
(
|
||||||
|
(object.o|model.c|lib.a|lib.so|<relative_path>/lib.a)
|
||||||
|
[(object_n.o|model_n.c|lib_n.a|lib_n.so|<relative_path>/lib_n.a)]
|
||||||
|
)]
|
||||||
|
[ICG IGNORE TYPES:
|
||||||
|
((Type #1) (Type #n)])]
|
||||||
|
[PYTHON_MODULE: (module_name)]
|
||||||
|
[REFERENCES:
|
||||||
|
((Reference #1) (Reference #n)])]
|
||||||
|
[ASSUMPTIONS AND LIMITATIONS:
|
||||||
|
((Assumption #1) (Assumption #n)])]
|
||||||
|
[PROGRAMMERS:
|
||||||
|
(((Name) (Company) (Date) [(other info)])
|
||||||
|
[((Name) (Company) (Date) [(other info)])]]
|
||||||
|
[ICG: (No|Nocomment)]
|
||||||
|
|
||||||
|
Introduced in Trick 16
|
||||||
|
@trick_parse(everything|attributes|dependencies_only)
|
||||||
|
@trick_exclude_typename(Type)
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
enum_label [=enum_value],
|
||||||
|
last_enum_label [= enum_value]
|
||||||
|
} enum_name ;
|
||||||
|
|
||||||
|
[typedef] struct [struct_tag] {
|
||||||
|
char|short|int|long|long long|
|
||||||
|
unsigned char|unsigned short|unsigned int|unsigned long|unsigned long long|
|
||||||
|
float|double [*]* param_name [[dim]]* ;
|
||||||
|
/* [**|*i|*o|*io] (trick_io|io)([**|*i|*o|*io]) (trick_chkpnt_io|cio)([**|*i|*o|*io])
|
||||||
|
trick_units([measurement_units]) description */
|
||||||
|
|
||||||
|
any_other_type [*]* param_name [[dim]]* ;
|
||||||
|
/* [**|*i|*o|*io] trick_io([**|*i|*o|*io]) trick_chkpnt_io([**|*i|*o|*io])
|
||||||
|
trick_units(measurement_units) description */
|
||||||
|
} struct_name ;
|
||||||
|
|
||||||
|
class <class_name> {
|
||||||
|
[
|
||||||
|
friend InputProcessor ;
|
||||||
|
friend init_attr<class_name>() ;
|
||||||
|
]
|
||||||
|
|
||||||
|
(public|protected|private):
|
||||||
|
char|short|int|long|long long|
|
||||||
|
unsigned char|unsigned short|unsigned int|unsigned long|unsigned long long|
|
||||||
|
float|double [*]* param_name [[dim]]* ;
|
||||||
|
/* [**|*i|*o|*io] trick_io([**|*i|*o|*io]) trick_chkpnt_io([**|*i|*o|*io])
|
||||||
|
trick_units([measurement_units]) description */
|
||||||
|
|
||||||
|
any_other_type [*]* param_name [[dim]]* ;
|
||||||
|
/* [**|*i|*o|*io] trick_io([**|*i|*o|*io]) trick_chkpnt_io([**|*i|*o|*io])
|
||||||
|
trick_units([measurement_units])measurement_units description */
|
||||||
|
} ;
|
||||||
|
```
|
||||||
|
##### Comment Header
|
||||||
|
|
||||||
|
The Trick comment header, which is optional, begins with `/* PURPOSE:`. Within the Trick comment header, the `PROGRAMMERS`, `REFERENCES`, `ASSUMPTIONS AND LIMITATIONS` and `ICG` are optional entries. Since parentheses, (), are used to delineate fields within the comment header, parentheses are not allowed as characters within the comment fields. Any other formatted comments may appear before and/or after the Trick comment header.
|
||||||
|
|
||||||
|
###### C++ Language Override, `LANGUAGE: (C++)`
|
||||||
|
|
||||||
|
If a header file has a C++ extension (e.g *.hh ) Trick’s parsers will realize that it is a C++ file and handle it appropriately. If the extension is *.h, Trick will assume it is a C file (not C++). If you want to make a C++ header file name with the *.h extension, you must explicitly tell Trick it is a C++ file with the `LANGUAGE: (C++)` declaration in the Trick comment header.
|
||||||
|
|
||||||
|
###### Telling ICG to ignore this header file, `ICG: (No)`
|
||||||
|
|
||||||
|
If `ICG: (No)` is in the comment header, Trick will not to process the header. This is useful if the header contains anything that Trick cannot process, or if the programmer wishes Trick to skip this header. For skipping entire sets of headers, see next item.
|
||||||
|
|
||||||
|
If `ICG: (Nocomment)` is in the comment header, Trick will not process any comments within the file. This option is useful if the user wants ICG to process the file but the file does not have comments that are Trick compliant.
|
||||||
|
|
||||||
|
###### Library Dependencies
|
||||||
|
|
||||||
|
```
|
||||||
|
LIBRARY DEPENDENCY:
|
||||||
|
((relative_path/model_1.c)
|
||||||
|
(relative_path/model_2.cpp))
|
||||||
|
```
|
||||||
|
|
||||||
|
Library dependencies list out model source code files required by the simulation. There are several locations to add library dependencies, one of which is in model source headers. The format of dependencies in the S_define file is a relative path to the model source file. The path is relative to -I include paths found in TRICK_CFLAGS and TRICK_CXXFLAGS.
|
||||||
|
|
||||||
|
For example if the full path to our model is /this/is/a/full/path/to/model.c and in our TRICK_CFLAGS we have -I/this/is/a/full as one of the included search paths, the library dependency must complete the full path to the file, in this case path/to/model.c. Library dependencies in the S_define file differ from ones found in model source code as they must be the full path to the source file not the object file.
|
||||||
|
|
||||||
|
This is the preferred library dependency syntax. There are other forms of library dependencies that are still valid and listed below.
|
||||||
|
|
||||||
|
The LIBRARY DEPENDENCY field may contain the object code files which the current file depends on. A self-reference is not necessary.
|
||||||
|
|
||||||
|
For example, for a file this.c which calls
|
||||||
|
|
||||||
|
* a function within the file that.c
|
||||||
|
* a function in a user object library my_library/libdog.a
|
||||||
|
* a function foo.c
|
||||||
|
|
||||||
|
The `LIBRARY DEPENDENCY` field might look like this:
|
||||||
|
|
||||||
|
```
|
||||||
|
LIBRARY DEPENDENCY:
|
||||||
|
((this.o)
|
||||||
|
(that.o)
|
||||||
|
(my_library/libdog.a)
|
||||||
|
(libcow.so)
|
||||||
|
(${FOO_ENV_VAR}/foo.o))
|
||||||
|
```
|
||||||
|
|
||||||
|
For references to objects outside the current source directory, the directory paths must be specified relative to the bin_${TRICK_HOST_CPU} directory. In this example, the that.c function might also have its own library dependency list, but the that.c dependencies do not need to appear in the this.c dependency list. The CP will automatically search and sort all the object code dependencies; the developer just has to make sure all dependencies are listed in the appropriate files.
|
||||||
|
|
||||||
|
There are two ways to specify dependencies to actual libraries, i.e. lib\*.a files:
|
||||||
|
|
||||||
|
`* <relative path>="">/<libraryname>.a`
|
||||||
|
|
||||||
|
If you use a relative path to the library, Trick will search the TRICK_CFLAGS for a directory that contains source code for the library. Once Trick locates the source code, it will automatically build the library and link it in the simulation.
|
||||||
|
|
||||||
|
`* <libraryname>.a`
|
||||||
|
|
||||||
|
If you do NOT specify a relative path, Trick will NOT build the library for you. It will simply search your -L paths in your `TRICK_USER_LINK_LIBS` for the library. If found, it will link the library into the simulation.
|
||||||
|
|
||||||
|
You may also have Trick link in a shared (`lib*.so`) library. You must supply the `*.so` extension. Trick will not automatically build a shared library, but it is smart enough to use it during link time.
|
||||||
|
|
||||||
|
The LIBRARY DEPENDENCY field also handles the `#ifdef`, `#else` and `#endif` statements such that different object files and libraries may be linked for different cases. The previous example might look like this:
|
||||||
|
|
||||||
|
```
|
||||||
|
LIBRARY DEPENDENCY:
|
||||||
|
((this.o)
|
||||||
|
(that.o)
|
||||||
|
#ifdef __animals
|
||||||
|
(my_library/libdog.a)
|
||||||
|
(libcow.so)
|
||||||
|
#else
|
||||||
|
(my_library/lib.a)
|
||||||
|
#endif
|
||||||
|
(${FOO_ENV_VAR}/foo.o))
|
||||||
|
```
|
||||||
|
|
||||||
|
Best practice is to add library dependencies for source code files for prototypes listed in the header.
|
||||||
|
|
||||||
|
###### `ICG_IGNORE_TYPES`
|
||||||
|
|
||||||
|
The `ICG IGNORE TYPES` field lists the structs or classes to be ignored. Any parameters of this type or inherited from are ignored. The `ICG IGNORE TYPES` field only valid for the current file. It does not extend to included header files.
|
||||||
|
|
||||||
|
###### `PYTHON_MODULE`
|
||||||
|
|
||||||
|
Specifying a `python_module` name will place any class/struct and function definitions in this header file in a python module of the same name. All classes and functions are flattened into the python `trick` namespace by default. This capability allows users to avoid possible name collisions between names when they are flattened.
|
||||||
|
|
||||||
|
##### Compiler Directives
|
||||||
|
|
||||||
|
Trick handles all compiler directives (`#if`, `#ifdef`, `#endif`, `#define`, `#include`, etc.) ICG also uses the -D and -U command line arguments for defines and undefines, respectively.
|
||||||
|
|
||||||
|
##### trick_parse
|
||||||
|
|
||||||
|
The trick_parse directive is a Doxygen style field serving the same functionality as the `PURPOSE:` keyword and `ICG: (No)`. The trick_parse directive like all Doxygen style directives are prefixed with either a `\` or an `@` character.
|
||||||
|
|
||||||
|
`@trick_parse(everything)`: Treat this comment as the Trick header comment. Search for library dependencies in this comment, and treat all comments following variable definitions as Trick comments.
|
||||||
|
|
||||||
|
`@trick_parse(attributes)`: Treat this comment as the Trick header comment. Search for library dependencies in this comment. Create I/O attributes for the classes and structures in the file, but do not read comments following variable definitions.
|
||||||
|
|
||||||
|
`@trick_parse(dependencies_only)`: Treat this comment as the Trick header comment. Search for library dependencies in this comment. Do not process the file any further.
|
||||||
|
|
||||||
|
##### `trick_exclude_typename`
|
||||||
|
|
||||||
|
`@trick_exclude_typename(type)` is equivalent to `ICG_IGNORE_TYPES` in a Doxygen style field. The `trick_exclude` field lists the structs or classes to be ignored. Multiple `trick_exclude_typename` fields may be used to ignore multiple types.
|
||||||
|
|
||||||
|
##### Enumerated Type Definitions
|
||||||
|
|
||||||
|
Trick provides complete support for enumerated types. Simple mathematical expressions using enumerated types are supported as well.
|
||||||
|
|
||||||
|
An example follows:
|
||||||
|
|
||||||
|
a.h
|
||||||
|
|
||||||
|
```C
|
||||||
|
typedef enum {
|
||||||
|
FIRST_ENUM = 45
|
||||||
|
} A_ENUM ;
|
||||||
|
```
|
||||||
|
|
||||||
|
b.h
|
||||||
|
|
||||||
|
```C
|
||||||
|
#include "a.h"
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
ME_TOO = 2
|
||||||
|
} OTHER_ENUM;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
SECOND_ENUM = FIRST_ENUM,
|
||||||
|
THIRD_ENUM = FIRST_ENUM * 3,
|
||||||
|
FOURTH_ENUM = SECOND_ENUM * 4,
|
||||||
|
FIFTH_ENUM = ME_TOO * 6
|
||||||
|
} B_ENUM ;
|
||||||
|
```
|
||||||
|
|
||||||
|
c.h
|
||||||
|
|
||||||
|
```C
|
||||||
|
#include "b.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int dummy; /* No comment necessary */
|
||||||
|
A_ENUM ae; /* No comment necessary */
|
||||||
|
B_ENUM be; /* No comment necessary */
|
||||||
|
int ia1[FIRST_ENUM]; /* No comment necessary */
|
||||||
|
int ia2[SECOND_ENUM]; /* No comment necessary */
|
||||||
|
int ia3[FIFTH_ENUM]; /* No comment necessary */
|
||||||
|
} DATA ;
|
||||||
|
```
|
||||||
|
|
||||||
|
##### Data Structure Definitions and Parameter Declarations
|
||||||
|
|
||||||
|
The data structure type definition statements, `typedef struct { ... } name;`, and `typedef union { ... } name;` `struct Foo { } name;` follows standard C syntax, and are supported by Trick. However, Trick requires a C comment immediately following every parameter declaration.
|
||||||
|
|
||||||
|
##### Parameter Data Types
|
||||||
|
|
||||||
|
Trick allows any data type declaration within the data structure `typedef` statement. However, only the following data types will be processed by Trick:
|
||||||
|
|
||||||
|
1 `int`,
|
||||||
|
1 `short`,
|
||||||
|
1 `long`,
|
||||||
|
1 `long long`
|
||||||
|
1 `char`,
|
||||||
|
1 `(un)signed int`,
|
||||||
|
1 `(un)signed short`,
|
||||||
|
1 `(un)signed long`,
|
||||||
|
1 `(un)signed char`,
|
||||||
|
1 `(un)singed long long`,
|
||||||
|
1 `(un)signed short int`,
|
||||||
|
1 `(un)signed long int`,
|
||||||
|
1 `float`,
|
||||||
|
1 `double`,
|
||||||
|
1 `wchar_t`,
|
||||||
|
1 `FILE *`
|
||||||
|
1 Bit fields (signed and unsigned) and
|
||||||
|
1 previously processed structure, union, enumerated types and typedefs.
|
||||||
|
|
||||||
|
All other types are ignored. Types may be defined and used within the same header if the types are defined before they are used (this is a C syntax rule, too).
|
||||||
|
|
||||||
|
##### Pointers
|
||||||
|
|
||||||
|
Any combination of pointers and array dimensions up to 8 dimensions may be used for parameter declarations; for example, `double ** four_dimensional_array[2][2];`, will be processed. Void pointers and function pointers are not processed. Parameters declared with pointers (like `four_dimensional_array` example), are treated differently; these are called unconstrained arrays. Trick will generate dynamic memory allocation source code for the developer which allows the developer to size the array dimensions (represented by the pointers) via special syntax in the runstream input file. The developer may 1) use the input file to input data to the arrays, 2) output the data via standard Trick logging functions, or 3) share the data through the variable server.
|
||||||
|
|
||||||
|
The user does have the option to perform their own memory management for parameters declared as pointers. In this case, instead of specifying the allocation in the input file, the user may allocate the data in a job. In order for Trick to process the data as if it was its own managed memory (and provide capabilities like logging, checkpointing, etc.), the memory address, and number and size of the allocation must be passed to the Trick `TMM_declare_extern_var` function. The user is also responsible for freeing the memory when done.
|
||||||
|
|
||||||
|
##### Intrinsic typedef and struct Support
|
||||||
|
|
||||||
|
Types declared using `typedef struct`, `typedef union`, and `typedef enum` are recognized by Trick. Intrinsic typedefs are supported as well and may be nested in structures. The example that follows details a header that Trick will handle:
|
||||||
|
|
||||||
|
```C
|
||||||
|
typedef unsigned char my_uchar;
|
||||||
|
typedef char my_char;
|
||||||
|
typedef wchar_t my_wchar;
|
||||||
|
typedef short int my_shortint;
|
||||||
|
typedef short my_short;
|
||||||
|
typedef unsigned short int my_ushortint;
|
||||||
|
typedef unsigned short my_ushort;
|
||||||
|
typedef int my_int;
|
||||||
|
typedef unsigned int my_uint;
|
||||||
|
typedef long int my_longint;
|
||||||
|
typedef long my_long;
|
||||||
|
typedef unsigned long int my_ulongint;
|
||||||
|
typedef unsigned long my_ulong;
|
||||||
|
typedef float my_float;
|
||||||
|
typedef double my_double;
|
||||||
|
typedef my_short my_short2;
|
||||||
|
|
||||||
|
struct Animal_Sound {
|
||||||
|
int moo ; /* -- Cow */
|
||||||
|
int baa ; /* -- Lamb */
|
||||||
|
int sss ; /* -- Snake */
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
my_uchar uc ; /* -- unsigned char */
|
||||||
|
my_char c ; /* -- char */
|
||||||
|
my_char ca[80] ; /* -- char */
|
||||||
|
my_wchar wc; /* -- wchar_t */
|
||||||
|
my wchar wca[100]; /* -- wchar_t */
|
||||||
|
my_shortint si ; /* -- short int */
|
||||||
|
my_short *s ; /* -- short stuff */
|
||||||
|
my_ushortint usi ; /* -- short stuff */
|
||||||
|
my_ushort us ; /* -- short stuff */
|
||||||
|
my_int i ; /* -- count */
|
||||||
|
my_int ia[5] ; /* -- count */
|
||||||
|
my_uint ui ; /* -- count */
|
||||||
|
my_longint li ; /* -- count */
|
||||||
|
my_long l ; /* -- count */
|
||||||
|
my_ulongint uli ; /* -- count */
|
||||||
|
my_ulong ul ; /* -- count */
|
||||||
|
my_float f ; /* -- count */
|
||||||
|
my_double d ; /* -- count */
|
||||||
|
my_short2 s20; /* -- short 20 */
|
||||||
|
my_short2 s21; /* -- short 21 */
|
||||||
|
struct Animal_Sound as /* -- Wild Kingdom */
|
||||||
|
} DATA ;
|
||||||
|
|
||||||
|
typedef DATA MY_DATA;
|
||||||
|
typedef MY_DATA MY_DATA_2;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
DATA id; /* -- testing typedef of struct */
|
||||||
|
MY_DATA mid; /* -- testing typedef of struct */
|
||||||
|
MY_DATA_2 mid2; /* -- testing typedef of struct */
|
||||||
|
} DATA_2 ;
|
||||||
|
```
|
||||||
|
|
||||||
|
##### Parameter Comments
|
||||||
|
|
||||||
|
Each parameter declaration within a data structure definition may be accompanied by a trailing comment. There are six possible fields in the parameter comment, but only two are required. All six fields of the parameter comment are stored for later reuse at simulation runtime.
|
||||||
|
|
||||||
|
###### The Input/Output Specification
|
||||||
|
|
||||||
|
The first three fields in the parameter comment are optional and specify the input/output processing for the parameter. I/O permissions may be set globally or individual capabilities may set their permissions separately. I/O permissions for checkpointing is available to set separately.
|
||||||
|
|
||||||
|
To set all permissions for general variable access start the comment with one of the following fields, `[**|*i|*o|*io]`. `trick_io([**|*i|*o|*io])` or `io([**|*i|*o|*io])` are equivalent forms to set general variable access.
|
||||||
|
|
||||||
|
* `**` indicates that Trick will not allow input or output for this parameter; i.e. the user can not input this parameter,record this parameter, or view its value.
|
||||||
|
* `*i` indicates that only input is allowed for the parameter. Parameter may be input through the checkpoint file or ref_assignment, but the parameter will not be recordable or written to a checkpoint file.
|
||||||
|
* `*o` indicates only output is allowed for the parameter. Parameter may be checkpointed or logged only. They are not reloaded during a checkpoint reload.
|
||||||
|
* `*io` specifies that both input and output are allowed for the parameter. This is the default condition if the field is omitted from the comment. Parameter may be in input file, may be checkpointed and logged.
|
||||||
|
|
||||||
|
Checkpoint I/O may be set separately by adding `trick_chkpnt_io([**|*i|*o|*io])` or `cio([**|*i|*o|*io])` to the comment. If this optional field is not present the general I/O access field is used to determine checkpoint permissions.
|
||||||
|
|
||||||
|
* `**` indicates that Trick will not allow checkpoint input or output. General variable access may still be available.
|
||||||
|
* `*i` indicates only checkpoint input is allowed for the parameter. Parameters will not be written to the checkpoint.
|
||||||
|
* `*o` indicates only checkpoint output is allowed for the parameter. Parameter is written to the checkpoint, but not reloaded.
|
||||||
|
* `*io` specifies that both input and output are allowed for the checkpointing.
|
||||||
|
|
||||||
|
###### The Measurement Units Specification
|
||||||
|
The second field, `trick_units([measurement_units])`, is a required field and specifies the internal source code units for the parameter. These units are important because they give the input processor the knowledge of what units the user's input data needs to be converted to. Trick uses a third-party package, UDUNITS, for units support. It's syntax is specified [here](https://www.unidata.ucar.edu/software/udunits/udunits-current/doc/udunits/udunits2lib.html#Syntax).
|
||||||
|
|
||||||
|
###### User Defined Attributes Fields
|
||||||
|
|
||||||
|
Following the measurement units specification, in the parameter comment, are two optional, user-defined attribute fields. Using these fields, a user can associate (up to 2) character strings with a parameter. These strings are stored in the ATTRIBUTES structures (in the io_src directory) generated by ICG. The first of these optional fields is delimited by brackets (‘[‘ and ‘]’) and is stored in the element ATTRIBUTES->alias. The second is delimited by braces (‘{‘ and ‘}’) and is stored in the element ATTRIBUTES->user_defined. The definition of the ATTRIBUTES structure is found in $TRICK_HOME/trick_source/sim_services/include/attributes.h.
|
||||||
|
|
||||||
|
###### Description Fields
|
||||||
|
|
||||||
|
The description field is required and must be the last field of the comment. The description field is basically everything after the first three fields. The description field may span multiple lines.
|
||||||
|
|
||||||
|
##### C++ Header Files
|
||||||
|
|
||||||
|
C++ headers may include constructs and concepts not found in C header files. In addition to all C syntax, Trick parses and understands many C++ features.
|
||||||
|
|
||||||
|
##### Public, Protected, and Private Access
|
||||||
|
|
||||||
|
Trick generates several files to support its various features. The data recorder and checkpointer rely on code produced by the Interface Code Generator (ICG), which bookkeeps the memory layout of variables within the simulation. `public` members are always available to these features. `protected` and `private` data is also available if there is no use of `TRICK_ICG` in the header file. If use is found, Trick will issue a warning during simulation compilation, and `private` and `protected` data will only be accessible to Trick if the following `friend`s are added to the offending classes:
|
||||||
|
|
||||||
|
```C++
|
||||||
|
friend class InputProcessor ;
|
||||||
|
friend void init_attr<class_name>() ;
|
||||||
|
```
|
||||||
|
|
||||||
|
The input processor and variable server rely on code produced by a third-party tool, the [Simplified Wrapper and Interface Generator (SWIG)](http://www.swig.org/). SWIG provides the functions that allow access to simulation variables from Python contexts. These features can only access `public` members. It is not possible to expose `protected` and `private` data to them.
|
||||||
|
|
||||||
|
##### Inheritance
|
||||||
|
|
||||||
|
Trick may use model code with any type of inheritance. Some limitations are present to Trick's ability to input process, checkpoint, etc. inherited variables.
|
||||||
|
|
||||||
|
* Public and protected inherited variables are available for access.
|
||||||
|
* Protected and private inheritance is ignored.
|
||||||
|
* Multiple inheritance is processed but not well tested.
|
||||||
|
* Template inheritance is not currently supported.
|
||||||
|
|
||||||
|
##### Namespaces
|
||||||
|
|
||||||
|
Currently one level of namespace is supported. Additional levels of namespaces are ignored. Similarly classes and enumerations embedded in other classes are ignored.
|
||||||
|
|
||||||
|
```C++
|
||||||
|
namespace my_ns {
|
||||||
|
// BB is processed
|
||||||
|
class BB {
|
||||||
|
public:
|
||||||
|
std::string str ;
|
||||||
|
// Class CC is ignored.
|
||||||
|
class CC {
|
||||||
|
...
|
||||||
|
}
|
||||||
|
} ;
|
||||||
|
// Everything enclosed in inner_ns is ignored.
|
||||||
|
namespace inner_ns {
|
||||||
|
...
|
||||||
|
} ;
|
||||||
|
} ;
|
||||||
|
```
|
||||||
|
|
||||||
|
##### Function Overloading
|
||||||
|
|
||||||
|
Trick parses function declarations for input file use. The python input processor understands class method overloading. Overloaded methods with different arguments may be called in the input files. Default arguments are to methods are understood and honored in the input file. Operator overloading is skipped by Trick processors. Operator overloading is not implemented in the input file.
|
||||||
|
|
||||||
|
##### Templates and the Standard Template Libraries (STL)
|
||||||
|
|
||||||
|
Trick attempts to process user defined templates. Simple templates are handled. We do not have a good definition of simple. Typedefs of templates is supported and encouraged. All protected and private data is ignored within templates. This is because it is not possible to specify the correct io_src friend function. Templates within templates are not processed. Finally abstract templates are not supported by Trick. These templates should be excluded from Trick processing. See below to see how to exclude code from processing.
|
||||||
|
|
||||||
|
STLs may be used in models. However, STL variables are not data recordable, they are not visible in the variable server, nor are they directly accessible in the input file. STL variables may be checkpointed with user help. Trick provides function templates to checkpoint and restore STLs. The user needs to call 3 functions, a checkpoint, post_checkpoint, and restart class jobs.
|
||||||
|
|
||||||
|
```C++
|
||||||
|
// A class with STLs to be checkpointed. 3 methods are defined to help Trick checkpoint the STLs
|
||||||
|
class STLCheckpoint {
|
||||||
|
public:
|
||||||
|
std::map< int , double > my_double_map ;
|
||||||
|
std::vector < double > my_double_vec ;
|
||||||
|
int checkpoint(string object_name);
|
||||||
|
int post_checkpoint(string object_name);
|
||||||
|
int restart(string object_name);
|
||||||
|
} ;
|
||||||
|
// The checkpoint job converts STLs to array data.
|
||||||
|
int STLCheckpoint::checkpoint(string object_name) {
|
||||||
|
/* checkpoint_stl is a templated function that takes an STL,
|
||||||
|
a sim_object name, and a variable name (usually the same
|
||||||
|
as the STL name) as arguments. It outputs memory_manager
|
||||||
|
arrays named object_name.<variable_name> that contain the
|
||||||
|
data in the STLs.
|
||||||
|
*/
|
||||||
|
checkpoint_stl(my_double_map, object_name , “my_double_map”) ;
|
||||||
|
checkpoint_stl(my_double_vec , object_name ,“my_double_vec”) ;
|
||||||
|
}
|
||||||
|
// The post_checkpoint job frees memory allocated in checkpoint job
|
||||||
|
int STLCheckpoint::post_checkpoint(string object_name) {
|
||||||
|
//delete_stl takes the same arguments as checkpoint_stl
|
||||||
|
checkpoint_stl(my_double_map, object_name , “my_double_map”) ;
|
||||||
|
checkpoint_stl(my_double_vec , object_name ,“my_double_vec”) ;
|
||||||
|
}
|
||||||
|
// The restart job restores STLs from a checkpoint file.
|
||||||
|
int STLCheckpoint::restart(string object_name) {
|
||||||
|
//restore_stl takes the same arguments as checkpoint_stl
|
||||||
|
restore_stl(my_double_map, object_name , “my_double_map”) ;
|
||||||
|
resotre_stl(my_double_vec , object_name ,“my_double_vec”) ;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Calls to checkpoint the STLs in the S_define.
|
||||||
|
|
||||||
|
```C++
|
||||||
|
class theSimObject : public Trick::SimObject {
|
||||||
|
public:
|
||||||
|
STLCheckpoint stls ;
|
||||||
|
theSimObject() {
|
||||||
|
/*
|
||||||
|
"name" is the string that is the sim_object
|
||||||
|
instance name. It is present in all sim objects
|
||||||
|
and automatically set by Trick.
|
||||||
|
*/
|
||||||
|
("checkpoint") stls.checkpoint(name) ;
|
||||||
|
("post_checkpoint") stls.post_checkpoint(name) ;
|
||||||
|
("restart") stls.restart(name) ;
|
||||||
|
} ;
|
||||||
|
```
|
||||||
|
|
||||||
|
##### Noncopyable Objects
|
||||||
|
|
||||||
|
Sometimes classes contain members that are not copyable or the math modeler wants to prevent the class from being copied. Declaring an unimplemented private copy constructor and assignment, "=", operator prevents the class from being copied.
|
||||||
|
```C++
|
||||||
|
class CantCopyMe {
|
||||||
|
private:
|
||||||
|
CantCopyMe( const CantCopyMe & ) ;
|
||||||
|
CantCopyMe & operator = ( const CantCopyMe ) ;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
When using such classes in Trick, classes that include non copyable classes must also declare themselves not copyable. this extends all the way up to sim objects in the S_define.
|
||||||
|
|
||||||
|
```C++
|
||||||
|
class MysimObject : public Trick::SimObject {
|
||||||
|
public:
|
||||||
|
CantCopyMe ccm ;
|
||||||
|
private:
|
||||||
|
MysimObject( const MysimObject & ) ;
|
||||||
|
MysimObject& operator = ( const MysimObject) ;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
##### Source Code in Header Files
|
||||||
|
|
||||||
|
Trick attempts to skip over class code in header files while searching for class variables and method declarations. However, code can sometimes confuse Trick and cause it to abort processing of header files. It is recommended to keep code out of the header file..
|
||||||
|
|
||||||
|
##### Library Dependencies
|
||||||
|
|
||||||
|
It is good practice to list all the source code files that define class methods in the class header file.
|
||||||
|
|
||||||
|
##### Excluding Header File Code
|
||||||
|
|
||||||
|
There are several ways to exclude code from processing.
|
||||||
|
|
||||||
|
Excluding Directories
|
||||||
|
|
||||||
|
Add paths to exclude to the TRICK_ICG_EXCLUDE environment variable or makefile variable. This works for both C and C++ headers.
|
||||||
|
|
||||||
|
###### Excluding File
|
||||||
|
|
||||||
|
Add `ICG: (No)` to the Trick comment header.
|
||||||
|
|
||||||
|
###### Excluding Lines
|
||||||
|
|
||||||
|
When processing header files Trick defines 2 #define variables, TRICK_ICG and SWIG. Code may be excluded by enclosing it in #ifndef blocks.
|
||||||
|
```C++
|
||||||
|
#ifndef TRICK_ICG
|
||||||
|
code that cannot be processed by ICG
|
||||||
|
#ifndef SWIG
|
||||||
|
code that cannot be processed by ICG or SWIG
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
```
|
||||||
|
|
||||||
|
##### Source Files
|
||||||
|
|
||||||
|
By source files, in this context, we mean functional model source code, i.e. *.c files.
|
||||||
|
|
||||||
|
```C
|
||||||
|
/* [TRICK_HEADER]
|
||||||
|
PURPOSE:
|
||||||
|
(Purpose statement.)
|
||||||
|
[REFERENCES:
|
||||||
|
((Reference #1) (Reference #n)])]
|
||||||
|
[ASSUMPTIONS AND LIMITATIONS:
|
||||||
|
((Assumption #1) (Assumption #n)])]
|
||||||
|
[LIBRARY DEPENDENCY:
|
||||||
|
(
|
||||||
|
(object.o|lib.a|lib.so|<relative_path>/lib.a)
|
||||||
|
[(object_n.o|lib_n.a|lib_n.so|<relative_path>/lib_n.a)]
|
||||||
|
)]
|
||||||
|
[PROGRAMMERS:
|
||||||
|
(((Name) (Company) (Date) [(other info)])
|
||||||
|
[((Name) (Company) (Date) [(other info)])]]
|
||||||
|
*/
|
||||||
|
|
||||||
|
// source code...
|
||||||
|
```
|
||||||
|
|
||||||
|
##### Comment Header
|
||||||
|
|
||||||
|
The Trick header is an optional comment block at the top of each source file. It is used for auto-documentation, and more importantly is the means of specifying dependencies to objects or libraries not processed by Trick. Separate functions within a source file do NOT require additional headers. Since parentheses, ( ), are used to delineate fields within the comment header, parentheses are not allowed as characters within the comment fields. NOTE: Even if you are coding a C++ file, you must still specify the comment header using C style comments (not C++ style comments).
|
||||||
|
|
||||||
|
###### Job Description
|
||||||
|
|
||||||
|
* The PURPOSE field should be a brief description of what the module does.
|
||||||
|
* The REFERENCES field may contain any number of references, with each reference possessing any number of sub items; notice the nested parentheses for the REFERENCES field.
|
||||||
|
* The ASSUMPTIONS AND LIMITATIONS field may contain any number of assumptions and limitations delimited by parentheses.
|
||||||
|
* The LIBRARY DEPENDENCIES. See Library_Dependencies section in the model header section
|
||||||
|
* The PROGRAMMERS field may contain any number of programmer fields, each of which may contain any number of sub items; e.g. programmer name, company, mod date, etc. The programmer fields are meant to provide an in-code means to track code changes.
|
||||||
|
|
||||||
|
##### Source Code
|
||||||
|
|
||||||
|
Trick is only interested in the header comment if one is present in source code files. Anything goes for the rest of the source code file.
|
||||||
|
|
||||||
|
##### Trick Version Compatibility
|
||||||
|
|
||||||
|
Trick is always changing. The interface to Trick functions may change with each major version. Sometimes even minor version upgrades changes the interface. When Trick builds model source code it includes -DTRICK_VER=<version> and -DTRICK_MINOR=<minor_version> to the TRICK_CFLAGS and TRICK_CXXFLAGS. This allows developers to key off the Trick version in model source code. If there are any compile issues dependent on Trick version, this #define may be useful.
|
||||||
|
|
||||||
|
[Continue to Environment Variables](Environment-Variables)
|
@ -0,0 +1,783 @@
|
|||||||
|
The Simulation Definition File or S_define is the file which lays out the architecture
|
||||||
|
of the simulation. Details about job frequencies, job class, job data, importing/exporting
|
||||||
|
data to other simulations, freeze cycles, integration, etc. are all housed in this one file.
|
||||||
|
It is the file which Trick's main processor, CP, parses to determine what will be part of
|
||||||
|
the simulation and how the pieces fit together.
|
||||||
|
|
||||||
|
This section begins with the syntax for the S_define, then details each and every entry
|
||||||
|
in the syntax template. This section also details how to use Trick's main processor, CP.
|
||||||
|
|
||||||
|
```
|
||||||
|
[/* [TRICK_HEADER]
|
||||||
|
|
||||||
|
PURPOSE: (purpose statement)
|
||||||
|
[LIBRARY DEPENDENCIES:
|
||||||
|
(
|
||||||
|
[(<rel_path_of_model>/<model_source_code_n.c>)]
|
||||||
|
)
|
||||||
|
]
|
||||||
|
|
||||||
|
[DEFAULT_DATA:
|
||||||
|
(
|
||||||
|
[(struct_type instance_name <rel_path_of_model>/<default_data_file>)]
|
||||||
|
)
|
||||||
|
]
|
||||||
|
*/]
|
||||||
|
|
||||||
|
#include "sim_objects/default_trick_sys.sm"
|
||||||
|
|
||||||
|
##include "<rel_path_of_model>/<model_header_file.h>"
|
||||||
|
|
||||||
|
%header{
|
||||||
|
/* User header code block */
|
||||||
|
%}
|
||||||
|
|
||||||
|
%{
|
||||||
|
/* User code block */
|
||||||
|
%}
|
||||||
|
|
||||||
|
class <sim_object_type_name> : public Trick::SimObject {
|
||||||
|
|
||||||
|
[(public|protected|private):]
|
||||||
|
|
||||||
|
<CLASS_TYPE|STRUCTURE_TYPE|ENUMERATED_TYPE|intrinsic_type> [*]* <data_varaible_name> [dims]*
|
||||||
|
|
||||||
|
<sim_object_type_name>([args]) {
|
||||||
|
[C<#>] [{job_tag}] [P<#>] ([<cycle_time>, [<start_time>, [<stop_time>,]]] <job_class>) \
|
||||||
|
[<return_var> =] <module>([args]) ;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[<method_name>([args]) { ... } ;]
|
||||||
|
} ;
|
||||||
|
|
||||||
|
[job_class_order {
|
||||||
|
<job_class_1>,
|
||||||
|
<job_class_2>,
|
||||||
|
...
|
||||||
|
} ;]
|
||||||
|
|
||||||
|
[<sim_object_type_name> <sim_object_instantiation>[(args)] ;]
|
||||||
|
|
||||||
|
[integrate <integrator_name> (<integration_dt>) <sim_object_name> [,<sim_object_name] ;]
|
||||||
|
|
||||||
|
[collect <reference> = {[<reference> [,<reference>]]};]
|
||||||
|
|
||||||
|
[void create_connections() { <glue_code> }]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Trick Header Comment
|
||||||
|
|
||||||
|
This optional section of the S_define file is a C style comment found anywhere in the S_define file.
|
||||||
|
CP will parse the Trick Header comment looking for library dependencies and default data. Library
|
||||||
|
dependencies are model source code files that are added to the list of files to be compiled and
|
||||||
|
linked into the simulation. These dependencies differ from the ones found in the actual model source
|
||||||
|
code in that they are the full relative path to the actual source code file, not the resulting object file.
|
||||||
|
CP also looks for old style default data files. Each default data entry has 3 fields, the structure type, the
|
||||||
|
instance name, and the relative path to the default data file. CP will read in the default data file
|
||||||
|
substituting each occurrence of the structure type in the file with the instance name. All of the default
|
||||||
|
data files are concatenated to the S_default.dat file.
|
||||||
|
|
||||||
|
#### S_define Library Dependencies
|
||||||
|
```
|
||||||
|
LIBRARY DEPENDENCY:
|
||||||
|
((relative_path/model_1.c)
|
||||||
|
(relative_path/model_2.cpp))
|
||||||
|
```
|
||||||
|
|
||||||
|
Library dependencies list out model source code files required by the simulation. There are several
|
||||||
|
locations to add library dependencies, one of which is in the S_define file. The format of
|
||||||
|
dependencies in the S_define file is a relative path to the model source file. The path is relative
|
||||||
|
to -I include paths found in TRICK_CFLAGS and TRICK_CXXFLAGS.
|
||||||
|
|
||||||
|
For example if the full path to our model is /this/is/a/full/path/to/model.c and in our TRICK_CFLAGS
|
||||||
|
we have -I/this/is/a/full as one of the included search paths, the library dependency must complete the
|
||||||
|
full path to the file, in this case path/to/model.c. Library dependendencies in the S_define file
|
||||||
|
differ from ones found in model source code as they must be the full path to the source file not the
|
||||||
|
object file.
|
||||||
|
|
||||||
|
### Include files
|
||||||
|
|
||||||
|
There are two types of includes in the S_define file.
|
||||||
|
|
||||||
|
#### Single pound "#" includes.
|
||||||
|
|
||||||
|
Include files with a single pound "#" are parsed as they are part of the S_define file. They are
|
||||||
|
treated just as #include files in C or C++ files. These files usually include other sim objects or
|
||||||
|
instantiations as part of the S_define file.
|
||||||
|
|
||||||
|
#### Double pound "#" includes.
|
||||||
|
|
||||||
|
Include files with a double pound "##" are not parsed as part of the S_define file. These files are the
|
||||||
|
model header files. They include the model class and structure definitions as well as C prototypes for
|
||||||
|
functions used in the S_define file. Double pound files are copied, minus one pound, to S_source.hh.
|
||||||
|
|
||||||
|
### User Header Code Block
|
||||||
|
|
||||||
|
This section of the S_define (encapsulated by "%header{...%}") can be used for including header files
|
||||||
|
directly into the S_source.hh. Header files listed here will not be input processed.
|
||||||
|
|
||||||
|
### User Code Block
|
||||||
|
|
||||||
|
This section of the S_define (encapsulated by %{.....%}) can be used for any user specific
|
||||||
|
global C code. CP will simply insert this section of code into the S_source.c file after
|
||||||
|
all header files are included. Typically this feature is used as a quick method for customizing
|
||||||
|
simulations with additions of global variables and functions.
|
||||||
|
|
||||||
|
### Simulation Object Definition
|
||||||
|
|
||||||
|
A simulation definition file may contain any number of simulation object definitions.
|
||||||
|
A simulation object definition is of the form: class <sim_object_name> : public Trick::SimObject { ... }.
|
||||||
|
All sim objects must inherit from the Trick::SimObject or a derivative. A sim object definition
|
||||||
|
may contain zero or more data structure declarations and zero or more module declarations.
|
||||||
|
|
||||||
|
### Model Classes and Data Structures
|
||||||
|
|
||||||
|
Model classes and data structures are declared within a sim object. Model classes and data structures
|
||||||
|
may be public, protected, or private within the sim object. Standard C++ privacy rules apply to
|
||||||
|
all data with the sim object. Sim object protected and private data will not be accessible to the input
|
||||||
|
processor.
|
||||||
|
|
||||||
|
Intrinsic types are allowed as sim object data members.
|
||||||
|
|
||||||
|
### Job Declarations
|
||||||
|
|
||||||
|
Jobs are the hands and feet of the simulation. They are the building blocks for the
|
||||||
|
simulation. Jobs are C or C++ routines with special Trick tags that determine scheduling,
|
||||||
|
object dependencies, etc.
|
||||||
|
|
||||||
|
Jobs only appear in the constructor of the sim object.
|
||||||
|
|
||||||
|
```
|
||||||
|
[C<#>] [{job_tag}] [P<#>] ([<cycle_time>, [<start_time>, [<stop_time>,]]] <job_class>) <module>([args]) ;
|
||||||
|
```
|
||||||
|
|
||||||
|
Most of these fields are optional depending on how the module is classified or utilized
|
||||||
|
within the sim. The following subsections detail the usage and purpose of each of these fields.
|
||||||
|
|
||||||
|
#### Child Thread Specification
|
||||||
|
|
||||||
|
The first field of a module declaration is an optional child process specification in
|
||||||
|
the form of a capital C immediately followed by an integer child ID number; i.e. C1, C2, C3,
|
||||||
|
etc. The child process specification allows parallel processing for simulation modules.
|
||||||
|
|
||||||
|
Every simulation has a parent process. A child specification will result in the spawning of
|
||||||
|
a thread for each distinct child ID specified. More than one job can be specified for each child ID.
|
||||||
|
Jobs with child specifications will run in parallel with other jobs within each software frame,
|
||||||
|
so users may be required to specify job dependencies (see Section 4.4.10) to keep parallel jobs
|
||||||
|
from stepping on each other's common data access. The collection of the parent process and all
|
||||||
|
of its children defined in one S_define file is referred to as a Process Group (PG). A simulation
|
||||||
|
can be composed of multiple synchronized or non-synchronized PGs which will be discussed in more
|
||||||
|
detail in Section 4.4.12. and Section 7.2.
|
||||||
|
|
||||||
|
In most cases, for maximum execution performance, jobs should only be specified to run on a child
|
||||||
|
process if the host workstation has more than one CPU; and preferably, one CPU per child specified.
|
||||||
|
With the same rule in mind, using more than one PG in the simulation design should only occur when
|
||||||
|
the simulation has parallel components and multiple process/multiple computers are available. When
|
||||||
|
the host workstation has only one CPU, a simulation with a job running on a child will be much slower
|
||||||
|
than the same simulation with no children. There are exceptions to this rule, like running asynchronous
|
||||||
|
background modules on a child that only runs the child during the wait cycle of a simulation set up for
|
||||||
|
real-time operations.
|
||||||
|
|
||||||
|
Child IDs start at 1 and may skip any integer values. The Trick Executive will spawn enough threads
|
||||||
|
to accomodate the highest Child ID specified in the S_define file. Jobs without a child specification
|
||||||
|
will be executed by the parent process. Jobs with a C1 child specification will be executed by the
|
||||||
|
first child thread; jobs with a C2 specification will be executed by the second child thread; and so on.
|
||||||
|
|
||||||
|
Child Threads have three different scheduling choices. See Section XYZ for child thread scheduling
|
||||||
|
details.
|
||||||
|
|
||||||
|
#### Job Tagging
|
||||||
|
|
||||||
|
This optional field allows you to tag a job or set of jobs. The tag is surrounded in curly
|
||||||
|
braces. In the input file, you may then operate on the tag. All jobs with the same tag will be
|
||||||
|
modified in the same manner. For example, if jobA and jobB are tagged BLUE, the input file may
|
||||||
|
have a statement:
|
||||||
|
|
||||||
|
```python
|
||||||
|
trick.add_read(13.0, """trick.exec_set_job_cycle("BLUE" , 0.001)""")
|
||||||
|
```
|
||||||
|
|
||||||
|
This will change the frequency of the jobs to 1 millisecond. You might also disable the jobs
|
||||||
|
tagged BLUE with the following:
|
||||||
|
|
||||||
|
```python
|
||||||
|
trick.add_read(10.0, """trick.exec_set_job_onoff("BLUE" , False)""")
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Job Phasing
|
||||||
|
|
||||||
|
The next field of a job declaration is an optional phase number specification in the form of a
|
||||||
|
capital P immediately followed by an integer phase ID number from 1 to 65534, e.g., P1, P2, P3, etc.
|
||||||
|
Without a specified phase field, the default phase number is 60000. The phase specification may be
|
||||||
|
used on all class jobs to sequence the execution of jobs in the same class. Jobs tagged with P1
|
||||||
|
execute first, then P2, etc. Jobs with the same phase number are executed in the order they are
|
||||||
|
in the S_define.
|
||||||
|
|
||||||
|
#### Execution Schedule Time Specification
|
||||||
|
|
||||||
|
The execution schedule specification specifies the job's execution cycle time, start time, and
|
||||||
|
stop time. The time specs must be a comma separated list of floating point numbers enclosed by
|
||||||
|
parentheses, e.g. (1.0,0.5,10.0) would execute a module starting at 0.5 seconds, and every 1.0
|
||||||
|
seconds thereafter until 10.0 seconds was reached (9.5 seconds would be the time of the last
|
||||||
|
job call). The start and stop fields are optional; e.g. (1.0,0.5) does the same as the previous
|
||||||
|
example except the module will keep being called after 10.0 seconds. Also, a (1.0) specification
|
||||||
|
will start the job at 0.0 (the default) and continue calling the job at 1.0 second intervals.
|
||||||
|
|
||||||
|
Only the jobs categorized as CYCLIC or also
|
||||||
|
the freeze_scheduled job class (see Table SD_1 below) require the execution time specification.
|
||||||
|
All schedule time specifications are in seconds.
|
||||||
|
|
||||||
|
All other job classes categorized in Table SD_1 should NOT specify an execution time specification:
|
||||||
|
- NON-CYCLIC (red color) of course do not require a spec because they run only once.
|
||||||
|
- FRAME-BOUNDARY (blue color) are tied to each execution frame and not a cycle time.
|
||||||
|
- INTEGRATOR (cyan color) are specified via the state integration specifications for the simulation (see Section 4.4.7).ME-BOUNDARY (blue color) are tied to each execution frame and not a cycle time.
|
||||||
|
- INTEGRATOR (cyan color) are specified via the state integration specifications for the simulation (see Section 4.4.7).
|
||||||
|
- SELF-SCHEDULING (yellow color) are responsible for scheduling themselves.
|
||||||
|
- FREEZE (purple color) are tied to the freeze frame (EXCEPT for freeze_scheduled class jobs which DO need the spec.)
|
||||||
|
- CHECKPOINT (orange color) are tied to checkpointing and run only once.
|
||||||
|
|
||||||
|
##### Job Class
|
||||||
|
The job class determines where in the simulation a job is run. Each job in the S_define file
|
||||||
|
requires a job class.
|
||||||
|
|
||||||
|
<center>
|
||||||
|
<b>KEY: Job Class Category Colors used in Table SD_1</b>
|
||||||
|
<table>
|
||||||
|
<tr bgcolor="#c0c0c0"><th>Category Color</th><th>The job classes in Table SD_1 are categorized as one of the following:</th></tr>
|
||||||
|
<tr><td bgcolor="#ff8080">NON-CYCLIC</td><td>jobs that run once either at simulation startup or termination</td></tr>
|
||||||
|
<tr><td bgcolor="#add8e6">FRAME-BOUNDARY</td><td>jobs that run cyclically before/after the scheduled job loop</td></tr>
|
||||||
|
<tr><td bgcolor="#ccffff">INTEGRATOR</td><td>jobs that run first in the scheduled job loop for Trick state integration</td></tr>
|
||||||
|
<tr><td bgcolor="#ffff99">SELF-SCHEDULING</td><td>jobs in the scheduled job loop that must schedule themselves when to run</td></tr>
|
||||||
|
<tr><td bgcolor="#ccffcc">CYCLIC</td><td>jobs in the scheduled job loop that run cyclically according to their specified cycle time</td></tr>
|
||||||
|
<tr><td bgcolor="#e6ceff">FREEZE</td><td>jobs that are run during the freeze execution mode</td></tr>
|
||||||
|
<tr><td bgcolor="#ffc285">CHECKPOINT</td><td>jobs that are run when a checkpoint is dumpded or loaded</td></tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<b>Table SD_1 Trick-Provided Job Classes</b>
|
||||||
|
<table>
|
||||||
|
<tr bgcolor="#c0c0c0"><th>Job Class Name</th><th>Description</th></tr>
|
||||||
|
<tr><td bgcolor="#ff8080">default_data</td><td>Module executes only once at simulation time = zero.
|
||||||
|
Called before input file is read.</td></tr>
|
||||||
|
<tr><td bgcolor="#ff8080">initialization</td><td>Module executes only once at simulation time = zero.
|
||||||
|
Called after input file is read.</td></tr>
|
||||||
|
<tr bgcolor="add8e6"><td colspan="2" align="center">BEGIN EXECUTION FRAME</td></tr>
|
||||||
|
<tr><td bgcolor="add8e6">top_of_frame</td><td>Module runs at the beginning of every execution frame, before the scheduled job loop,
|
||||||
|
even before any child threads are started for the frame.</td></tr>
|
||||||
|
<tr bgcolor="ccffcc"><td colspan="2" align="center">BEGIN SCHEDULED JOB LOOP</td></tr>
|
||||||
|
<tr><td bgcolor="#ccffff">pre_integration</td><td>Runs only once before the integration loop.
|
||||||
|
For example, in the case of a Runge Kutta 4, the derivative and integration jobs will be called
|
||||||
|
four times during the integration steps. A pre_integration job will execute a
|
||||||
|
single time before this four step integration process has occurred.</td></tr>
|
||||||
|
<tr bgcolor="ccffff"><td colspan="2" align="center">BEGIN INTEGRATION LOOP</td></tr>
|
||||||
|
<tr><td bgcolor="#ccffff">derivative</td><td>Equations of motion (EOM) derivative function.</td></tr>
|
||||||
|
<tr><td bgcolor="#ccffff">integration</td><td>Equations of motion state integration function.</td></tr>
|
||||||
|
<tr bgcolor="ccffff"><td colspan="2" align="center">END INTEGRATION LOOP</td></tr>
|
||||||
|
<tr><td bgcolor="#ccffff">post_integration</td><td>Runs only once after the integration loop.</td></tr>
|
||||||
|
<tr><td bgcolor="#ccffff">dynamic_event</td><td>Runs after the integration loop
|
||||||
|
(after any post_integration jobs). Provides a continuous time dependent equation whose root
|
||||||
|
defines a discontinuous event in the system EOM, evaluation of function returns an
|
||||||
|
estimated delta time to reach the root.</td></tr>
|
||||||
|
<tr><td bgcolor="ffff99">automatic</td><td>Module which reschedules its own next call time, and will run before other CYCLIC jobs in the frame.</td></tr>
|
||||||
|
<tr><td bgcolor="#ccffcc">environment</td><td>Time dependent boundary conditions (mother nature).</td></tr>
|
||||||
|
<tr><td bgcolor="#ccffcc">sensor</td><td> Simulated interface between dynamics and control simulation components.</td></tr>
|
||||||
|
<tr><td bgcolor="#ccffcc">sensor_emitter</td><td>Same as sensor, but for the emitter portion of an integrated
|
||||||
|
multi-component sensor system.</td></tr>
|
||||||
|
<tr><td bgcolor="#ccffcc">sensor_reflector</td><td>Same as sensor, but for the reflector portion of an
|
||||||
|
integrated multi-component sensor system.</td></tr>
|
||||||
|
<tr><td bgcolor="#ccffcc">sensor_receiver</td><td>Same as sensor, but for the receiver portion of an
|
||||||
|
integrated multi-component sensor system.</td></tr>
|
||||||
|
<tr><td bgcolor="#ccffcc">scheduled</td><td>Typical flight software and hardware subsystems.</td></tr>
|
||||||
|
<tr><td bgcolor="#ccffcc">effector</td><td>Simulated interface between control and force generator
|
||||||
|
simulation components.</td></tr>
|
||||||
|
<tr><td bgcolor="#ccffcc">effector_emitter</td><td>Same as effector, but for the action portion of an
|
||||||
|
action-reaction effector system.</td></tr>
|
||||||
|
<tr><td bgcolor="#ccffcc">effector_receiver</td><td>Same as effector, but for the reaction portion of an
|
||||||
|
action-reaction effector system.</td></tr>
|
||||||
|
<tr><td bgcolor="#ccffcc">logging</td><td>Simulation data recording or displaying.</td></tr>
|
||||||
|
<tr><td bgcolor="#ffff99">automatic_last</td><td>Module which reschedules its own next call time, and will run after other CYCLIC jobs in the frame.</td></tr>
|
||||||
|
<tr bgcolor="ccffcc"><td colspan="2" align="center">END SCHEDULED JOB LOOP</td></tr>
|
||||||
|
<tr><td bgcolor="add8e6">end_of_frame</td><td>Module runs at the end of every execution frame, after the scheduled job loop completes.</td></tr>
|
||||||
|
<tr bgcolor="add8e6"><td colspan="2" align="center">END EXECUTION FRAME</td></tr>
|
||||||
|
<tr><td bgcolor="#e6ceff">freeze_init</td><td>Module executes only once upon entering FREEZE mode.</td></tr>
|
||||||
|
<tr bgcolor="e6ceff"><td colspan="2" align="center">BEGIN FREEZE FRAME</td></tr>
|
||||||
|
<tr bgcolor="e6ceff"><td colspan="2" align="center">BEGIN FREEZE LOOP</td></tr>
|
||||||
|
<tr><td bgcolor="#e6ceff">freeze_scheduled</td><td>Module executes cyclically during simulation FREEZE mode according to its specified cycle time.</td></tr>
|
||||||
|
<tr bgcolor="e6ceff"><td colspan="2" align="center">END FREEZE LOOP</td></tr>
|
||||||
|
<tr><td bgcolor="#e6ceff">freeze</td><td>Module runs at end of every freeze frame, after the freeze loop completes.</td></tr>
|
||||||
|
<tr bgcolor="e6ceff"><td colspan="2" align="center">END FREEZE FRAME</td></tr>
|
||||||
|
<tr><td bgcolor="#e6ceff">unfreeze</td><td>Module executes only once upon leaving FREEZE mode before returning to RUN mode.</td></tr>
|
||||||
|
<tr><td bgcolor="#ffc285">checkpoint</td><td>Module executes only once before a checkpoint is dumped.</td></tr>
|
||||||
|
<tr><td bgcolor="#ffc285">post_checkpoint</td><td>Module executes only once after a checkpoint is dumped.</td></tr>
|
||||||
|
<tr><td bgcolor="#ffc285">preload_checkpoint</td><td>Module executes only once before a checkpoint is loaded.</td></tr>
|
||||||
|
<tr><td bgcolor="#ffc285">restart</td><td>Module executes only once after a checkpoint is loaded.</td></tr>
|
||||||
|
<tr><td bgcolor="#ff8080">shutdown</td><td>Module executes only once at simulation termination to allow a
|
||||||
|
graceful shutdown.</td></tr>
|
||||||
|
</table>
|
||||||
|
</center>
|
||||||
|
|
||||||
|
##### Job Return Type
|
||||||
|
|
||||||
|
All integration class jobs must return an integer value which represents the current integration
|
||||||
|
pass identifier. If all integration passes are complete, the job must return a zero.
|
||||||
|
|
||||||
|
All dynamic_event class jobs must return a double precision value representing the estimated time
|
||||||
|
to go to the defined event, in seconds.
|
||||||
|
|
||||||
|
All other jobs managed by the Trick executive, not integration or dynamic_event, may return any
|
||||||
|
type. If a function is declared with an integer return value, the job must return a non-negative
|
||||||
|
integer or else the executive will assume an error occurred an immediately terminate the simulation.
|
||||||
|
If the job does not return an integer, Trick will not take any action based on a return value. Note
|
||||||
|
that initialization job return values are NOT checked by the executive.
|
||||||
|
|
||||||
|
##### Job Name
|
||||||
|
|
||||||
|
This field specifies the job name of the job as defined in the job’s source code.
|
||||||
|
|
||||||
|
C function and C++ member functions can be called as a jobs. Here is a quick example of a C and C++
|
||||||
|
calls.
|
||||||
|
|
||||||
|
```C++
|
||||||
|
%{
|
||||||
|
extern "C" {
|
||||||
|
c_function() ;
|
||||||
|
}
|
||||||
|
%}
|
||||||
|
|
||||||
|
class MySimObject() : public Trick::SimObject {
|
||||||
|
|
||||||
|
public:
|
||||||
|
Ball my_ball ;
|
||||||
|
|
||||||
|
MySimObject() {
|
||||||
|
(1.0 , "scheduled") c_function() ;
|
||||||
|
(1.0 , "scheduled") my_ball.print_state() ;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### Job Calling Arguments
|
||||||
|
|
||||||
|
Job calling arguments adhere to C++ calling argument standards.
|
||||||
|
|
||||||
|
### Sim Object Methods
|
||||||
|
|
||||||
|
Methods may be defined within a sim object. These methods may be used as simulation jobs.
|
||||||
|
A possible use for sim object methods would be to call non C/C++ code with minimal overhead from
|
||||||
|
the S_define file.
|
||||||
|
|
||||||
|
### Specifying Scheduled Loop Job Class Order
|
||||||
|
|
||||||
|
This section of the S_define (encapsulated by "job_class_order{...};) can be used to specify a new
|
||||||
|
scheduled loop job class order. The user may simply re-order the existing job classes that exist or
|
||||||
|
can specify a new set of scheduled loop job classes. Job classes that are eligible for reassignment
|
||||||
|
are listed in Table SD_1 between automatic and automatic_last inclusive. The order they are shown
|
||||||
|
in the table is the default ordering.
|
||||||
|
|
||||||
|
```C++
|
||||||
|
job_class_order {
|
||||||
|
my_job_class_1 ;
|
||||||
|
my_job_class_2 ;
|
||||||
|
scheduled ;
|
||||||
|
my_job_class_3 ;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Simulation Object C++ properties
|
||||||
|
|
||||||
|
Sim objects are C++ objects. They possess all of the capabilities of C++ objects. This section
|
||||||
|
describes how to use some C++ features with sim objects.
|
||||||
|
|
||||||
|
#### Simulation Object Instantiations
|
||||||
|
|
||||||
|
##### Multiple Instantiations
|
||||||
|
|
||||||
|
Sim objects are instantiated within the S_define file. They are regular class objects, and as such
|
||||||
|
are treated that way. Sim objects may be multiply instantiated. Multiply instantiated sim objects
|
||||||
|
works with both C and C++ models contained within the sim object.
|
||||||
|
|
||||||
|
```C++
|
||||||
|
class ballSimObject : public Trick::SimObject {
|
||||||
|
public:
|
||||||
|
Ball obj ;
|
||||||
|
ballSimObject() {
|
||||||
|
("initialization") obj.state_init() ;
|
||||||
|
("derivative") obj.force_field() ;
|
||||||
|
("derivative") obj.state_deriv() ;
|
||||||
|
("integration", &my_integ) trick_ret = obj.state_integ() ;
|
||||||
|
(10.0, "scheduled") trick_ret = obj.state_print() ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make 2 balls
|
||||||
|
ballSimObject ball ;
|
||||||
|
ballSimObject ball2 ;
|
||||||
|
```
|
||||||
|
|
||||||
|
##### Sim Object Constructor Arguments and Initializer Lists
|
||||||
|
|
||||||
|
Sim objects instantiations may take arguments. These arguments may be used in the sim object's
|
||||||
|
initialization list. An initialization list constructs member variables of the class. They
|
||||||
|
are listed as a comma separated list after the declaration of a constructor. Arguments passed
|
||||||
|
to the sim object constructor may be passed onto member variable constructors.
|
||||||
|
|
||||||
|
C structures may be zeroed out when included in the sim object's initialization list.
|
||||||
|
|
||||||
|
```C++
|
||||||
|
class ballSimObject : public Trick::SimObject {
|
||||||
|
public:
|
||||||
|
Ball obj ;
|
||||||
|
C_STRUCT c_struct ;
|
||||||
|
|
||||||
|
// passes int argument to obj constructor. Zeros out c_struct.
|
||||||
|
ballSimObject(int num) : obj(num) , c_struct() {
|
||||||
|
} ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sim object constructor requires an integer argument.
|
||||||
|
ballSimObject ball(5) ;
|
||||||
|
```
|
||||||
|
|
||||||
|
##### Sim Object Constructor Arguments and Job Control
|
||||||
|
|
||||||
|
Arguments to sim objects may also be used to control job execution. Most items in the job
|
||||||
|
specification may be set to the value of an argument.
|
||||||
|
|
||||||
|
```C++
|
||||||
|
class ballSimObject : public Trick::SimObject {
|
||||||
|
public:
|
||||||
|
Ball obj ;
|
||||||
|
ballSimObject(int phase, double cycle , const char * job_class) {
|
||||||
|
(job_class) obj.state_init() ;
|
||||||
|
Pphase ("derivative") obj.force_field() ;
|
||||||
|
("derivative") obj.state_deriv() ;
|
||||||
|
("integration", &my_integ) trick_ret = obj.state_integ() ;
|
||||||
|
(cycle, "scheduled") trick_ret = obj.state_print() ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ballSimObject ball(1 , 10.0 , ~@~\initialization~@~]) ;
|
||||||
|
// This ball has different job properties than the first ball.
|
||||||
|
ballSimObject ball2( 2 , 5.0 , ~@~\default_data~@~] ) ;
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Multiple Constructors
|
||||||
|
|
||||||
|
Sim objects may define multiple constructors. Each constructor may define different job
|
||||||
|
parameters or even an entirely different set of jobs. Arguments to the sim object
|
||||||
|
instantiation determine which sim object constructor and which jobs are run.
|
||||||
|
|
||||||
|
```C++
|
||||||
|
class ballSimObject : public Trick::SimObject {
|
||||||
|
public:
|
||||||
|
Ball obj ;
|
||||||
|
ballSimObject(int phase, double cycle , const char * job_class) {
|
||||||
|
(job_class) obj.state_init() ;
|
||||||
|
Pphase ("derivative") obj.force_field() ;
|
||||||
|
("derivative") obj.state_deriv() ;
|
||||||
|
("integration", &my_integ) trick_ret = obj.state_integ() ;
|
||||||
|
(cycle, "scheduled") trick_ret = obj.state_print() ;
|
||||||
|
}
|
||||||
|
ballSimObject(const char * job_class) {
|
||||||
|
(job_class) obj.state_init() ;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ballSimObject ball(1 , 10.0 , "initialization") ;
|
||||||
|
ballSimObject ball2( "default_data" ) ;
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Sim Object Inheritance
|
||||||
|
|
||||||
|
Sim objects may inherit from other sim objects. Jobs in the derived class will be run after those
|
||||||
|
of the base sim object class. Both C and C++ jobs may be inherited.
|
||||||
|
|
||||||
|
```C++
|
||||||
|
class ballSimObject : public Trick::SimObject {
|
||||||
|
public:
|
||||||
|
Ball obj ;
|
||||||
|
ballSimObject() {
|
||||||
|
(10.0, "scheduled") trick_ret = obj.state_print() ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class anotherBallSimObject : public ballSimObject {
|
||||||
|
public:
|
||||||
|
anotherBallSimObject() {
|
||||||
|
// This job will run after the above state_print()
|
||||||
|
(10.0, "scheduled") another_print() ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
anotherBallSimObject ball() ;
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Polymorphism in Sim Object jobs.
|
||||||
|
|
||||||
|
Polymorphism can be used to dynamically set objects at initialization or even change object types
|
||||||
|
during runtime. Given an abstract class and two derived classes:
|
||||||
|
|
||||||
|
```C++
|
||||||
|
class Ball {
|
||||||
|
public:
|
||||||
|
virtual void print_type() = 0 ;
|
||||||
|
} ;
|
||||||
|
|
||||||
|
class Baseball : public Ball {
|
||||||
|
public:
|
||||||
|
virtual void print_type() ;
|
||||||
|
} ;
|
||||||
|
|
||||||
|
class Soccerball : public Ball {
|
||||||
|
public:
|
||||||
|
virtual void print_type() ;
|
||||||
|
} ;
|
||||||
|
```
|
||||||
|
|
||||||
|
We may use a Ball base pointer in the S_define.
|
||||||
|
|
||||||
|
```C++
|
||||||
|
class ballSimObject : public Trick::SimObject {
|
||||||
|
public:
|
||||||
|
Ball * ball_ptr ;
|
||||||
|
ballSimObject() {
|
||||||
|
(1.0 , "scheduled") ball_ptr->print_type() ;
|
||||||
|
}
|
||||||
|
} ;
|
||||||
|
|
||||||
|
ballSimObject ball ;
|
||||||
|
```
|
||||||
|
|
||||||
|
`ball_ptr` is not instantiated when the simulation is compiled. If nothing is assigned to `ball_ptr`
|
||||||
|
before the first scheduled call of `ball_ptr->print_type()` then the call will fail and the sim
|
||||||
|
will core. We can allocate `ball_ptr` in the input file. We can even change `ball_ptr` in the
|
||||||
|
middle of the simulation.
|
||||||
|
|
||||||
|
```python
|
||||||
|
ball.ball_ptr = trick.TMM_declare_var_s("Soccerball[1]")
|
||||||
|
trick.add_read(20.0 , """ball.ball_ptr = trick.TMM_declare_var_s("Baseball[1]")""")
|
||||||
|
```
|
||||||
|
|
||||||
|
### State Integration Specification
|
||||||
|
|
||||||
|
Trick manages state integration with exceptional flexibility. The integration specification
|
||||||
|
allows the developer to group the derivative, integration, and dynamic_event class modules
|
||||||
|
(for any combination of sim objects) for state integration using a particular integrator and
|
||||||
|
state integration time step. Some simulations will have several different sets of state
|
||||||
|
parameters, each set requiring a unique state integration scheme and integration time step.
|
||||||
|
Likewise, other simulations will require all the derivative class modules from a group of
|
||||||
|
sim objects to be executed before the integration class modules of the same sim object group.
|
||||||
|
The integration specification provides this capability.
|
||||||
|
|
||||||
|
The integration specification is of the following form:
|
||||||
|
|
||||||
|
```
|
||||||
|
integrate <integrator_name> (<integration_dt>) <sim_object_name> [,<sim_object_name_n>] ;
|
||||||
|
```
|
||||||
|
|
||||||
|
An alternative instantiation syntax which is pure C++ is of the form:
|
||||||
|
|
||||||
|
```C++
|
||||||
|
IntegLoopSimObject <integrator_name> (<integration_dt>, <sim_object_name> [,<sim_object_name_n>], NULL ) ;
|
||||||
|
```
|
||||||
|
|
||||||
|
This form must have NULL as the final argument to the instantiation.
|
||||||
|
|
||||||
|
The integrate tag is a reserved word for the CP. The <integration_dt> is a state integration
|
||||||
|
cycle time in seconds. At least one sim object name must be specified followed by any number
|
||||||
|
of additional sim object names separated by commas. An S_define can have at most one integrate
|
||||||
|
statement per sim object, and at least one integrate statement for all sim objects.
|
||||||
|
|
||||||
|
### Parameter Collection Mechanism
|
||||||
|
|
||||||
|
The parameter collection mechanism is probably the most difficult capability of the CP to
|
||||||
|
understand and utilize. This capability is useful when the user wants a single job to handle
|
||||||
|
`n` number (either a known or unknown `n`) of parameters of the same type. The parameter
|
||||||
|
collection mechanism is an alternative for a variable calling argument list The collection
|
||||||
|
mechanism syntax in the S_define file is as follows:
|
||||||
|
|
||||||
|
```C++
|
||||||
|
collect <reference> = { } ;
|
||||||
|
```
|
||||||
|
|
||||||
|
or
|
||||||
|
|
||||||
|
```C++
|
||||||
|
collect <reference> = { <reference_1> [,<reference_n>] } ;
|
||||||
|
```
|
||||||
|
|
||||||
|
There is also a C code equivalent to adding collect references one at a time that may
|
||||||
|
be put in a create_connections section of the S_define file. The advantage of this
|
||||||
|
method is that not all of the collects must be listed in a single collect statement.
|
||||||
|
This function call syntax may also be used in the input file to add collects at runtime.
|
||||||
|
|
||||||
|
```C++
|
||||||
|
void create_connections() {
|
||||||
|
reference = add_collect( reference , reference_1 ) ;
|
||||||
|
reference = add_collect( reference , reference_2 ) ;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The collect capability allows the developer to build a job which accesses an unknown number
|
||||||
|
of independent simulation parameters. For example, if designed correctly, a derivative class
|
||||||
|
module should be capable of incorporating any number of known and unknown (future capabilities)
|
||||||
|
external forces and torques without any code changes to the derivative module. The collection
|
||||||
|
mechanism stores the addresses of, and number of, any number of independent parameters in a
|
||||||
|
single pointer array. The derivative module can use this array to access each parameter in the
|
||||||
|
collection list. See Section 10.0 for programming requirements for this capability.
|
||||||
|
|
||||||
|
The collect statements in the S_define file must be supported by source code implemented by
|
||||||
|
the math model developer. This collect support code can reside in any function in the simulation,
|
||||||
|
including functions that are not listed in the S_define file. In general, for every collect
|
||||||
|
statement in the S_define file, there are two places where source code must be developed: a
|
||||||
|
data structure definition file (`*.h`) and a function source file (`*.c`).
|
||||||
|
|
||||||
|
As a real world example, orbital dynamics can include a large number of environmental effects
|
||||||
|
for high precision state propagation, or a small number of effects for general purpose state
|
||||||
|
propagation. A spacecraft EOM derivative module should be designed to include any number and
|
||||||
|
combination of known and unknown (future) effects. A low fidelity parameter collection for
|
||||||
|
external torques on the spacecraft might look like:
|
||||||
|
|
||||||
|
```C++
|
||||||
|
collect shuttle.orbital.rotation.external_torque[0] = {
|
||||||
|
shuttle.aero.out.torque[0] } ;
|
||||||
|
```
|
||||||
|
|
||||||
|
A higher fidelity parameter collection might look like:
|
||||||
|
|
||||||
|
```C++
|
||||||
|
collect shuttle.orbital.rotation.external_torque[0] = {
|
||||||
|
shuttle.aero.out.torque[0] ,
|
||||||
|
shuttle.grav.out.gravity_gradient_torque[0] ,
|
||||||
|
shuttle.solar_pressure.out.torque[0] } ;
|
||||||
|
```
|
||||||
|
|
||||||
|
For those cases when there are no parameters to collect:
|
||||||
|
|
||||||
|
```C++
|
||||||
|
collect shuttle.orbital.rotation.external_torque[0] = { } ;
|
||||||
|
```
|
||||||
|
|
||||||
|
The key here is that if a new external torque for the spacecraft is added to the simulation,
|
||||||
|
that torque can be accessed by the existing derivative module without code modification to the
|
||||||
|
derivative module. Note that all parameters listed must be of the same type and array dimension.
|
||||||
|
|
||||||
|
To use the parameter collection mechanism of the S_define file, the developer must perform three tasks:
|
||||||
|
|
||||||
|
1. from the example above, the external_torque parameter must be declared in its data structure
|
||||||
|
definition file as a two dimensional void pointer, i.e. `void ** external_torque ;`,
|
||||||
|
|
||||||
|
2. a loop must be placed in the derivative module which accesses the collected parameters, and
|
||||||
|
|
||||||
|
3. the parameter collection statement must be added to the S_define.
|
||||||
|
|
||||||
|
The external_torque parameter must be declared as a two dimensional void pointer for two reasons.
|
||||||
|
First, the void type is not processed by the ICG. This means that this parameter cannot be recorded
|
||||||
|
for output or assigned data for input. If the type was any other type than void, the ICG would
|
||||||
|
assume the parameter required dynamic memory allocation and the resulting ICG generated code would
|
||||||
|
cause a fatal runtime error (usually accompanied by a core dump). Second, from an automatic code
|
||||||
|
generation viewpoint, the external_torque parameter is actually an unconstrained array of pointers,
|
||||||
|
where the pointers in the unconstrained array could be of any type (including data structure pointers);
|
||||||
|
i.e. the first pointer (*) of the declaration is the array dimension, the second is the address to
|
||||||
|
each of the collected parameters.
|
||||||
|
|
||||||
|
To make the collection mechanism work, the developer must add specific collection mechanism code to
|
||||||
|
their module. For the above example, the derivative module code might look like the following; the
|
||||||
|
text in bold indicates code which will be unchanged regardless of the parameters being collected:
|
||||||
|
|
||||||
|
```C++
|
||||||
|
#include "dynamics/v2/dynamics.h"
|
||||||
|
#include "sim_services/include/collect_macros.h"
|
||||||
|
|
||||||
|
int derivative_job( DYN_ROT * R ) {
|
||||||
|
|
||||||
|
int i ;
|
||||||
|
double **collect ;
|
||||||
|
double total_torque[3] ;
|
||||||
|
|
||||||
|
total_torque[0] = total_torque[1] = total_torque[2] = 0.0 ;
|
||||||
|
|
||||||
|
/* typecast the void ** as a usable double** */
|
||||||
|
collect = (double**)R->external_torque ;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Loop on the number of collected items
|
||||||
|
from the above collect statement example:
|
||||||
|
collect[0] -> shuttle.aero.out.torque
|
||||||
|
collect[1] -> shuttle.grav.out.gravity_gradient_torque
|
||||||
|
collect[2] -> shuttle.solar_pressure.out.torque
|
||||||
|
*/
|
||||||
|
for( i = 0 ; i < NUM_COLLECT(collect) ; i++ ) {
|
||||||
|
total_torque[0] += collect[i][0] ;
|
||||||
|
total_torque[1] += collect[i][1] ;
|
||||||
|
total_torque[2] += collect[i][2] ;
|
||||||
|
}
|
||||||
|
|
||||||
|
return( 0 ) ;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Several aspects of this example code which need mentioning are listed below.
|
||||||
|
|
||||||
|
1. A local pointer parameter must be declared of the same type as the parameters being
|
||||||
|
collected, in this case the parameters being collected are double precision; hence,
|
||||||
|
`double **collect ;`.
|
||||||
|
|
||||||
|
2. The `shuttle.orbital.rotation.external_torque` (actually a `void**`) is typecast as a
|
||||||
|
`double**` and assigned to the local variable: `collect = (double**)R->external_torque ;`.
|
||||||
|
|
||||||
|
3. The number of parameters collected is saved in the first eight bytes before the
|
||||||
|
address to the `external_torque` parameter. The conditional statement of the for loop
|
||||||
|
demonstrates how the number of collected parameters is retrieved: `NUM_COLLECT(collect)`.
|
||||||
|
4. This example, and all other collection mechanism code implementations, assume the
|
||||||
|
developer knows the type and array size of the parameters being collected. In this
|
||||||
|
example, the parameters collected were single dimensioned double precision arrays with
|
||||||
|
three elements per array.
|
||||||
|
|
||||||
|
### Create Connections
|
||||||
|
|
||||||
|
The create_connections section contains arbitrary code that is executed right after sim
|
||||||
|
object instantiations. Code in this section is performed before any job of any job class.
|
||||||
|
The intended use of this section is to glue the sim objects together. Sim objects that
|
||||||
|
need pointers to other sim objects may be assigned in the create_connections routine.
|
||||||
|
Default parameters may also be set such as defining a default simulation stop time. Any
|
||||||
|
arbitrary code may be added to the create_connections section.
|
||||||
|
|
||||||
|
There may be multiple create_connection sections in the S_define file. They will be
|
||||||
|
concatenated together in the order they appear in the S_define file.
|
||||||
|
|
||||||
|
```C++
|
||||||
|
class AsimObject : public Trick::SimObject {
|
||||||
|
public:
|
||||||
|
modelA a ;
|
||||||
|
// This pointer points to a different sim object
|
||||||
|
modelB * b_ptr ;
|
||||||
|
|
||||||
|
AsimObject() {
|
||||||
|
// This job requires type modelB from a different sim object
|
||||||
|
(1.0 , "scheduled") a.job(b_ptr) ;
|
||||||
|
}
|
||||||
|
} ;
|
||||||
|
|
||||||
|
class BsimObject: public Trick::SimObject {
|
||||||
|
public:
|
||||||
|
modelB b ;
|
||||||
|
};
|
||||||
|
|
||||||
|
AsimObject A ;
|
||||||
|
BsimObject B ;
|
||||||
|
|
||||||
|
void create_connections() {
|
||||||
|
|
||||||
|
// Connects the AsimObject and BsimObject together.
|
||||||
|
A.b_ptr = &B.b
|
||||||
|
|
||||||
|
// Sets a default stop time for the simulation.
|
||||||
|
exec_set_terminate_time(300.0) ;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
[Continue to Making The Simulation](Making-the-Simulation)
|
@ -0,0 +1,244 @@
|
|||||||
|
During a simulation build, Trick generates several rounds of files to support data recording, checkpointing, and Python access:
|
||||||
|
|
||||||
|
* Trick generates `S_source.hh` from the `S_define`
|
||||||
|
* ICG recursively builds a tree of all header files included from `S_source.hh` and generates an `io_*.cpp` and `py_*.i` file for each
|
||||||
|
* SWIG converts all `py_*.i` to `py_*.cpp` files
|
||||||
|
* Trick compiles all `io_*.cpp` and `py_*.cpp` files
|
||||||
|
|
||||||
|
The time required grows with the number of included header files and can represent a significant portion of the build process. During subsequent builds, only headers files that have changed are reprocessed. However, `make clean` removes all of the generated files, so the next build will have to run the entire process again.
|
||||||
|
|
||||||
|
For external libraries, which do not change from build to build, this is unnecessary and wasteful. In this case, we would like to compile the `io_*.cpp` and `py_*.cpp` files once and simply link against them during simulation build. As of version 17.1, Trick supports "Trickifying" a set of headers via the `trickify.mk` makefile.
|
||||||
|
|
||||||
|
# Who's Responsible?
|
||||||
|
Support of Trickification is the project owner's responsibility. While it is possible for anyone to Trickify any set of headers, you really want the project to maintain the files we're going to talk about. This will ensure that's it done correctly, in one place, and stays synchronized with the project.
|
||||||
|
|
||||||
|
# Trickifying Your Project
|
||||||
|
Trickifying your project requires a list of headers and the paths at which they can be found. This list should include the headers for which you want data recording, checkpointing, and Python access, which probably means most or even all of them. Specify the list by creating a file named `S_source.hh` that includes the headers you want processed and nothing else. This is not the same `S_source.hh` generated by Trick during the simulation build process, but Trick's tools expect that name, so you have to use it for now. Specify the header paths via the `TRICKIFY_CXX_FLAGS` variable, which you can set when you call `make` or export from your own makefile. I don't recommend setting it in your shell via `export` or `setenv`. All of Trick's environment variables can be specified at compile time, exposed at run time, and limited to the duration of the executable. There's no reason to permanently pollute your environment from your `.cshrc`, `.bashrc`, etc.
|
||||||
|
|
||||||
|
For example, say we have a tiny project that looks like this:
|
||||||
|
|
||||||
|
<pre><b>${HOME}/myproject/
|
||||||
|
include/
|
||||||
|
Foo.hh
|
||||||
|
Bar.hh
|
||||||
|
Baz.hh</b></pre>
|
||||||
|
|
||||||
|
To Trickify this project, we'll make a file called `S_source.hh` which includes all three headers:
|
||||||
|
|
||||||
|
```c++
|
||||||
|
#include "Foo.hh"
|
||||||
|
#include "Bar.hh"
|
||||||
|
#include "Baz.hh"
|
||||||
|
```
|
||||||
|
|
||||||
|
I recommend putting your `S_source.hh` in its own directory since Trick is going to generate a bunch of files, for some of which you can't yet specify the output directory. Let's call it `trickified`:
|
||||||
|
|
||||||
|
<pre>${HOME}/myproject/
|
||||||
|
include/
|
||||||
|
Foo.hh
|
||||||
|
Bar.hh
|
||||||
|
Baz.hh
|
||||||
|
<b>trickified/
|
||||||
|
S_source.hh</b></pre>
|
||||||
|
|
||||||
|
In the `trickified` directory, run:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make -f ${TRICK_HOME}/share/trick/makefiles/trickify.mk TRICKIFY_CXX_FLAGS=-I${HOME}/myproject/include
|
||||||
|
```
|
||||||
|
|
||||||
|
The result should be:
|
||||||
|
|
||||||
|
<pre>${HOME}/myproject/
|
||||||
|
include/
|
||||||
|
Foo.hh
|
||||||
|
Bar.hh
|
||||||
|
Baz.hh
|
||||||
|
trickified/
|
||||||
|
S_source.hh
|
||||||
|
<b>trickified.o
|
||||||
|
build/
|
||||||
|
python/</b></pre>
|
||||||
|
|
||||||
|
`trickified.o` contains all of the `io_*.cpp` and `py_*.cpp` code. The name is configurable via the `TRICKIFY_OBJECT_NAME` variable, which can include directories, which will automatically be created if necessary. `build` contains a lot of ICG and SWIG artifacts. You can't change its name or location at this time, but it's useful to keep around as it will allow you to rebuild only the parts of the project that change in the future. `python` includes a bunch of crazily-named Python modules which serve as the input file interface to the content of the header files. You can configure its location via the `TRICKIFY_PYTHON_DIR` variable. Directories will be automatically created as needed.
|
||||||
|
|
||||||
|
Your Trickified library can be produced in three different formats based on the value of `TRICKIFY_BUILD_TYPE`:
|
||||||
|
1. `STATIC` (.a)
|
||||||
|
Create a static library. This will require the use of `--whole-archive` (on Linux) or `-all_load`/`-force_load` (on Mac) when linking the sim executable. Trick uses `dlsym` to dynamically load symbols at run time, but the linker, by default, will not include symbols from static libraries that are not known to be needed at compile time.
|
||||||
|
2. `SHARED` (.so)
|
||||||
|
Create a shared object (dynamically linked library). This may require the use of `-rpath` to ensure the linker can find the shared object at runtime unless you explicitly link against it (as opposed to using `-L` and `-l`) during compilation.
|
||||||
|
3. `PLO` (.o)
|
||||||
|
Create a partially-linked object (see the `--relocatable` option of `ld`). No special linker options are required. This is the default build type.
|
||||||
|
|
||||||
|
Note that Trick does not automatically append file extensions and will use the value of `TRICKIFY_OBJECT_NAME` regardless of the value of `TRICKIFY_BUILD_TYPE`.
|
||||||
|
|
||||||
|
## Simplify with a Makefile
|
||||||
|
Let's be honest. You're not going to remember that command line. And who wants to type all that stuff every time? Let's do it once in our own makefile and just call `make` on that. It seems sensible to put this in the `trickified` directory right next to `S_source.hh`.
|
||||||
|
|
||||||
|
<pre>${HOME}/myproject/
|
||||||
|
include/
|
||||||
|
Foo.hh
|
||||||
|
Bar.hh
|
||||||
|
Baz.hh
|
||||||
|
trickified/
|
||||||
|
<b>Makefile</b>
|
||||||
|
S_source.hh
|
||||||
|
trickified.o
|
||||||
|
build/
|
||||||
|
python/</pre>
|
||||||
|
|
||||||
|
```make
|
||||||
|
ifndef TRICK_HOME
|
||||||
|
$(error TRICK_HOME must be set)
|
||||||
|
endif
|
||||||
|
|
||||||
|
TRICKIFY := $(TRICK_HOME)/share/trick/makefiles/trickify.mk
|
||||||
|
|
||||||
|
ifeq ($(wildcard $(TRICKIFY)),)
|
||||||
|
$(error This makefile requires at least Trick 17.1)
|
||||||
|
endif
|
||||||
|
|
||||||
|
export TRICKIFY_OBJECT_NAME := trickified_myproject.o
|
||||||
|
export TRICKIFY_CXX_FLAGS := -I$(HOME)/myproject/include
|
||||||
|
|
||||||
|
all:
|
||||||
|
@$(MAKE) -s -f $(TRICKIFY)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@rm -rf build python $(TRICKIFY_OBJECT_NAME)
|
||||||
|
```
|
||||||
|
|
||||||
|
Now just type `make` in `trickified` and everything is taken care of. I even added a check to make sure you're using a recent enough version of Trick. I've silenced a lot of make's output because I prefer to see echoed commands only when debugging, but you're welcome to get rid of the `@` and `-s` if you enjoy such verbosity. Note that I've used `TRICKIFY_OBJECT_NAME` to rename the default `trickified.o` to something a little less generic. If you're following along, you can remove the `trickified.o` we built earlier.
|
||||||
|
|
||||||
|
## Don't Version Control Build Artifacts!
|
||||||
|
The only Trickification-related files you want under version control are `S_source.hh` and `Makefile`. You should ignore all of the generated files. For instance, the appropriate `.gitignore` for the `trickified` directory when using default values for the Trickification variables is:
|
||||||
|
|
||||||
|
```git
|
||||||
|
build
|
||||||
|
python
|
||||||
|
trick
|
||||||
|
*.o
|
||||||
|
```
|
||||||
|
|
||||||
|
The generated Python modules can be particularly problematic if they are accidentally version controlled. The names are created by hashing the full file path, both during Trickification and again when the sim is built. If the paths change between Trickification and sim compilation, the names won't match, and you'll get confusing linker errors.
|
||||||
|
|
||||||
|
# Using a Trickified Project
|
||||||
|
Using a project that's been Trickified is a lot like using an external library, but there are a couple of extra things to take care of. Continuing with the example above, we would need to add the following to our sim's `S_overrides.mk`:
|
||||||
|
|
||||||
|
``` make
|
||||||
|
TRICK_LDFLAGS += $(HOME)/myproject/trickified/trickified_myproject.o
|
||||||
|
```
|
||||||
|
|
||||||
|
This line links in the Trickified object. Note that you may need additional flags if you used `TRICKIFY_BUILD_TYPE` to build a static library or shared object.
|
||||||
|
|
||||||
|
```make
|
||||||
|
TRICK_EXT_LIB_DIRS += :$(HOME)/myproject
|
||||||
|
```
|
||||||
|
|
||||||
|
This line tells Trick to expect `io_*` and `py_*` code for the headers in the specified directory (and all directories below it), but not to generate it itself. This is different than `TRICK_ICG_EXCLUDE` and `TRICK_EXCLUDE`, which cause ICG to ignore the headers entirely. It also tells Trick not to compile any source files in the specified directory (and all directories below it) that may be referenced as `LIBRARY_DEPENDENCIES` in user files. Note that it is a colon-delimited list of paths.
|
||||||
|
|
||||||
|
You'll need to be more selective if the sim itself or additional non-Trickified headers or source are under the same directory as Trickified headers or source. You may have to resort to individually specifying the full path to every file to be excluded, perhaps using some fancy `find` options to automatically generate the list.
|
||||||
|
|
||||||
|
```make
|
||||||
|
TRICK_PYTHON_PATH += :$(HOME)/myproject/trickified/python
|
||||||
|
```
|
||||||
|
|
||||||
|
This line tells Trick where to find the Python modules generated by SWIG so that you can access the Trickified project from the input file. It is also a colon-delimited list of paths.
|
||||||
|
|
||||||
|
```make
|
||||||
|
TRICK_SWIG_FLAGS += -I$(HOME)/myproject/trickified
|
||||||
|
```
|
||||||
|
|
||||||
|
This line tells Trick where to find the `py_*.i` files generated by ICG and should point to the directory containing `build`. These are necessary if any of your headers include headers from the Trickified project, which is likely, since you otherwise wouldn't be using it. It is a space-delimited list of options. Don't forget to prepend the path with `-I`.
|
||||||
|
|
||||||
|
## Simplify Your Users' Lives
|
||||||
|
While the above is sufficient to use a Trickified project, it's awfully inconvenient to have to add all that stuff to every sim's `S_overrides.mk`. Plus, there are probably more things that need to be added, like header paths and linker flags for any additional libraries on which the project depends. Your users will love your project even more if you provide them with a makefile they can simply include from their `S_overrides.mk`. And it's not just the users that benefit! You'll have to answer far fewer questions about why they can't get your project compiled into their sim if, when your project inevitably changes, all they have to do is pull down the new makefile instead of changing all of their `S_overrides.mk`. Everybody wins! Turning once again to our example, let's call the makefile `myproject.mk` and put it in the `trickified` directory. You may have a name or location that makes more sense for your project. Maybe you already have a `makefiles` directory, or maybe your project supports a number of third party tools and you have a directory for Trick support. But let's keep the example simple:
|
||||||
|
|
||||||
|
<pre>${HOME}/myproject/
|
||||||
|
include/
|
||||||
|
Foo.hh
|
||||||
|
Bar.hh
|
||||||
|
Baz.hh
|
||||||
|
trickified/
|
||||||
|
Makefile
|
||||||
|
<b>myproject.mk</b>
|
||||||
|
S_source.hh
|
||||||
|
trickified_myproject.o
|
||||||
|
build/
|
||||||
|
python/</pre>
|
||||||
|
|
||||||
|
Here's the contents of `myproject.mk`. It's everything from the previous section plus some other things you might find useful.
|
||||||
|
|
||||||
|
```make
|
||||||
|
# We know this file's position relative to the root directory of the project,
|
||||||
|
# and MAKEFILE_LIST will give us the full path to this file no matter where the
|
||||||
|
# user has installed this project.
|
||||||
|
export MYPROJECT_HOME := $(abspath $(dir $(lastword $(MAKEFILE_LIST)))/..)
|
||||||
|
|
||||||
|
# Make MYPROJECT_HOME available to the sim at run time. This isn't necessary,
|
||||||
|
# but it can be useful if your users need to reference something from your
|
||||||
|
# project at run time.
|
||||||
|
TRICK_GTE_EXT += MYPROJECT_HOME
|
||||||
|
|
||||||
|
# Specify include paths for your headers.
|
||||||
|
MYPROJECT_INCLUDE := -I$(MYPROJECT_HOME)/include
|
||||||
|
|
||||||
|
# Specify include paths for your source, which users will need if they list
|
||||||
|
# any of your project's source files in a LIBRARY_DEPENDENCIES section.
|
||||||
|
MYPROJECT_SOURCE := -I$(MYPROJECT_HOME)/source
|
||||||
|
|
||||||
|
# Users may set different flags for C and C++, so you should really modify both
|
||||||
|
# to be safe.
|
||||||
|
TRICK_CFLAGS += $(MYPROJECT_INCLUDE) $(MYPROJECT_SOURCE)
|
||||||
|
TRICK_CXXFLAGS += $(MYPROJECT_INCLUDE) $(MYPROJECT_SOURCE)
|
||||||
|
|
||||||
|
# Enable Trickification support if Trick >= 17.1.
|
||||||
|
# Otherwise, let Trick generate all of the io_* and py_* code as usual.
|
||||||
|
ifneq ($(wildcard $(TRICK_HOME)/share/trick/makefiles/trickify.mk),)
|
||||||
|
|
||||||
|
MYPROJECT_TRICK := $(MYPROJECT_HOME)/trickified/trickified_myproject.o
|
||||||
|
|
||||||
|
# Tell Trick the headers and source at this location are part of a
|
||||||
|
# Trickified project
|
||||||
|
TRICK_EXT_LIB_DIRS += :$(MYPROJECT_HOME)
|
||||||
|
|
||||||
|
# Tell Trick where to find the Python modules generated by SWIG
|
||||||
|
TRICK_PYTHON_PATH += :$(MYPROJECT_HOME)/trickified/python
|
||||||
|
|
||||||
|
# Tell SWIG where to find py_*.i files
|
||||||
|
TRICK_SWIG_FLAGS += -I$(MYPROJECT_HOME)/trickified
|
||||||
|
|
||||||
|
# Link in the Trickified object
|
||||||
|
TRICK_LDFLAGS += $(MYPROJECT_TRICK)
|
||||||
|
|
||||||
|
# Append a prerequisite to the $(SWIG_SRC) target. This will build the
|
||||||
|
# Trickified library along with the sim if it does not already exist. Using
|
||||||
|
# $(SWIG_SRC) ensures that all Trickified .i files are created before SWIG is
|
||||||
|
# run on any simulation .i files, which may %import them. Note that this does
|
||||||
|
# NOT cause the Trickified library to be rebuilt if it already exists, even if
|
||||||
|
# the Trickified source code has changed.
|
||||||
|
$(SWIG_SRC): $(MYPROJECT_TRICK)
|
||||||
|
|
||||||
|
endif
|
||||||
|
|
||||||
|
$(MYPROJECT_TRICK):
|
||||||
|
@$(MAKE) -s -C $(MYPROJECT_HOME)/trickified
|
||||||
|
```
|
||||||
|
|
||||||
|
Now to use your project, all the user has to do is add one line to his `S_overrides.mk`:
|
||||||
|
|
||||||
|
```make
|
||||||
|
include <myproject>/trickified/myproject.mk
|
||||||
|
```
|
||||||
|
|
||||||
|
They'll have to replace `<myproject>` with the location to which they installed your project, of course. They might choose to hardcode the path or use a variable, but that's up to them.
|
||||||
|
|
||||||
|
# You Still Need a Core Library
|
||||||
|
Trickification is great and all, but it only builds the `io_*` and `py_*` code into an object. And because your project's headers and source are now under `TRICK_EXT_LIB_DIRS`, Trick won't be determining dependencies or compiling source code. Trickification thus necessitates that you build all of your source code into a library. There are plenty of internet tutorials available on that topic, so I won't be suggesting anything here. But once you've got that taken care of, you should incorporate it into your user-facing makefile by adding it to `TRICK_LDFLAGS`. You can also create a rule to call its build system and add the library as a prerequisite to `$(S_MAIN)` to have it built along with the sim if necessary.
|
||||||
|
|
||||||
|
# A Real Life Trickified Project
|
||||||
|
Here's a real project we used as the guinea pig for Trickification. It provides a makefile that a user can include from his `S_overrides.mk` that causes both a core library and Trickified object to be built if they don't already exist whenever the sim is compiled. The makefile is located at `3rdParty/trick/makefiles/trickified.mk`. The Trickified stuff is at `3rdParty/trick/lib`.
|
||||||
|
|
||||||
|
https://github.com/nasa/IDF
|
||||||
|
|
||||||
|
[Continue to Running A Simulation](../running_a_simulation/Running-a-Simulation)
|
427
docs/documentation/data_products/DP-Product-File-Format.md
Normal file
@ -0,0 +1,427 @@
|
|||||||
|
Since Trick 10, the DP Product Specification File Format is changed to XML. The DP Product XML file
|
||||||
|
DTD is defined as following:
|
||||||
|
|
||||||
|
|
||||||
|
### Product.dtd
|
||||||
|
|
||||||
|
```
|
||||||
|
<!-- Trick DP Product definition -->
|
||||||
|
<!-- V 1.0 -->
|
||||||
|
<!ELEMENT fname (#PCDATA)>
|
||||||
|
<!ELEMENT title (#PCDATA)>
|
||||||
|
<!ELEMENT tstart (#PCDATA)>
|
||||||
|
<!ELEMENT tstop (#PCDATA)>
|
||||||
|
<!ELEMENT frequency (#PCDATA)>
|
||||||
|
<!ELEMENT label (#PCDATA)>
|
||||||
|
<!ELEMENT units (#PCDATA)>
|
||||||
|
<!ELEMENT measurement (var, units)>
|
||||||
|
<!ELEMENT var (#PCDATA)>
|
||||||
|
|
||||||
|
<!-- A varcase construct is used to indicate that two or variable names mean the same thing.
|
||||||
|
If the data for a curve can't be found for the first name, try the second and so forth.
|
||||||
|
-->
|
||||||
|
<!ELEMENT varcase (var, var, var?)>
|
||||||
|
<!ELEMENT xaxis (label?, units?)>
|
||||||
|
<!ELEMENT yaxis (label?, units?)>
|
||||||
|
<!ELEMENT zaxis (label?, units?)>
|
||||||
|
<!ELEMENT column (label?, units?, var)>
|
||||||
|
<!ELEMENT curve ((var, var, var?)|varcase+)>
|
||||||
|
<!ELEMENT table (title?, tstart?, tstop?, frequency?, column+)>
|
||||||
|
<!ELEMENT plot (title?, tstart?, tstop?, frequency?, (xaxis|yaxis|zaxis)*, curve+)>
|
||||||
|
<!ELEMENT page (title?, tstart?, tstop?, frequency?, plot+)>
|
||||||
|
<!ELEMENT inputs (var+)>
|
||||||
|
<!ELEMENT outputs (measurement+)>
|
||||||
|
<!ELEMENT extfn (fname, inputs, outputs)>
|
||||||
|
<!ELEMENT product (title?, tstart?, tstop?, frequency?, extfn*, (page|table)+)>
|
||||||
|
|
||||||
|
<!ATTLIST product version CDATA #REQUIRED>
|
||||||
|
<!ATTLIST product foreground_color CDATA #IMPLIED>
|
||||||
|
<!ATTLIST product background_color CDATA #IMPLIED>
|
||||||
|
|
||||||
|
<!ATTLIST page foreground_color CDATA #IMPLIED>
|
||||||
|
<!ATTLIST page background_color CDATA #IMPLIED>
|
||||||
|
<!ATTLIST page hcells CDATA #IMPLIED>
|
||||||
|
<!ATTLIST page vcells CDATA #IMPLIED>
|
||||||
|
|
||||||
|
<!ATTLIST page presentation CDATA #IMPLIED>
|
||||||
|
<!ATTLIST page gnuplot_template CDATA #IMPLIED>
|
||||||
|
<!ATTLIST page gnuplot_object CDATA #IMPLIED>
|
||||||
|
<!ATTLIST page gnuplot_geom CDATA #IMPLIED>
|
||||||
|
<!ATTLIST page gnuplot_plot_ratio CDATA #IMPLIED>
|
||||||
|
<!ATTLIST page gnuplot_page_orientation CDATA #IMPLIED>
|
||||||
|
|
||||||
|
<!ATTLIST table foreground_color CDATA #IMPLIED>
|
||||||
|
<!ATTLIST table background_color CDATA #IMPLIED>
|
||||||
|
|
||||||
|
<!ATTLIST plot x_scale CDATA #IMPLIED>
|
||||||
|
<!ATTLIST plot xmin CDATA #IMPLIED>
|
||||||
|
<!ATTLIST plot xmax CDATA #IMPLIED>
|
||||||
|
<!ATTLIST plot y_scale CDATA #IMPLIED>
|
||||||
|
<!ATTLIST plot ymin CDATA #IMPLIED>
|
||||||
|
<!ATTLIST plot ymax CDATA #IMPLIED>
|
||||||
|
<!ATTLIST plot grid CDATA #IMPLIED>
|
||||||
|
<!ATTLIST plot grid_color CDATA #IMPLIED>
|
||||||
|
<!ATTLIST plot foreground_color CDATA #IMPLIED>
|
||||||
|
<!ATTLIST plot background_color CDATA #IMPLIED>
|
||||||
|
<!ATTLIST plot font CDATA #IMPLIED>
|
||||||
|
|
||||||
|
<!-- The format attribute specifies the printf() format string to -->
|
||||||
|
<!-- be used for printing y variable data. (e.g., "%18.6e") -->
|
||||||
|
<!ATTLIST yaxis format CDATA #IMPLIED>
|
||||||
|
|
||||||
|
<!-- The format attribute specifies the printf() format string to -->
|
||||||
|
<!-- be used for printing column data. (e.g., "%18.6e") -->
|
||||||
|
<!ATTLIST column format CDATA #IMPLIED>
|
||||||
|
|
||||||
|
<!-- =============================================================== -->
|
||||||
|
<!-- <var> ATTRIBUTES -->
|
||||||
|
<!-- =============================================================== -->
|
||||||
|
<!ATTLIST var label CDATA #IMPLIED>
|
||||||
|
|
||||||
|
<!-- <var>'s from_units attribute specifies the units to be assumed -->
|
||||||
|
<!-- for the recorded data if and only if the recorded data doesn't -->
|
||||||
|
<!-- contain units information for it's variables. -->
|
||||||
|
<!-- This attribute is used for data streams that don't supply -->
|
||||||
|
<!-- actual units. For streams that supply actual units (like .trk -->
|
||||||
|
<!-- files) this attribute is ignored. -->
|
||||||
|
<!ATTLIST var from_units CDATA #IMPLIED>
|
||||||
|
|
||||||
|
<!-- <var>'s units attribute indicates the units that recorded data -->
|
||||||
|
<!-- should be converted to, below being displayed. -->
|
||||||
|
<!ATTLIST var units CDATA #IMPLIED>
|
||||||
|
|
||||||
|
<!ATTLIST var bias CDATA #IMPLIED>
|
||||||
|
<!ATTLIST var scale CDATA #IMPLIED>
|
||||||
|
<!ATTLIST var max CDATA #IMPLIED>
|
||||||
|
<!ATTLIST var symbol_style CDATA #IMPLIED>
|
||||||
|
<!ATTLIST var symbol_size CDATA #IMPLIED>
|
||||||
|
<!ATTLIST var line_style CDATA #IMPLIED>
|
||||||
|
<!ATTLIST var line_color CDATA #IMPLIED>
|
||||||
|
<!ATTLIST var gnuplot_line_style CDATA #IMPLIED>
|
||||||
|
```
|
||||||
|
|
||||||
|
The root element of the DP Product XML file is <b>product</b>. It contains all other elements.
|
||||||
|
There are three main elements under product element that are: <b>page</b>, <b>table</b>, and
|
||||||
|
<b>extfn</b>. <b>page</b> refers to a page of X-Y-(Z) plots. <b>table</b> refers to ASCII
|
||||||
|
text formats. The product specification file may contain any number of pages and tables, but at least one
|
||||||
|
page or table. <b>extfn</b> refers to an external program designed to manipulate recorded data
|
||||||
|
into a format which is more easily displayed and its occurrence is not required.
|
||||||
|
|
||||||
|
### DP Page Element Specifications
|
||||||
|
A DP product file may have one or more <b>page</b> elements. Each <b>page</b> element must
|
||||||
|
have at least one <b>plot</b> elment and may have more plots sepcified. All attributes of a
|
||||||
|
<b>page</b> element as stated earlier in @ref product_dtd "Product.dtd" are:
|
||||||
|
de foreground_color, background_color, hcells, vcells, presentation, gnuplot_template, gnuplot_object, gnuplot_geom, gnuplot_plot_ratio, gnuplot_page_orientation@endcode
|
||||||
|
The <b>page</b> element will be discussed in following sections: @ref plot_element_specifictions "6.2.1.1 Plot Element Specifications",
|
||||||
|
@ref general_variable_options "6.2.1.2 General Variable Options",
|
||||||
|
@ref specific_variable_options "6.2.1.3 DP Specific Y (or Z) Variable Options", and
|
||||||
|
@ref curves "6.2.1.4 Curves".
|
||||||
|
|
||||||
|
#### DP Plot Element Specifications
|
||||||
|
|
||||||
|
The <b>tstart</b> and <b>tstop</b> options have the same function as in the session file. If either of these options
|
||||||
|
is specified, they will override any values specified in the session file for this particular plot page.
|
||||||
|
Each plot page specification can include up to nine individual plot specifications. The size of each
|
||||||
|
of the plots on a plot page is automatically sized to fit within the plot page window regardless of
|
||||||
|
the number of plots specified for the plot page.
|
||||||
|
|
||||||
|
#### General Variable Options
|
||||||
|
|
||||||
|
The general variable options are options that apply to a variable regardless when it's for X, or Y, or Z.
|
||||||
|
They are:
|
||||||
|
|
||||||
|
- The <b>label</b> attribte of var element allows the user to give the parameter
|
||||||
|
(or program token) a name to be used in the legend of a plot.
|
||||||
|
- The <b>units</b> attribute of <b>var</b> allows the user to specify the measurement
|
||||||
|
units in which the specified parameter will be displayed. The measurement units specification
|
||||||
|
syntax is identical to that used in the input processor and ICG parameter comments.
|
||||||
|
- The <b>bias</b> attribute of <b>var</b> allows the user to shift the plot.
|
||||||
|
It is applied after the scaling and unit conversion. X or Y or Z may be shifted.
|
||||||
|
- The <b>max</b> attribute of <b>var</b> allows the user to override the max range options
|
||||||
|
specified at the plot level.
|
||||||
|
- The <b>scale</b> attribute of <b>var</b> allows the user to scale the specified parameter
|
||||||
|
value by a factor of the value specified by this attribute. The scale factor is applied after the
|
||||||
|
measurement units (if specified) conversion is performed.
|
||||||
|
|
||||||
|
#### DP Specific Y (or Z) Variable Options
|
||||||
|
|
||||||
|
The Y (Z) variable specification has additional options which allow the user to specify distinct line, symbol,
|
||||||
|
and color attributes. Even though <b>var</b> element XML specification doesn't limit a X variable having
|
||||||
|
all these options, such restriction is implemented at GUI level.
|
||||||
|
|
||||||
|
These options are:
|
||||||
|
|
||||||
|
- <b>ymbol_style</b>: None|Square|Circle|Star|XX|Triangle|Solid_Square|Solid_Circle|Thick_Square|Thick_Circle
|
||||||
|
- <b>symbol_size</b>: Tiny|Small|Medium|Large
|
||||||
|
- <b>line_sytle</b>: Plain|Dash|No_Line|X_Thick_Line|Fine_Dash|Med_Fine_Dash|Long_Dash|X_Long_Dash|Dot_Dash|2_Dot_Dash|3_Dot_Dash|4_Dot_Dash
|
||||||
|
- <b>line_color</b>: system supported color
|
||||||
|
- <b>gnuplot_line_sytle</b>: lines|points|linespoints|impulses|dots|steps|fsteps|histeps|boxes
|
||||||
|
|
||||||
|
The <b>symbol_style</b> attribute of <b>var</b> allows the user to mark each data point with a specific symbol.
|
||||||
|
The default is None.
|
||||||
|
The <b>line_style attribute</b> of <b>var</b> allows the user to change the line style which connects the X-Y(-Z) data points.
|
||||||
|
The default is Plain.
|
||||||
|
The <b>line_color</b> attribute of <b>var</b> allows the user to specify a color to be used for the X-Y(-Z) plot line and symbol.
|
||||||
|
the <b>gnuplot_line_sytle</b> attribute of <b>var</b> allows the user to change the line style in a Gnuplot.
|
||||||
|
You may specify the line style by name. The default is lines.
|
||||||
|
|
||||||
|
#### Curves
|
||||||
|
Each curve has either specified 2 or 3 variables stated as <b>var</b> or has <b>
|
||||||
|
varcase</b> specified. The first <b>var</b> element is for X, the second <b>var</b>
|
||||||
|
element is for Y and the third is for Z. A <b>curve</b> element can not have both <b>var</b>
|
||||||
|
and <b>varcase</b> elements at same time.
|
||||||
|
If you have specified multiple RUN_ directories that contain the same X, Y, and (Z) variable names, Trick can
|
||||||
|
generate a curve for each RUN_ directory, or a single comparison plot. However, the only <b>var</b>
|
||||||
|
specification makes it very difficult to compare a parameter with one variable name in RUN_A and a different
|
||||||
|
variable name in RUN_B. The <b>varcase</b> specification, on the other hand, allows multiple X, Y, and (Z),
|
||||||
|
which are lists of possible XY(Z) variables that define the curve for each RUN_ directory. If <b>varcase</b>
|
||||||
|
elements do not have unique variable names, DP will use the first <b>varcase</b> that it finds in the logged
|
||||||
|
data and ignores the other <b>varcase</b> elements.
|
||||||
|
As shown in the following DP specification example, it compares sys.exec.out.time (X) and
|
||||||
|
ball.obj.state.output.acceleration[1] (Y) variables from RUN_A and my_other_data.time (X)
|
||||||
|
and my_other_data.acceleration[1] (Y) variables from RUN_B. It also generates curves for
|
||||||
|
sys.exec.out.time (X) and ball.obj.state.output.external_force[0] (Y) from
|
||||||
|
both RUN_A and RUN_B.
|
||||||
|
|
||||||
|
```
|
||||||
|
<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
|
||||||
|
<!DOCTYPE product PUBLIC "-//Tricklab//DTD Product V1.0//EN" "Product.dtd">
|
||||||
|
<product background_color="#ede9e3" foreground_color="#000000" version="1.0">
|
||||||
|
<tstart>-1.0E20</tstart>
|
||||||
|
<tstop>1.0E20</tstop>
|
||||||
|
<frequency>0.0</frequency>
|
||||||
|
<page background_color="#ede9e3" foreground_color="#000000">
|
||||||
|
<title>Page</title>
|
||||||
|
<plot background_color="#ede9e3" foreground_color="#000000" grid="Yes" grid_color="#ffffff">
|
||||||
|
<title>Plot</title>
|
||||||
|
<curve>
|
||||||
|
<varcase>
|
||||||
|
<var units="--">sys.exec.out.time</var>
|
||||||
|
<var units="m/s2">ball.obj.state.output.acceleration[1]</var>
|
||||||
|
</varcase>
|
||||||
|
<varcase>
|
||||||
|
<var units="--">my_other_data.time</var>
|
||||||
|
<var units="m/s2">my_other_data.acceleration[1]</var>
|
||||||
|
</varcase>
|
||||||
|
</curve>
|
||||||
|
<curve>
|
||||||
|
<var units="--">sys.exec.out.time</var>
|
||||||
|
<var units="N">ball.obj.state.output.external_force[0]</var>
|
||||||
|
</curve>
|
||||||
|
</plot>
|
||||||
|
</page>
|
||||||
|
</product>
|
||||||
|
```
|
||||||
|
|
||||||
|
### DP Table Specifications
|
||||||
|
|
||||||
|
Each table is comprised of one or more columns and each column is only for one variable. Each <b>column</b> element
|
||||||
|
has an optional <b>format</b> attribute that allows the user to specify the text format for the variable's data. The
|
||||||
|
syntax of <b>format</b> is the same as that for a C language @p printf format field. Each variable element of
|
||||||
|
<b>column</b> element has those general variable options as stated in
|
||||||
|
Section @ref general_variable_options "6.2.1.2 GeneralVariable Options".
|
||||||
|
|
||||||
|
As shown in the following product example XML file, it has one <b>table</b> defined. This <b>table</b> has
|
||||||
|
4 different columns and each column is corresponding to a specific <b>var</b>.
|
||||||
|
|
||||||
|
```
|
||||||
|
<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
|
||||||
|
<!DOCTYPE product PUBLIC "-//Tricklab//DTD Product V1.0//EN" "Product.dtd">
|
||||||
|
<product background_color="#ede9e3" foreground_color="#000000" version="1.0">
|
||||||
|
<tstart>-1.0E20</tstart>
|
||||||
|
<tstop>1.0E20</tstop>
|
||||||
|
<frequency>0.0</frequency>
|
||||||
|
<table>
|
||||||
|
<title>Table</title>
|
||||||
|
<column>
|
||||||
|
<units>--</units>
|
||||||
|
<var units="m/s2">ball.obj.state.output.acceleration[0]</var>
|
||||||
|
</column>
|
||||||
|
<column>
|
||||||
|
<units>--</units>
|
||||||
|
<var units="m/s2">ball.obj.state.output.acceleration[1]</var>
|
||||||
|
</column>
|
||||||
|
<column>
|
||||||
|
<units>--</units>
|
||||||
|
<var units="N">ball.obj.state.output.external_force[0]</var>
|
||||||
|
</column>
|
||||||
|
<column>
|
||||||
|
<units>--</units>
|
||||||
|
<var units="N">ball.obj.state.output.external_force[1]</var>
|
||||||
|
</column>
|
||||||
|
</table>
|
||||||
|
</product>
|
||||||
|
```
|
||||||
|
|
||||||
|
An example data of the specified table:
|
||||||
|
|
||||||
|
```
|
||||||
|
------------------------------------------------------------------------
|
||||||
|
acceleration[0] acceleration[1] external_force[0] external_force[1]
|
||||||
|
-- -- -- --
|
||||||
|
------------------------------------------------------------------------
|
||||||
|
-6.859943e-01 -4.115966e-01 -6.859943e+00 -4.115966e+00
|
||||||
|
-6.853979e-01 -4.125891e-01 -6.853979e+00 -4.125891e+00
|
||||||
|
-6.848069e-01 -4.135693e-01 -6.848069e+00 -4.135693e+00
|
||||||
|
-6.842212e-01 -4.145375e-01 -6.842212e+00 -4.145375e+00
|
||||||
|
-6.836408e-01 -4.154939e-01 -6.836408e+00 -4.154939e+00
|
||||||
|
-6.830657e-01 -4.164388e-01 -6.830657e+00 -4.164388e+00
|
||||||
|
-6.824956e-01 -4.173724e-01 -6.824956e+00 -4.173724e+00
|
||||||
|
-6.819306e-01 -4.182949e-01 -6.819306e+00 -4.182949e+00
|
||||||
|
-6.813706e-01 -4.192065e-01 -6.813706e+00 -4.192065e+00
|
||||||
|
-6.808155e-01 -4.201075e-01 -6.808155e+00 -4.201075e+00
|
||||||
|
-6.802652e-01 -4.209980e-01 -6.802652e+00 -4.209980e+00
|
||||||
|
-6.797196e-01 -4.218782e-01 -6.797196e+00 -4.218782e+00
|
||||||
|
-6.791788e-01 -4.227484e-01 -6.791788e+00 -4.227484e+00
|
||||||
|
-6.786426e-01 -4.236086e-01 -6.786426e+00 -4.236086e+00
|
||||||
|
-6.781109e-01 -4.244592e-01 -6.781109e+00 -4.244592e+00
|
||||||
|
-6.775837e-01 -4.253003e-01 -6.775837e+00 -4.253003e+00
|
||||||
|
-6.770610e-01 -4.261320e-01 -6.770610e+00 -4.261320e+00
|
||||||
|
-6.765426e-01 -4.269545e-01 -6.765426e+00 -4.269545e+00
|
||||||
|
-6.760285e-01 -4.277680e-01 -6.760285e+00 -4.277680e+00
|
||||||
|
-6.755186e-01 -4.285727e-01 -6.755186e+00 -4.285727e+00
|
||||||
|
-6.750130e-01 -4.293687e-01 -6.750130e+00 -4.293687e+00
|
||||||
|
-6.745114e-01 -4.301562e-01 -6.745114e+00 -4.301562e+00
|
||||||
|
-6.740139e-01 -4.309353e-01 -6.740139e+00 -4.309353e+00
|
||||||
|
```
|
||||||
|
|
||||||
|
### DP External Programs
|
||||||
|
|
||||||
|
The <b>extfn</b> element provides a means for transforming data. Users build a program that is dynamically linked into
|
||||||
|
Trick data products for manipulating data specified in the DP Product XML file and its document type definition file
|
||||||
|
is stated as @ref product_dtd "Product.dtd".
|
||||||
|
|
||||||
|
#### Element extfn Specifications
|
||||||
|
The <b>extfn</b> needs to have 3 element specifications associated with it. These elements are <b>fname</b>, <b>inputs</b>, and <b>outputs</b>.
|
||||||
|
The <b>fname</b> is a full path to a program which accepts the inputs and generates the outputs. This
|
||||||
|
program must adhere to strict interface requirements. This program will be dynamically linked into the data products,
|
||||||
|
which implies it must be built under specific guidelines. Only ONE <b>extfn</b> may be defined per DP XML file.
|
||||||
|
The <b>inputs</b> are specified as a list of simulation variable names or <b>var</b> elements. The <b>outputs</b> is a user defined name list which
|
||||||
|
provides a unique variable name for each of the external program output arguments. These outputs variables may be used throughout
|
||||||
|
the product XML specification file wherever a simulation variable name or <b>var</b> element is required.
|
||||||
|
Inputs will be cast to doubles going to the external program, and outputs must be doubles as well.
|
||||||
|
The following example shows an external program that takes 3 double inputs and return the addition of these 3 inputs.
|
||||||
|
The product specification file (DP_* file) might look like this:
|
||||||
|
|
||||||
|
```
|
||||||
|
<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
|
||||||
|
<!DOCTYPE product PUBLIC "-//Tricklab//DTD Product V1.0//EN" "Product.dtd">
|
||||||
|
<product background_color="#edeceb" foreground_color="#1a1a1a" version="1.0">
|
||||||
|
<tstart>-1.0E20</tstart>
|
||||||
|
<tstop>1.0E20</tstop>
|
||||||
|
<frequency>0.0</frequency>
|
||||||
|
<extfn>
|
||||||
|
<fname>/users/hchen3/trick_test/myextfn/dp_test.so</fname>
|
||||||
|
<inputs>
|
||||||
|
<var units="m">ball.obj.state.output.position[0]</var>
|
||||||
|
<var units="m">ball.obj.state.output.position[1]</var>
|
||||||
|
<var units="m">ball.obj.state.output.position[0]</var>
|
||||||
|
</inputs>
|
||||||
|
<outputs>
|
||||||
|
<measurement>
|
||||||
|
<var>out</var>
|
||||||
|
<units>--</units>
|
||||||
|
</measurement>
|
||||||
|
</outputs>
|
||||||
|
</extfn>
|
||||||
|
<page background_color="#edeceb" foreground_color="#1a1a1a" hcells="0" vcells="0">
|
||||||
|
<title>Page</title>
|
||||||
|
<plot background_color="#edeceb" foreground_color="#1a1a1a" grid="Yes" grid_color="#ffffff">
|
||||||
|
<title>Plot</title>
|
||||||
|
<curve>
|
||||||
|
<var units="s">sys.exec.out.time</var>
|
||||||
|
<var units="--">out</var>
|
||||||
|
</curve>
|
||||||
|
</plot>
|
||||||
|
</page>
|
||||||
|
</product>
|
||||||
|
```
|
||||||
|
|
||||||
|
#### External Program Source Code
|
||||||
|
|
||||||
|
To use the external program feature of the product specification file, a user must either access a previously written
|
||||||
|
program, or write their own.
|
||||||
|
The following is an example external program source file which reads the three inputs and generates one output as
|
||||||
|
specified above. The code example below contains comments which explain the function of the code segments.
|
||||||
|
|
||||||
|
```
|
||||||
|
/* Used for dp test */
|
||||||
|
|
||||||
|
// This line should not change from program to program. The content of this function is application specific and up to user to define.
|
||||||
|
int extGetNextRecord(double *in, int numIn, double *out, int numOut) ;
|
||||||
|
|
||||||
|
// This line should not change from program to program. The content of this function is application specific and up to user to define.
|
||||||
|
int extGetNextRecord(double *in, int numIn __attribute__ ((unused)), double *out, int numOut __attribute__ ((unused)))
|
||||||
|
{
|
||||||
|
out[0] = in[0] + in[1] + in[2];
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Building The External Program
|
||||||
|
|
||||||
|
##### Linux
|
||||||
|
|
||||||
|
- Step 1. cc -c <myprogram1>.c (compile all individual object this way)
|
||||||
|
- Step 2. ld -shared -o <myprogram>.so <myfunction1>.o <myfunction2>.o ... <myfunctionN>.o <myLib>.a -lc
|
||||||
|
|
||||||
|
##### MacOS X
|
||||||
|
|
||||||
|
- Step 1. cc -c <myprogram1>.c (compile all individual object this way)
|
||||||
|
- Step 2. cc -bundle -o <myprogram>.so <myfunction1>.o <myfunction2>.o ... <myfunctionN>.o <myLib>.a -lc
|
||||||
|
|
||||||
|
In the above example, <myprogram>.so is the name that needs to be specified in the DP specification file.
|
||||||
|
If LD_LIBRARY_PATH doesn't point to the location of your shared object, then you just need to sepcify the full path
|
||||||
|
of the shared object in the DP sepcification file.
|
||||||
|
The example above links in <myLib>.a too. It's that simple.
|
||||||
|
Do the following to see if your newly created shared object has unresolved dependencies:
|
||||||
|
|
||||||
|
- @b UNIX @b Prompt> nm <myprogram>.so
|
||||||
|
|
||||||
|
#### External Program Summary
|
||||||
|
|
||||||
|
To use an external program:
|
||||||
|
1. Build a DP spec file with the program name, inputs and outputs.
|
||||||
|
2. Write an external program (or scam one off a friend).
|
||||||
|
3. Build the external program.
|
||||||
|
4. Run the data products, and hopefully the results you expect will be there.
|
||||||
|
|
||||||
|
#### External Program Proglems And Caveats
|
||||||
|
|
||||||
|
- Can't load shared library!!! The external program (*.so program) may have unresolved dependencies.
|
||||||
|
Try "nm" on your external program, and look for "U"s. The objects that you have linked in might have extern definitions that aren't there.
|
||||||
|
- Make sure you specify the full path of the shared object if LD_LIBRARY_PATH is not defined or doesn't point to the location of the shared object.
|
||||||
|
- You cannot scale or bias X values with external programs.
|
||||||
|
- External programs convert everything to doubles, and only accept and output doubles.
|
||||||
|
- External programs have no notion of unit conversion.
|
||||||
|
|
||||||
|
### A general DP Product XML File Example
|
||||||
|
|
||||||
|
```
|
||||||
|
<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
|
||||||
|
<!DOCTYPE product PUBLIC "-//Tricklab//DTD Product V1.0//EN" "Product.dtd">
|
||||||
|
<product background_color="#ede9e3" foreground_color="#000000" version="1.0">
|
||||||
|
<tstart>-1.0E20</tstart>
|
||||||
|
<tstop>1.0E20</tstop>
|
||||||
|
<frequency>0.0</frequency>
|
||||||
|
<page background_color="#ede9e3" foreground_color="#000000">
|
||||||
|
<title>Page</title>
|
||||||
|
<plot background_color="#ede9e3" foreground_color="#000000" grid="Yes" grid_color="#ffffff">
|
||||||
|
<title>Plot</title>
|
||||||
|
<curve>
|
||||||
|
<var units="--">sys.exec.out.time</var>
|
||||||
|
<var units="N">ball.obj.state.output.external_force[0]</var>
|
||||||
|
</curve>
|
||||||
|
</plot>
|
||||||
|
<plot background_color="#ede9e3" foreground_color="#000000" grid="Yes" grid_color="#ffffff">
|
||||||
|
<title>Plot</title>
|
||||||
|
<curve>
|
||||||
|
<var units="--">sys.exec.out.time</var>
|
||||||
|
<var units="N">ball.obj.state.output.external_force[1]</var>
|
||||||
|
</curve>
|
||||||
|
</plot>
|
||||||
|
</page>
|
||||||
|
</product>
|
||||||
|
```
|
||||||
|
|
||||||
|
[Continue to Plot Printing](Plot-Printing)
|
120
docs/documentation/data_products/DP-Session-File-Format.md
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
|
||||||
|
Since Trick 10, the DP Session file is changed to XML format. The Session XML Document
|
||||||
|
Type Definitions(DTD) is defined as following:
|
||||||
|
|
||||||
|
### Session.dtd
|
||||||
|
|
||||||
|
```
|
||||||
|
<!-- Trick DP Session definition -->
|
||||||
|
<!-- V 1.0 -->
|
||||||
|
|
||||||
|
<!ELEMENT tstart (#PCDATA)>
|
||||||
|
<!ELEMENT tstop (#PCDATA)>
|
||||||
|
<!ELEMENT frequency (#PCDATA)>
|
||||||
|
<!ELEMENT file (#PCDATA)>
|
||||||
|
<!ELEMENT dir (#PCDATA)>
|
||||||
|
<!ELEMENT timename (#PCDATA)>
|
||||||
|
<!ELEMENT run (dir)>
|
||||||
|
<!ELEMENT product_files (file+)>
|
||||||
|
<!ELEMENT session ((tstart|tstop|frequency)*, run+, product_files)>
|
||||||
|
|
||||||
|
<!ATTLIST run timename CDATA #IMPLIED>
|
||||||
|
|
||||||
|
<!ATTLIST session version CDATA #REQUIRED>
|
||||||
|
|
||||||
|
<!-- session@presentation attribute
|
||||||
|
|
||||||
|
"simple" - One curve per plot. #plots = #runs x #plot_specifications
|
||||||
|
"comparison" - Multiple runs per plot.
|
||||||
|
"delta" - difference of two runs.
|
||||||
|
"contrast" - some weird thing Danny dreamed up.
|
||||||
|
-->
|
||||||
|
<!ATTLIST session presentation CDATA #REQUIRED>
|
||||||
|
|
||||||
|
<!-- session@mode attribute
|
||||||
|
Indicates a restriction on what in a DP file.
|
||||||
|
|
||||||
|
"plot" - means that only the plots described in a DP file may be created.
|
||||||
|
"table" - means that only tables described in a DP file may be created.
|
||||||
|
default - all plots and tables in the DP may be created.
|
||||||
|
-->
|
||||||
|
<!ATTLIST session mode CDATA #IMPLIED>
|
||||||
|
|
||||||
|
<!ATTLIST session device CDATA #IMPLIED>
|
||||||
|
<!ATTLIST session gnuplot_terminal CDATA #IMPLIED>
|
||||||
|
<!ATTLIST session machine CDATA #IMPLIED>
|
||||||
|
<!ATTLIST session port CDATA #IMPLIED>
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
The <b>session</b> element is required and is the root element of the Session XML file.
|
||||||
|
It encloses all the other elements.
|
||||||
|
|
||||||
|
The optional <b>tstart, tstop</b> child elements of <b>session</b> specify the data
|
||||||
|
within this range gets plotted.
|
||||||
|
|
||||||
|
The optional <b>frequency </b> child element of <b>session</b> specifies the delta time
|
||||||
|
between data points for display purposes. If it is smaller than the delta time of the recorded data
|
||||||
|
or if it is not defined, then the recorded data frequency is used. If it is greater than the recorded
|
||||||
|
data delta time, then it is used. It is specified in seconds.
|
||||||
|
|
||||||
|
The required <b>run</b> child element of session can occur once or more times.
|
||||||
|
It specifies a simulation RUN_ directory as <b>dir</b> stated from which to retrieve data.
|
||||||
|
|
||||||
|
By default, the time name for each run is sys.exec.out.time, however, an optional attribute of each
|
||||||
|
<b>run - timename</b> can be specified if a different name other than
|
||||||
|
the default one is desired.
|
||||||
|
|
||||||
|
The required <b>product_files</b> child element of <b>session</b> can only occur once.
|
||||||
|
It specifies product specification file(s) to use for this session. Any number (but at least one)
|
||||||
|
of product specification files may be specified through its <b>file</b> element. In other words,
|
||||||
|
it can have one or more <b>file</b> elements. In general the product specification files specify
|
||||||
|
the type of product parameters to display for the product, and the display attributes for each parameter.
|
||||||
|
Product specification files are discussed in greater detail in Section @ref DPProductFileFormat "6.2 DP Product File Format".
|
||||||
|
|
||||||
|
The required <b>version</b> attribute of <b>session</b> specifies the version of this file.
|
||||||
|
|
||||||
|
The required <b>presentation</b> attribute of <b>session</b> is only useful when more than
|
||||||
|
one data set is specified. It can be <b>Simple|Comparison|Delta|Contrast</b>. The <b>Simple</b>
|
||||||
|
option will display the data products independently for all data sets specified. The <b>parison</b> option
|
||||||
|
will display the data from all data sets in the same display. The <b>Delta</b> option subtracts
|
||||||
|
the nth data set data from the first data set data and presents the result for data sets 2 through n in
|
||||||
|
the same display. <b>Simple</b> is the default option.
|
||||||
|
|
||||||
|
@anchor session_device The <b>device</b> attribute of <b>session</b> specifies the visualization device
|
||||||
|
for data output. By default, the output data is displayed on the user's current login terminal screen.
|
||||||
|
Device types are currently <b>Terminal (default), Printer, and File</b>.
|
||||||
|
@li In order for Printer to work, you need to set your system variables as stated in "Plot Printing".
|
||||||
|
|
||||||
|
The <b>gnuplot_terminal</b> attribute of <b>session</b> instructs gnuplot to use the given
|
||||||
|
terminal device for output. The terminals supported are <b>X11, postscript color, postscript, png, eps, and aqua
|
||||||
|
(X11 is the default)</b>. The "postscript" terminal yields black-n-white printable files. Thpng will create
|
||||||
|
an image in Portable Network Graphics format. The aqua terminal is for Macintosh and uses native Aqua for plot display.
|
||||||
|
|
||||||
|
The optional <b>machine, port</b> attributes of <b>session</b> specify the name of a machine and the port
|
||||||
|
number for plotting.
|
||||||
|
|
||||||
|
|
||||||
|
### DP Session File Example
|
||||||
|
|
||||||
|
```
|
||||||
|
<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
|
||||||
|
<!DOCTYPE session PUBLIC "-//Tricklab//DTD Session V1.0//EN" "Session.dtd">
|
||||||
|
<session device="Terminal" gnuplot_terminal="" mode="Plot" presentation="Simple" version="1.0">
|
||||||
|
<tstart>-1.0E20</tstart>
|
||||||
|
<tstop>1.0E20</tstop>
|
||||||
|
<frequency>0.0</frequency>
|
||||||
|
<run>
|
||||||
|
<dir>/users/hchen/trick_sims/trunk/SIM_Ball++_L1/RUN_realtime</dir>
|
||||||
|
</run>
|
||||||
|
<run>
|
||||||
|
<dir>/users/hchen/trick_sims/trunk/SIM_Ball++_L1/RUN_test</dir>
|
||||||
|
</run>
|
||||||
|
<product_files>
|
||||||
|
<file>/users/hchen/trick_sims/trunk/SIM_Ball++_L1/DP_Product/DP_test_4.xml</file>
|
||||||
|
<file>/users/hchen/trick_sims/trunk/SIM_Ball++_L1/DP_Product/DP_test_5.xml</file>
|
||||||
|
</product_files>
|
||||||
|
</session>
|
||||||
|
```
|
||||||
|
|
||||||
|
[Continue to DP Product File Format](DP-Product-File-Format)
|
882
docs/documentation/data_products/Data-Products-GUIs.md
Normal file
@ -0,0 +1,882 @@
|
|||||||
|
|
||||||
|
There are two main GUIs for viewing Trick logged data:
|
||||||
|
|
||||||
|
- TrickDP
|
||||||
|
- TrickQP
|
||||||
|
|
||||||
|
These two applications work together and allow the user to plot and tabularize Trick data.
|
||||||
|
|
||||||
|
- Viewing Data
|
||||||
|
|
||||||
|
This section gives various examples of viewing Trick logged data using Trick DP and Trick QP.
|
||||||
|
|
||||||
|
### Trick DP - Data Products Application
|
||||||
|
|
||||||
|
The trick_dp (data products) is designed to make use of data product specification files (DP files). DP specification
|
||||||
|
files are input files which tell data products how and what to display in plots and tables. If time is taken to create the DP
|
||||||
|
specification files, this tool shows its power in perusing large sets of data. The "Help" menu option on the GUI also gives
|
||||||
|
detailed information on its use. To launch the program:
|
||||||
|
|
||||||
|
- <b>UNIX Prompt></b> trick_dp&
|
||||||
|
|
||||||
|
|
||||||
|
### Trick DP GUI
|
||||||
|
|
||||||
|
![trick_dp](images/trick_dp.jpg)
|
||||||
|
|
||||||
|
The graphical user interface of trick_dp contains the menu bar, toolbar and five display areas
|
||||||
|
as shown in the above image. The interface is explained with further details in the following sections:
|
||||||
|
|
||||||
|
- Menu bar
|
||||||
|
- Toolbar
|
||||||
|
- Display areas
|
||||||
|
|
||||||
|
|
||||||
|
#### Trick DP Menu bar
|
||||||
|
|
||||||
|
##### Trick DP Session Menu
|
||||||
|
|
||||||
|
![trick_dp_session_menu](images/trick_dp_session_menu.jpg)
|
||||||
|
|
||||||
|
- <b>New...</b>
|
||||||
|
- Starts a new session.
|
||||||
|
- <b>Open...</b>
|
||||||
|
- Brings up the Open File dialog box to let the user to open a session file.
|
||||||
|
- <b>Save...</b>
|
||||||
|
- Brings up the Save File dialog box to let the user to save the current session to a file.
|
||||||
|
- <b>Refresh...</b>
|
||||||
|
- Refreshes the Sims/Runs Tree.
|
||||||
|
- <b>Look and Feel</b>
|
||||||
|
- Changes the Look and Feel for the GUI.
|
||||||
|
- <b>Show Exit Confirmation Prompt</b>
|
||||||
|
- Toggles whether to show the Confirm Exit dialog box before exiting the GUI.
|
||||||
|
- <b>Exit</b>
|
||||||
|
- Exits the GUI. If Show Exit Confirmation Prompt is checked, Confirm Exit dialog box would be displayed. Otherwise, exits immediately.
|
||||||
|
|
||||||
|
##### Trick DP Simrun Menu
|
||||||
|
|
||||||
|
![trick_dp_simrun_menu](images/trick_dp_simrun_menu.jpg)
|
||||||
|
|
||||||
|
- <b>Import Sim Dir...</b>
|
||||||
|
- Imports a SIM dir that will be added to the Sims/Runs Tree area.
|
||||||
|
- <b>Add Run Dir...</b>
|
||||||
|
- Adds the selected RUN dir to the Run Selections area.
|
||||||
|
|
||||||
|
<b>Data Product</b>
|
||||||
|
|
||||||
|
![trick_dp_dataproduct_menu](images/trick_dp_dataproduct_menu.jpg)
|
||||||
|
|
||||||
|
- <b>Add DP...</b>
|
||||||
|
- Adds the selected DP file to the "DP Selections" area.
|
||||||
|
- <b>Edit DP...</b>
|
||||||
|
- Edits the selected DP file by opening up the Quickplot Application.
|
||||||
|
- <b>Filter...</b>
|
||||||
|
- Filters the displayed "DP Tree" so that is shows only DP files that contain the specified characters.
|
||||||
|
|
||||||
|
![trick_dp_settings_menu](images/trick_dp_settings_menu.jpg)
|
||||||
|
- <b>Device</b>
|
||||||
|
- This option sets where the plot should go to. 3 available options are:
|
||||||
|
- Terminal (by default)
|
||||||
|
- Printer
|
||||||
|
- File
|
||||||
|
- <b>Plot Utility</b>
|
||||||
|
- This option sets which plotting utility to use. 2 available options:
|
||||||
|
- Fermi
|
||||||
|
- Gnuplot
|
||||||
|
|
||||||
|
##### Trick DP Actions Menu
|
||||||
|
|
||||||
|
![trick_dp_actions_menu](images/trick_dp_actions_menu.jpg)
|
||||||
|
|
||||||
|
- <b>Single Plot...</b>
|
||||||
|
- Displays the data products independently for all data sets specified.
|
||||||
|
- <b>Comparison Plot...</b>
|
||||||
|
- Displays the data from all data sets in the same display.
|
||||||
|
- <b>Error Plot...</b>
|
||||||
|
- Subtracts the nth data set data from the first data set data and presents the result for data set 2 through n in the same display.
|
||||||
|
- <b>Contrast Plot...</b>
|
||||||
|
- Displays a comparison plot and a delta plot on the same page.
|
||||||
|
- <b>Table...</b>
|
||||||
|
- Displays selected variable data in a table.
|
||||||
|
- <b>Table Error...</b>
|
||||||
|
- TBD.
|
||||||
|
- <b>GNUplot Postscript Single Plot...</b>
|
||||||
|
- TBD.
|
||||||
|
- <b>GNUplot Postscript Comparison Plot...</b>
|
||||||
|
- TBD.
|
||||||
|
- <b>GNUplot Postscript Error Plot...</b>
|
||||||
|
- TBD.
|
||||||
|
- <b>Quickplot</b>
|
||||||
|
- Launches the Quickplot application.
|
||||||
|
- <b>Create PDF Booklet...</b>
|
||||||
|
- Allows users to view, merge, or create a PDF file for the selected postscript file(s).
|
||||||
|
|
||||||
|
##### Trick DP Help Menu
|
||||||
|
|
||||||
|
![trick_dp_help_menu](images/trick_dp_help_menu.jpg)
|
||||||
|
|
||||||
|
- <b>Help Contents</b>
|
||||||
|
- Brings up on-line help.
|
||||||
|
- <b>About...</b>
|
||||||
|
- Shows the information about this application.
|
||||||
|
|
||||||
|
#### Toolbar
|
||||||
|
|
||||||
|
![trick_dp_toolbar](images/trick_dp_toolbar.jpg)
|
||||||
|
|
||||||
|
These icon buttons eables easier access to those commonly used functions. The functionality of each button is the same as
|
||||||
|
the menu item that shares the same icon. A tooltip of the button will be displayed if moving the mouse pointer over any
|
||||||
|
of these buttons.
|
||||||
|
|
||||||
|
#### Display areas
|
||||||
|
|
||||||
|
There are 5 display areas that are Sims/Runs Tree (upper left), DP Tree (upper right),
|
||||||
|
Run Selections (middle left), DP Selections (middle right) and the bottom is
|
||||||
|
a message display area.
|
||||||
|
|
||||||
|
Please note that all sim directories start with <b>SIM</b>, all run directories starts with <b>RUN</b> or <b>MONTE_RUN</b>, and
|
||||||
|
all data product files start with <b>DP</b> and are placed in <b>DP_Product</b> directory within a <b>SIM</b> directory.
|
||||||
|
|
||||||
|
##### Sims/Runs Tree
|
||||||
|
|
||||||
|
Launching trick_dp in a directory that contains SIM directories will cause those SIM directories to be displayed
|
||||||
|
in this area as shown below. If no SIM directories exist in the launch directory, trick_dp will display SIMs from
|
||||||
|
$TRICK_USER_HOME by default. If $TRICK_USER_HOME is not defined, SIMs from $HOME will be displayed. If this is not
|
||||||
|
the first time to run trick_dp on this machine, all previously imported SIMs will be displayed also.
|
||||||
|
|
||||||
|
SIMs initially appear unexpanded in the Sims/Runs Tree. Double clicking a SIM node or
|
||||||
|
single clicking the node icon on the left will show runs contained in that SIM. Runs in black contain data and
|
||||||
|
in grey contain no data.
|
||||||
|
|
||||||
|
<b>Trick DP - Sims/Runs Tree</b>
|
||||||
|
|
||||||
|
![trick_dp_simrun_area](images/trick_dp_simrun_area.jpg)
|
||||||
|
|
||||||
|
##### Sims/Runs Tree Popup Menus
|
||||||
|
|
||||||
|
![trick_dp_simrun_popup1](images/trick_dp_simrun_popup1.jpg)
|
||||||
|
|
||||||
|
- <b>Refresh</b>
|
||||||
|
- Refreshes the highlighted directory.
|
||||||
|
- <b>Opentree</b>
|
||||||
|
- Expands the highlighted directory.
|
||||||
|
- <b>Closetree</b>
|
||||||
|
- Collapses the highlighted directory.
|
||||||
|
- <b>Remove</b>
|
||||||
|
- Removes the highlighted directory from the tree. It does not physically remove the directory from your file system.
|
||||||
|
|
||||||
|
##### Sims/Runs Tree Popup Menus
|
||||||
|
|
||||||
|
![trick_dp_simrun_popup2](images/trick_dp_simrun_popup2.jpg)
|
||||||
|
|
||||||
|
- <b>Add run(s)</b>
|
||||||
|
- Adds all RUN directories that contains data in all highlighted SIM directories to the "Run Selections" area.
|
||||||
|
- <b>Read DP List</b>
|
||||||
|
- Adds all DP files in that SIM directory to the DP Tree area if any of RUN directories in that
|
||||||
|
SIM directory contains data.
|
||||||
|
- <b>Refresh</b>
|
||||||
|
- Refreshes the highlighted directory.
|
||||||
|
- <b>Opentree</b>
|
||||||
|
- Expands the highlighted directory.
|
||||||
|
- <b>Closetree</b>
|
||||||
|
- Collapses the highlighted directory.
|
||||||
|
- <b>Remove</b>
|
||||||
|
- Removes the selected directory from the tree. It does not physically remove the directory from your file system.
|
||||||
|
|
||||||
|
###### Sims/Runs Tree Popup Menus
|
||||||
|
|
||||||
|
![trick_dp_simrun_popup3](images/trick_dp_simrun_popup3.jpg)
|
||||||
|
|
||||||
|
- <b>Add run(s)</b>
|
||||||
|
- Adds all highlighted RUN directories that contains data to the "Run Selections" area.
|
||||||
|
- <b>Quickplot...</b>
|
||||||
|
- Launches the Quickplot application.
|
||||||
|
- <b>Run Sim</b>
|
||||||
|
- Runs the sim from each sim directory using the input.py from the corresponding highlighted RUN directory.
|
||||||
|
|
||||||
|
###### DP Tree
|
||||||
|
|
||||||
|
DP files in DP_Product of SIM directories are displayed here in a tree structure. Double clicking a SIM node
|
||||||
|
or single clicking the node icon on the left of a SIM node from the Sims/Runs Tree will make all DP files
|
||||||
|
displayed here automatically. You also can add all DP files in a desired SIM directory by right clicking it
|
||||||
|
from Sims/Runs Tree and selecting Read DP List from the popup menu list.
|
||||||
|
|
||||||
|
<b>Trick DP - DP Tree</b>
|
||||||
|
|
||||||
|
![trick_dp_dptree_area](images/trick_dp_dptree_area.jpg)
|
||||||
|
|
||||||
|
###### DP Tree Popup Menus
|
||||||
|
|
||||||
|
Right clicking on a tree node at any level from the DP Tree as shown above causes a corresponding popup menu displayed.
|
||||||
|
|
||||||
|
###### DP Tree Popup Menus
|
||||||
|
|
||||||
|
![trick_dp_tree_popup1](images/trick_dp_tree_popup1.jpg)
|
||||||
|
|
||||||
|
- <b>Add DPs</b>
|
||||||
|
- Adds all DP files in the highlighted directories to the DP Selections.
|
||||||
|
- <b>Refresh</b>
|
||||||
|
- Refreshes all highlighted directories.
|
||||||
|
- <b>Remove</b>
|
||||||
|
- Removes the highlighted directory from the tree. It does not physically remove the directory from your file system.
|
||||||
|
|
||||||
|
###### DP Tree Popup Menus
|
||||||
|
|
||||||
|
![trick_dp_tree_popup2](images/trick_dp_tree_popup2.jpg)
|
||||||
|
|
||||||
|
- <b>Add DPs</b>
|
||||||
|
- Adds all DP files in the highlighted directories to the DP Selections.
|
||||||
|
- <b>Refresh</b>
|
||||||
|
- Refreshes all highlighted directories.
|
||||||
|
- <b>Remove</b>
|
||||||
|
- Removes the highlighted directory from the tree. It does not physically remove the directory from your file system.
|
||||||
|
|
||||||
|
###### DP Tree Popup Menus
|
||||||
|
|
||||||
|
![trick_dp_tree_popup3](images/trick_dp_tree_popup3.jpg)
|
||||||
|
|
||||||
|
- <b>Add DPs</b>
|
||||||
|
- Adds all DP files in the highlighted directories to the "DP Selections".
|
||||||
|
- <b>Refresh</b>
|
||||||
|
- Refreshes all highlighted directories.
|
||||||
|
|
||||||
|
###### DP Tree Popup Menus
|
||||||
|
|
||||||
|
![trick_dp_tree_popup4](images/trick_dp_tree_popup4.jpg)
|
||||||
|
|
||||||
|
- <b>Add DPs</b>
|
||||||
|
- Adds all highlighted DP files to the DP Selections.
|
||||||
|
- <b>Edit DP...</b>
|
||||||
|
- Opens the selected DP file with Quickplot application for editing.
|
||||||
|
|
||||||
|
###### Run Selections
|
||||||
|
|
||||||
|
All selected RUN directories for retriving data from for plotting are listed here. You can select a RUN or RUN(s) by:
|
||||||
|
- Double clicking a RUN directory in black from Sims/Runs Tree
|
||||||
|
- Right clicking on highlighted RUN directories and selecting Add Runs
|
||||||
|
- Right clicking on highlighted SIM directories and selecting Add Runs
|
||||||
|
<b>Trick DP - Run Selections</b>
|
||||||
|
|
||||||
|
![trick_dp_runselections_area](images/trick_dp_runselections_area.jpg)
|
||||||
|
|
||||||
|
###### Run Selections Popup Menus
|
||||||
|
|
||||||
|
Right clicking on a RUN from the list brings up a popup menu.
|
||||||
|
|
||||||
|
![trick_run_selections_popup1](images/trick_run_selections_popup1.jpg)
|
||||||
|
|
||||||
|
- <b>Remove</b>
|
||||||
|
- Removes all of highlighted RUN from the list.
|
||||||
|
- <b>Remove All</b>
|
||||||
|
- Removes all RUN directories from the list.
|
||||||
|
- <b>Quickplot...</b>
|
||||||
|
- Launches Quickplot application for the selected RUN(s).
|
||||||
|
- <b>Configure Time Name...</b>
|
||||||
|
- Brings up the following input dialog to let users to configure the RUN's time name.
|
||||||
|
- By default, RUN's time name is sys.exec.out.time
|
||||||
|
|
||||||
|
![trick_run_selections_input_timename](images/trick_run_selections_input_timename.jpg)
|
||||||
|
|
||||||
|
###### DP Selections
|
||||||
|
|
||||||
|
All selected DP files that tell data products how and what to display in plots and tables are listed here.
|
||||||
|
<b>Trick DP - DP Selections</b>
|
||||||
|
![trick_dp_dpselections_area](images/trick_dp_dpselections_area.jpg)
|
||||||
|
|
||||||
|
###### DP Selections Popup Menus
|
||||||
|
|
||||||
|
Right clicking on a DP file from the list brings up a popup menu.
|
||||||
|
|
||||||
|
![trick_dp_selections_popup1](images/trick_dp_selections_popup1.jpg)
|
||||||
|
|
||||||
|
- <b>Edit DP...</b>
|
||||||
|
- Opens the selected DP file with Quickplot application for editing.
|
||||||
|
- <b>Remove</b>
|
||||||
|
- Removes all of highlighted DP files from the list.
|
||||||
|
- <b>Remove All</b>
|
||||||
|
- Removes all DP files from the list.
|
||||||
|
|
||||||
|
###### Message Display
|
||||||
|
|
||||||
|
This display redirects all screen printout to here to let users know what it is been doing or what has gone wrong.
|
||||||
|
<b>Trick DP - Message Display</b>
|
||||||
|
![trick_dp_msg_area](images/trick_dp_msg_area.jpg)
|
||||||
|
|
||||||
|
### Trick QP - Quickplot Application
|
||||||
|
|
||||||
|
The trick_qp is designed for a quick peek at data in a particular RUN. It is also designed to create the DP specification
|
||||||
|
files that the trick_dp uses. Quickplot usage can be abused. It is best to take time to make a DP specification file using
|
||||||
|
Quickplot, then use the trick_dp for plotting. To launch the quickplot program:
|
||||||
|
|
||||||
|
```
|
||||||
|
<b>UNIX Prompt></b> trick_dp
|
||||||
|
```
|
||||||
|
|
||||||
|
Select a RUN directory (or multiple RUN directories if comparing data sets).
|
||||||
|
Click the blue lightning bolt icon to launch Quickplot.
|
||||||
|
|
||||||
|
OR
|
||||||
|
|
||||||
|
```
|
||||||
|
<b>UNIX Prompt></b> trick_qp RUN<name> &
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Trick QP GUI
|
||||||
|
|
||||||
|
![trick_qp](images/trick_qp.jpg)
|
||||||
|
|
||||||
|
Similar to Trick DP, the graphical user interface of Trick QP also contains the menu bar, toolbar and five display areas
|
||||||
|
as shown in the above image. The interface is explained with further details in the following sections:
|
||||||
|
|
||||||
|
- Menu bar
|
||||||
|
- Toolbar
|
||||||
|
- Display areas
|
||||||
|
|
||||||
|
##### Menu bar
|
||||||
|
|
||||||
|
This table shows all of the menus along with their menu items and functionalities related to the Trick QP menu bar:
|
||||||
|
|
||||||
|
##### Trick QP File Menu
|
||||||
|
|
||||||
|
![trick_qp_file_menu](images/trick_qp_file_menu.jpg)
|
||||||
|
|
||||||
|
- <b>New DP...</b>
|
||||||
|
- Starts a new DP file.
|
||||||
|
- <b>Open DP...</b>
|
||||||
|
- Brings up the Open File dialog box to let the user to open a DP file.
|
||||||
|
- <b>Refresh...</b>
|
||||||
|
- Refreshes all variables in "Vars" area.
|
||||||
|
- <b>Save...</b>
|
||||||
|
- Saves to the currently opened DP file if available, otherwise, users can sepecify a file to save to.
|
||||||
|
- <b>Save As...</b>
|
||||||
|
- Brings up the Save File dialog box to let the use to save to a specified DP file.
|
||||||
|
- <b>Look and Feel</b>
|
||||||
|
- Changes the Look and Feel for the GUI.
|
||||||
|
- <b>Show Exit Confirmation Prompt</b>
|
||||||
|
- Toggles whether to show the Confirm Exit dialog box before exiting the GUI.
|
||||||
|
- <b>Exit</b>
|
||||||
|
- Exits the GUI. If Show Exit Confirmation Prompt is checked, Confirm Exit dialog box would be displayed. Otherwise, exits immediately.
|
||||||
|
|
||||||
|
##### Trick QP Vars Menu
|
||||||
|
|
||||||
|
![trick_qp_vars_menu](images/trick_qp_vars_menu.jpg)
|
||||||
|
|
||||||
|
- <b>Add Var</b>
|
||||||
|
- Adds the Vars highlighted variables to DP Content on the right.
|
||||||
|
- If nothing is highlighted or if "Plots" is highlighted:
|
||||||
|
- One plot per page for each selected variable will be created.
|
||||||
|
- If "Tables" is highlighted:
|
||||||
|
- One table with each variable representing one column will be created.
|
||||||
|
- If "Programs" is highlighted :
|
||||||
|
- Nothing will happen.
|
||||||
|
- If any sub node of "Plots", "Tables", or "Programs" is highlighted:
|
||||||
|
- Variables will be added to the corresponding node if possible.
|
||||||
|
- <b>Expand Var</b>
|
||||||
|
- Expands the Vars highlighted variables.
|
||||||
|
- <b>Contract Var</b>
|
||||||
|
- Collaps the Vars highlighted variables.
|
||||||
|
- <b>Change Units...</b>
|
||||||
|
- Prompts for changing highlighted variables (first one if multiple variables selected) units.
|
||||||
|
|
||||||
|
##### Trick QP Runs Menu
|
||||||
|
|
||||||
|
![trick_qp_runs_menu](images/trick_qp_runs_menu.jpg)
|
||||||
|
|
||||||
|
- <b>Add Run...</b>
|
||||||
|
- Adds the highlighted RUN directory to "Runs" area.
|
||||||
|
- <b>Remove Run</b>
|
||||||
|
- Removes all highlighted RUN directories from "Runs" area.
|
||||||
|
|
||||||
|
##### Trick QP Plots Menu
|
||||||
|
|
||||||
|
![trick_qp_plots_menu](images/trick_qp_plots_menu.jpg)
|
||||||
|
|
||||||
|
- <b>New Page</b>
|
||||||
|
- Adds an empty new page.
|
||||||
|
- <b>Remove All Pages</b>
|
||||||
|
- Removes all currently shown pages.
|
||||||
|
- <b>New Plot</b>
|
||||||
|
- Adds a new empty plot to the currently selected page.
|
||||||
|
- <b>New Curve</b>
|
||||||
|
- Adds a new empty curve to the currently selected plot.
|
||||||
|
- <b>New Varcase</b>
|
||||||
|
- Adds a new varcase to the currently selected curve.
|
||||||
|
|
||||||
|
##### Trick QP Tables Menu
|
||||||
|
|
||||||
|
![trick_qp_tables_menu](images/trick_qp_tables_menu.jpg)
|
||||||
|
|
||||||
|
- <b>New Table</b>
|
||||||
|
- Adds a new empty table.
|
||||||
|
- <b>Remove All Tables</b>
|
||||||
|
- Removes all tables.
|
||||||
|
- <b>New Column</b>
|
||||||
|
- Adds a new empty column to the currently selected table.
|
||||||
|
|
||||||
|
##### Trick QP Programs Menu
|
||||||
|
|
||||||
|
![trick_qp_programs_menu](images/trick_qp_programs_menu.jpg)
|
||||||
|
|
||||||
|
- <b>New Program</b>
|
||||||
|
- Adds a new empty program.
|
||||||
|
- See External Programs for more details about a program.
|
||||||
|
- <b>Remove All Programs</b>
|
||||||
|
- Removes all programs.
|
||||||
|
- <b>New Output...</b>
|
||||||
|
- Adds a new output for the currently selected program.
|
||||||
|
|
||||||
|
##### Trick QP Programs Menu
|
||||||
|
|
||||||
|
![trick_qp_settings_menu](images/trick_qp_settings_menu.jpg)
|
||||||
|
|
||||||
|
- <b>Plot Utility</b>
|
||||||
|
- Selects either Fermi or Gnuplot for plotting.
|
||||||
|
|
||||||
|
##### Trick QP Programs Menu
|
||||||
|
|
||||||
|
![trick_qp_actions_menu](images/trick_qp_actions_menu.jpg)
|
||||||
|
|
||||||
|
- <b>Single Plot...</b>
|
||||||
|
- Displays the data products independently for all data sets specified.
|
||||||
|
- <b>Comparison Plot...</b>
|
||||||
|
- Displays the data from all data sets in the same display.
|
||||||
|
- <b>Error Plot...</b>
|
||||||
|
- Subtracts the nth data set data from the first data set data and presents the result for data set 2 through n in the same display.
|
||||||
|
- <b>Contrast Plot...</b>
|
||||||
|
- Displays a comparison plot and a delta plot on the same page.
|
||||||
|
- <b>Table...</b>
|
||||||
|
- Displays selected variable data in a table.
|
||||||
|
- <b>Table Error...</b>
|
||||||
|
- TBD.
|
||||||
|
|
||||||
|
##### Trick QP Programs Menu
|
||||||
|
|
||||||
|
![trick_qp_help_menu](images/trick_qp_help_menu.jpg)
|
||||||
|
|
||||||
|
- <b>Help Contents</b>
|
||||||
|
- Brings up on-line help.
|
||||||
|
- <b>About...</b>
|
||||||
|
- Shows the information about this application.
|
||||||
|
|
||||||
|
##### Toolbar
|
||||||
|
|
||||||
|
![trick_qp_toolbar](images/trick_qp_toolbar.jpg)
|
||||||
|
|
||||||
|
These icon buttons eables easier access to those commonly used functions. The functionality of each button is the same as
|
||||||
|
the menu item that shares the same icon. A tooltip of the button will be displayed if moving the mouse pointer over any
|
||||||
|
of these buttons.
|
||||||
|
|
||||||
|
|
||||||
|
##### Display areas
|
||||||
|
|
||||||
|
There are 5 display areas that are Vars (upper left), DP Content (upper right),
|
||||||
|
Runs (middle left), Property Notebook (middle right) and the bottom is
|
||||||
|
a message display area.
|
||||||
|
|
||||||
|
|
||||||
|
##### Vars
|
||||||
|
|
||||||
|
All variables that are found in Trick log data files from the selected RUN directories are listed here. If variables shown in red, means that they do not exist in every RUN directory.
|
||||||
|
|
||||||
|
<b>Trick QP - Vars</b>
|
||||||
|
![trick_qp_vars_area](images/trick_qp_vars_area.jpg)
|
||||||
|
|
||||||
|
##### Vars Popup Menus
|
||||||
|
|
||||||
|
Right clicking on a variable from the Vars as shown above causes a corresponding popup menu displayed. This menu is actually the same as Vars menu.
|
||||||
|
|
||||||
|
##### Vars Popup Menus
|
||||||
|
|
||||||
|
![trick_vars_popup1](images/trick_qp_vars_popup1.jpg)
|
||||||
|
- <b>Add Var</b>
|
||||||
|
- Adds the Vars highlighted variables to DP Content on the right.
|
||||||
|
- If nothing is highlighted or if "Plots" is highlighted:
|
||||||
|
- One plot per page for each selected variable will be created.
|
||||||
|
- If "Tables" is highlighted:
|
||||||
|
- One table with each variable representing one column will be created.
|
||||||
|
- If "Programs" is highlighted :
|
||||||
|
- Nothing will happen.
|
||||||
|
- If any sub node of "Plots", "Tables", or "Programs" is highlighted:
|
||||||
|
- Variables will be added to the corresponding node if possible.
|
||||||
|
- <b>Expand Var</b>
|
||||||
|
- Expands the Vars highlighted variables.
|
||||||
|
- <b>Contract Var</b>
|
||||||
|
- Collaps the Vars highlighted variables.
|
||||||
|
- <b>Change Units...</b>
|
||||||
|
- Prompts for changing highlighted variables (first one if multiple variables selected) units.
|
||||||
|
|
||||||
|
###### DP Content
|
||||||
|
|
||||||
|
DP Content area presents the content of a DP file graphically.
|
||||||
|
|
||||||
|
<b>Trick QP - DP Content</b>
|
||||||
|
|
||||||
|
![trick_qp_dpcontent_area](images/trick_qp_dpcontent_area.jpg)
|
||||||
|
|
||||||
|
###### DP Content Popup Menus
|
||||||
|
|
||||||
|
Right clicking on a tree node at any level from the DP Content as shown above causes a corresponding popup menu displayed.
|
||||||
|
|
||||||
|
###### DP Content Popup Menus
|
||||||
|
|
||||||
|
![trick_qp_dpcontent_popup1](images/trick_qp_dpcontent_popup1.jpg)
|
||||||
|
|
||||||
|
- <b>New Page</b>
|
||||||
|
- Creates a new page node.
|
||||||
|
- <b>Remove All Pages</b>
|
||||||
|
- Removes all pages.
|
||||||
|
|
||||||
|
###### DP Content Popup Menus
|
||||||
|
|
||||||
|
![trick_qp_dpcontent_popup2](images/trick_qp_dpcontent_popup2.jpg)
|
||||||
|
|
||||||
|
- <b>New Plot</b>
|
||||||
|
- Creates a new plot node for the page.
|
||||||
|
- <b>Remove</b>
|
||||||
|
- Removes this page.
|
||||||
|
|
||||||
|
###### DP Content Popup Menus
|
||||||
|
|
||||||
|
![trick_qp_dpcontent_popup3](images/trick_qp_dpcontent_popup3.jpg)
|
||||||
|
|
||||||
|
- <b>New Curve</b>
|
||||||
|
- Creates a new curve node for the plot.
|
||||||
|
- <b>Remove</b>
|
||||||
|
- Removes this plot.
|
||||||
|
|
||||||
|
###### DP Content Popup Menus
|
||||||
|
|
||||||
|
![trick_qp_dpcontent_popup4](images/trick_qp_dpcontent_popup4.jpg)
|
||||||
|
|
||||||
|
- <b>Add Var</b>
|
||||||
|
- Adds the highlighted variable from Vars to this curve.
|
||||||
|
- If more than one variables are highlighted, error window will be shown.
|
||||||
|
- Only one variable can be added to a curve and by default, the X variable is sys.exec.out.time.
|
||||||
|
- A variable from Vars can be dragged over sys.exec.out.time to replace it.
|
||||||
|
- Also, a variable from Vars can be added to a curve by dragging it over the curve node.
|
||||||
|
- <b>Remove</b>
|
||||||
|
- Removes this curve.
|
||||||
|
- <b>New Varcase</b>
|
||||||
|
- Adds a new varcase node.
|
||||||
|
- If there are already variables added for this curve, new varcase node can not be added.
|
||||||
|
|
||||||
|
###### DP Content Popup Menus
|
||||||
|
|
||||||
|
![trick_qp_dpcontent_popup5](images/trick_qp_dpcontent_popup5.jpg)
|
||||||
|
|
||||||
|
- <b>Remove</b>
|
||||||
|
- Removes this variable.
|
||||||
|
- X variable can not be removed.
|
||||||
|
- X variable can be replaced.
|
||||||
|
- Y variable can be removed.
|
||||||
|
- Y variable can not be replaced. You need to simply remove the Y variable, and then add a new variable.
|
||||||
|
|
||||||
|
###### DP Content Popup Menus
|
||||||
|
|
||||||
|
![trick_qp_dpcontent_popup6](images/trick_qp_dpcontent_popup6.jpg)
|
||||||
|
|
||||||
|
- <b>Add Var</b>
|
||||||
|
- Adds the highlighted variable from Vars to the varcase.
|
||||||
|
- If more than one variables are highlighted, error window will be shown.
|
||||||
|
- Only one variable can be added to a varcase and by default, the X variable is sys.exec.out.time.
|
||||||
|
- A variable from Vars can be dragged over sys.exec.out.time to replace it.
|
||||||
|
- Also, a variable from Vars can be added to a varcase by dragging it over the varcase node.
|
||||||
|
- <b>Remove</b>
|
||||||
|
- Removes this variable.
|
||||||
|
- X variable can not be removed.
|
||||||
|
- X variable can be replaced.
|
||||||
|
- Y variable can be removed.
|
||||||
|
- Y variable can not be replaced. You need to simply remove the Y variable, and then add a new variable.
|
||||||
|
|
||||||
|
###### DP Content Popup Menus
|
||||||
|
|
||||||
|
![trick_qp_dpcontent_popup7](images/trick_qp_dpcontent_popup7.jpg)
|
||||||
|
|
||||||
|
- <b>New Table</b>
|
||||||
|
- Creates a new table without any columns.
|
||||||
|
- <b>Remove All Tables</b>
|
||||||
|
- Removes all tables.
|
||||||
|
|
||||||
|
###### DP Content Popup Menus
|
||||||
|
|
||||||
|
![trick_qp_dpcontent_popup8](images/trick_qp_dpcontent_popup8.jpg)
|
||||||
|
|
||||||
|
- <b>Add Var</b>
|
||||||
|
- Adds highlighted variables from Vars to this table. Each variable represents a column.
|
||||||
|
- <b>Remove</b>
|
||||||
|
- Removes this table.
|
||||||
|
|
||||||
|
###### DP Content Popup Menus
|
||||||
|
|
||||||
|
![trick_qp_dpcontent_popup9](images/trick_qp_dpcontent_popup9.jpg)
|
||||||
|
|
||||||
|
- <b>Remove</b>
|
||||||
|
- Removes this column.
|
||||||
|
|
||||||
|
###### DP Content Popup Menus
|
||||||
|
|
||||||
|
![trick_qp_dpcontent_popup10](images/trick_qp_dpcontent_popup10.jpg)
|
||||||
|
|
||||||
|
- <b>Remove</b>
|
||||||
|
- Removes the this hightlighted variable.
|
||||||
|
- Also removes the column which it belongs to as each column has only on variable associated with it.
|
||||||
|
|
||||||
|
###### DP Content Popup Menus
|
||||||
|
|
||||||
|
![trick_qp_dpcontent_popup11](images/trick_qp_dpcontent_popup11.jpg)
|
||||||
|
|
||||||
|
- <b>New Program</b>
|
||||||
|
- Adds a new PROGRAM.
|
||||||
|
- See External Programs for more details about a program.
|
||||||
|
- <b>Remove All Programs</b>
|
||||||
|
- Removes all programs. Currently only one program is supported.
|
||||||
|
|
||||||
|
###### DP Content Popup Menus
|
||||||
|
|
||||||
|
![trick_qp_dpcontent_popup12](images/trick_qp_dpcontent_popup12.jpg)
|
||||||
|
|
||||||
|
- <b>Remove</b>
|
||||||
|
- Removes the program.
|
||||||
|
|
||||||
|
###### DP Content Popup Menus
|
||||||
|
|
||||||
|
![trick_qp_dpcontent_popup13](images/trick_qp_dpcontent_popup13.jpg)
|
||||||
|
|
||||||
|
- <b>Add Var</b>
|
||||||
|
- Adds highlighted variables from Vars to Input.
|
||||||
|
|
||||||
|
###### DP Content Popup Menus
|
||||||
|
|
||||||
|
![trick_qp_dpcontent_popup14](images/trick_qp_dpcontent_popup14.jpg)
|
||||||
|
|
||||||
|
- <b>Remove</b>
|
||||||
|
- Removes the highlighted variable.
|
||||||
|
|
||||||
|
###### DP Content Popup Menus
|
||||||
|
|
||||||
|
![trick_qp_dpcontent_popup15](images/trick_qp_dpcontent_popup15.jpg)
|
||||||
|
|
||||||
|
- <b>New Output</b>
|
||||||
|
- Brings up a window for users to enter the output name for the program.
|
||||||
|
|
||||||
|
![trick_qp_dpcontent_popup16](images/trick_qp_dpcontent_popup16.jpg)
|
||||||
|
|
||||||
|
- Accepts the entered name by clicking Ok and the output name will be added to Vars in red such as "out" as shown .
|
||||||
|
|
||||||
|
![trick_qp_dpcontent_popup17](images/trick_qp_dpcontent_popup17.jpg)
|
||||||
|
|
||||||
|
##### Trick QP Run Selections
|
||||||
|
All selected RUN directories for retriving data from for plotting are listed here.
|
||||||
|
|
||||||
|
![trick_qp_runs_area](images/trick_qp_runs_area.jpg)
|
||||||
|
###### Runs Popup Menus
|
||||||
|
|
||||||
|
Right clicking on a RUN from the list brings up a corresponding popup menu.
|
||||||
|
|
||||||
|
![trick_qp_runs_popup1](images/trick_qp_runs_popup1.jpg)
|
||||||
|
|
||||||
|
- <b>Remove</b>
|
||||||
|
- Removes all of highlighted RUN from the list.
|
||||||
|
- <b>Configure Time Name...</b>
|
||||||
|
- Brings up the following input dialog to let users to configure the RUN's time name.
|
||||||
|
- By default, RUN's time name is sys.exec.out.time
|
||||||
|
|
||||||
|
![trick_qp_runs_selections_input_timename](images/trick_qp_runs_selections_input_timename.jpg)
|
||||||
|
###### Property Notebook
|
||||||
|
|
||||||
|
All editable data entries for the selected node from DP Content are displayed here.
|
||||||
|
You are required to click <b>Apply Change</b> button to save all the changes made.
|
||||||
|
Otherwise, all changes will be lost if browsing a different node and come back to it.
|
||||||
|
<b>Trick QP - Property Notebeook</b>
|
||||||
|
|
||||||
|
![trick_qp_notebook_area](images/trick_qp_notebook_area.jpg)
|
||||||
|
|
||||||
|
###### Message Display
|
||||||
|
|
||||||
|
This display redirects all screen printout to here to let users know what it is been doing or what has gone wrong.
|
||||||
|
<b>Trick QP - Message Display</b>
|
||||||
|
|
||||||
|
![trick_qp_msg_area](images/trick_qp_msg_area.jpg)
|
||||||
|
|
||||||
|
### Viewing Data
|
||||||
|
|
||||||
|
In this section, <b>SIM_cannon_analytic</b> that comes with Trick distribution and is located at $TRICK_HOME/trick_sims will be used.
|
||||||
|
Assuming you already have had corresponding data recorded by executing the related sim. The data from a single run will be viewed
|
||||||
|
using Trick DP together with Trick QP. When plotting, single plotting is used. Please see Trick Tutorial
|
||||||
|
for more examples that also have comparison or error plotting with multiple runs. You certainly can perform similar exercises using your own sim.
|
||||||
|
|
||||||
|
#### Plotting With Trick DP & Trick QP
|
||||||
|
|
||||||
|
Begin by launching Trick DP.
|
||||||
|
|
||||||
|
```
|
||||||
|
<b>UNIX Prompt></b> cd <path_to_sim_cannon_analytic>/SIM_cannon_analytic
|
||||||
|
<b>UNIX Prompt></b> trick_dp &
|
||||||
|
```
|
||||||
|
|
||||||
|
##### Plotting Time -vs- Postion
|
||||||
|
|
||||||
|
1. Double click the pathname containing your sim directory if it is not expanded yet (or single click the symbol next to the name)
|
||||||
|
1. Double click the SIM_cannon_analytic name in the Sims/Runs Tree. This will reveal the RUN_test directory.
|
||||||
|
1. Double click the RUN_test name or right click the RUN_test followed by selecting "Add run(s)".
|
||||||
|
This will bring RUN_test into the RUN Selections below.
|
||||||
|
1. Click the blue lightning button in the tool bar to launch Quickplot application (Trick QP). The Trick QP GUI will pop up.
|
||||||
|
1. In Trick QP, right click dyn.cannon.pos[0-1] and select "Expand Var" if the interested variable is one of the element in an array
|
||||||
|
which is not expanded yet.
|
||||||
|
1. Double click the dyn.cannon.pos[0] variable in the left pane. This sets up to create one page with one plot (time -vs- pos[0]).
|
||||||
|
- Make sure nothing is highlighted or "Plots" is highlighted on the right in DP Content
|
||||||
|
- If "Tables" is highlighted, it sets up to create a table with one column instead.
|
||||||
|
- The X variable is sys.exec.out.time by default and the Y variable is dyn.cannon.pos[0].
|
||||||
|
- Later, you will learn how to replace the X (sys.exec.out.time) with a different variable.
|
||||||
|
1. Now click the dyn.cannon.pos[1] variable and drag it to the pane on the right. Drop it on the line with "Page" (see the white-n-black window looking icon).
|
||||||
|
This will result in one page containing two plots.
|
||||||
|
1. In Trick QP, click the plain white sheet icon located on the toolbar. A single window with two plots should pop up:
|
||||||
|
|
||||||
|
![plot2](images/plot2.jpg)
|
||||||
|
|
||||||
|
1. If you want to specify the number of plots horizontally and vertically on a page, click "Page" node and edit its Horizontal Cells and Vertical Cells
|
||||||
|
propterties from Proptery Notebook (use the scroll bar or change the GUI window size if necessary). Change Horizontal Cells
|
||||||
|
from 0 to 2 and Vertical Cells from 0 to 1 and click "Apply Change" button on the top of Proptery Notebook.
|
||||||
|
If click the plain white sheet icon located on the toolbar, a single window with two plots side by side should pop up:
|
||||||
|
- "Apply Change" needs to be selected to save the changes made to the Proptery Notebook.
|
||||||
|
|
||||||
|
![plot1](images/plot1.jpg)
|
||||||
|
|
||||||
|
##### Plotting XPosition -vs- YPosition
|
||||||
|
|
||||||
|
Now, let's change the default X variable from sys.exec.out.time to a different variable.
|
||||||
|
1. Assuming the Trick QP application is still up, click the "New" plot icon located on the far left of the toolbar.
|
||||||
|
Click "Ok" when asked if you want to start over. This will clear the plots from the DP Content.
|
||||||
|
1. Double-click dyn.cannon.pos[1].
|
||||||
|
1. Drag-n-drop the dyn.cannon.pos[0] variable over the sys.exec.out.time variable in the Plot located in the DP Content.
|
||||||
|
You will be asked to confirm the replacement. Click "Ok".
|
||||||
|
- Now, the X variable is dyn.cannon.pos[0] and the Y variable is dyn.cannon.pos[1].
|
||||||
|
1. To see the plot, click the white sheet icon on the toolbar.
|
||||||
|
|
||||||
|
![plot3](images/plot3.jpg)
|
||||||
|
|
||||||
|
#### Creating DP Product File
|
||||||
|
|
||||||
|
The information needed for the plot created earlier can be saved off to a file using Trick QP and can be reused by both
|
||||||
|
Trick DP and Trick QP. This example shows how to save XPosition -vs- YPosition plotting stated earlier
|
||||||
|
to a file named as DP_cannon_xy.
|
||||||
|
1. With the Trick QP GUI still up and the x -vs- y position still chosen, click the dyn.cannon.pos[1]
|
||||||
|
variable located in the pane on the right. The dyn.cannon.pos[1] variable should be highlighted in dark blue.
|
||||||
|
The "Y Var" notebook page should be visible in the lower right pane.
|
||||||
|
1. In the "Y Var" notebook page, select "Symbol Style->Circle" from the drop-down menu.
|
||||||
|
1. In the "Y Var" notebook page, select "Symbol Size->Tiny" from the drop-down menu.
|
||||||
|
1. Click the "Apply Change" button (you may need to scroll up/down to see all the fields/button).
|
||||||
|
1. Save this information by clicking the menu option "File->Save As". Click "New Folder"
|
||||||
|
button to create the DP_Product folder if necessary.
|
||||||
|
Choose the directory button SIM_cannon_analytic/DP_Product". Enter file name as "DP_cannon_xy".
|
||||||
|
- A file called DP_cannon_xy.xml is saved as it is in XML format.
|
||||||
|
1. Close the quick plot GUI, but keep trick_dp up and running.
|
||||||
|
|
||||||
|
#### Plotting with only Trick DP using a DP file
|
||||||
|
|
||||||
|
Now that DP_cannon_xy has been saved, the data can be viewed with Trick DP.
|
||||||
|
1. Assuming the Trick DP is still up and running from the previous steps, Click "Session->Refresh..."
|
||||||
|
and double click SIM_cannon_analytic to reveal DP_cannon_xy.xml in the top right pane.
|
||||||
|
- If the Trick DP is not up, go to the sim directory and launch it as:
|
||||||
|
- <b>UNIX Prompt></b> trick_dp &
|
||||||
|
1. Make sure that Sims/Runs->SIM_cannon_analytic/RUN_test has been selected.
|
||||||
|
- You can tell by checking to see if it is listed in Run Selections.
|
||||||
|
1. Choose the DP_cannon_xy.xml in the top right pane by double clicking it or right click followed by selecting "Add DPs".
|
||||||
|
- This will bring the DP_cannon_xy.xml into the DP selections pane.
|
||||||
|
1. To see the trajectory again, click the plain white single sheet icon on the toolbar.
|
||||||
|
Zoom in by holding the middle mouse button and drag across a section of the plot. Then release the
|
||||||
|
mouse button. Notice that there is a tiny circle on each x-y point recorded.
|
||||||
|
|
||||||
|
![plot4](images/plot4.jpg)
|
||||||
|
|
||||||
|
#### Plotting with only Trick QP
|
||||||
|
|
||||||
|
1. Go to the SIM directory we have worked on earlier and launch Trick QP as:
|
||||||
|
- <b>UNIX Prompt></b> trick_qp RUN_test &
|
||||||
|
- Once Trick QP is up, you should notice that:
|
||||||
|
- "<path_to_sim_cannon_analytic>/SIM_cannon_analytic/RUN_test" is listed in Runs.
|
||||||
|
- All logged variables found from "<path_to_sim_cannon_analytic>/SIM_cannon_analytic/RUN_test" are listed in Vars.
|
||||||
|
- You can add more runs by clicking "Runs->Add Run..." if needed.
|
||||||
|
1. Select variables from Vars for plotting as exercises done earlier.
|
||||||
|
1. Or click "File->Open DP..." or click the open file icon on the toolbar.
|
||||||
|
- Select a DP file such as DP_cannon_xy.xml and click "Ok".
|
||||||
|
- If intertested file is not listed, make sure you are in the right directory.
|
||||||
|
- The selected DP_ file is presented graphically in DP Content
|
||||||
|
1. To see the trajectory again, click the plain white single sheet on the toolbar.
|
||||||
|
|
||||||
|
#### Creating DP Session File
|
||||||
|
|
||||||
|
1. Launch Trick DP as:
|
||||||
|
- <b>UNIX Prompt></b> trick_dp &
|
||||||
|
1. Select RUN directories from Sims/Runs Tree and add them to Run Selections.
|
||||||
|
1. Select DP files from DP Tree and add them to DP Selections.
|
||||||
|
1. Click "Session->Save..." or click save icon on the toolbar to save the current session to a DP session file.
|
||||||
|
- By default, the session file is saved in your SIM directory.
|
||||||
|
- A file with xml extension is saved as the session file is in XML format.
|
||||||
|
|
||||||
|
|
||||||
|
#### Plotting from the Command Line
|
||||||
|
Once you a DP session file created, you can view the data the way as you specified using "fxplot" or "gxplot" command.
|
||||||
|
- Go to the SIM directory you have your session file saved.
|
||||||
|
- <b>UNIX Prompt></b> fxplot <session_file>
|
||||||
|
- Or
|
||||||
|
- <b>UNIX Prompt></b> gxplot <session_file>
|
||||||
|
- You should see plots as you specified in the file.
|
||||||
|
|
||||||
|
|
||||||
|
#### Using Tables
|
||||||
|
|
||||||
|
##### Using Tables Exercise A
|
||||||
|
|
||||||
|
1. Go to the SIM_cannon_analytic directory and launch Trick QP as:
|
||||||
|
- <b>UNIX Prompt></b> trick_qp RUN_test &
|
||||||
|
- Only using Trick QP to simply the example. In some cases, you'll still need to start "trick_dp" and then "trick_qp".
|
||||||
|
1. Click "Tables" shown under DP Content. The "Tables" node should be highlighted in blue.
|
||||||
|
- Make sure "Tables" node is selected.
|
||||||
|
1. Double click dyn.cannon.pos[0-1] or right click it followed by selecting "Add Var".
|
||||||
|
- A "Table" node is created under "Tables".
|
||||||
|
- This table has 3 columns: sys.exec.out.time (added by default), dyn.cannon.pos[0], and dyn.cannon.pos[1].
|
||||||
|
1. Click the table icon on the toolbar or click "Actions->Table..." to view the data in a table.
|
||||||
|
- You can save the current tabular data in a text file through the "Save" button on the left top corner.
|
||||||
|
|
||||||
|
![plot5](images/plot5.jpg)
|
||||||
|
|
||||||
|
##### Using Tables Exercise B
|
||||||
|
|
||||||
|
1. Go to the SIM_cannon_analytic directory and launch Trick QP as:
|
||||||
|
- <b>UNIX Prompt></b> trick_qp RUN_test &
|
||||||
|
1. Click "Tables->New Table" or right click "Tables" under DP Content followed by selecting "New Table".
|
||||||
|
- Now you see a new "Table" node is created under "Tables".
|
||||||
|
1. Click the newly created "Table" node. It should be highlighted in blue.
|
||||||
|
1. Right click dyn.cannon.pos[0-1] and then select "Expand Var".
|
||||||
|
1. Click dyn.cannon.pos[0] and then "Shift"+click dyn.cannon.pos[1]. These 2 variables should be highlighed in blue.
|
||||||
|
1. Right click the highlighted variables and then select "Add Var"
|
||||||
|
- Now 2 columns are inserted to the currently selected "Table": dyn.cannon.pos[0] and dyn.cannon.pos[1].
|
||||||
|
1. Click the table icon on the toolbar or click "Actions->Table..." to view the data in a table.
|
||||||
|
|
||||||
|
![plot6](images/plot6.jpg)
|
||||||
|
|
||||||
|
#### Using External Program
|
||||||
|
|
||||||
|
The external program $TRICK_HOME/trick_source/data_products/Apps/ExternalPrograms/dp_substract.c that comes with Trick distribution will be used in this section. This program takes 2 double inputs and returns the subtraction of these 2 inputs. Assuming the program is alreay built and the corresponding shared object is available for use.
|
||||||
|
|
||||||
|
1. Go to the SIM_cannon_analytic directory and launch Trick QP as:
|
||||||
|
- <b>UNIX Prompt></b> trick_qp RUN_test &
|
||||||
|
1. Click "Programs->New Program" or right click "Programs" under DP Content followed by selecting "New Program".
|
||||||
|
- Now you see a new "PROGRAM" node with "Input" and "Output" is created under "Programs".
|
||||||
|
- Please note that only one program at a time is currently supported.
|
||||||
|
1. Click "PROGRAM" and click "Browse..." from Property Notebook to select the shared object for the program.
|
||||||
|
- In this case, select the file dp_subtract.so that is located at "$TRICK_HOME/trick_source/data_products/Apps/ExternalPrograms/object_Linux_4.4_x86_64/".
|
||||||
|
1. Click "Apply Change". The name of "PROGRAM" is now changed to the full path of the shared object.
|
||||||
|
1. Click "Input" so it is highlighted in blue.
|
||||||
|
1. Double click dyn.cannon.pos[0-1]. Both dyn.cannon.pos[0] and dyn.cannon.pos[1] are inserted under "Input".
|
||||||
|
1. Right click Output and then select "New Output...". Enter a name for the output as prompted such as "out" and then click "Ok".
|
||||||
|
- Now you should see "out" in red shown in Vars list.
|
||||||
|
1. Drag "out" to "Plots" under DP Content. A page with one plot with one curve is created.
|
||||||
|
- The X variable is sys.exec.out.time.
|
||||||
|
- The Y variable is out which is the subtraction of dyn.cannon.pos[0] and dyn.cannon.pos[1].
|
||||||
|
1. Click the plain white single sheet icon on the toolbar to see the plot.
|
||||||
|
|
||||||
|
![plot7](images/plot7.jpg)
|
||||||
|
|
||||||
|
[Continue to Simulation Capabilities](../simulation_capabilities/Simulation-Capabilities)
|
21
docs/documentation/data_products/Data-Products.md
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
The Data Products (DP) is a simulation data post processor designed to allow visualization of data recorded in the Trick simulation.
|
||||||
|
|
||||||
|
The data products can plot ASCII, Binary & HDF5 data. HDF5 is the new data format supported since Trick 10.
|
||||||
|
|
||||||
|
Normally, a user will create DP formatted files for viewing by using the trick_dp and quickplot (trick_qp) GUIs (see 6.4 Data Products GUIs), and will not have to worry about DP file formats as well as the underlying Trick applications "fxplot" or "gxplot", which do the work of displaying plots and tables. However, there are times that a user may want to program scripts or do something command line and need to know the usage of these internal applications. There are two basic DP programs for displaying data: fxplot, and gxplot. "fxplot" creates X-Y plots using a 3rd party Fermi-Lab plot widget as well as creates ASCII tabular data. "gxplot" uses gnuplot for generating report quality plots.
|
||||||
|
|
||||||
|
The usage for fxplot and gxplot are seen below:
|
||||||
|
|
||||||
|
```
|
||||||
|
UNIX Prompt> fxplot <session_file>
|
||||||
|
UNIX Prompt> gxplot <session_file>
|
||||||
|
```
|
||||||
|
|
||||||
|
This session is arranged as following:
|
||||||
|
|
||||||
|
- [DP Session File Format](DP-Session-File-Format)
|
||||||
|
- [DP Product File Format](DP-Product-File-Format)
|
||||||
|
- [Plot Printing](Plot-Printing)
|
||||||
|
- [Data Products GUIs](Data-Products-GUIs)
|
||||||
|
|
||||||
|
[Continue to DP Session File Format](DP-Session-File-Format)
|
16
docs/documentation/data_products/Plot-Printing.md
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
To print fermi plots, simply bring up the fermi plot, and press either the "Print" (printer icon) button or the individual "Print" (printer icon) buttons on the plots themselves. In order for this to work you should set two environment variables:
|
||||||
|
|
||||||
|
```
|
||||||
|
UNIX Prompt> setenv TRICK_PRINT_CMD <your print command e.g. lpr>
|
||||||
|
UNIX Prompt> setenv TRICK_PRINTER_NAME <printer name e.g. xerox>
|
||||||
|
```
|
||||||
|
|
||||||
|
In all other cased, just choose the device to be "file", then print the file. If the device is set to be "printer" either in a DP <session_file> (device attribute of session element) or through -device option of "fxplot" application as following or through "trick_dp" gui, all plotting will go to the specified printer automatically.
|
||||||
|
|
||||||
|
To specify the -device option of "fxplot" command for sending the plots to a printer (-device option overrides the device setting in the <session_file>):
|
||||||
|
|
||||||
|
```
|
||||||
|
UNIX Prompt> fxplot -device=printer <session_file>
|
||||||
|
```
|
||||||
|
|
||||||
|
[Continue to Data Products GUIs](Data-Products-GUIs)
|
BIN
docs/documentation/data_products/images/plot1.jpg
Normal file
After Width: | Height: | Size: 56 KiB |
BIN
docs/documentation/data_products/images/plot2.jpg
Normal file
After Width: | Height: | Size: 47 KiB |
BIN
docs/documentation/data_products/images/plot3.jpg
Normal file
After Width: | Height: | Size: 36 KiB |
BIN
docs/documentation/data_products/images/plot4.jpg
Normal file
After Width: | Height: | Size: 30 KiB |
BIN
docs/documentation/data_products/images/plot5.jpg
Normal file
After Width: | Height: | Size: 63 KiB |
BIN
docs/documentation/data_products/images/plot6.jpg
Normal file
After Width: | Height: | Size: 40 KiB |
BIN
docs/documentation/data_products/images/plot7.jpg
Normal file
After Width: | Height: | Size: 44 KiB |
BIN
docs/documentation/data_products/images/trick_dp.jpg
Normal file
After Width: | Height: | Size: 94 KiB |
After Width: | Height: | Size: 23 KiB |
After Width: | Height: | Size: 3.7 KiB |
After Width: | Height: | Size: 9.9 KiB |
BIN
docs/documentation/data_products/images/trick_dp_dptree_area.jpg
Normal file
After Width: | Height: | Size: 21 KiB |
BIN
docs/documentation/data_products/images/trick_dp_help_menu.jpg
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
docs/documentation/data_products/images/trick_dp_msg_area.jpg
Normal file
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 9.2 KiB |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 7.8 KiB |
BIN
docs/documentation/data_products/images/trick_dp_simrun_area.jpg
Normal file
After Width: | Height: | Size: 21 KiB |
BIN
docs/documentation/data_products/images/trick_dp_simrun_menu.jpg
Normal file
After Width: | Height: | Size: 4.2 KiB |
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 20 KiB |
After Width: | Height: | Size: 16 KiB |
BIN
docs/documentation/data_products/images/trick_dp_toolbar.jpg
Normal file
After Width: | Height: | Size: 10 KiB |
BIN
docs/documentation/data_products/images/trick_dp_tree_popup1.jpg
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
docs/documentation/data_products/images/trick_dp_tree_popup2.jpg
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
docs/documentation/data_products/images/trick_dp_tree_popup3.jpg
Normal file
After Width: | Height: | Size: 9.5 KiB |
BIN
docs/documentation/data_products/images/trick_dp_tree_popup4.jpg
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
docs/documentation/data_products/images/trick_qp.jpg
Normal file
After Width: | Height: | Size: 111 KiB |
After Width: | Height: | Size: 9.8 KiB |
After Width: | Height: | Size: 21 KiB |
After Width: | Height: | Size: 6.1 KiB |
After Width: | Height: | Size: 8.9 KiB |
After Width: | Height: | Size: 9.3 KiB |
After Width: | Height: | Size: 7.1 KiB |
After Width: | Height: | Size: 8.4 KiB |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 24 KiB |
After Width: | Height: | Size: 6.3 KiB |
After Width: | Height: | Size: 7.7 KiB |
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 8.9 KiB |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 6.7 KiB |
After Width: | Height: | Size: 6.5 KiB |
After Width: | Height: | Size: 7.9 KiB |
BIN
docs/documentation/data_products/images/trick_qp_file_menu.jpg
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
docs/documentation/data_products/images/trick_qp_help_menu.jpg
Normal file
After Width: | Height: | Size: 2.7 KiB |
BIN
docs/documentation/data_products/images/trick_qp_menu.jpg
Normal file
After Width: | Height: | Size: 9.6 KiB |
BIN
docs/documentation/data_products/images/trick_qp_msg_area.jpg
Normal file
After Width: | Height: | Size: 8.8 KiB |
After Width: | Height: | Size: 30 KiB |
BIN
docs/documentation/data_products/images/trick_qp_plots_menu.jpg
Normal file
After Width: | Height: | Size: 7.8 KiB |
After Width: | Height: | Size: 5.4 KiB |
BIN
docs/documentation/data_products/images/trick_qp_runs_area.jpg
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
docs/documentation/data_products/images/trick_qp_runs_menu.jpg
Normal file
After Width: | Height: | Size: 3.2 KiB |
BIN
docs/documentation/data_products/images/trick_qp_runs_popup1.jpg
Normal file
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 20 KiB |
After Width: | Height: | Size: 4.1 KiB |
BIN
docs/documentation/data_products/images/trick_qp_tables_menu.jpg
Normal file
After Width: | Height: | Size: 5.4 KiB |
BIN
docs/documentation/data_products/images/trick_qp_toolbar.jpg
Normal file
After Width: | Height: | Size: 10 KiB |
BIN
docs/documentation/data_products/images/trick_qp_vars_area.jpg
Normal file
After Width: | Height: | Size: 9.0 KiB |
BIN
docs/documentation/data_products/images/trick_qp_vars_menu.jpg
Normal file
After Width: | Height: | Size: 4.9 KiB |
BIN
docs/documentation/data_products/images/trick_qp_vars_popup1.jpg
Normal file
After Width: | Height: | Size: 7.6 KiB |
After Width: | Height: | Size: 20 KiB |
After Width: | Height: | Size: 11 KiB |
433
docs/documentation/install_guide/Install-Guide.md
Normal file
@ -0,0 +1,433 @@
|
|||||||
|
| [Home](/trick/index) → Install Guide |
|
||||||
|
|------------------------------|
|
||||||
|
|
||||||
|
# Introduction
|
||||||
|
This document will walk you through the process of installing Trick on your computer. Please read each section carefully.
|
||||||
|
|
||||||
|
# Package Dependencies
|
||||||
|
Trick requires various free third party utilities in order to function. All the following products are used by Trick and may already be installed as part of your OS distribution. **Install any missing dependencies with your operating system's [package manager](https://en.wikipedia.org/wiki/Package_manager).**
|
||||||
|
|
||||||
|
| Utility | Version | Description | Usage |
|
||||||
|
|-:|:-:|:-:|:-|
|
||||||
|
| [gcc] and g++ | 4.8+ | C/C++ Compiler | Compiles Trick and Trick simulations. |
|
||||||
|
| [clang]/[llvm] | 3.4.2 | C/C++ Compiler | Utilized by the interface code generator. |
|
||||||
|
| [python] | 2.6 | Programming Language | Lets the user interact with a simulation. |
|
||||||
|
| [perl] | 5.6 | Programming Language | Allows executable scripts in the bin directory to run. |
|
||||||
|
| [java] | 1.8 | Programming Language | Necessary for Trick GUIs. |
|
||||||
|
| [swig] | 1.3.40 | Language Interfacing | Connects the python input processor with Trick's C code. |
|
||||||
|
| [make] | 3.78 | Build Automation | Automates the building and cleaning of Trick. |
|
||||||
|
| [openmotif] | 2.2.0 | GUI Toolkit | Covers Trick GUIs not made with Java. |
|
||||||
|
| [udunits] | 2.x | C Unit Library/Database | Provides support for units of physical quantities. |
|
||||||
|
|
||||||
|
[gcc]: https://gcc.gnu.org/
|
||||||
|
[clang]: https://clang.llvm.org/
|
||||||
|
[llvm]: https://llvm.org/
|
||||||
|
[python]: https://www.python.org/
|
||||||
|
[perl]: https://www.perl.org/
|
||||||
|
[java]: https://www.java.com/
|
||||||
|
[swig]: http://www.swig.org/
|
||||||
|
[make]: https://www.gnu.org/software/make/
|
||||||
|
[openmotif]: http://www.opengroup.org/openmotif/
|
||||||
|
[udunits]: https://www.unidata.ucar.edu/software/udunits/
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
### Clang/LLVM compiler and libraries
|
||||||
|
Clang/LLVM can be installed and located manually should your package manager fail to acquire it. You can tell Trick where to find Clang/LLVM with the "--with-llvm" configuration option specified [below](TODO).
|
||||||
|
### 32-bit Mode
|
||||||
|
If you intend to build Trick in 32-bit mode, you will need 32-bit versions of the libraries in the above table. If a 32-bit version of udunits is not available through your package manager, you can build it from [source](ftp://ftp.unidata.ucar.edu/pub/udunits/udunits-2.2.25.tar.gz):
|
||||||
|
```bash
|
||||||
|
tar xfvz udunits-2.2.25.tar.gz
|
||||||
|
cd udunits-2.2.25
|
||||||
|
export CFLAGS="-m32"
|
||||||
|
./configure --prefix=/usr
|
||||||
|
make
|
||||||
|
make install
|
||||||
|
```
|
||||||
|
|
||||||
|
### Java
|
||||||
|
Trick needs the javac compiler included in the Java Development Kit (JDK). Trick will work with either the Oracle JDK or OpenJDK, but we prefer the Oracle JDK located [here](http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html).
|
||||||
|
**Installing both the Oracle JDK and OpenJDK may lead to problems and confusion.** Both use the alternatives program to tell the system which *java* to use, but the OpenJDK packages are inconsistent in their alternatives priority settings and result in unintuitive installation results.
|
||||||
|
|
||||||
|
# Operating Systems
|
||||||
|
Trick runs on GNU/Linux and MacOSX, though any System V/POSIX compatible UNIX workstation should accept the Trick software with very little source code porting. Below are instructions for installing the prerequisites on popular operating systems here at NASA.
|
||||||
|
|
||||||
|
| Quick Jump Menu |
|
||||||
|
|---|
|
||||||
|
|[RedHat Enterprise Linux (RHEL) 7](#redhat7)|
|
||||||
|
|[RedHat Enterprise Linux (RHEL) 6](#redhat6)|
|
||||||
|
|[Fedora 24](#fedora24)|
|
||||||
|
|[Ubuntu 16.04/15.10](#ubuntu16.04)|
|
||||||
|
|[Ubuntu 15.04](#ubuntu15.04)|
|
||||||
|
|[MacOSX 10.12/10.11](#macosx)|
|
||||||
|
|[Windows 10.0.15063 (Creators Update)](#windows10)|
|
||||||
|
|
||||||
|
---
|
||||||
|
<a name="redhat7"></a>
|
||||||
|
|
||||||
|
### RedHat Enterprise Linux (RHEL) 7
|
||||||
|
Trick requires the clang/llvm compiler to compile and link the Trick Interface Code Generator. clang/llvm is available through the [Extra Packages for Enterprise Linux](https://fedoraproject.org/wiki/EPEL) repository. Download and install the 'epel-release' package.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# From the EPEL repository
|
||||||
|
yum install llvm llvm-devel llvm-static clang clang-devel
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
Trick also requires development packages from the base and epel repositories
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# From the base repository
|
||||||
|
yum install bison flex gcc gcc-c++ libxml2-devel make ncurses-devel \
|
||||||
|
openmotif openmotif-devel python-devel perl perl-Digest-MD5 swig zlib-devel
|
||||||
|
#UDUnits is required and is in the EPEL repository
|
||||||
|
yum install udunits2 udunits2-devel
|
||||||
|
```
|
||||||
|
|
||||||
|
The javac compiler must be installed. The javac compiler is included with the Java Development Kit (JDK). Trick will work with either the Oracle JDK or OpenJDK, but we prefer the Oracle JDK.
|
||||||
|
At the time of this writing (March 2015) the Oracle JDK 1.8 is available from the [Oracle download site](http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html).
|
||||||
|
|
||||||
|
Alternatively OpenJDK is available through yum
|
||||||
|
|
||||||
|
```bash
|
||||||
|
yum install java-1.8.0-openjdk java-1.8.0-openjdk-devel
|
||||||
|
```
|
||||||
|
|
||||||
|
Trick makes use of several optional packages if they are present on the system. These include using the HDF5 package for logging, the GSL packages for random number generation, and google test (gtest) for Trick's unit testing. These are available from the EPEL repository
|
||||||
|
|
||||||
|
```bash
|
||||||
|
yum install hdf5-devel gsl-devel gtest-devel
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
<a name="redhat6"></a>
|
||||||
|
|
||||||
|
### RedHat Enterprise Linux (RHEL) 6
|
||||||
|
Trick requires gcc version 4.8+ to compile. gcc 4.9 is available through RHEL's [Software Collections](https://access.redhat.com/documentation/en/red-hat-software-collections/) capability. To install the software collections, the software collections reposotory needs to be added as a yum repository and the scl-utils package needs to be optionally installed. The instructions below are specific to Scientific Linux 6, an RHEL derivative. Repository location will be different for the official RHEL 6 and CentOS.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
wget http://ftp.scientificlinux.org/linux/scientific/6x/external_products/softwarecollections/yum-conf-softwarecollections-2.0-1.el6.noarch.rpm
|
||||||
|
rpm -ivh yum-conf-softwarecollections-2.0-1.el6.noarch.rpm
|
||||||
|
|
||||||
|
# From the software collections repository
|
||||||
|
yum install devtoolset-3-gcc-c++
|
||||||
|
```
|
||||||
|
|
||||||
|
Trick requires the clang/llvm compiler to compile and link the Trick Interface Code Generator. clang/llvm is available through the [Extra Packages for Enterprise Linux](https://fedoraproject.org/wiki/EPEL) repository. Download and install the 'epel-release' package.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# From the EPEL repository
|
||||||
|
yum install llvm llvm-devel llvm-static clang clang-devel
|
||||||
|
```
|
||||||
|
|
||||||
|
Trick also requires development packages from the base and epel repositories
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# From the base repository
|
||||||
|
yum install bison flex gcc gcc-c++ libxml2-devel make \
|
||||||
|
openmotif openmotif-devel python-devel perl swig zlib-devel
|
||||||
|
#UDUnits is required and is in the EPEL repository
|
||||||
|
yum install udunits2 udunits2-devel
|
||||||
|
```
|
||||||
|
|
||||||
|
The javac compiler must be installed. The javac compiler is included with the Java Development Kit (JDK). Trick will work with either the Oracle JDK or OpenJDK, but we prefer the Oracle JDK.
|
||||||
|
At the time of this writing (March 2015) the Oracle JDK 1.8 is available from the [Oracle download site](http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html).
|
||||||
|
|
||||||
|
Alternatively OpenJDK is available through yum
|
||||||
|
|
||||||
|
```bash
|
||||||
|
yum install java-1.8.0-openjdk java-1.8.0-openjdk-devel
|
||||||
|
```
|
||||||
|
|
||||||
|
Trick makes use of several optional packages if they are present on the system. These include using the HDF5 package for logging, the GSL packages for random number generation, and google test (gtest) for Trick's unit testing. These are available from the EPEL repository
|
||||||
|
|
||||||
|
```bash
|
||||||
|
yum install hdf5-devel gsl-devel gtest-devel
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
<a name="fedora24"></a>
|
||||||
|
|
||||||
|
### Fedora 28, 24
|
||||||
|
Trick requires development packages from the base repositories.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
dnf install bison flex gcc gcc-c++ libxml2-devel make openmotif \
|
||||||
|
openmotif-devel python-devel perl swig zlib-devel llvm llvm-devel \
|
||||||
|
llvm-static clang clang-devel perl-Text-Balanced perl-Digest-MD5 \
|
||||||
|
udunits2 udunits2-devel ncurses-devel
|
||||||
|
```
|
||||||
|
|
||||||
|
Be sure to install the Oracle JDK. Alternatively, install OpenJDK with this command:
|
||||||
|
```bash
|
||||||
|
dnf install java-1.8.0-openjdk-devel
|
||||||
|
```
|
||||||
|
|
||||||
|
Trick makes use of several optional packages if they are present on the system. These include using the HDF5 package for logging, the GSL packages for random number generation, and google test (gtest) for Trick's unit testing. These are available from the EPEL repository
|
||||||
|
|
||||||
|
```bash
|
||||||
|
dnf install hdf5-devel gsl-devel gtest-devel
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
<a name="ubuntu16.04"></a>
|
||||||
|
|
||||||
|
### Ubuntu 18.04/16.04/15.10
|
||||||
|
All packages required for Trick may be installed through apt-get.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo apt-get install bison curl flex g++ libx11-dev libxml2-dev libxt-dev \
|
||||||
|
libmotif-common libmotif-dev make openjdk-8-jdk python2.7-dev swig \
|
||||||
|
zlib1g-dev llvm llvm-dev clang libclang-dev libudunits2-dev
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
<a name="ubuntu15.04"></a>
|
||||||
|
|
||||||
|
### Ubuntu 15.04
|
||||||
|
Follow the 16.04 instructions above.
|
||||||
|
|
||||||
|
Trick requires the clang/llvm compiler to compile and link the Trick Interface Code Generator. The instructions below install clang 3.6.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo apt-get install clang-3.6 llvm-3.6 llvm-3.6-dev
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<a name="macosx"></a>
|
||||||
|
|
||||||
|
### MacOSX 10.14
|
||||||
|
|
||||||
|
1. Install XCode from the App Store.
|
||||||
|
|
||||||
|
2. Download and install Command Line Tools for MacOSX by opening a terminal and running the following command.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
xcode-select --install
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Install system header files into /usr/include
|
||||||
|
```bash
|
||||||
|
sudo installer -pkg /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg -target /
|
||||||
|
```
|
||||||
|
|
||||||
|
4. Install Homebrew, MacOSX's unofficial package manager.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# bash
|
||||||
|
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
|
||||||
|
```
|
||||||
|
or
|
||||||
|
```csh
|
||||||
|
# csh
|
||||||
|
curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install | ruby
|
||||||
|
```
|
||||||
|
|
||||||
|
5. Install cask to get java and xquartz.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# brew install caskroom may not be required anymore
|
||||||
|
# brew install caskroom/cask/brew-cask
|
||||||
|
brew cask install java xquartz
|
||||||
|
```
|
||||||
|
|
||||||
|
6. Finally, install the remaining dependencies.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
brew install llvm swig udunits openmotif
|
||||||
|
```
|
||||||
|
|
||||||
|
Openmotif may install dependent packages that conflict with other installations, fontconfig and freetype. Use the following command to skip installing these packages if you encounter conflicts.
|
||||||
|
```bash
|
||||||
|
brew install --ignore-dependencies openmotif
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<a name="macosx"></a>
|
||||||
|
|
||||||
|
### MacOSX 10.13/10.12/10.11
|
||||||
|
|
||||||
|
1. Install XCode from the App Store.
|
||||||
|
|
||||||
|
2. Download and install Command Line Tools for MacOSX by opening a terminal and running the following command.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
xcode-select --install
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Install Homebrew, MacOSX's unofficial package manager.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# bash
|
||||||
|
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
|
||||||
|
```
|
||||||
|
or
|
||||||
|
```csh
|
||||||
|
# csh
|
||||||
|
curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install | ruby
|
||||||
|
```
|
||||||
|
|
||||||
|
4. Install cask to get java and xquartz.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# brew install caskroom may not be required anymore
|
||||||
|
# brew install caskroom/cask/brew-cask
|
||||||
|
brew cask install java xquartz
|
||||||
|
```
|
||||||
|
|
||||||
|
5. Finally, install the remaining dependencies.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
brew install llvm swig udunits openmotif
|
||||||
|
```
|
||||||
|
|
||||||
|
Openmotif may install dependent packages that conflict with other installations, fontconfig and freetype. Use the following command to skip installing these packages if you encounter conflicts.
|
||||||
|
```bash
|
||||||
|
brew install --ignore-dependencies openmotif
|
||||||
|
```
|
||||||
|
|
||||||
|
To configure Trick with an older llvm (No longer needed now that llvm 6 works with Xcode 9.2).
|
||||||
|
```bash
|
||||||
|
brew install llvm@5
|
||||||
|
./configure --with-llvm=/usr/local/opt/llvm@5
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
<a name="windows10"></a>
|
||||||
|
|
||||||
|
### Windows 10 version 1803 and 1709
|
||||||
|
|
||||||
|
1. Install Ubuntu 18.04 in the Windows Linux Subsystem following these [instructions.](https://msdn.microsoft.com/en-us/commandline/wsl/install_guide).
|
||||||
|
|
||||||
|
2. Open a bash shell and install the following packages
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt install bison curl flex g++ libx11-dev libxml2-dev \
|
||||||
|
libxt-dev libxtst6 libxi6 libmotif-common libmotif-dev make python2.7-dev \
|
||||||
|
swig zlib1g-dev llvm-6.0-dev llvm clang libclang-dev libudunits2-dev
|
||||||
|
```
|
||||||
|
|
||||||
|
*Note This will install about 150 dependent packages on a new machine.
|
||||||
|
|
||||||
|
3. Install Java JDK 11 through the ppa repository
|
||||||
|
```bash
|
||||||
|
sudo apt-add-repository ppa:linuxuprising/java
|
||||||
|
sudo apt update
|
||||||
|
sudo apt install oracle-java10-installer
|
||||||
|
```
|
||||||
|
|
||||||
|
4. Install an X-windows server like [Xming.](https://sourceforge.net/projects/xming/?source=typ_redirect)
|
||||||
|
|
||||||
|
5. Ensure hostname resolves to an address.
|
||||||
|
```bash
|
||||||
|
# Get name of machine
|
||||||
|
hostname
|
||||||
|
# Get IP of name
|
||||||
|
hostname -i
|
||||||
|
# If hostname -i returns an error find IP address
|
||||||
|
ifconfig
|
||||||
|
# Add an entry to /etc/hosts to associate IP address to hostname "numeric.ip.address hostname"
|
||||||
|
sudo <edit_cmd> /etc/hosts
|
||||||
|
```
|
||||||
|
|
||||||
|
6. You may have to change the sslVersion that git uses.
|
||||||
|
```bash
|
||||||
|
# Edit ${HOME}/.gitconfig
|
||||||
|
<edit_cmd> ${HOME}/.gitconfig
|
||||||
|
```
|
||||||
|
|
||||||
|
Add the following text to ${HOME}/.gitconfig
|
||||||
|
|
||||||
|
```
|
||||||
|
[httpd]
|
||||||
|
sslVersion = tlsv1.2
|
||||||
|
```
|
||||||
|
|
||||||
|
### Windows 10 Version 1703 OS build 15063 (Creators Update)
|
||||||
|
|
||||||
|
1. Set up the Ubuntu Linux Subsystem following these [instructions.](https://msdn.microsoft.com/en-us/commandline/wsl/install_guide)
|
||||||
|
|
||||||
|
2. Open a bash shell and install the following packages.with
|
||||||
|
```bash
|
||||||
|
sudo apt install bison curl flex g++ libx11-dev libxml2-dev \
|
||||||
|
libxt-dev libmotif-common libmotif-dev make python2.7-dev \
|
||||||
|
swig zlib1g-dev llvm llvm-dev clang libclang-dev libudunits2-dev
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Install Java JDK 8 through the ppa repository
|
||||||
|
```bash
|
||||||
|
sudo apt-add-repository ppa:webupd8team/java
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt install oracle-java8-installer
|
||||||
|
```
|
||||||
|
|
||||||
|
4. Install an X-windows server like [Xming.](https://sourceforge.net/projects/xming/?source=typ_redirect)
|
||||||
|
|
||||||
|
5. Ensure hostname resolves to an address.
|
||||||
|
```bash
|
||||||
|
# Get name of machine
|
||||||
|
hostname
|
||||||
|
# Get IP of name
|
||||||
|
hostname -i
|
||||||
|
# If hostname -i returns an error find IP address
|
||||||
|
ifconfig
|
||||||
|
# Add an entry to /etc/hosts to associate IP address to hostname "numeric.ip.address hostname"
|
||||||
|
sudo <edit_cmd> /etc/hosts
|
||||||
|
```
|
||||||
|
|
||||||
|
# Install Trick
|
||||||
|
|
||||||
|
## 1.) Clone Trick
|
||||||
|
|
||||||
|
The following commands will clone the Trick repository into a folder named *trick* in your home directory. You can install multiple copies of Trick in different locations to isolate your simulation environments from one another.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd ${HOME}
|
||||||
|
git clone https://github.com/nasa/trick
|
||||||
|
```
|
||||||
|
|
||||||
|
## 2.) Configure Trick
|
||||||
|
Navigate to the *trick* directory you just created and run the *configure* script.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd ${HOME}/trick
|
||||||
|
./configure
|
||||||
|
```
|
||||||
|
|
||||||
|
The *configure* script will generate makefiles and locate project dependencies automatically. It may be necessary to specify dependency paths manually. Run the following command to see the possible options *configure* will accept.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./configure --help
|
||||||
|
```
|
||||||
|
|
||||||
|
## 3.) Compile Trick
|
||||||
|
Now that Trick has been configured and a makefile has been generated, we can run *make* to compile Trick. To build Trick in 32-bit mode, first set the `TRICK_FORCE_32BIT` environment variable to `1`.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make
|
||||||
|
```
|
||||||
|
|
||||||
|
### Install Trick
|
||||||
|
You can also install Trick on your machine by running *sudo make install* after you compile Trick.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo make install
|
||||||
|
```
|
||||||
|
|
||||||
|
You will need super user privileges in order to copy files directly to the default **/usr/local** directory. This install directory can be modified with the configuration script.
|
||||||
|
|
||||||
|
|
||||||
|
## 4.) Optionally Update Your Environment
|
||||||
|
Gone are the days when you needed to set several environment variables to use Trick. Trick can now be used completely environmentlessly*. You no longer need to set `TRICK_HOME` and friends.
|
||||||
|
|
||||||
|
Trick still makes use of shell variables, but their existence is only required during simulation compilation and execution. If they are not set, Trick will infer them without polluting your environment. Furthermore, they will be available to any processes that are spawned as part of compilation or execution, so even your own tools may no longer need these variables to be manually set.
|
||||||
|
|
||||||
|
Similarly, Trick does not require its executables to be on your `PATH`, but you may find it convenient to add them if you prefer to not specify the full path to `trick-CP` every time you build a sim. They are located in `bin` under Trick's root directory. However, if you frequently work with multiple versions of Trick, it is often easier to use a full path than to keep changing an environment variable.
|
||||||
|
|
||||||
|
Finally, although setting `TRICK_CFLAGS` and `TRICK_CXXFLAGS` is not necessary, it can be useful to do so if you want a set of flags (`-g` or `-Wall`, for instance) to be applied to all simulation builds.
|
||||||
|
|
||||||
|
*The exception to this is if you're building in 32-bit mode, in which case the `TRICK_FORCE_32BIT` environment variable must be set to `1` before you build Trick or any simulation.
|
||||||
|
|
||||||
|
[Continue to Building A Simulation](../building_a_simulation/Building-a-Simulation)
|
7
docs/documentation/introduction/Introduction.md
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
The responsibility for this document lies with the [Simulation and Graphics Branch (ER7)](https://er.jsc.nasa.gov/ER7/) of the [Automation, Robotics and Simulation Division](https://er.jsc.nasa.gov/) of the NASA JSC Engineering Directorate.
|
||||||
|
|
||||||
|
The purpose of this document is to provide Trick simulation developers and users with a detailed user’s reference guide on how to install Trick, use Trick processors and utilities, and how to operate a simulation from execution to data post processing.
|
||||||
|
|
||||||
|
To see how to build a simulation from scratch, refer to the Trick Tutorial document. For details about the high level design of Trick, refer to the Trick Design document. Details of specific NASA programmatic math models and simulations will not be addressed in this document.
|
||||||
|
|
||||||
|
[Continue to Install Guide](../install_guide/Install-Guide)
|
@ -0,0 +1,143 @@
|
|||||||
|
|
||||||
|
### Interface Code Generator - ICG
|
||||||
|
|
||||||
|
ICG is the processor that %Trick uses to parse header files. It is normally called
|
||||||
|
internally from the main %Trick processor, CP. However, it may be used manually by
|
||||||
|
developers.
|
||||||
|
|
||||||
|
The ICG parses developer created data structure definition files and generates
|
||||||
|
runtime executive input/output source code. The source code generated is compiled
|
||||||
|
into a simulation which uses the types parsed.
|
||||||
|
|
||||||
|
The command syntax for the ICG is as follows (with restrictions outlined afterward):
|
||||||
|
|
||||||
|
```
|
||||||
|
<b>UNIX Prompt></b> ICG [-d] [-D <define>] [-U <undefine>] <filename>.h
|
||||||
|
<b>UNIX Prompt></b> ICG -u
|
||||||
|
```
|
||||||
|
|
||||||
|
The ICG can process multiple files at a
|
||||||
|
time and does accept UNIX wild card character designations (*.h) in the filename. The
|
||||||
|
optional "-d" (for debug) argument tells the ICG to echo every character successfully
|
||||||
|
parsed from the file; if a syntax error occurs in the file, the user will know the exact
|
||||||
|
character which caused the problem. The optional "-D" and "-U" arguments are compiler
|
||||||
|
directives, used in concert with #defines, #undefs etc. and work like their CFLAGS
|
||||||
|
counterparts. The optional "-u" argument tells ICG to display the current measurement
|
||||||
|
units primitives allowed in the parameter comment fields of the data structure definition
|
||||||
|
files.
|
||||||
|
|
||||||
|
The ICG generates one source code file for each data structure definition file it
|
||||||
|
processes, with a file name in the form of io_src/io_<file_name>.c; where "io_" is a
|
||||||
|
standard prefix for all ICG generated files, and <file_name> is the original data
|
||||||
|
structure definition file name.
|
||||||
|
|
||||||
|
Any characters or statements the ICG recognizes as valid syntax, but does not process,
|
||||||
|
will be echoed to the screen with an informative message on why it did not process the
|
||||||
|
parameter.
|
||||||
|
|
||||||
|
In general, the following items are not processed by the ICG:
|
||||||
|
1. global parameters decalred outside of a struct, union, or enum typedef,
|
||||||
|
1. all parameter declarations of a type other than the basic C types listed in the
|
||||||
|
Parameter Data Types section or the types contained within the data structure and
|
||||||
|
enumerated type databases (structure and enumerated types previously processed by the ICG),
|
||||||
|
1. all parameters that have a "**" in the measurement units field of the parameter comment, and
|
||||||
|
1. all function declarations.
|
||||||
|
|
||||||
|
The ICG will always give the "ICG complete." message upon successful completion of processing.
|
||||||
|
|
||||||
|
### Building Model Source
|
||||||
|
|
||||||
|
Trick's main processor, CP handles building models from a high level. However,
|
||||||
|
developers may desire to build a local cache of source and include files in a model
|
||||||
|
directory. Or the developer may want to build a library from a model directory of
|
||||||
|
source and include files. Trick's make_build and UNIX's make may be used for these
|
||||||
|
purposes.
|
||||||
|
|
||||||
|
#### Makefile Generator - make_build
|
||||||
|
|
||||||
|
The make_build processor takes the src and include files in a model directory and
|
||||||
|
autogenerates a Makefile. Note that make_build will work for mixed *.c and *.h files
|
||||||
|
in the same directory or for src and include subdirectories. make_build generates a
|
||||||
|
complete dependency list for the source and header files processed. make_build should
|
||||||
|
only be run after the ICG processor has been run on all appropriate data structure
|
||||||
|
definition files. This ensures the io_*.c files created by ICG are processed by
|
||||||
|
make_build. The command syntax for make_build is as follows:
|
||||||
|
|
||||||
|
```
|
||||||
|
<b>UNIX Prompt></b> make_build [lib <lib_name>]
|
||||||
|
```
|
||||||
|
|
||||||
|
The lib argument causes make_build to generate Makefile syntax for building an
|
||||||
|
archived (UNIX ar) library for the object files and give the library the name <lib_name>.
|
||||||
|
|
||||||
|
The make_build command is rarely used.
|
||||||
|
|
||||||
|
#### Make Processor - make
|
||||||
|
|
||||||
|
Developers will be running GNU make on Makefiles in the SIM directory or model
|
||||||
|
directories. Running make in a SIM_ directory with a Makefile generated by CP will
|
||||||
|
result, hopefully, in a simulation. Running make in a model directory with a
|
||||||
|
Makefile generated by make_build will result in either object code for the model
|
||||||
|
source local to that directory or a library.
|
||||||
|
|
||||||
|
Makefile options may be found by typing in:
|
||||||
|
|
||||||
|
```
|
||||||
|
<b>UNIX Prompt></b> make help
|
||||||
|
```
|
||||||
|
|
||||||
|
Additional documentation for make can be found in UNIX manuals for your workstation.
|
||||||
|
|
||||||
|
#### Viewing Parameters In SIE Database
|
||||||
|
|
||||||
|
Sometimes you are trying to remember the name of a parameter.... "Ummm. Let's see.
|
||||||
|
It's errr. Uhhh. clock something..." Try running this in your built simulation
|
||||||
|
directory where the S_sie.resource file is located.
|
||||||
|
|
||||||
|
```
|
||||||
|
<b>UNIX Prompt></b> sie [-nocase] <search string>
|
||||||
|
```
|
||||||
|
|
||||||
|
As an example, if you know the parameter name contains clock but don't know
|
||||||
|
anything else, try:
|
||||||
|
|
||||||
|
```
|
||||||
|
<b>UNIX Prompt></b> sie clock
|
||||||
|
```
|
||||||
|
|
||||||
|
The search returns each %Trick processed variable (including Trick's "sys" variables)
|
||||||
|
from your simulation that contains the search string. Beneath each variable returned
|
||||||
|
is information from its header file definition: user supplied description, type,
|
||||||
|
input/output spec, and units spec.
|
||||||
|
|
||||||
|
For a case-insensitive search (e.g., to find occurrences of "clock" and "Clock"),
|
||||||
|
simply specify the -nocase option.
|
||||||
|
|
||||||
|
### kill_sim
|
||||||
|
|
||||||
|
The following command will kill all simulations and their children that you own.
|
||||||
|
|
||||||
|
```
|
||||||
|
<b>UNIX Prompt></b> kill_sim
|
||||||
|
```
|
||||||
|
|
||||||
|
### Current Trick Version
|
||||||
|
|
||||||
|
The following command echoes the installed %Trick version release:
|
||||||
|
|
||||||
|
```
|
||||||
|
<b>UNIX Prompt></b> trick_version
|
||||||
|
```
|
||||||
|
|
||||||
|
### Checksumming
|
||||||
|
|
||||||
|
Trick comes with a file that contains checksums for the %Trick package. You may run:
|
||||||
|
|
||||||
|
```
|
||||||
|
<b>UNIX Prompt></b> trick_verify_checksums
|
||||||
|
```
|
||||||
|
|
||||||
|
at any time to see what, if any, files have changed from the original package. The checksum is
|
||||||
|
done on source files, not object code.
|
||||||
|
|
||||||
|
[Continue to Python Variable Server Client](Python-Variable-Server-Client)
|
@ -0,0 +1,373 @@
|
|||||||
|
`variable_server.py` is a Python module for communicating with a sim's variable server from a Python program. Its primary purpose is to easily get and set variable values and units, but it also includes some additional convenience methods for affecting the sim's state. The code itself is well-commented, so I won't be reproducing the API here. Run `pydoc variable_server` (in the containing directory) for that.
|
||||||
|
|
||||||
|
# Release Your Resources!
|
||||||
|
First things first. Communicating
|
||||||
|
with the variable server means opening sockets. Sockets are a resource. Threads are also a resource, and this module uses them as well. The OS gets angry when you leak resources, so you should do your best to dispose of them when you're done. Python doesn't support RAII well, and `__del__` [isn't a good place to free resources](https://stackoverflow.com/a/6104568), so I'm afraid I couldn't automatically clean up after you. You're going to have to be explicit about it, which [Python style](https://www.python.org/dev/peps/pep-0020/) prefers anyway.
|
||||||
|
|
||||||
|
## Call Close when You're Done
|
||||||
|
So how do we release this module's resources? I've provided a handy little function called `close` that takes care of everything for you. All you have to do is remember to call it when you're done. I know, I know, I hate having to remember to call close functions too. They're unassuming, not particularly interesting, and easy to forget about. But there's no way around it, so do your best. In truth, the world won't come crashing down around you if you do forget. You probably won't even notice a difference unless you're leaking hundreds of `VariableServer` instances, in which case you're probably _trying_ to break everything. But call it anyway, ok?
|
||||||
|
|
||||||
|
```python
|
||||||
|
from variable_server import VariableServer
|
||||||
|
variable_server = VariableServer('localhost', 7000)
|
||||||
|
# I'm using variable_server here.
|
||||||
|
# Getting values.
|
||||||
|
# Setting units.
|
||||||
|
# Doing other stuff.
|
||||||
|
# Ok, I'm done.
|
||||||
|
variable_server.close() # don't forget to call close!
|
||||||
|
```
|
||||||
|
|
||||||
|
## Or Use a Context Manager
|
||||||
|
Wait a tick! Python has the concept of context managers, which support automatic finalization within a limited scope. This is perfect if you only need to create an instance for a single block of code. However, it doesn't work if the use is spread over multiple scopes (many different methods sharing the same instance, for example), so you'll have to decide what works best for you.
|
||||||
|
|
||||||
|
```python
|
||||||
|
from variable_server import VariableServer
|
||||||
|
with VariableServer('localhost', 7000) as variable_server:
|
||||||
|
# Hmmm, this syntax is a little strange, but I'll go with it.
|
||||||
|
# Actually, the more I look at it, the more I like it.
|
||||||
|
# Python is pretty cool!
|
||||||
|
# Oh yeah, I'm supposed to be using variable_server here.
|
||||||
|
# Ok, I'm done.
|
||||||
|
# Look, ma! No need to call close!
|
||||||
|
```
|
||||||
|
|
||||||
|
`close` is automatically called when the `with` block exits, no matter how that occurs: normally, via exception, ~~even if you pull the power cord from your computer!~~
|
||||||
|
|
||||||
|
# How do I Make One of These `VariableServer` Thingies?
|
||||||
|
If you know the host and port of the simulation you want to connect to, you can call `VariableServer`'s constructor directly.
|
||||||
|
|
||||||
|
```python
|
||||||
|
>>> from variable_server import VariableServer
|
||||||
|
>>> variable_server = VariableServer('localhost', 7000)
|
||||||
|
```
|
||||||
|
|
||||||
|
If no one's listening, you'll get an error.
|
||||||
|
|
||||||
|
```python
|
||||||
|
Traceback (most recent call last):
|
||||||
|
File "<stdin>", line 1, in <module>
|
||||||
|
File "variable_server.py", line 216, in __init__
|
||||||
|
self._synchronous_socket = socket.create_connection((hostname, port))
|
||||||
|
File "/usr/lib64/python2.7/socket.py", line 571, in create_connection
|
||||||
|
raise err
|
||||||
|
socket.error: [Errno 111] Connection refused
|
||||||
|
```
|
||||||
|
|
||||||
|
If you don't know the host and port (sims select a random available port by default), look no further than `find_simulation`, which will create a `VariableServer` for you from all sorts of simulation parameters.
|
||||||
|
|
||||||
|
```python
|
||||||
|
>>> help(variable_server.find_simulation)
|
||||||
|
|
||||||
|
find_simulation(host=None, port=None, user=None, pid=None, version=None, sim_directory=None, s_main=None, input_file=None, tag=None, timeout=None)
|
||||||
|
Listen for simulations on the multicast channel over which all sims broadcast
|
||||||
|
their existence. Connect to the one that matches the provided arguments that
|
||||||
|
are not None.
|
||||||
|
|
||||||
|
If there are multiple matches, connect to the first one we happen to find.
|
||||||
|
If all arguments are None, connect to the first sim we happen to find.
|
||||||
|
Such matches will be non-deterministic.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
host : str
|
||||||
|
Host name of the machine on which the sim is running as reported by
|
||||||
|
Trick.
|
||||||
|
port : int
|
||||||
|
Variable Server port.
|
||||||
|
user : str
|
||||||
|
Simulation process user.
|
||||||
|
pid : int
|
||||||
|
The sim's process ID.
|
||||||
|
version : str
|
||||||
|
Trick version.
|
||||||
|
sim_directory : str
|
||||||
|
SIM_* directory. If this starts with /, it will be considered an
|
||||||
|
absolute path.
|
||||||
|
s_main : str
|
||||||
|
Filename of the S_main* executable. Not an absolute path.
|
||||||
|
input_file : str
|
||||||
|
Path to the input file relative to the simDirectory.
|
||||||
|
tag : str
|
||||||
|
Simulation tag.
|
||||||
|
timeout : positive float or None
|
||||||
|
How long to look for the sim before giving up. Pass None to wait
|
||||||
|
indefinitely.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
VariableServer
|
||||||
|
A VariableServer connected to the sim matching the specified
|
||||||
|
parameters.
|
||||||
|
|
||||||
|
Raises
|
||||||
|
------
|
||||||
|
socket.timeout
|
||||||
|
If a timeout occurs.
|
||||||
|
```
|
||||||
|
|
||||||
|
# Just Tell Me How to Get a Frickin' Value
|
||||||
|
Looking for the TL;DR version, eh? Alright, here you go:
|
||||||
|
|
||||||
|
```python
|
||||||
|
>>> from variable_server import VariableServer
|
||||||
|
>>> variable_server = VariableServer('localhost', 7000)
|
||||||
|
>>> variable_server.get_value('ball.obj.state.input.mass')
|
||||||
|
'10'
|
||||||
|
```
|
||||||
|
|
||||||
|
## What!? That Returned a String. Mass isn't a String!
|
||||||
|
Well if you weren't in such a rush, we could talk a bit more about your options. What's that? You suddenly have some time to actually read the documentation? Great! Let's dive in.
|
||||||
|
|
||||||
|
## Specifying Type
|
||||||
|
`get_value` has a parameter called `type_` that is used to convert the string value returned by the sim into something more useful. Want an int? Pass `int`. Want a float? Pass `float`. Want a string? Don't pass anything; `str` is the default. Whatever you pass to `type_` is actually called on the string from the sim, so you can pass any function that accepts one argument. Even a custom lambda!
|
||||||
|
|
||||||
|
```python
|
||||||
|
>>> variable_server.get_value('ball.obj.state.input.mass', type_=int)
|
||||||
|
10
|
||||||
|
>>> variable_server.get_value('ball.obj.state.input.mass', type_=float)
|
||||||
|
10.0
|
||||||
|
>>> variable_server.get_value('ball.obj.state.input.mass', type_=lambda x: int(x) * 2)
|
||||||
|
20
|
||||||
|
```
|
||||||
|
|
||||||
|
You'll get an error if you try an invalid conversion.
|
||||||
|
|
||||||
|
```python
|
||||||
|
>>> variable_server.get_value('ball.obj.state.input.mass', type_=dict)
|
||||||
|
Traceback (most recent call last):
|
||||||
|
File "<stdin>", line 1, in <module>
|
||||||
|
File "variable_server.py", line 331, in get_value
|
||||||
|
return type_(value)
|
||||||
|
ValueError: dictionary update sequence element #0 has length 1; 2 is required
|
||||||
|
```
|
||||||
|
|
||||||
|
## Specifying Units
|
||||||
|
`get_value` has a parameter for that too: `units`.
|
||||||
|
|
||||||
|
```python
|
||||||
|
>>> variable_server.get_value('ball.obj.state.input.mass', units='g', type_=int)
|
||||||
|
10000
|
||||||
|
```
|
||||||
|
|
||||||
|
You'll get an error if you try an invalid conversion.
|
||||||
|
|
||||||
|
```python
|
||||||
|
>>> variable_server.get_value('ball.obj.state.input.mass', units='m')
|
||||||
|
Traceback (most recent call last):
|
||||||
|
File "<stdin>", line 1, in <module>
|
||||||
|
File "variable_server.py", line 329, in get_value
|
||||||
|
_assert_units_conversion(name, units, actualUnits)
|
||||||
|
File "variable_server.py", line 927, in _assert_units_conversion
|
||||||
|
raise UnitsConversionError(name, expectedUnits)
|
||||||
|
variable_server.UnitsConversionError: [ball.obj.state.input.mass] cannot be converted to [m]
|
||||||
|
```
|
||||||
|
|
||||||
|
# What About Setting Values?
|
||||||
|
Of course you can set values! It's even easier than getting them.
|
||||||
|
|
||||||
|
```python
|
||||||
|
>>> variable_server.set_value('ball.obj.state.input.mass', 5)
|
||||||
|
>>> variable_server.get_value('ball.obj.state.input.mass', type_=int)
|
||||||
|
5
|
||||||
|
```
|
||||||
|
|
||||||
|
You can specify units when you set variables too.
|
||||||
|
|
||||||
|
```python
|
||||||
|
>>> variable_server.set_value('ball.obj.state.input.mass', 5, units='g')
|
||||||
|
```
|
||||||
|
|
||||||
|
Doing so has no effect on subsequent calls to `get_value`, which continues to use the original units (kg, in this case)
|
||||||
|
|
||||||
|
```python
|
||||||
|
>>> variable_server.get_value('ball.obj.state.input.mass', type_=float)
|
||||||
|
0.005
|
||||||
|
```
|
||||||
|
|
||||||
|
unless you say otherwise.
|
||||||
|
|
||||||
|
```python
|
||||||
|
>>> variable_server.get_value('ball.obj.state.input.mass', units='g', type_=float)
|
||||||
|
5.0
|
||||||
|
```
|
||||||
|
|
||||||
|
# Single-Value Fetches are for Chumps. I Want Multiple Values Simultaneously!
|
||||||
|
To get any fancier, we have to talk about implementation details a bit. Trick's variable server doesn't actually have a "one-shot" value fetching option. Instead, it's designed to periodically send a set of variable values over and over again. If you're familiar with variable server commands, `get_value` actually calls `var_add`, `var_send`, and `var_clear` every time it's called. If we want multiple values, we're better off doing all the `var_adds` together and just calling `var_send` and `var_clear` once. If you don't know what I'm talking about, don't worry about it. All you need to know is that `get_values` is more efficient than calling `get_value` for fetching multiple variables.
|
||||||
|
|
||||||
|
It's also a little more complicated. Having a parameter list like `name1, units1, type1, name2, units2, type2` and so on would get ugly fast. So say goodbye to the simple interface! Time to encapsulate that data in a class.
|
||||||
|
|
||||||
|
## The `Variable` Class
|
||||||
|
`Variable` represents a simulation variable. It's constructor takes the same parameters we've been using with `get_value` and `set_value`: `name`, `units`, and `type_`. `Variables` are used with the `get_values` function (note the trailing `s`), which accepts an arbitrary number of them. `get_values` uses the information in each `Variable` in the same way that `get_value` uses its parameters, and the observable behavior is largely the same: you get back a list of values.
|
||||||
|
|
||||||
|
```python
|
||||||
|
>>> from variable_server import Variable
|
||||||
|
>>> position = Variable('ball.obj.state.input.position[0]', type_=int)
|
||||||
|
>>> mass = Variable('ball.obj.state.input.mass', units='g', type_=float)
|
||||||
|
>>> variable_server.get_values(position, mass)
|
||||||
|
[5, 10000.0]
|
||||||
|
```
|
||||||
|
|
||||||
|
And you get an error if a units or type_ conversion fails.
|
||||||
|
|
||||||
|
```python
|
||||||
|
>>> variable_server.get_values(Variable('ball.obj.state.input.mass', units='m'))
|
||||||
|
Traceback (most recent call last):
|
||||||
|
File "<stdin>", line 1, in <module>
|
||||||
|
File "variable_server.py", line 430, in get_values
|
||||||
|
_assert_units_conversion(variable.name, variable.units, units)
|
||||||
|
File "variable_server.py", line 941, in _assert_units_conversion
|
||||||
|
raise UnitsConversionError(name, expectedUnits)
|
||||||
|
variable_server.UnitsConversionError: [ball.obj.state.input.mass] cannot be converted to [m]
|
||||||
|
|
||||||
|
>>> variable_server.get_values(Variable('ball.obj.state.input.mass', type_=dict))
|
||||||
|
Traceback (most recent call last):
|
||||||
|
File "<stdin>", line 1, in <module>
|
||||||
|
File "variable_server.py", line 438, in get_values
|
||||||
|
return [variable.value for variable in variables]
|
||||||
|
File "variable_server.py", line 145, in value
|
||||||
|
return self._type(self._value)
|
||||||
|
ValueError: dictionary update sequence element #0 has length 1; 2 is required
|
||||||
|
```
|
||||||
|
|
||||||
|
But wait, there's more! Each `Variable` is also updated in place, so you can ignore the returned list and use each `Variable`'s `value` property instead if that's more convenient.
|
||||||
|
|
||||||
|
```python
|
||||||
|
>>> position.value
|
||||||
|
5
|
||||||
|
```
|
||||||
|
|
||||||
|
Units are also available and are automatically filled in if you didn't specify them when creating the `Variable`.
|
||||||
|
|
||||||
|
```python
|
||||||
|
>>> position.units
|
||||||
|
'm'
|
||||||
|
```
|
||||||
|
|
||||||
|
You were probably going to save the returned values somewhere anyway, right? Might as well save them with the `Variable`s themselves! However, the returned list can be useful if you want to use the values in the same expression in which they're fetched.
|
||||||
|
|
||||||
|
```python
|
||||||
|
>>> x = Variable('ball.obj.state.output.position[0]')
|
||||||
|
>>> y = Variable('ball.obj.state.output.position[1]')
|
||||||
|
>>> print 'The ball is at position ({0}, {1})'.format(*variable_server.get_values(x, y))
|
||||||
|
The ball is at position (3.069993744436219, -11.04439115432281)
|
||||||
|
```
|
||||||
|
|
||||||
|
Or if you don't want to save the values at all!
|
||||||
|
|
||||||
|
```python
|
||||||
|
>>> print 'The ball is at position ({0}, {1})'.format(*variable_server.get_values(
|
||||||
|
... Variable('ball.obj.state.output.position[0]'),
|
||||||
|
... Variable('ball.obj.state.output.position[1]')))
|
||||||
|
The ball is at position (3.069993744436219, -11.04439115432281)
|
||||||
|
```
|
||||||
|
|
||||||
|
Which are both equivalent to, but more compact than:
|
||||||
|
|
||||||
|
```python
|
||||||
|
>>> x = Variable('ball.obj.state.output.position[0]')
|
||||||
|
>>> y = Variable('ball.obj.state.output.position[1]')
|
||||||
|
>>> variable_server.get_values(x, y)
|
||||||
|
['3.069993744436219', '-11.04439115432281']
|
||||||
|
>>> print 'The ball is at position ({0}, {1})'.format(x.value, y.value)
|
||||||
|
The ball is at position (3.069993744436219, -11.04439115432281)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Don't Mess With `Variable` Attributes
|
||||||
|
You should consider `Variable` read-only. This module ensures that each `Variable`'s state remains consistent. Once you've constructed one, you should not directly set any of its fields, and you shouldn't need to. Of course, this is Python, so there's nothing to stop you from doing:
|
||||||
|
|
||||||
|
```python
|
||||||
|
>>> mass.value = 1337
|
||||||
|
```
|
||||||
|
|
||||||
|
But that's certainly not going to affect the corresponding variable in the sim.
|
||||||
|
|
||||||
|
```python
|
||||||
|
>>> variable_server.get_value('ball.obj.state.input.mass', type_=float)
|
||||||
|
5.0
|
||||||
|
```
|
||||||
|
|
||||||
|
And changing a `Variable`'s units
|
||||||
|
|
||||||
|
```python
|
||||||
|
>>> mass.units = 'g'
|
||||||
|
```
|
||||||
|
|
||||||
|
is not going to automagically perform a conversion.
|
||||||
|
|
||||||
|
```python
|
||||||
|
>>> mass
|
||||||
|
ball.obj.state.input.mass = 1337.0 g
|
||||||
|
```
|
||||||
|
|
||||||
|
A `Variable` only reflects the state of its corresponding variable in the sim. It does not manipulate it. Always use `set_value` to change the value. The units can be specified in `Variable`'s constructor. They can also be changed via `set_units`, but only for `Variable`s that are being periodically sampled.
|
||||||
|
|
||||||
|
# Periodic Sampling
|
||||||
|
Ah, now we're _really_ cooking! This is what the variable server was made for: sending sets of variable values at a specified rate. If you find yourself calling `get_values` over and over again on the same set of variables, perhaps you'd like to step up to the big leagues and take a crack at asynchronous periodic sampling. Don't worry, it's not as scary as it sounds. In fact, we're already familiar with the core data structure: our old friend `Variable`.
|
||||||
|
|
||||||
|
## Adding `Variable`s
|
||||||
|
Periodic sampling uses the same `Variable`s we used with `get_values`. To get started, just call `add_variables`!
|
||||||
|
|
||||||
|
```python
|
||||||
|
>>> position = Variable('ball.obj.state.output.position[0]', type_=float)
|
||||||
|
>>> variable_server.add_variables(position)
|
||||||
|
```
|
||||||
|
|
||||||
|
After checking for units and type_ conversion errors, this causes the sim to periodically send the value of `ball.obj.state.output.position[0]` to us, which is used to automatically update `position`.
|
||||||
|
|
||||||
|
```python
|
||||||
|
>>> position.value
|
||||||
|
-7.24269488786
|
||||||
|
>>> position.value
|
||||||
|
-9.0757620175
|
||||||
|
>>> position.value
|
||||||
|
-9.751339991
|
||||||
|
```
|
||||||
|
|
||||||
|
Look at that! `position` is updating all on its own. Now you can stick your periodic logic in a nice `while` loop and run forever!
|
||||||
|
|
||||||
|
```python
|
||||||
|
>>> import time
|
||||||
|
>>> while True:
|
||||||
|
... position.value
|
||||||
|
... time.sleep(1)
|
||||||
|
-2.065295422179974
|
||||||
|
1.5358082417288299
|
||||||
|
4.8450427189593777
|
||||||
|
```
|
||||||
|
|
||||||
|
## Triggering Callbacks
|
||||||
|
Using a `while` loop with a `sleep` might work for applications that don't care about the "staleness" of the data when it arrives, but we write real-time code around here; I can't suffer unnecessary delays! The problem with the above approach is that there's no synchronization between when the updates occur and when our sleep happens to return. Sure, we could use `set_period` to tell the sim to send data at the same rate that we're sleeping, but we're bound to drift apart over time, and we can't ensure that we start a new cycle at the same time the sim does. Plus, there's network latency. And what if we ask the sim to send as fast as possible? Then we don't even know what the rate _is_!
|
||||||
|
|
||||||
|
But wait, it gets worse! If your processing cycle is faster than the sim's update cycle, you'll needlessly reprocess values that haven't been updated since the last time you processed them, which is wasteful. But if your cycle is slower, you'll miss some updates entirely.
|
||||||
|
|
||||||
|
For some applications, these issues may truly not matter, and using a simple `while` loop might be sufficient. For the rest of us, there's `register_callback`.
|
||||||
|
|
||||||
|
```python
|
||||||
|
>>> def foo():
|
||||||
|
... print position.value
|
||||||
|
>>> variable_server.register_callback(foo)
|
||||||
|
0.632962631449
|
||||||
|
0.598808711027
|
||||||
|
0.564218072538
|
||||||
|
```
|
||||||
|
|
||||||
|
Now `foo` will be called each and every time there's an update, as soon as it arrives. Huzzah! You can set the period at which updates are sent via `set_period`, which applies to _all_ variables that this instance is tracking, regardless of when they're added. If you want to receive another set at a different rate, you should create another `VariableServer`.
|
||||||
|
|
||||||
|
## Concurrency Concerns
|
||||||
|
Callback functions are executed on the variable sampling thread, which is started when you instantiate `VariableServer` and runs until you call `close` (either explicitly or via a `with` statement). This means that new updates can't be processed until all callback functions have returned. The variable sampling thread spends most of its time blocked, waiting for new updates to arrive, so time consumed by callback functions usually isn't an issue. But if your callback performs a long-running task, you should probably do it in another thread so it doesn't cause the variable sampling thread to fall behind.
|
||||||
|
|
||||||
|
# The API
|
||||||
|
Wikis are great for how-tos and high-level discussions, but if you want to get down to the nuts and bolts, you need to look at the API. You can do so by running `pydoc variable_server` in the directory containing `variable_server.py` or programmatically by calling `help` on the feature in which you're interested.
|
||||||
|
|
||||||
|
```python
|
||||||
|
>>> import variable_server
|
||||||
|
>>> help(variable_server.Variable)
|
||||||
|
Help on class Variable in module variable_server:
|
||||||
|
|
||||||
|
class Variable(__builtin__.object)
|
||||||
|
| A variable whose value and units will be updated from the sim. You
|
||||||
|
| should not directly change any part of this class.
|
||||||
|
```
|
||||||
|
|
||||||
|
[Continue to Software Requirements](software_requirements_specification/SRS)
|
594
docs/documentation/running_a_simulation/Input-File.md
Normal file
@ -0,0 +1,594 @@
|
|||||||
|
|
||||||
|
The primary interface between the simulation executable and the user is the runstream
|
||||||
|
input file. The Trick simulation input file syntax is Python. All Python syntax rules
|
||||||
|
apply
|
||||||
|
|
||||||
|
Rather than discuss an explicit syntax definition (which would probably be more
|
||||||
|
confusing than informative), each specific capability of the input processor, and
|
||||||
|
its associated input file syntax, will be discussed.
|
||||||
|
|
||||||
|
### Accessing Simulation Parameters
|
||||||
|
|
||||||
|
The parameter naming convention for ALL input parameters is the parameter's actual
|
||||||
|
source code name. The following is a line from an input file :
|
||||||
|
```python
|
||||||
|
ball.obj.state.output.position[0] = 1.0 ;
|
||||||
|
```
|
||||||
|
In this example, ball is the sim object name in the S_define file for a sim object
|
||||||
|
which contains the data structure named obj, where the obj data structure declaration
|
||||||
|
is as follows:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
class BallSimObject : Trick::SimObject {
|
||||||
|
...
|
||||||
|
Ball obj ;
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
|
BallSimObject ball ;
|
||||||
|
```
|
||||||
|
|
||||||
|
`state` is a class member found in the `Ball` class.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
class Ball {
|
||||||
|
...
|
||||||
|
public:
|
||||||
|
BallState state; /**< -- Ball state object. */
|
||||||
|
...
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
`output` is a member of the `BallState` class, and finally `position` is
|
||||||
|
a member of the `BallStateOutput` class.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
class BallState {
|
||||||
|
...
|
||||||
|
public:
|
||||||
|
BallStateOutput output; /**< trick_units(--) User outputs. */
|
||||||
|
...
|
||||||
|
};
|
||||||
|
|
||||||
|
class BallStateOutput {
|
||||||
|
...
|
||||||
|
public:
|
||||||
|
double position[2]; /**< trick_units(m) X(horizontal), Y(vertical) position. */
|
||||||
|
...
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
Arrays of simulation parameters may be read and written to with one Python statement.
|
||||||
|
|
||||||
|
```python
|
||||||
|
"""
|
||||||
|
These variables are declared in the ball structure.
|
||||||
|
double da[3] ;
|
||||||
|
double daa[3][3] ;
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Python lists are the equivalent of the C/C++ arrays.
|
||||||
|
|
||||||
|
ball.da = [ 1.0 , 2.0 , 3.0 ]
|
||||||
|
print ball.da
|
||||||
|
# [ 1.0 , 2.0 , 3.0 ] is printed
|
||||||
|
|
||||||
|
ball.daa = [[ 1.0 , 0.0 , 0.0 ] , [ 0.0 , 1.0 , 0.0 ] , [0.0 , 0.0 , 1.0]]
|
||||||
|
print ball.daa
|
||||||
|
|
||||||
|
# [[ 1.0 , 0.0 , 0.0 ] ,
|
||||||
|
# [ 0.0 , 1.0 , 0.0 ] ,
|
||||||
|
# [0.0 , 0.0 , 1.0]]
|
||||||
|
# is printed
|
||||||
|
```
|
||||||
|
|
||||||
|
### Accessing Simulation Enumerated Types
|
||||||
|
|
||||||
|
Global Enumerations are available through the `trick` module.
|
||||||
|
|
||||||
|
```python
|
||||||
|
# from sim_services/include/Flag.h
|
||||||
|
|
||||||
|
print trick.True trick.False trick.Yes trick.No
|
||||||
|
1 0 1 0
|
||||||
|
```
|
||||||
|
|
||||||
|
### Accessing Simulation Functions and Object Member functions
|
||||||
|
|
||||||
|
Almost all functions and public object methods are available to call from the Python input file.
|
||||||
|
Arguments must be filled in just as they would be in C/C++ code. There is more information about what
|
||||||
|
Trick simulation services routines are available later in this chapter.
|
||||||
|
|
||||||
|
```python
|
||||||
|
# Trick simulation services routines are called by "trick.<function>".
|
||||||
|
trick.exec_get_sim_time()
|
||||||
|
trick.checkpoint(100.0)
|
||||||
|
trick.stop(300.0)
|
||||||
|
|
||||||
|
# C User model functions are also called by "trick.<function>".
|
||||||
|
trick.ball_print(ball.state)
|
||||||
|
|
||||||
|
# C++ User model class methods are called by referencing the full object path just like in C++
|
||||||
|
ball.obj.state.print_position()
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
When calling functions, intrinsic typed simulation variables, e.g. int or double, will not work directly
|
||||||
|
as intrisic typed arguments.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
// If we have a c function
|
||||||
|
void foo( double d) ;
|
||||||
|
|
||||||
|
// And a structure with a variable declared as this
|
||||||
|
double length ; /* (m) length */
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
This call in the input will not work
|
||||||
|
|
||||||
|
```python
|
||||||
|
# Will not work
|
||||||
|
foo(length)
|
||||||
|
```
|
||||||
|
|
||||||
|
The reason is that in python space the variable length is an object that contains both the value of length
|
||||||
|
and the units. The built in python command `float()` will strip the units off leaving a double that can be
|
||||||
|
used in the function call.
|
||||||
|
|
||||||
|
```python
|
||||||
|
# Works
|
||||||
|
foo(float(length))
|
||||||
|
```
|
||||||
|
|
||||||
|
Structure and class variables do not carry around units, and therefore the units do not have to be removed.
|
||||||
|
|
||||||
|
### Creating New Objects and Allocating Memory
|
||||||
|
|
||||||
|
It is possible to create new objects and allocate new memory for structures directly in the Python
|
||||||
|
input file. There are at least two ways to allocate memory.
|
||||||
|
|
||||||
|
The first method is to call the `Trick::MemoryManager` routines to allocate memory. This is the preferred method.
|
||||||
|
There are 3 `Trick::MemoryManager` calls with varying arguments that can be used to allocate memory
|
||||||
|
|
||||||
|
```python
|
||||||
|
trick.TMM_declare_var_s("declaration")
|
||||||
|
trick.TMM_declare_var_1d("enh_type_spec", e_elems)
|
||||||
|
trick.alloc_type(e_elems , "enh_type_spec")
|
||||||
|
|
||||||
|
# Some examples using a c++ declaration
|
||||||
|
# double * foo ;
|
||||||
|
# All 3 of the following statments allocates the same amount of memory
|
||||||
|
|
||||||
|
foo = trick.TMM_declare_var_s("double[6]")
|
||||||
|
foo = trick.TMM_declare_var_1d("double", 6)
|
||||||
|
foo = trick.alloc_type(6 , "double")
|
||||||
|
|
||||||
|
# Some examples using a c++ declaration
|
||||||
|
# double ** food ;
|
||||||
|
# All 3 of the following statments allocates the same amount of memory
|
||||||
|
|
||||||
|
food = trick.TMM_declare_var_s("double *[3]")
|
||||||
|
food[0] = trick.TMM_declare_var_s("double [4]")
|
||||||
|
food[1] = trick.TMM_declare_var_s("double [5]")
|
||||||
|
food[2] = trick.TMM_declare_var_s("double [6]")
|
||||||
|
|
||||||
|
food = trick.TMM_declare_var_1d("double *", 3)
|
||||||
|
food[0] = trick.TMM_declare_var_1d("double", 4)
|
||||||
|
food[1] = trick.TMM_declare_var_1d("double", 5)
|
||||||
|
food[2] = trick.TMM_declare_var_1d("double", 6)
|
||||||
|
|
||||||
|
food = trick.alloc_type(3, "double *")
|
||||||
|
food[0] = trick.alloc_type(4, "double")
|
||||||
|
food[1] = trick.alloc_type(5, "double")
|
||||||
|
food[2] = trick.alloc_type(6, "double")
|
||||||
|
```
|
||||||
|
|
||||||
|
Memory allocated using the above routines are tracked by the memory manager and is checkpointable and data recordable.
|
||||||
|
|
||||||
|
The second method is to call the wrapped constructor of the class directly. This is analogous to declaring local
|
||||||
|
variables in C/C++ routines. And like local variables in C/C++ if the python variable goes out of scope in the
|
||||||
|
input file, then python will try and free the memory associated with the local object. Memory allocated this
|
||||||
|
way is not checkpointable or data recordable.
|
||||||
|
|
||||||
|
For example if we are trying to instantiate a new C++ `Ball` object in the input file.
|
||||||
|
|
||||||
|
```python
|
||||||
|
# The new_ball_1 instantiation is at the top level, new_ball_1 will not be freed.
|
||||||
|
new_ball_1 = trick.Ball() ;
|
||||||
|
|
||||||
|
# The new_ball_2 instantiation is in the function foo.
|
||||||
|
# When foo returns new_ball_2 will be freed by python
|
||||||
|
|
||||||
|
def foo():
|
||||||
|
new_ball_2 = trick.Ball() ;
|
||||||
|
```
|
||||||
|
|
||||||
|
To stop python from freeing this memory we must tell python that it does not own the memory.
|
||||||
|
This can be done in two ways. 1) Tell Python it does not own the memory by modifying the
|
||||||
|
`thisown` flag. 2) Use a non-constructor routine that allocates memory and returns that
|
||||||
|
to the Python variable.
|
||||||
|
|
||||||
|
```python
|
||||||
|
# In the above example, we can avoid new_ball_2 from being freed
|
||||||
|
# when foo returns by setting the thisown flag to 0 in the new_ball_2 object.
|
||||||
|
|
||||||
|
def foo():
|
||||||
|
new_ball_2 = trick.Ball() ;
|
||||||
|
new_ball_2.thisown = 0 ;
|
||||||
|
|
||||||
|
# Alternatively we could call a non-constructor C/C++ routine that returns a new Ball
|
||||||
|
# object to python. The python interpreter does not sense it allocated anything and
|
||||||
|
# will not free it.
|
||||||
|
|
||||||
|
"""
|
||||||
|
C++ code for get_new_ball_obj()
|
||||||
|
|
||||||
|
Ball * get_new_ball_obj() {
|
||||||
|
return(new Ball) ;
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
def foo():
|
||||||
|
new_ball_2 = trick.get_new_ball_obj() ;
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### Comments
|
||||||
|
|
||||||
|
Comments in Python come in two forms.
|
||||||
|
|
||||||
|
```python
|
||||||
|
# A single line comment starts with a '#' sign
|
||||||
|
|
||||||
|
"""
|
||||||
|
Multi line comments are enclosed in
|
||||||
|
three sets of double quotes.
|
||||||
|
"""
|
||||||
|
```
|
||||||
|
|
||||||
|
### Nested File Inclusion
|
||||||
|
|
||||||
|
There are several ways to include files in Python.
|
||||||
|
|
||||||
|
```python
|
||||||
|
# One way is to use the execfile command
|
||||||
|
execfile("Modified_data/data_record.py")
|
||||||
|
|
||||||
|
# Another way is to make the included file a module and import it.
|
||||||
|
# Import search paths may be added using the sys.path.append command.
|
||||||
|
|
||||||
|
sys.path.append("/my/python/dir") ;
|
||||||
|
import my_new_module
|
||||||
|
```
|
||||||
|
|
||||||
|
### Local Python Variables
|
||||||
|
|
||||||
|
Local variables may be used anywhere in the Python input file. Local variables will follow normal
|
||||||
|
Python scoping rules. Shortcut variable names may be created to reference simulation variables.
|
||||||
|
|
||||||
|
```python
|
||||||
|
my_position = ball.obj.state.output.position
|
||||||
|
|
||||||
|
my_position[0] = 4.5
|
||||||
|
my_position[1] = 6.7
|
||||||
|
|
||||||
|
print ball.obj.state.output_position
|
||||||
|
# printout would read "4.5, 6.7"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Environment Variables
|
||||||
|
|
||||||
|
Environment Variables are available through the Python `os.getenv` call
|
||||||
|
|
||||||
|
```python
|
||||||
|
print os.getenv("TRICK_CFLAGS")
|
||||||
|
```
|
||||||
|
|
||||||
|
### Measurement Units
|
||||||
|
|
||||||
|
Every input parameter has associated measurement units specified in its corresponding data
|
||||||
|
structure definition file declaration. It specifies the units for the internal source code to
|
||||||
|
use for that parameter. However, Trick users also have certain control over units specification
|
||||||
|
from the input file.
|
||||||
|
|
||||||
|
`trick.attach_units()` attaches a unit to a value or some Python objects.
|
||||||
|
|
||||||
|
```python
|
||||||
|
"""
|
||||||
|
This variables is declared in the ball structure.
|
||||||
|
double position[3] ; /* (m) X,Y,Z position */
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Assign X position to 2m
|
||||||
|
ball.position[0] = trick.attach_units( "m" , 2.0 )
|
||||||
|
|
||||||
|
# Automatic units conversion is done if the attached unit is compatible with the variable.
|
||||||
|
# Assign Y position to 2ft
|
||||||
|
ball.position[1] = trick.attach_units( "ft" , 2.0 )
|
||||||
|
|
||||||
|
# Error is raised.
|
||||||
|
ball.position[2] = trick.attach_units( "ft/s" , 3.0 )
|
||||||
|
|
||||||
|
# Units may be attached to python lists and assigned to the array with one statement
|
||||||
|
# Automatic units conversion is done on the entire list.
|
||||||
|
ball.position = trick.attach_units( "ft" , [1.0 , 2.0, 3.0] )
|
||||||
|
|
||||||
|
# Lists may even include values of different units. Automatic units conversion is
|
||||||
|
# done element by element.
|
||||||
|
ball.position = [trick.attach_units( "ft" , 1.0 ) , trick.attach_units( "m" , 2.0 ) , trick.attach_units( "cm" , 3.0 )]
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
Printing parameters in the Python script will include the attached units.
|
||||||
|
|
||||||
|
```pycon
|
||||||
|
>>> print ball.position
|
||||||
|
[1.0m , 2.0m , 3.0m]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Time Based Input Processing
|
||||||
|
|
||||||
|
The input processor allows pieces of the input file to be processed at a later simulation time.
|
||||||
|
To process code at a later time call `trick.add_read(<time>, "<code_to_be_executed>")`.
|
||||||
|
|
||||||
|
```python
|
||||||
|
# simple statement
|
||||||
|
trick.add_read(1.0 , "ball.obj.state.out.position[0] = 4.0") ;
|
||||||
|
|
||||||
|
# Use triple quotes for multi line input or code segments that include quotes.
|
||||||
|
trick.add_read(2.0 , """
|
||||||
|
ball.obj.state.out.position[0] = 4.0
|
||||||
|
print "This is a quoted string inside the triple quotes"
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Use a local python variable called read to get an appearance similar previous Trick input files
|
||||||
|
read = 4.0
|
||||||
|
trick.add_read(read , ... )
|
||||||
|
|
||||||
|
read += 0.2
|
||||||
|
trick.add_read(read , ... )
|
||||||
|
|
||||||
|
read = 5.0
|
||||||
|
trick.add_read(read , ... )
|
||||||
|
```
|
||||||
|
|
||||||
|
### Freeze the Simulation
|
||||||
|
|
||||||
|
To freeze a simulation call `trick.freeze([<freeze_time>])`. `trick.freeze()` called with no
|
||||||
|
arguments will freeze immediately. An optional freeze time may be provided to freeze some time
|
||||||
|
in the future.
|
||||||
|
|
||||||
|
```python
|
||||||
|
# Freezes immediately
|
||||||
|
trick.freeze()
|
||||||
|
|
||||||
|
# Freezes at an absolute time
|
||||||
|
trick.freeze(100.0)
|
||||||
|
|
||||||
|
# Freezes 5 seconds relative from the current sim_time
|
||||||
|
trick.freeze(trick.exec_get_sim_time() + 5.0)
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### Checkpoint the Simulation
|
||||||
|
|
||||||
|
To checkpoint a simulation call `trick.checkpoint([<checkpoint_time>])`. `trick.checkpoint()` called with no
|
||||||
|
arguments will checkpoint immediately. An optional checkpoint time may be provided to checkpoint some time
|
||||||
|
in the future.
|
||||||
|
|
||||||
|
```python
|
||||||
|
# Checkpoints immediately
|
||||||
|
trick.checkpoint()
|
||||||
|
|
||||||
|
# Checkpoints at an absolute time
|
||||||
|
trick.checkpoint(100.0)
|
||||||
|
|
||||||
|
# Checkpoints 5 seconds relative from the current sim_time
|
||||||
|
trick.checkpoint(trick.exec_get_sim_time() + 5.0)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Stopping the Simulation
|
||||||
|
|
||||||
|
To shutdown a simulation call trick.stop([<stop_time>]). trick.stop() called with no
|
||||||
|
arguments will shutdown immediately. An optional stop time may be provided to shutdown some time
|
||||||
|
in the future.
|
||||||
|
|
||||||
|
```python
|
||||||
|
# Stop immediately
|
||||||
|
trick.stop()
|
||||||
|
|
||||||
|
# Stop at an absolute time
|
||||||
|
trick.stop(100.0)
|
||||||
|
|
||||||
|
# Stop 5 seconds relative from the current sim_time
|
||||||
|
trick.stop(trick.exec_get_sim_time() + 5.0)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Events and Malfunctions
|
||||||
|
|
||||||
|
Trick 10 events are a hybrid of Trick 07 events and malfunctions. A Trick 07 event has one or more conditions, one action, and is evaluated by the input processor. A Trick 07 malfunction also has one or more conditions (called triggers) that you can disable/enable, multiple actions, manual mode, and is evaluated before/after a specified job. Multiple conditions in malfunctions are ORed in 07, while multiple conditions in events can be specified by the user as being ORed or ANDed. Here is the Python syntax showing how Trick 10 events implement all of this functionality.
|
||||||
|
|
||||||
|
For information on how Trick processes events during runtime, see [[Event Processing|Event Manager]].
|
||||||
|
|
||||||
|
#### Basic Event Usage
|
||||||
|
|
||||||
|
```python
|
||||||
|
# Create an event that can be viewed and manipulated in MTV, and can be checkpointed
|
||||||
|
<event name> = trick.new_event("<event name>")
|
||||||
|
# Alternatively, you can create an unnamed event (hidden in MTV and not checkpointable)
|
||||||
|
<event name> = trick.new_event()
|
||||||
|
|
||||||
|
# Set the event condition
|
||||||
|
# (note that because there can be multiple conditions, you must specify a condition index starting at 0)
|
||||||
|
# The number of conditions an event can have is unlimited 0...n
|
||||||
|
# When an (enabled) event condition is true, we say it has "fired"
|
||||||
|
<event name>.condition(<index>, "<input text string>" [,"<optional comment displayed in mtv>"])
|
||||||
|
|
||||||
|
# Set the condition evaluation such that ANY fired condition will cause all of this event's (enabled) actions to run
|
||||||
|
# (conditions are ORed -- this is the default)
|
||||||
|
<event name>.condition_any()
|
||||||
|
# Set the condition evaluation such that ALL (enabled) conditions must fire to cause all of event's (enabled) actions to run
|
||||||
|
# (conditions are ANDed)
|
||||||
|
<event name>.condition_all()
|
||||||
|
|
||||||
|
# Set the frequency that the event condition(s) will be evaluated at
|
||||||
|
<event name>.set_cycle(<cycle time in seconds>)
|
||||||
|
|
||||||
|
# Set the event action to occur when any/all condition(s) have fired
|
||||||
|
# (again specify an index because there can be multiple actions)
|
||||||
|
# The number of actions an event can have is unlimited 0...n
|
||||||
|
<event name>.action(<index>, "<input text string>", [,"<optional comment displayed in mtv>"])
|
||||||
|
|
||||||
|
# Set the event active so that it is processed (default is not active, and event is also deactivated when fired)
|
||||||
|
<event name>.activate() # the opposite would be <event name>.deactivate()
|
||||||
|
# Note that your event will be a one-time thing unless you put the activate statement in your action
|
||||||
|
# This behavior can be overridden using "manual mode" described below
|
||||||
|
|
||||||
|
# Add the event to the input processor's list of events (it will be processed at top of frame before scheduled jobs)
|
||||||
|
trick.add_event(<event name>)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Advanced Event (Malfunction) Usage
|
||||||
|
|
||||||
|
```python
|
||||||
|
# Insert the event before/after a "target" job so that it is evaluated then (as opposed to top of frame)
|
||||||
|
# Note that the event cycle is ignored in this case, the event takes on the cycle time of the target job
|
||||||
|
# Also note that an event can be inserted before/after multiple target jobs,
|
||||||
|
# in which case it will be evaluated multiple times per frame
|
||||||
|
# The job name string is the "sim_object.job_name" from the S_define file.
|
||||||
|
# The job instance is used to specify which instance of the job to use if identically named jobs are
|
||||||
|
# multiply defined in a sim object. If the argument is not specified, the first instance of the is the default.
|
||||||
|
trick.add_event_before(<event name>, "<job name string>" [, <job instance> = 1])
|
||||||
|
trick.add_event_after(<event name>, "<job name string>" [, <job instance> = 1])
|
||||||
|
|
||||||
|
# Remove an event from everywhere it's been added (you can then subsequently add the event again if you want)
|
||||||
|
trick.remove_event(<event_name>)
|
||||||
|
|
||||||
|
# Delete an event permanently from the sim so that you can no longer add it again
|
||||||
|
trick.delete_event(<event_name>)
|
||||||
|
|
||||||
|
# Use a model variable or job as a condition
|
||||||
|
# It is more optimal to use model code as a condition, because of the python parsing involved in a normal condition()
|
||||||
|
# Variable (the variable's value will be taken as the condition boolean) :
|
||||||
|
<event name>.condition_var(<index>, "<variable name>" [,"<optional comment displayed in mtv>"])
|
||||||
|
# Job (the job's return value will be taken as the condition boolean) :
|
||||||
|
<event name>.condition_job(<index>, "<job name>" [,"<optional comment displayed in mtv>"])
|
||||||
|
# Any combination of condition(), condition_var(), or condition_job() can be used for your malfunction condition(s).
|
||||||
|
# NOTE: If the job is something you created just for use in malfunctions (e.g. it is not a scheduled job),
|
||||||
|
then it must be specified once and only once in the S_define file as a "malfunction" class job.
|
||||||
|
|
||||||
|
# Set an event condition's "hold" on so that when it fires, it stays in the fired state, causing actions to run every cycle
|
||||||
|
# (the default is hold off so fire only once)
|
||||||
|
<event name>.condtion_hold_on(<index>) # the opposite would be <event name>.condition_hold_off(<index>)
|
||||||
|
# Note that you would still need "activate" in your action otherwise hold_on won't have any effect.
|
||||||
|
|
||||||
|
# Disable a condition from being evaluated (default is enabled)
|
||||||
|
<event name>.condition_disable(<index>) # the opposite would be <event name>.condition_enable(<index>)
|
||||||
|
|
||||||
|
# Use a model job as an action
|
||||||
|
# It is more optimal to use model code as an action, because of the python parsing involved in a normal action()
|
||||||
|
<event name>.action_job(<index>, "<job name>" [,"<optional comment displayed in mtv>"])
|
||||||
|
# Turn a model job ON/OFF as an action
|
||||||
|
<event name>.action_job_on(<index>, "<job name>" [,"<optional comment displayed in mtv>"])
|
||||||
|
<event name>.action_job_off(<index>, "<job name>" [,"<optional comment displayed in mtv>"])
|
||||||
|
# Any combination of action(), action_job(), action_job_on(), or action_job_off() can be used for your malfunction action(s).
|
||||||
|
# NOTE: If the job is something you created just for use in malfunctions (e.g. it is not a scheduled job),
|
||||||
|
then it must be specified once and only once in the S_define file as a "malfunction" class job.
|
||||||
|
|
||||||
|
# Disable an action from being run (default is enabled)
|
||||||
|
<event name>.action_disable(<index>) # the opposite would be <event name>.action_enable(<index>)
|
||||||
|
|
||||||
|
# Manually fire the event once now, so that its actions will run once now
|
||||||
|
# (this event is now in "manual mode" and its conditions will not be evaluated until manual_done commanded)
|
||||||
|
<event name>.manual_fire()
|
||||||
|
|
||||||
|
# Manually set an event as fired and hold on, so that its actions will run each cycle
|
||||||
|
# (this event is now in "manual mode" and its conditions will not be evaluated until manual_done commanded)
|
||||||
|
<event name>.manual_on()
|
||||||
|
|
||||||
|
# Manually set an event as not fired, so that its actions will not run
|
||||||
|
# (this event is now in "manual mode" and its conditions will not be evaluated until manual_done commanded)
|
||||||
|
<event name>.manual_off()
|
||||||
|
|
||||||
|
# Exit "manual mode" for this event and return to normal processing of its conditions
|
||||||
|
<event name>.manual_done()
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Setting variables synchronously: Real Time Variable Injector
|
||||||
|
|
||||||
|
You can also use `rti_add`/`rti_fire` commands in your event action syntax (or as standalone commands in the input file or
|
||||||
|
via the variable server) to set variables. See "Real Time Variable Injector".
|
||||||
|
|
||||||
|
#### Accessing the current Event state
|
||||||
|
|
||||||
|
```python
|
||||||
|
<event name>.condtion_fired(<index>) # boolean: test if a particular event condition fired this cycle
|
||||||
|
<event name>.condition_fired_count(<index>) # integer: number of times a particular event condition has fired
|
||||||
|
<event name>.condtion_fired_time(<index>) # double: last sim time a particular event condition has fired
|
||||||
|
<event name>.action_ran(<index>) # boolean: test if a particular event action ran this cycle
|
||||||
|
<event name>.action_ran_count(<index>) # integer: number of times a particular event action has run
|
||||||
|
<event name>.action_ran_time(<index>) # double: last sim time a particular event action has run
|
||||||
|
<event name>.fired # boolean: test if the event conditions setup evaluated to true this cycle
|
||||||
|
<event name>.fired_count # integer: number of times this event has fired
|
||||||
|
<event name>.fired_time # double: last sim time this event has fired
|
||||||
|
<event name>.ran # boolean: test if any event action ran this cycle
|
||||||
|
<event name>.ran_count # integer: number of times this event has run an action
|
||||||
|
<event name>.ran_time # double: last sim time this event has run an action
|
||||||
|
<event name>.manual # boolean: test if this event is in "manual mode"
|
||||||
|
<event name>.manual_fired # boolean: test if this event was fired manually this cycle
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Event Example
|
||||||
|
|
||||||
|
Hopefully this example shows the various things you can do using events without being too confusing. Even the event components themselves can be queried and changed.
|
||||||
|
|
||||||
|
```python
|
||||||
|
# In this event example:
|
||||||
|
# evaluate velocity before integration...
|
||||||
|
# if it is over 50, print a message
|
||||||
|
# if it is over 100, reset the velocity to 0 after data recording is done for this frame
|
||||||
|
# if our sim has gone past 500 seconds, do not reset velocity when it goes over 100,
|
||||||
|
# but instead shutdown when velocity goes over 200
|
||||||
|
|
||||||
|
vel_event = trick.new_event("vel_event")
|
||||||
|
vel_event.condition(0, "trick.as_pyfloat(ball.obj.state.output.velocity) > 50.0")
|
||||||
|
vel_event.condition(1, "trick.as_pyfloat(ball.obj.state.output.velocity) > 100.0")
|
||||||
|
vel_event.action(0, """
|
||||||
|
print "VELOCITY = ", ball.obj.state.ouput.velocity
|
||||||
|
vel_event.activate()
|
||||||
|
""")
|
||||||
|
vel_event.activate()
|
||||||
|
|
||||||
|
over100_event = trick.new_event("over100_event")
|
||||||
|
over100_event.condition(0, "vel_event.condition_fired(1)")
|
||||||
|
over100_event.action(0, "trick.as_pyfloat(ball.obj.state.output.velocity) = 0.0")
|
||||||
|
over100_event.action(1, "trick.stop()")
|
||||||
|
over100_event.action(2, "over100_event.activate()")
|
||||||
|
over100_event.action_disable(1)
|
||||||
|
over100_event.activate()
|
||||||
|
|
||||||
|
change_event = trick.new_event("change_event")
|
||||||
|
change_event.condition(0, "trick.exec_get_sim_time() > 500.0")
|
||||||
|
change_event.action(0, """
|
||||||
|
over100_event.action_disable(0)
|
||||||
|
over100_event.action_enable(1)
|
||||||
|
vel_event.condition(1, "trick.as_pyfloat(ball.obj.state.output.velocity) > 200.0")
|
||||||
|
""")
|
||||||
|
change_event.activate()
|
||||||
|
|
||||||
|
trick.add_event_before(vel_event, "ball.obj.state_integ")
|
||||||
|
trick.add_event_before(change_event, "ball.obj.state_integ")
|
||||||
|
trick.add_event_after(over100_event, "data_record_group1.Ball")
|
||||||
|
```
|
||||||
|
|
||||||
|
### Trick Specific Python Usage
|
||||||
|
|
||||||
|
Many of Trick's functions can be called using Python commands in the input file (or via the variable server)
|
||||||
|
to perform various operations or to customize/configure Trick.
|
||||||
|
|
||||||
|
Look for a Trick flag icon like this beside each user callable function for details in the Class pages listed below.
|
||||||
|
|
||||||
|
### I Just Want to Know How Do I Set this Value...
|
||||||
|
|
||||||
|
[Continue to Runtime GUIs](runtime_guis/Runtime-GUIs)
|
@ -0,0 +1,40 @@
|
|||||||
|
S_main_${TRICK_HOST_CPU}.exe is generated by the CP and is the simulation main executable program.
|
||||||
|
|
||||||
|
The runtime configuration of the executive and its associated support utilities may be manipulated through entries in the simulation input file. The input file is described in detail in Input_File.
|
||||||
|
|
||||||
|
The command line for the runtime executive is:
|
||||||
|
|
||||||
|
```
|
||||||
|
S_main_${TRICK_HOST_CPU}.exe [trick_version] [sie]
|
||||||
|
RUN_<name>/<input_file_name> [-d]
|
||||||
|
[-O <output_file_path>]
|
||||||
|
[-OO <output_file_path>]
|
||||||
|
[-u <user_defined_arguments>]
|
||||||
|
```
|
||||||
|
|
||||||
|
- The first argument in the command line must be the simulation input file name. The input file name can be in the form of a full path name but MUST have a RUN_<name> directory immediately above the input file name. By default, all the simulation output is directed to this RUN_<name> directory. The standard <input_file_name> is input.py; however, a simulation could be started from a checkpoint file by substituting chkpnt_<time> in for <input_file_name> for non-Master/Slave and non-Import/Export simulations. For Master/Slave and Import/Export simulations you must have the simulation running, and the simulation must be in a freeze state before reloading a checkpoint.
|
||||||
|
- The trick_version option will tell what version of Trick built the S_main executable.
|
||||||
|
- The sie option will generate the smart input editor (SIE) resource file (CP will by default invoke the S_main executable with the sie option to generate this file).
|
||||||
|
- The '-d' argument is optional and, if specified, starts the simulation in an input file verification mode. In this mode the entire input file is read, echoed to standard out, and then the simulation exits without calling any jobs listed in the S_define file. This mode helps debug input file syntax errors.
|
||||||
|
- The '-O <output_file_path>' option allows the user to specify the directory to which simulation data log files will be written. If this option is omitted, the RUN_<name> directory is used.
|
||||||
|
- The '-OO <output_file_path>' option allows the user to specify the directory to which ALL simulation output files will be written. If this option is omitted, the RUN_<name> directory is used.
|
||||||
|
- The '-u' option specifies that all remaining arguments are meant to be used by user supplied jobs. All arguments after the -u can be accessed internal to the simulation jobs by calling the get_cmnd_args() function of the executive as illustrated below. In a master/slave simulation, the master's -u args will be passed to the slave.
|
||||||
|
|
||||||
|
The following code example shows how a function can access the command line arguments during execution.
|
||||||
|
|
||||||
|
```c++
|
||||||
|
#include "trick/command_line_protos.h"
|
||||||
|
|
||||||
|
void test_job( void ) {
|
||||||
|
int num_args ;
|
||||||
|
char **args ;
|
||||||
|
int ii ;
|
||||||
|
num_args = command_line_args_get_argc() ;
|
||||||
|
args = command_line_args_get_argv() ;
|
||||||
|
for( ii = 0 ; ii < num_args ; ii++ )
|
||||||
|
printf( "argument #%d = %s\n" , ii , args[ii] ) ;
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
[Continue to Input File](Input-File)
|
13
docs/documentation/running_a_simulation/Runtime-Output.md
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
Executing the simulation main executable S_main_${TRICK_HOST_CPU}.exe generates a handful of log files that document a simulation run.
|
||||||
|
|
||||||
|
The log files are written to the RUN_<name> directory by default. The destination can be redirected by specifying the -O or -OO option for the runtime executive. Two of the log files are described below.
|
||||||
|
|
||||||
|
S_job_execution lists the jobs executed by name, the job types, the arguments, and start and stop times.
|
||||||
|
|
||||||
|
S_run_summary documents the name and path of the executable and the input file, the build time of the executable, and the Trick version. It also contains the list of environment variables used when the executable was built and the model versions.
|
||||||
|
|
||||||
|
log_<group_name>.* log files and log header files. These files are created by the Data Recording capabilities in Trick. They contain cyclic recorded parameters from within the simulation.
|
||||||
|
|
||||||
|
send_hs all messages written by send_hs or message_publish will be saved to the send_hs file.
|
||||||
|
|
||||||
|
[Continue to Data Products](../data_products/Data-Products)
|
@ -0,0 +1,173 @@
|
|||||||
|
### Events/Malfunctions Trick View
|
||||||
|
Events/Malfunctions Trick View (hereafter referred to as MTV) is a graphical user interface that has two main functions:
|
||||||
|
|
||||||
|
1. to view/control Trick-managed event activity while the simulation is running, and
|
||||||
|
1. to create/edit Trick-managed events for saving to a file or for sending directly to a running simulation.
|
||||||
|
|
||||||
|
"Malfunctions" is a legacy term from when events and malfunctions were separate entities in a previous version of Trick. The functionality of both malfunctions and events have been combined and simply called "Events".
|
||||||
|
|
||||||
|
#### Launching
|
||||||
|
Typically MTV is launched via the Actions menu in the @ref SimControlPanel "Simulation Control Panel". MTV will then load and display any events you've defined in your Run input file:
|
||||||
|
|
||||||
|
![MTV Launch](images/mtv_launch.jpg)
|
||||||
|
|
||||||
|
If you want MTV to launch every time you run a simulation, you can automatically launch MTV each run by coding the following in your Run input file:
|
||||||
|
```
|
||||||
|
trick.malfunctions_trick_view_set_enabled(1)
|
||||||
|
```
|
||||||
|
MTV can also be launched from the command line via:
|
||||||
|
```
|
||||||
|
mtv <hostname> <port>
|
||||||
|
```
|
||||||
|
The mtv launch script is located in $TRICK_HOME/bin. If you only want to use MTV to create/edit a new event, you can simply type:
|
||||||
|
```
|
||||||
|
mtv
|
||||||
|
```
|
||||||
|
on the command line in your simulation directory (without the <hostname> or <port> arguments). You can save your newly created event to a file but you of course can't send it to a running simulation in this mode (See @ref MTV_send_to_sim "Send To Sim Button" below).
|
||||||
|
|
||||||
|
For additional launching options, see "Automatically Launching Applications".
|
||||||
|
|
||||||
|
#### The MTV GUI (in View Mode)
|
||||||
|
MTV has two main screens, one for viewing events in a running simulation (View Mode), and one for creating / editing events (Edit Mode). The MTV GUI pictured below is in **View** Mode. It may have a different look and feel based on the architecture of the machine on which it is running,
|
||||||
|
but the functionality will remain the same.
|
||||||
|
|
||||||
|
![MTV View](images/mtv_view.jpg)
|
||||||
|
|
||||||
|
##### View/Edit Tab
|
||||||
|
Click the "View" Tab to view the events for a running simulation (View Mode). Click the "Edit" Tab to create / edit an event (Edit Mode).
|
||||||
|
|
||||||
|
##### Some Background on Event Processing
|
||||||
|
There is a Trick job called process_event() that is run near the top of the execution frame to evaluate all "Added" events. See @ref Event_Processing "Event Processing" for more details.
|
||||||
|
|
||||||
|
##### Event / Condition / Action Active Toggle
|
||||||
|
The 1st column in View Mode is the Active Toggle.
|
||||||
|
* Clicking an Active toggle button for an **Event** will make that Event active/inactive in Normal mode.
|
||||||
|
* Clicking the Active toggle for a **Condition** will make that Condition active/inactive in Normal mode.
|
||||||
|
* Clicking the Active toggle for an **Action** will make that Action active/inactive in both Normal and Manual mode.
|
||||||
|
|
||||||
|
##### Event Name, Conditions and Actions
|
||||||
|
The 2nd column in View Mode is the event name. Each event name is shown on a gray line in the MTV display.
|
||||||
|
The name is the string that was passed to the `new_event()` command. The event's condition(s) are listed next, followed by the event's action(s). The first 50 characters of each condition/action string are shown, unless the optional comment was passed to the `condition()` or `action()` command. If the comment was specified, it is what will be displayed as the condition or action name. The number in parentheses shown in each condition / action is the index number (from 0..n) used in the `condition()` or `action()` command.
|
||||||
|
|
||||||
|
##### Event Fired & Ran Status
|
||||||
|
Columns 3, 4, 5, and 6 in View Mode show when and how many times the event and its components fired/ran.
|
||||||
|
* A **Condition** fires when it is Active in Normal mode and is evaluated as true.
|
||||||
|
* An **Event** fires when it is Active in Normal mode and its condition(s) are evaluated as true, or when it is in Manual mode and the command issued is either `manual_fire()` or `manual_on()`.
|
||||||
|
* An **Action** runs if it is Active and the event fires. An event runs when at least one of its actions runs.
|
||||||
|
|
||||||
|
##### Condition Hold Toggle
|
||||||
|
The 7th column in View Mode is the Hold toggle, only valid for Conditions. Clicking the Hold toggle on a Condition will turn on/off the Hold status for that condition. If Hold is on, when the condition evaluates to true it will be "held" as true so that the condition will fire each time it is evaluated.
|
||||||
|
|
||||||
|
##### Event Mode
|
||||||
|
The 8th column in View Mode is the Event Mode selector:
|
||||||
|
|
||||||
|
1. **Normal** The default, event conditions are evaluated to determine when the event fires (issues a `manual_done()` command).
|
||||||
|
1. **Manual FIRE** Fire the event once now, remain in manual OFF mode (issues a `manual_fire()` command).
|
||||||
|
1. **Manual ON** Fire the event every time it is evaluated, remain in manual ON mode (issues a `manual_on()` command).
|
||||||
|
1. **Manual OFF** Do not fire the event, remain in manual OFF mode (issues a `manual_off()` command).
|
||||||
|
|
||||||
|
When in one of the Manual modes, the event's conditions are not evaluated, the manual command issued determines if the event fires.
|
||||||
|
|
||||||
|
NOTE: The `manual_fire()` command has the side effect of "restarting" an event's cycle. For instance, if the event cycle is 1.0, in Normal mode it will be evaluated at time 0.0, 1.0, 2.0, etc. However, if you issue a `manual_fire()` command at say, time 2.5, when you return to Normal mode the event will be evaluated at 3.5, 4.5, etc.
|
||||||
|
|
||||||
|
##### Event Added Toggle
|
||||||
|
The 9th column in View Mode is the Event Added Toggle. Clicking an Event's Added toggle will add/remove the event from the list of events that Trick's process_event() job will evaluate. If an event is not added, then it will not fire cyclically in Normal mode or even in Manual ON mode. However, you can fire an event that has not been added, only one shot at a time by issuing a manual FIRE (`manual_fire()`) command. When you click on the Added toggle to uncheck it, a `remove_event()` command is issued.
|
||||||
|
|
||||||
|
NOTE: Instead of adding an event (via `add_event()`) to the list to be evaluated by `process_event()`, you can alternatively add an event before or after a model job with the `add_event_before()` or `add_event_after()` command. When you do this, the event is evaluated immediately before/after that model job (the event cycle is ignored). The initial `add_event_before()` or `add_event_after()` command must be done in the Run input file, but from then on if you click the Added toggle in MTV to remove that event and then click Added to add it later, MTV will remember where it was and will add the event back in the same position before or after the model job you removed it from.
|
||||||
|
|
||||||
|
So when you click on the Added Toggle to check it, the event is added using either `add_event()`, `add_event_before()`, or `add_event_after()`.
|
||||||
|
|
||||||
|
##### Colors Used in MTV
|
||||||
|
1. **Black font** An event in Normal mode that is both Active and Added, having been added using the `add_event()` command.
|
||||||
|
1. **Brown font** An event in Normal mode that is both Active and Added, having been added using the `add_event_before()` or `add_event_after()` command.
|
||||||
|
1. **Gray font** An event that is either not Active or not Added, or a condition/action that is not Active (this color overrides the previous two colors).
|
||||||
|
1. **Blue font** An event in Manual mode (this color overrides the previous three colors, except that actions can be inactive in Manual mode, so inactive actions will be gray).
|
||||||
|
1. **Red background** An event's Fired Time column is highlighted in red when it fires.
|
||||||
|
1. **Green background** An event's Ran Time column is highlighted in green when it runs.
|
||||||
|
|
||||||
|
##### File Menu
|
||||||
|
You can select Load Event(s) from the File menu to have Trick read in a file containing one or more events when MTV is connected to a simulation. MTV will then add the newly loaded events to the View Mode window.
|
||||||
|
|
||||||
|
##### View Menu
|
||||||
|
###### Delete Event
|
||||||
|
If you select an event row in the MTV display, then select Delete Event from the View Menu, you can delete an event permanently from the simulation you are connected to. MTV will remove the event from the display and you can no longer reference that event during the simulation. This will NOT delete any file where the event was loaded from. The event object itself will be deleted from memory in the running simulation.
|
||||||
|
|
||||||
|
###### Customize Event Display
|
||||||
|
Selecting Customize Event Display from the File Menu will pop up a window where you can select which events you want MTV to display. This is handy when your simulation contains many events and the display window cannot display them all without scrolling. The default is for MTV to display all events contained in the running simulation, up to a maximum of 500. If your simulation has more than 500 events, you must use Customize Event Display to choose a set of 500 or fewer events to display (only the first 500 loaded will initially be shown).
|
||||||
|
|
||||||
|
If you have the need to use many events, you may want to create event "groups" by defining your events in the Run input file using Python classes. For instance, the events `mygroup.this_event` and `mygroup.that_event` shown in the MTV GUI picture above were defined like this :
|
||||||
|
|
||||||
|
```python
|
||||||
|
class MyGroup:
|
||||||
|
this_event = trick.new_event("mygroup.this_event")
|
||||||
|
this_event.condition(0, "test.obj.run_status<1")
|
||||||
|
this_event.action(0, "trick.freeze()")
|
||||||
|
this_event.action(1, "test.obj.run_status=1")
|
||||||
|
this_event.activate()
|
||||||
|
trick.add_event(this_event)
|
||||||
|
that_event = trick.new_event("mygroup.that_event")
|
||||||
|
that_event.condition(0, "test.obj.run_status>1")
|
||||||
|
that_event.action(0, "trick.run()")
|
||||||
|
that_event.activate()
|
||||||
|
trick.add_event(that_event)
|
||||||
|
mygroup = MyGroup()
|
||||||
|
```
|
||||||
|
|
||||||
|
The Customize Event Display popup will recognize such event groups and allow you to select / deselect events by group name. It will contain a Tab for each event group labeled with the group name; events that do not belong to any group will be in a Tab labeled "Events".
|
||||||
|
|
||||||
|
![MTV Customize](images/mtv_customize.jpg)
|
||||||
|
|
||||||
|
You may notice some events named "no_name_specified". These are either events created for `add_read()` statements in the Run input file, or events created by the `new_event()` command when no name string was passed in. By default MTV does not display unnamed events, but you can display them if you want by selecting them in Customize Event Display.
|
||||||
|
|
||||||
|
##### Cycle Menu
|
||||||
|
The Cycle Menu allows you to set how fast the MTV GUI receives updates from the simulation it is connected to. The default cycle update rate is 0.50, but the Cycle Menu lets you pick from 0.05 (fastest) to 1.0 (slowest).
|
||||||
|
|
||||||
|
##### Connection Status Bar
|
||||||
|
At the bottom of the MTV GUI is the Connection Status Bar. At the far left of the bar is an area where status messages are displayed. It normally says "Connected" or "Disconnected" depending on if MTV is connected to a running simulation. When the MTV GUI display updates the events being displayed (at startup or after you selected Customize Event Display), each event name will be briefly displayed in this status message area while loading.
|
||||||
|
|
||||||
|
There are two text fields containing the host name and port number of the connected simulation. When not connected, the user can enter the appropriate host name and port number into these text fields and click the Connect button at the right to connect to a running simulation. (The port number is the Trick variable server port number that can be found on the bottom of the "Simulation Control Panel" if it is up.)
|
||||||
|
|
||||||
|
#### The MTV GUI (in Edit Mode)
|
||||||
|
MTV has two main screens, one for viewing events in a running simulation (View Mode), and one for creating / editing events (Edit Mode). The MTV GUI pictured below is in **Edit** Mode.
|
||||||
|
|
||||||
|
![MTV Edit](images/mtv_edit.jpg)
|
||||||
|
|
||||||
|
##### View/Edit Tab
|
||||||
|
Click the "Edit" Tab to create / edit an event (Edit Mode). Click the "View" Tab to view the events for a running simulation (View Mode).
|
||||||
|
|
||||||
|
##### Event Name Text Field
|
||||||
|
When you first bring up the Edit Mode screen in MTV, the Event Name string is set to "put_new_event_name_here". You must enter a new Event Name string here before you can begin to edit the event. Note that you must press the "Enter" key on your keyboard to register the new Event Name and enable the "Event Syntax" and "User Data" areas.
|
||||||
|
|
||||||
|
##### Event Syntax Area
|
||||||
|
Once you've entered an Event Name, MTV will automatically generate a default set of commands to configure your new event. The part of the commands shown under the Event Syntax column on the left is not editable. You can add or delete commands using the "Edit Menu" described below.
|
||||||
|
|
||||||
|
##### User Data Area
|
||||||
|
The part of the event commands shown under the User Data column on the right is editable. You can double click the User Data text you want to change and enter in whatever you want. Note that there is no means of checking your syntax, so if you enter incorrect syntax, you won't find out until you send the event to your simulation and it is evaluated by Trick during execution. A Python syntax error in your event will be printed to the screen and looks something like this:
|
||||||
|
```
|
||||||
|
File "<string>", line 1
|
||||||
|
trick_ip.ip.return_val = XXX
|
||||||
|
SyntaxError: unexpected EOF while parsing
|
||||||
|
```
|
||||||
|
|
||||||
|
Where "XXX" is the offending string from your event command.
|
||||||
|
|
||||||
|
##### Send To Sim Button
|
||||||
|
When you have created and edited an event to your satisfaction, you can click the Send To Sim button to the right of the Event Name to send the new event to a connected simulation. Trick will read in the new event and it will be displayed in the MTV View Mode window.
|
||||||
|
|
||||||
|
##### File Menu
|
||||||
|
You can select Save Event from the File Menu if you want to save your newly created event to a file. If you don't do this, it will be lost once you quit MTV or when your connected simulation terminates.
|
||||||
|
|
||||||
|
Currently there is no way to Load Event(s) from a file into the MTV editor. It is strictly for creating new events from scratch.
|
||||||
|
|
||||||
|
##### Edit Menu
|
||||||
|
###### Create New Event
|
||||||
|
If you select Create New Event from the Edit Menu, any editing you've done that is currently displayed under Event Syntax and User Data will be discarded, and the Event Name will be set to "put_new_event_name_here" where you must enter a new Event Name string to continue.
|
||||||
|
|
||||||
|
###### Delete Line
|
||||||
|
If you select an event statement shown under Event Syntax / User Data, then select Delete Line from the Edit Menu, that line will be deleted from the event you are editing.
|
||||||
|
|
||||||
|
###### Add Line to condition/action
|
||||||
|
You can add more line(s) to a condition or action by first selecting a condition or action statement under Event Syntax / User Data, then select Add Line to condition/action from the Edit Menu.
|
||||||
|
|
||||||
|
###### Add Statement
|
||||||
|
You can add more event commands to the event you are editing by selecting Add Statement from the Edit Menu. A selection of common valid event commands are then popped up for you to select. Some advanced Trick commands, such as trick.remove_event(), can only be added manually after you have "stubbed-out" a new event via MTV.
|
@ -0,0 +1,102 @@
|
|||||||
|
### Monte Monitor
|
||||||
|
|
||||||
|
Monte Monitor (hereafter referred to as MM) is a graphical user interface that allows users to view and modify the states
|
||||||
|
of slaves in a Monte Carlo simulation.
|
||||||
|
|
||||||
|
#### Launching
|
||||||
|
|
||||||
|
MM can be launched from the command line via:
|
||||||
|
|
||||||
|
'''
|
||||||
|
${TRICK_HOME}/bin/mm [options]
|
||||||
|
'''
|
||||||
|
|
||||||
|
Pass <code>--help</code> for a description of available options. For additional launching options, see
|
||||||
|
"Automatically Launching Applications".
|
||||||
|
|
||||||
|
#### The GUI
|
||||||
|
|
||||||
|
The GUI pictured below may have a different look and feel based on the architecture of the machine on which it is running,
|
||||||
|
but the functionality will remain the same.
|
||||||
|
|
||||||
|
![Monte Monitor](images/MonteMonitor.jpg)
|
||||||
|
|
||||||
|
##### Progress Bar
|
||||||
|
|
||||||
|
The progress bar displays a visual and textual representation of how far the Monte Carlo has progressed. The format is
|
||||||
|
<code>\<resolved runs\> / \<total runs\> (\<percent resolved\>)</code>.
|
||||||
|
|
||||||
|
##### Slave Table
|
||||||
|
|
||||||
|
The slave table displays information on each of the slaves. From left to right, this information is:
|
||||||
|
|
||||||
|
<ul><li><b>ID</b><br>
|
||||||
|
The unique ID of the slave.
|
||||||
|
|
||||||
|
<li><b>Status</b><br>
|
||||||
|
The current status of the slave. It can be one of:
|
||||||
|
|
||||||
|
<ul><li><b>Unitialized</b><br>
|
||||||
|
The slave has yet to be spawned.
|
||||||
|
|
||||||
|
<li><b>Initializing</b><br>
|
||||||
|
The slave has been spawned, and the master is waiting for initialization information from it. Once initialized, the
|
||||||
|
slave will be in the <code>Ready</code> state. Since Monte Carlo cannot determine if slaves spawn correctly, slaves
|
||||||
|
that fail to spawn will remain in this state for the duration of the Monte Carlo.
|
||||||
|
|
||||||
|
<li><b>Ready</b><br>
|
||||||
|
The slave is awaiting a dispatch.
|
||||||
|
|
||||||
|
<li><b>Running</b><br>
|
||||||
|
The slave is processing a run. Once completed, the slave will be in the <code>Ready</code> state.
|
||||||
|
|
||||||
|
<li><b>Stopping</b><br>
|
||||||
|
The slave is processing a run. Once completed, the slave will be in the <code>Stopped</code> state.
|
||||||
|
|
||||||
|
<li><b>Stopped</b><br>
|
||||||
|
The slave is not accepting dispatches.
|
||||||
|
<li><b>Finished</b><br>
|
||||||
|
No runs remain to dispatch to the slave.
|
||||||
|
|
||||||
|
<li><b>Unresponsive - Running</b><br>
|
||||||
|
The slave has timed out and is also in the <code>Running</code> state.
|
||||||
|
|
||||||
|
<li><b>Unresponsive - Stopping</b><br>
|
||||||
|
The slave has timed out and is also in the <code>Stopping</code> state.
|
||||||
|
|
||||||
|
<li><b>Disconnected</b><br>
|
||||||
|
The connection to the slave has been lost.
|
||||||
|
|
||||||
|
<li><b>Unknown</b><br>
|
||||||
|
MM could not interpret the state of the slave as reported by the Monte Carlo simulation.
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<li><b>Machine Name</b><br>
|
||||||
|
The name of the machine on which the slave is running.
|
||||||
|
|
||||||
|
<li><b>Current Run</b><br>
|
||||||
|
The ID of the run the slave is currently processing.
|
||||||
|
|
||||||
|
<li><b>Total Runs</b><br>
|
||||||
|
The number of runs the slave has completed.
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
##### New Slave Field
|
||||||
|
|
||||||
|
The new slave field allows the user to add a new slave by machine name while the Monte Carlo is running. Note that slaves
|
||||||
|
that fail to spawn for any reason (a bad machine name, for instance) will nevertheless appear in the slave table with a
|
||||||
|
status of <code>Initializing</code>.
|
||||||
|
|
||||||
|
##### Connection Panel
|
||||||
|
|
||||||
|
The connection panel displays host and port information when MM is connected to a simulation, and allows the user to
|
||||||
|
specify these parameters when disconnected.
|
||||||
|
|
||||||
|
#### Starting and Stopping
|
||||||
|
|
||||||
|
Slaves can be started and stopped while the Monte Carlo is running via the <code>Monte Carlo</code> and
|
||||||
|
<code>Slaves</code> menus. Selecting a command from the <code>Monte Carlo</code> menu is equivalent to applying the same
|
||||||
|
command from the <code>Slaves</code> menu to all slaves in the slave table. Stopping a slave will prevent any further
|
||||||
|
runs from being dispatched to it after its current dispatch completes. Starting a slave will resume dispatches to it.
|
||||||
|
|
@ -0,0 +1,141 @@
|
|||||||
|
Trick provides the following graphical user interfaces:
|
||||||
|
|
||||||
|
### Simulation Control Panel
|
||||||
|
|
||||||
|
Send control commands to and view the status of a simulation.
|
||||||
|
|
||||||
|
### [Trick View](TrickView)
|
||||||
|
|
||||||
|
Browse and modify a simulation's variables while it's running. Launch integrated strip charts.
|
||||||
|
|
||||||
|
### [Events/Malfunctions Trick View](MalfunctionsTrickView)
|
||||||
|
|
||||||
|
Manage the events and malfunctions of a simulation.
|
||||||
|
|
||||||
|
### [Monte Monitor](MonteMonitor)
|
||||||
|
|
||||||
|
Monitor the status of a Monte Carlo simulation; create, start, and stop slaves.
|
||||||
|
|
||||||
|
### Managing External Applications
|
||||||
|
|
||||||
|
External applications are managed by instantiating and invoking calls on instances of launcher classes, which provide interfaces for setting up external applications from the input file or user model code. For instance, to manipulate Trick View from the input file:
|
||||||
|
```
|
||||||
|
trickView = trick.TrickView()
|
||||||
|
```
|
||||||
|
|
||||||
|
You now have an instance of the Trick View launcher class on which you can invoke calls to modify the actual Trick View application's behavior at launch. For instance, you could set the host and port:
|
||||||
|
```
|
||||||
|
trickView.set_host("localhost")
|
||||||
|
trickView.set_port(7000)
|
||||||
|
```
|
||||||
|
|
||||||
|
And then add it for automatic launching:
|
||||||
|
```
|
||||||
|
trick.add_external_application(trickView)
|
||||||
|
```
|
||||||
|
|
||||||
|
Provided launcher classes are derived from and listed in Trick::ExternalApplication. Some functionality is shared among launcher classes, and each class provides its own specific additional options. Trick allows any number of instances of any subclass of ExternalApplication. This means you could automatically launch two different Trick Views with completely separate settings (if you find that sort of thing useful).
|
||||||
|
|
||||||
|
### Automatically Launching Applications
|
||||||
|
|
||||||
|
Applications can be set to automatically launch during the initialization job phase by adding them to the queue of external applications managed by Trick. To do this, instantiate an instance of the appropriate launcher class (see above) and call Trick::ExternalApplication::add_external_application.
|
||||||
|
|
||||||
|
### Manually Launching Applications
|
||||||
|
|
||||||
|
Trick automatically launches all applications that have been added to its queue during simulation initialization. However, applications may also be manually launched via Trick::ExternalApplication::launch.
|
||||||
|
|
||||||
|
### Launch Command
|
||||||
|
|
||||||
|
Default commands suitable to launch each application are provided by their individual constructors. However, they may be changed, if desired, via Trick::ExternalApplication::set_startup_command.
|
||||||
|
|
||||||
|
### Launching Custom Applications or Commands
|
||||||
|
|
||||||
|
Having Trick automatically launch a custom application, or execute any command at all really, is a simple matter of instantiating an instance of the base class ExternalApplication and then setting the desired command as described above.
|
||||||
|
```
|
||||||
|
customApplication = trick.ExternalApplication()
|
||||||
|
customApplication.set_startup_command("echo Hello World!")
|
||||||
|
customApplication.set_arguments("")
|
||||||
|
trick.add_external_application(customApplication)
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that ExternalApplication automatically appends the host and port argument unless you set the arguments by calling Trick::ExternalApplication::set_arguments.
|
||||||
|
|
||||||
|
Why would anyone want to have Trick automatically run additional commands? Well, for one thing, it saves you from manually running them each time you run a sim or writing a script to do it. But more importantly, applications managed by Trick are included in binary checkpoints, which means they can be saved and restored with no work on your part!
|
||||||
|
|
||||||
|
### Shared Options
|
||||||
|
|
||||||
|
As each Trick GUI was written by a different developer and few standards were in place, most options vary according to each GUI. The following apply to at least Trick View and Monte Monitor. Application-specific options can be passed from the input file or user model code via Trick::ExternalApplication::set_arguments or Trick::ExternalApplication::add_arguments.
|
||||||
|
|
||||||
|
#### Host
|
||||||
|
|
||||||
|
The host of the Variable Server to which the application will connect at launch can be specified via one of:
|
||||||
|
|
||||||
|
- From the command line, use the --host option.
|
||||||
|
- From the input file or user model code, use Trick::ExternalApplication::set_host
|
||||||
|
|
||||||
|
If no host is specified, it will automatically be set to that of the simulation which is launching this application.
|
||||||
|
|
||||||
|
#### Port
|
||||||
|
|
||||||
|
The port of the Variable Server to which the application will connect at launch can be specified via one of:
|
||||||
|
|
||||||
|
- From the command line, use the --port option.
|
||||||
|
- From the input file or user model code, use Trick::ExternalApplication::set_port
|
||||||
|
|
||||||
|
If no port is specified, it will automatically be set to that of the simulation which is launching this application.
|
||||||
|
|
||||||
|
#### Automatically Reconnect
|
||||||
|
|
||||||
|
The application can be configured to automatically reestablish lost connections via one of:
|
||||||
|
|
||||||
|
- From the command line, use the --autoReconnect option.
|
||||||
|
- From the input file or user model code, use Trick::ExternalApplication::set_auto_reconnect
|
||||||
|
- From the application, use the File->Settings menu.
|
||||||
|
|
||||||
|
The default value is false.
|
||||||
|
|
||||||
|
#### Window Size and Placement
|
||||||
|
|
||||||
|
The window's coordinates and dimensions at launch can be set via one of:
|
||||||
|
- From the command line, use the --x, --y, --width, or --height options.
|
||||||
|
- From the input file or user model code, use Trick::ExternalApplication::set_x, Trick::ExternalApplication::set_y, Trick::ExternalApplication::set_width, or Trick::ExternalApplication::set_height.
|
||||||
|
|
||||||
|
#### Cycle Period
|
||||||
|
|
||||||
|
The period (in seconds) at which the Variable Server sends information to the application can be specified via one of:
|
||||||
|
|
||||||
|
- From the command line, use the --cycle option.
|
||||||
|
- From the input file or user model code, use Trick::ExternalApplication::set_cycle_period.
|
||||||
|
- From the application, use the File->Settings menu.
|
||||||
|
|
||||||
|
The cycle period must be a non-negative number. Specify 0 to recieve updates at the maximum rate. Values below the minimum cycle period will be set to the minimum cycle period.
|
||||||
|
|
||||||
|
#### Minimum Cycle Period
|
||||||
|
|
||||||
|
The minimum period (in seconds) at which the Variable Server can be requested to send information to the application can be specified via one of:
|
||||||
|
|
||||||
|
- From the command line, use the --minCycle option.
|
||||||
|
- From the input file or user model code, use Trick::ExternalApplication::set_minimum_cycle_period.
|
||||||
|
|
||||||
|
The minimum cycle period must be a non-negative number. The recommended and default value is 0.1. Values below this may cause instability in Trick GUIs.
|
||||||
|
|
||||||
|
#### Application Behavior
|
||||||
|
|
||||||
|
The application can take one of several actions when it loses the connection with the simulation:
|
||||||
|
|
||||||
|
- Close
|
||||||
|
Terminate and close.
|
||||||
|
|
||||||
|
- Notify
|
||||||
|
Present a notification dialog describing the failure.
|
||||||
|
|
||||||
|
- Nothing
|
||||||
|
Do nothing.
|
||||||
|
|
||||||
|
This behavior can be specified via one of:
|
||||||
|
|
||||||
|
- From the command line, use the --disconnectBehavior option.
|
||||||
|
- From the input file or user model code, use Trick::ExternalApplication::set_disconnect_behavior.
|
||||||
|
- From the application, use the File->Settings menu.
|
||||||
|
|
||||||
|
[Continue to Runtime Output](../Runtime-Output)
|
@ -0,0 +1,284 @@
|
|||||||
|
Trick View (hereafter referred to as TV) is a graphical user interface that allows users to view and modify Trick-managed variables in a simulation while it is running. It also provides for the launching of integrated strip charts and can save and restore lists of variables and their associated strip charts.
|
||||||
|
|
||||||
|
#### Launching
|
||||||
|
TV can be launched via one of:
|
||||||
|
|
||||||
|
- From the Simulation Control Panel, under the **Actions** menu.
|
||||||
|
|
||||||
|
![Launching Trick View from the Simulation Control Panel](images/Launch.jpg)
|
||||||
|
|
||||||
|
- From the command line:
|
||||||
|
`trick-tv [options]`
|
||||||
|
The TV launch script is located in `$TRICK_HOME/bin`. Pass `--help` for a description of available options.
|
||||||
|
|
||||||
|
For additional launching options, see [Automatically Launching Applications](Runtime-GUIs#automatically-launching-applications).
|
||||||
|
|
||||||
|
#### Automatically Opening Files
|
||||||
|
|
||||||
|
Files that are to be automatically opened when TV launches can be specified via one of:
|
||||||
|
|
||||||
|
- From the command line, use the `--open` option.
|
||||||
|
File paths are relative to the directory from which TV launches.
|
||||||
|
|
||||||
|
- From the input file or user model code, use `Trick::TrickView::set_auto_open_file`.
|
||||||
|
File paths are relative to the directory containing the S_main executable.
|
||||||
|
|
||||||
|
Opening a TV file will overwrite the current cycle period or any argument to `--cycle` with the value from the file, subject to the minimum cycle period.
|
||||||
|
|
||||||
|
#### Automatically Opening and Setting Files
|
||||||
|
|
||||||
|
Files that are to be automatically opened and set when TV launches can be specified via one of:
|
||||||
|
|
||||||
|
- From the command line, use the `--openSet` option.
|
||||||
|
File paths are relative to the directory from which TV launches.
|
||||||
|
|
||||||
|
- From the input file or user model code, use `Trick::TrickView::set_auto_open_and_set_file`.
|
||||||
|
File paths are relative to the directory containing the S_main executable.
|
||||||
|
|
||||||
|
Opening a TV file will overwrite the current cycle period or any argument to `--cycle` with the value from the file, subject to the minimum cycle period.
|
||||||
|
|
||||||
|
#### Automatically Setting Files
|
||||||
|
|
||||||
|
Files that are to be automatically set when TV launches can be specified via one of:
|
||||||
|
|
||||||
|
- From the command line, use the `--set` option.
|
||||||
|
File paths are relative to the directory from which TV launches.
|
||||||
|
|
||||||
|
- From the input file or user model code, use `Trick::TrickView::set_auto_set_file`.
|
||||||
|
File paths are relative to the directory containing the S_main executable.
|
||||||
|
|
||||||
|
#### Strip-Chart-Only Mode
|
||||||
|
|
||||||
|
Once a collection of strip charts is established and saved to a TV file, you may wish to prevent future launches from displaying the main GUI window to allow users to view the strip charts without providing them (potentially dangerous) access to the simulation's internal variables. You can cause Trick View to launch in strip-chart-only mode via one of:
|
||||||
|
|
||||||
|
- From the command line, use the `--stripChartsOnly` option.
|
||||||
|
|
||||||
|
- From the input file or user model code, use `Trick::TrickView::set_strip_charts_only`.
|
||||||
|
|
||||||
|
Note that you must provide a TV file to be automatically opened as described above when launching in strip-chart-only mode.
|
||||||
|
|
||||||
|
#### The Trick View GUI
|
||||||
|
|
||||||
|
The GUI pictured below may have a different look and feel based on the architecture of the machine on which it is running, but the functionality will remain the same.
|
||||||
|
|
||||||
|
![TrickView](images/TrickView.jpg)
|
||||||
|
|
||||||
|
##### File Buttons
|
||||||
|
|
||||||
|
The file buttons provide persistent storage of variable lists. From left to right, they are:
|
||||||
|
|
||||||
|
- **New**
|
||||||
|
Clears the variable table.
|
||||||
|
|
||||||
|
- **Open**
|
||||||
|
Opens a dialog allowing the user to select a TV file. The variable table will be cleared and replaced by the variables from the file. The saved cycle period and any strip charts will be restored.
|
||||||
|
|
||||||
|
- **Open And Set**
|
||||||
|
Opens a dialog allowing the user to select a TV file. The variable table will be cleared and replaced by the variables from the file. Additionally, the variables will be set to their corresponding values in the file. The saved cycle period and any strip charts will be restored.
|
||||||
|
|
||||||
|
- **Set**
|
||||||
|
Opens a dialog allowing the user to select a TV file. The variables listed in the file will be set to their corresponding values in the file. The variable table, cycle period, and any strip charts will be unaffected.
|
||||||
|
|
||||||
|
- **Save**
|
||||||
|
Opens a dialog allowing the user to specify a file name. The variables in the variable table and their associated information, the cycle period, and any strip charts will be written to the file.
|
||||||
|
|
||||||
|
##### Monitor Button
|
||||||
|
|
||||||
|
The monitor button displays the current state of the monitor and allows the user to toggle receiving updates on the variables in the variable table. A blue screen indicates that updates are being received. A black screen indicates they are not.
|
||||||
|
|
||||||
|
##### Variable Buttons
|
||||||
|
|
||||||
|
The variable buttons affect variables in the variable table. From left to right, they are:
|
||||||
|
|
||||||
|
- **Strip Chart**
|
||||||
|
Launches a strip chart that will plot all selected variables on the same graph while the simulation is running.
|
||||||
|
|
||||||
|
- **Delete**
|
||||||
|
Removes the selected variables from the variable table and all strip charts.
|
||||||
|
|
||||||
|
##### Variable Hierarchy Tree
|
||||||
|
|
||||||
|
This panel displays all of the simulation's Trick-managed variables in a hierarchical format. Initially, only the top-level simulation objects are displayed. A variable representing a structure or class containing variables can be expanded or collapsed by double-clicking its name or by single-clicking the expand/collapse node to the left of its name. Double-clicking a variable that does not represent a structure or class will add it to the variable table. Multiple variables can be simultaneously selected via the shift and control (command on Mac) keys. Variables can also be added by selecting them, right-clicking anywhere in the variable hierarchy tree, and selecting **Add Selection** from the pop-up menu. Adding a variable that represents a structure or class will add all of its contained variables (at all lower levels). The top layer of the variable hierarchy tree will be populated when TV has finished parsing the information from the simulation, which takes place in the background. Lower levels are loaded on-demand as the tree is expanded. Although unlikely to occur in practice, it is possible that expanding every node in a large simulation will consume all of the application's available memory, in which case it will become unresponsive.
|
||||||
|
|
||||||
|
##### Search Panel
|
||||||
|
|
||||||
|
The search panel allows the user to search the variable hierarchy tree by partial name or regular expression, with an option for case sensitivity. Resulting listed variables can be added to the variable table in manners similar to those of the variable hierarchy tree. The search panel becomes available for use at the same time as the variable hierarchy tree. Search progress is indicated by a progress bar below the results list. During the initial search, only an indication of activity is given while the application counts the total number of variables. In subsequent searches, a quantitative value of progress is displayed.
|
||||||
|
|
||||||
|
##### Index Specification Window
|
||||||
|
|
||||||
|
When adding variables to the variable table, if any variables are pointers or arrays, the index specification window will be displayed, allowing the user to specify the ranges to add.
|
||||||
|
|
||||||
|
![Specify Indices](images/SpecifyIndices.jpg)
|
||||||
|
|
||||||
|
Each array displays a combo box over its allowable range. Each pointer has a single text box that accepts values in the form `minimum-maximum`. Character pointers and arrays have a check box allowing them to be treated as strings. The position radio buttons specify where in the variable table the variables will be added, relative to the currently selected row.
|
||||||
|
|
||||||
|
##### Variable Table
|
||||||
|
|
||||||
|
The variable table lists all the added variables, displaying their names, values, units, and formats. Columns can be freely rearranged by clicking and dragging their headers. Rows can be sorted by clicking the column header corresponding to the property by which they should be sorted. Rows are sorted first by the most recently clicked column header, then by the header clicked before that, and so forth. Rows can be manually reordered by clicking and dragging them. Note that manual reordering will remove any currently applied sorting. Further display customization is available via the Column Control Menu, which is accessed by clicking the miniature table icon in the upper right-hand corner of the table. Pressing the **Delete** key while the variable table has focus is equivalent to clicking the delete variable button.
|
||||||
|
|
||||||
|
While you cannot actually change a variable's name, you can quickly add another variable of a similar name by double-clicking the name cell of a variable and modifying it. The original variable will remain unchanged, and a variable of the new name will be added.
|
||||||
|
|
||||||
|
Each variable's value is displayed according to its type and format. Booleans are represented by check boxes; enumerated types, by combo boxes; and all other types, by a string. Modifying a variable's value is achieved by clicking the check box, selecting a value from the combo box, or directly entering a new value. Inputs are validated against the variable's type before being submitted to the Variable Server. Note that the displayed value will not change until the Variable Server reflects the change.
|
||||||
|
|
||||||
|
Variable units are displayed via a combo box containing all of the supported units. To change a variable's units, click its units cell and select a new value. Note that the displayed units will not change until the Variable Server reflects the change.
|
||||||
|
|
||||||
|
Variable formats are displayed via a combo box containing all of the supported formats for the variable's type. To change a variable's format, click its format cell and select a new value. The displayed value will be updated immediately.
|
||||||
|
|
||||||
|
Multiple, non-contiguous selections are allowed and may be used to affect mass value, unit, and format changes. When performing a mass edit, the assigned/selected value will only be applied to variables that can accept it.
|
||||||
|
|
||||||
|
###### Invalid References
|
||||||
|
|
||||||
|
Variables that the Variable Server failed to resolve display values of **\<Invalid Reference\>** and are highlighted in red. Such a variable's value and units cannot be changed, but its name can still be modified for the purpose of adding new variables.
|
||||||
|
|
||||||
|
##### Manual Entry Field
|
||||||
|
|
||||||
|
The manual entry field provides the user a means by which to directly add a variable of any name. This is useful if a variable's information is not present in the S_sie.resource file or the file itself is not present, or if the variable is a pointer to the beginning of an array. Multiple elements of an arrayed variable can be added by specifying the range within the brackets, such as:
|
||||||
|
|
||||||
|
`ball.obj.state.output.position[0-1]`
|
||||||
|
|
||||||
|
Note that pointers cannot be dereferenced using the pointer dereference operator (*) in TV. Instead, the user should treat the pointer as a single-element array and append the variable's name with `[0]`.
|
||||||
|
|
||||||
|
##### Purge Button
|
||||||
|
|
||||||
|
The purge button removes all variables from the variable table that have a value of **\<Invalid Reference\>**.
|
||||||
|
|
||||||
|
##### Resolve Button
|
||||||
|
|
||||||
|
The resolve button submits a request to the Variable Server to attempt to resolve all invalid references to legal values, which can be useful if a previously null pointer has become valid.
|
||||||
|
|
||||||
|
##### Connection Status Bar
|
||||||
|
|
||||||
|
The connection panel displays host and port information when TV is connected to a simulation. When disconnected, clicking on the combo box displays a list of available simulations to which to connect. Alternately, the information can be entered directly into the panel in the form of `host:port`.
|
||||||
|
|
||||||
|
##### Clearing Logged Data
|
||||||
|
|
||||||
|
TV records the value of every variable in the variable table each time the Variable Server sends a report. This allows newly launched strip charts to include data going back all the way to the point at which the variable was first added. This can eventually result in a large amount of memory usage. If performance begins to degrade, you can clear the log of all values via the **Action** menu of either TV or any strip chart. Note that this will erase any data currently being displayed on any strip charts.
|
||||||
|
|
||||||
|
##### Settings
|
||||||
|
|
||||||
|
The Settings dialog can be accessed via the **File** menu and allows the user to alter the behavior of TV.
|
||||||
|
See [[Runtime GUIs]] for a detailed description of Application Behavior and Cycle Period options.
|
||||||
|
|
||||||
|
![](images/Settings.png)
|
||||||
|
|
||||||
|
###### Variable Tree Order
|
||||||
|
|
||||||
|
The order in which the variable hierarchy is displayed has three options:
|
||||||
|
|
||||||
|
- **None**
|
||||||
|
Top-level variables are sorted alphabetically A to Z. Lower-level variables are sorted according to their order of declaration within the simulation.
|
||||||
|
|
||||||
|
- **Ascending Alphabetical**
|
||||||
|
Variables are sorted alphabetically A to Z.
|
||||||
|
|
||||||
|
- **Descending Alphabetical**
|
||||||
|
Variables are sorted alphabetically Z to A.
|
||||||
|
|
||||||
|
###### Variable Addition
|
||||||
|
|
||||||
|
The placement of newly added variables within the variable table is specified via the Position combo box. The available options are **Top**, **Before**, **After**, and **Bottom**. The **Before** and **After** options are relative to the currently selected row.
|
||||||
|
|
||||||
|
Character pointers and arrays can be treated as strings by default by checking the **char[] as string** check box. When added as such, arrays will be collapsed into single string entries. Otherwise, they will be displayed element by element.
|
||||||
|
|
||||||
|
###### Font Size
|
||||||
|
|
||||||
|
This setting affects the variable hierarchy tree, search panel, and variable table text size.
|
||||||
|
|
||||||
|
###### Default Units
|
||||||
|
|
||||||
|
Default units for each unit type can be specified via its corresponding combo box, which lists all of its available units. Selecting **xx** results in units as specified in the model code. The **Default All** check box, when selected, is equivalent to selecting **xx** for all unit types.
|
||||||
|
|
||||||
|
###### Default Formats
|
||||||
|
|
||||||
|
Default formats for each variable type can be specified via its corresponding combo box.
|
||||||
|
|
||||||
|
#### The Strip Chart GUI
|
||||||
|
|
||||||
|
Strip charts allow users to plot variables in the variable table in real-time. The GUI pictured below may have a different look and feel based on the architecture of the machine on which it is running, but the functionality will remain the same.
|
||||||
|
|
||||||
|
![stripchart](images/Stripchart.jpg)
|
||||||
|
|
||||||
|
##### Domain Axis Panel
|
||||||
|
|
||||||
|
The domain axis panel allows the user to affect the range of the domain axis.
|
||||||
|
|
||||||
|
- **All**
|
||||||
|
The domain axis will continuously adjust to contain the entirety of all plotted variables' domain values.
|
||||||
|
|
||||||
|
- **Strip**
|
||||||
|
The domain axis will continuously scroll such that the latest sub-set (as set by the adjacent text box) of domain values is contained.
|
||||||
|
|
||||||
|
- **Fixed**
|
||||||
|
The domain axis will not automatically change.
|
||||||
|
|
||||||
|
##### Display Panel
|
||||||
|
|
||||||
|
The display panel allows the user to specify whether or not the chart should display certain features.
|
||||||
|
|
||||||
|
- **Lines**
|
||||||
|
When enabled, lines will be drawn between the data points.
|
||||||
|
|
||||||
|
- **Points**
|
||||||
|
When enabled, the data points themselves will be drawn.
|
||||||
|
|
||||||
|
- **Legend**
|
||||||
|
When enabled, the chart's legend will be shown.
|
||||||
|
|
||||||
|
##### Variables Panel
|
||||||
|
|
||||||
|
The variables panel allows the user to add and remove dependent variables, and to change the independent variable. To add a dependent variable, select it from the adjacent combo box and click the **Add** button. To remove a dependent variable, select it from the adjacent combo box and click the **Remove** button. To change the independent variable, select it from the adjacent combo box.
|
||||||
|
|
||||||
|
##### Right-Click Menu
|
||||||
|
|
||||||
|
Right-clicking the plot area will display a context menu with the following options:
|
||||||
|
|
||||||
|
- **Properties**
|
||||||
|
Opens a dialog allowing the user to customize the plot as described below.
|
||||||
|
|
||||||
|
- **Copy**
|
||||||
|
Copies the plot to the clipboard, allowing the user to paste the content into other applications.
|
||||||
|
|
||||||
|
- **Save As...**
|
||||||
|
Opens a dialog allowing the user to save the plot as a PNG file.
|
||||||
|
|
||||||
|
- **Print...**
|
||||||
|
Opens a dialog allowing the user to print the plot.
|
||||||
|
|
||||||
|
- **Zoom In**
|
||||||
|
Zooms in either or both axes. This can also be achieved by left-click-dragging a box from its top-left to bottom-right
|
||||||
|
corner.
|
||||||
|
|
||||||
|
- **Zoom Out**
|
||||||
|
Zooms out either or both axes. This can also be achieved by left-click-dragging any other way than described above.
|
||||||
|
|
||||||
|
- **Auto Range**
|
||||||
|
Automatically adjusts one or both axes.
|
||||||
|
|
||||||
|
##### Chart Properties Dialog
|
||||||
|
The Chart Properties dialog can be opened by selecting **Properties** from the plot's right-click menu. It allows the user to customize the appearance of the chart. These settings are part of the properties that are saved in TV files.
|
||||||
|
|
||||||
|
![ChartPropertiesTitleTab](images/ChartPropertiesTitleTab.jpg)
|
||||||
|
|
||||||
|
The **Title** tab allows the user to toggle visibility of the title and to set the title's text, font, size, and color.
|
||||||
|
|
||||||
|
![ChartPropertiesPlotTab](images/ChartPropertiesPlotTab.jpg)
|
||||||
|
|
||||||
|
The **Plot** tab allows the user to set the label text, font, size, and color for the domain and range axes. It also provides for toggling the visibility of each axis' tick labels and marks, for setting each axis' label font and size, and for adjusting the range of each axis.
|
||||||
|
|
||||||
|
![ChartPropertiesAppearanceTab](images/ChartPropertiesAppearanceTab.jpg)
|
||||||
|
|
||||||
|
The **Appearance** tab within the **Plot** tab allows the user to set the plot's border's width and color and the plot's background color. It also provides for inverting the axes.
|
||||||
|
|
||||||
|
![ChartPropertiesOtherTab](images/ChartPropertiesOtherTab.jpg)
|
||||||
|
|
||||||
|
The **Other** tab allows the user to set the background color of the area surrounding the plot (outside of the plot's borders) and also provides for toggling of the anti-aliasing feature. Modifying series properties is not currently supported.
|
||||||
|
|
||||||
|
#### TV Files
|
||||||
|
|
||||||
|
TV files allow the user to store the states of the variable table and any existing strip charts to persistent memory. This saves configuration time for commonly used variable lists and strip chart selections.
|
||||||
|
|
||||||
|
TV files are stored as XML, the schema for which can be found [here](https://github.com/nasa/trick/blob/master/trick_source/java/src/trick/tv/resources/trickView.xsd). Trick 15 TV files are not backwards compatible with any previous version of Trick. However, a script exists to convert Trick 13 TV files. See ${TRICK_HOME}/bin/convert_tv_file.
|
||||||
|
|
||||||
|
While it is possible to manually modify TV files, users do so at their own risk. TV only checks that a file is well-formed. No further validation is performed.
|
||||||
|
|
||||||
|
Forward compatibility of TV files with future releases is not guaranteed.
|
After Width: | Height: | Size: 76 KiB |
After Width: | Height: | Size: 79 KiB |
After Width: | Height: | Size: 96 KiB |
After Width: | Height: | Size: 58 KiB |
After Width: | Height: | Size: 59 KiB |
After Width: | Height: | Size: 151 KiB |