Category Color | The job classes in Table SD_1 are categorized as one of the following: |
---|---|
NON-CYCLIC | jobs that run once either at simulation startup or termination |
FRAME-BOUNDARY | jobs that run cyclically before/after the scheduled job loop |
INTEGRATOR | jobs that run first in the scheduled job loop for Trick state integration |
SELF-SCHEDULING | jobs in the scheduled job loop that must schedule themselves when to run |
CYCLIC | jobs in the scheduled job loop that run cyclically according to their specified cycle time |
FREEZE | jobs that are run during the freeze execution mode |
CHECKPOINT | jobs that are run when a checkpoint is dumpded or loaded |
Job Class Name | Description |
---|---|
default_data | Module executes only once at simulation time = zero. + Called before input file is read. |
initialization | Module executes only once at simulation time = zero. + Called after input file is read. |
BEGIN EXECUTION FRAME | |
top_of_frame | Module runs at the beginning of every execution frame, before the scheduled job loop, + even before any child threads are started for the frame. |
BEGIN SCHEDULED JOB LOOP | |
pre_integration | 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. |
BEGIN INTEGRATION LOOP | |
derivative | Equations of motion (EOM) derivative function. |
integration | Equations of motion state integration function. |
END INTEGRATION LOOP | |
post_integration | Runs only once after the integration loop. |
dynamic_event | 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. |
automatic | Module which reschedules its own next call time, and will run before other CYCLIC jobs in the frame. |
environment | Time dependent boundary conditions (mother nature). |
sensor | Simulated interface between dynamics and control simulation components. |
sensor_emitter | Same as sensor, but for the emitter portion of an integrated + multi-component sensor system. |
sensor_reflector | Same as sensor, but for the reflector portion of an + integrated multi-component sensor system. |
sensor_receiver | Same as sensor, but for the receiver portion of an + integrated multi-component sensor system. |
scheduled | Typical flight software and hardware subsystems. |
effector | Simulated interface between control and force generator + simulation components. |
effector_emitter | Same as effector, but for the action portion of an + action-reaction effector system. |
effector_receiver | Same as effector, but for the reaction portion of an + action-reaction effector system. |
logging | Simulation data recording or displaying. |
automatic_last | Module which reschedules its own next call time, and will run after other CYCLIC jobs in the frame. |
END SCHEDULED JOB LOOP | |
end_of_frame | Module runs at the end of every execution frame, after the scheduled job loop completes. |
END EXECUTION FRAME | |
freeze_init | Module executes only once upon entering FREEZE mode. |
BEGIN FREEZE FRAME | |
BEGIN FREEZE LOOP | |
freeze_scheduled | Module executes cyclically during simulation FREEZE mode according to its specified cycle time. |
END FREEZE LOOP | |
freeze | Module runs at end of every freeze frame, after the freeze loop completes. |
END FREEZE FRAME | |
unfreeze | Module executes only once upon leaving FREEZE mode before returning to RUN mode. |
checkpoint | Module executes only once before a checkpoint is dumped. |
post_checkpoint | Module executes only once after a checkpoint is dumped. |
preload_checkpoint | Module executes only once before a checkpoint is loaded. |
restart | Module executes only once after a checkpoint is loaded. |
shutdown | Module executes only once at simulation termination to allow a + graceful shutdown. |
${HOME}/myproject/ + include/ + Foo.hh + Bar.hh + Baz.hh+ +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`: + +
${HOME}/myproject/ + include/ + Foo.hh + Bar.hh + Baz.hh + trickified/ + S_source.hh+ +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: + +
${HOME}/myproject/ + include/ + Foo.hh + Bar.hh + Baz.hh + trickified/ + S_source.hh + trickified.o + build/ + python/+ +`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`. + +
${HOME}/myproject/ + include/ + Foo.hh + Bar.hh + Baz.hh + trickified/ + Makefile + S_source.hh + trickified.o + build/ + python/+ +```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: + +
${HOME}/myproject/ + include/ + Foo.hh + Bar.hh + Baz.hh + trickified/ + Makefile + myproject.mk + S_source.hh + trickified_myproject.o + build/ + python/+ +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