Merge branch 'nasa:master' into development-yca-precision
5
.github/workflows/test_linux.yml
vendored
@ -11,6 +11,10 @@ on:
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
ACTIONS_RUNNER_FORCE_ACTIONS_NODE_VERSION: node16
|
||||
ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
strategy:
|
||||
@ -95,6 +99,7 @@ jobs:
|
||||
- cfg: { arch: rhel, arch_ver: 7 }
|
||||
pkg_mgr: yum
|
||||
conf_pkg: |
|
||||
sed -i -e "s|mirrorlist=|#mirrorlist=|g" -e "s|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g" /etc/yum.repos.d/CentOS-* &&
|
||||
yum -y install epel-release
|
||||
yum -y update
|
||||
yum -y install wget
|
||||
|
23
.github/workflows/test_macos.yml
vendored
@ -13,34 +13,27 @@ on:
|
||||
|
||||
jobs:
|
||||
macOS:
|
||||
runs-on: macos-latest
|
||||
runs-on: macos-13
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@master
|
||||
|
||||
uses: actions/checkout@v3
|
||||
- name: Install gtest
|
||||
run: |
|
||||
brew install googletest
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
# sudo installer -pkg /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.15.pkg -target /
|
||||
brew update
|
||||
brew upgrade || true
|
||||
brew install --cask xquartz
|
||||
brew install udunits openmotif maven
|
||||
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-14.0.6/clang+llvm-14.0.6-x86_64-apple-darwin.tar.xz
|
||||
tar -xvf clang+llvm-14.0.6-x86_64-apple-darwin.tar.xz
|
||||
brew install autoconf automake libtool
|
||||
wget https://github.com/swig/swig/archive/refs/tags/v4.1.1.tar.gz
|
||||
tar -xvzf v4.1.1.tar.gz
|
||||
cd swig-4.1.1
|
||||
./autogen.sh
|
||||
./configure
|
||||
make
|
||||
make install
|
||||
cd ..
|
||||
brew install swig
|
||||
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-15.0.7/clang+llvm-15.0.7-x86_64-apple-darwin21.0.tar.xz
|
||||
tar -xvf clang+llvm-15.0.7-x86_64-apple-darwin21.0.tar.xz
|
||||
- name: Build Trick
|
||||
run: |
|
||||
export MAKEFLAGS=-j4
|
||||
./configure --with-llvm=${GITHUB_WORKSPACE}/clang+llvm-14.0.6-x86_64-apple-darwin
|
||||
./configure --with-llvm=${GITHUB_WORKSPACE}/clang+llvm-15.0.7-x86_64-apple-darwin21.0
|
||||
make
|
||||
- name: Test
|
||||
run: |
|
||||
|
9
.github/workflows/trickops.yml
vendored
@ -1,9 +1,6 @@
|
||||
name: TrickOps
|
||||
# This workflow is triggered on pushes to the repository.
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 0 * * 0'
|
||||
workflow_dispatch:
|
||||
on: [pull_request]
|
||||
|
||||
defaults:
|
||||
run:
|
||||
@ -34,7 +31,7 @@ jobs:
|
||||
source ../.venv/bin/activate
|
||||
export PATH="/tmp/koviz-master/bin:${PATH}"
|
||||
./run_tests.py
|
||||
- uses: actions/upload-artifact@master
|
||||
- uses: actions/upload-artifact@v3.0.0
|
||||
if: ${{ always() }}
|
||||
with:
|
||||
name: doctests
|
||||
@ -66,7 +63,7 @@ jobs:
|
||||
source ../.venv/bin/activate
|
||||
export PATH="/tmp/koviz-master/bin:${PATH}"
|
||||
./run_tests.py
|
||||
- uses: actions/upload-artifact@master
|
||||
- uses: actions/upload-artifact@v3.0.0
|
||||
if: ${{ always() }}
|
||||
with:
|
||||
name: doctests
|
||||
|
@ -1,4 +1,9 @@
|
||||
// `llvm/Support/Host.h` is deprecated in favour of `llvm/TargetParser/Host.h` since clang 17
|
||||
#if LIBCLANG_MAJOR > 16
|
||||
#include "llvm/TargetParser/Host.h"
|
||||
#else
|
||||
#include "llvm/Support/Host.h"
|
||||
#endif
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
|
@ -275,10 +275,13 @@ Add the <b>class_string</b> to the SWIG interface text.
|
||||
1. While there's class content text remaining to be processed,
|
||||
repeatedly search for data members that match : <b>template_name '<'</b> <i>template-params</i> <b>'>' name ;</b>
|
||||
For each match, create a SWIG %template directive to create an instantiation
|
||||
of the specific templated type used by the data member. Add the
|
||||
SWIG %template directive to the templated typedefs string that
|
||||
Otherwise append whatever wasn't matched in process contents to
|
||||
the SWIG interface text.
|
||||
of the specific templated type used by the data member. Due to changes in SWIG 4,
|
||||
template directives must be specified before their respective data members. As such,
|
||||
the template directives are inserted immediately prior to the class definition.
|
||||
SWIG does not resolve namespaces in these directives the same as C++ does
|
||||
(it will only check local scope, not global). To account for this,
|
||||
if the directive specifies a template outside the local namespace, convert_swig will
|
||||
escape the current namespace in the format : } template_directive namespace name {
|
||||
|
||||
## process_typedef_struct
|
||||
|
||||
|
@ -187,7 +187,7 @@ to accomodate the highest Child ID specified in the S_define file. Jobs without
|
||||
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
|
||||
Child Threads have three different scheduling choices. See [Executive Scheduler](https://nasa.github.io/trick/documentation/simulation_capabilities/Executive-Scheduler) -> [Thread Control](https://nasa.github.io/trick/documentation/simulation_capabilities/Executive-Scheduler#thread-control) for child thread scheduling
|
||||
details.
|
||||
|
||||
### Job Tagging
|
||||
|
@ -9,16 +9,16 @@ Trick requires various free third party utilities in order to function. All the
|
||||
|
||||
| Utility | Version | Description | Usage | Notes |
|
||||
|---------------:|:-------:|:-----------------------:|:---------------------------------------------------------:|:------------------------------------------------------|
|
||||
| [gcc] and g++ | 4.8+ | C/C++ Compiler | Compiles Trick and Trick simulations. | |
|
||||
| [clang]/[llvm] | <=14 | C/C++ Compiler | Utilized by the interface code generator. | Trick Versions <= 19.3 should use LLVM <= 9 |
|
||||
| [python] | 2.7+ | Programming Language | Lets the user interact with a simulation. | Trick has been tested up to python 3.11 as of 04/23 |
|
||||
| [gcc] and `g++` | 4.8+ | C/C++ Compiler | Compiles Trick and Trick simulations. | |
|
||||
| [clang]/[llvm] | <=18 | C/C++ Compiler | Utilized by the interface code generator. | Trick Versions <= 19.3 should use LLVM <= 9. Please open an issue if you encounter a problem related to newer versions of LLVM. |
|
||||
| [python] | 2.7+ | Programming Language | Lets the user interact with a simulation. | Trick has been tested up to python 3.12 as of 05/2024. |
|
||||
| [perl] | 5.6+ | Programming Language | Allows executable scripts in the bin directory to run. | |
|
||||
| [java] | 11+ | Programming Language | Necessary for Trick GUIs. | |
|
||||
| [swig] | 3.x-4.x | Language Interfacing | Connects the python input processor with Trick's C code. | 3.0+ is now required for Trick. SWIG 4.x is compatible with Trick, but has some [issues](https://github.com/nasa/trick/issues/1288). Please open an issue if you encounter a problem related to SWIG 4. |
|
||||
| [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. | |
|
||||
| [maven] | x.x | Java package manager | Downloads Java dependencies and builds trick GUIs | |
|
||||
| [maven] | x.x | Java package manager | Downloads Java dependencies and builds Trick GUIs. | |
|
||||
|
||||
[gcc]: https://gcc.gnu.org/
|
||||
[clang]: https://clang.llvm.org/
|
||||
@ -34,10 +34,11 @@ Trick requires various free third party utilities in order to function. All the
|
||||
|
||||
## 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).
|
||||
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. If the version of Clang/LLVM installed by your package manager doesn't work, see [Build Clang and LLVM](#build-clang-and-llvm).
|
||||
|
||||
|
||||
### Java
|
||||
Trick needs the javac compiler included in the Java Development Kit (JDK). Trick will work with either the Oracle JDK or OpenJDK.
|
||||
Trick needs the `javac` compiler included in the Java Development Kit (JDK). Trick will work with either the Oracle JDK or OpenJDK.
|
||||
|
||||
|
||||
**Installing both the Oracle JDK and OpenJDK may lead to problems and confusion.**
|
||||
@ -56,7 +57,10 @@ Trick runs on GNU/Linux and macOS, though any System V/POSIX compatible UNIX wor
|
||||
|[Fedora](#fedora)|
|
||||
|[Ubuntu](#ubuntu)|
|
||||
|[macOS](#macos)|
|
||||
|[Apple Silicon Mac](#apple_silicon_mac)|
|
||||
|[Windows 10 (Linux Subsystem Only)](#windows10)|
|
||||
|[Build Clang and LLVM](#build-clang-and-llvm)|
|
||||
|[Build SWIG](#build-swig)|
|
||||
|[Troubleshooting](#trouble)|
|
||||
|
||||
---
|
||||
@ -68,7 +72,7 @@ Sometimes environment variables affect the Trick build and can cause it to fail.
|
||||
|
||||
|
||||
```
|
||||
JAVA_HOME # Trick and Maven will use JAVA_HOME to build the GUIs instead of javac in PATH if it is set.
|
||||
JAVA_HOME # Trick and Maven will use JAVA_HOME to build the GUIs instead of Javac in PATH if it is set.
|
||||
TRICK_HOME # This variable is optional but may cause a Trick build to fail if it is set to the wrong directory.
|
||||
CFLAGS, CXXFLAGS, LDFLAGS # If these flags are set they may affect flags passed to your compiler and linker
|
||||
```
|
||||
@ -151,6 +155,7 @@ yum install hdf5-devel gsl-devel gtest-devel
|
||||
proceed to [Install Trick](#install) section of the install guide
|
||||
|
||||
---
|
||||
|
||||
<a name="fedora"></a>
|
||||
|
||||
### Fedora
|
||||
@ -168,11 +173,12 @@ Trick makes use of several optional packages if they are present on the system.
|
||||
```bash
|
||||
dnf install hdf5-devel gsl-devel gtest-devel
|
||||
```
|
||||
<a name="ubuntu"></a>
|
||||
|
||||
proceed to [Install Trick](#install) section of the install guide
|
||||
|
||||
---
|
||||
|
||||
<a name="ubuntu"></a>
|
||||
### Ubuntu
|
||||
All packages required for Trick may be installed through apt-get. If your package manager cannot find these packages, try searching for alternatives, or your Ubuntu version may be too old.
|
||||
|
||||
@ -195,10 +201,13 @@ export PYTHON_VERSION=3
|
||||
proceed to [Install Trick](#install) section of the install guide
|
||||
|
||||
---
|
||||
|
||||
<a name="macos"></a>
|
||||
### macOS Monterey, Big Sur, Catalina
|
||||
#### These instructions are for Intel-based macs. For the latest Apple silicon (M1) instructions see this issue: https://github.com/nasa/trick/issues/1283
|
||||
1. Install the latest Xcode. I recommend installing Xcode through the App Store.
|
||||
### macOS Sonoma, Ventura, Monterey, Big Sur, Catalina
|
||||
#### These instructions are for both Intel-based and Apple Silicon Macs. Some are only applicable to Apple Silicon.
|
||||
|
||||
1. Install the latest Xcode. we recommend installing Xcode through the App Store.
|
||||
|
||||
|
||||
2. Download and install Xcode Command Line Tools for macOS. The following command in the terminal should do the job:
|
||||
|
||||
@ -206,42 +215,53 @@ proceed to [Install Trick](#install) section of the install guide
|
||||
xcode-select --install
|
||||
```
|
||||
|
||||
3. Install Homebrew, macOS's unofficial package manager. They typically have a single line that can be executed in your terminal to install brew at their homepage at https://brew.sh/
|
||||
3. Install Homebrew, macOS's unofficial package manager. They typically have a single line that can be executed in your terminal to install brew at their homepage at https://brew.sh/. By default, it is installed into `/usr/local` on Intel-based machines and `/opt/homebrew` on Apple Silicon.
|
||||
|
||||
|
||||
4. Install the following dependencies using brew (note, we do not currently support installing llvm through brew. Trick WILL NOT work with brew's llvm. See step 5).
|
||||
4. Install the following dependencies using brew (See step 5 if `brew install llvm` doesn't work for your Trick build).
|
||||
|
||||
```bash
|
||||
brew install python java xquartz swig maven udunits openmotif
|
||||
brew install python java xquartz swig maven udunits openmotif llvm
|
||||
|
||||
```
|
||||
IMPORTANT: Make sure to follow the instructions for adding java and swig to your `PATH` provided by brew. If you missed them, you can see them again by using `brew info java` and `brew info swig`. Remember, you may need to restart your terminal for these `PATH` changes to take effect. Note that `swig@3` is now deprecated on Mac.
|
||||
IMPORTANT: Make sure to follow the instructions for adding Java and SWIG to your `PATH` provided by brew. If you missed them, you can see them again by using `brew info java` and `brew info swig`. Remember, you may need to restart your terminal for these `PATH` changes to take effect. Note `brew install swig` will install the latest version. If a particular SWIG version is needed instead, see [Build SWIG](#build-swig).
|
||||
|
||||
5. Download and un-compress the latest pre-built clang+llvm from llvm-project github. Go to https://github.com/llvm/llvm-project/releases
|
||||
and download the latest version llvm that matches your Xcode version from the release assets. For example, if your Xcode version is 14 then you will want the latest 14.x.x release of llvm. 13.0.1 is the latest as of the writing of this guide, the link I used is below:
|
||||
https://github.com/llvm/llvm-project/releases/download/llvmorg-13.0.1/clang+llvm-13.0.1-x86_64-apple-darwin.tar.xz
|
||||
Tip: I suggest renaming the untar'd directory to something simple like llvm13 and putting it in your home directory or development environment.
|
||||
|
||||
5. Skip this step if `brew install llvm` works for your Trick build. Otherwise, download and un-compress a pre-built clang+llvm from llvm-project github. Go to https://github.com/llvm/llvm-project/releases and download the available version llvm from the release assets for your platform.
|
||||
```
|
||||
For example, the latest as of the writing of this guide:
|
||||
1. Intel-based: https://github.com/llvm/llvm-project/releases/download/llvmorg-15.0.7/clang+llvm-15.0.7-x86_64-apple-darwin21.0.tar.xz
|
||||
2. Apple Silicon: https://github.com/llvm/llvm-project/releases/download/llvmorg-17.0.6/clang+llvm-17.0.6-arm64-apple-darwin22.0.tar.xz
|
||||
```
|
||||
Tip: We suggest renaming the untar'd directory to something simple like llvm15 and putting it in your home directory or development environment. If a pre-built clang+llvm for your platform is not available, see [Build Clang and LLVM](#build-clang-and-llvm).
|
||||
|
||||
6. Read the following macOS optional steps/caveats and then go to the Install Trick section of this document.
|
||||
|
||||
IMPORTANT: Your mac might complain during configuration or build that llvm is downloaded from the internet and can not be trusted. You may need to find a safe solution for this on your own. DO THIS AT YOUR OWN RISK: What worked for us was enabling Settings->Security & Privacy->Privacy->Developer Tools->Terminal.
|
||||
|
||||
IMPORTANT: when doing the configure step in the install trick section, you need to point trick to llvm. It is also possible that the current iteration of our configure script will not be able to find the udunits package, so you may need to point trick to udunits as well (I believe this is only an issue on M1 macs).
|
||||
IMPORTANT: when doing the configure step in the [Install Trick](#install) section, you need to point Trick to `llvm`. It is also possible that the current iteration of our configure script will not be able to find the udunits package, so you may need to point Trick to udunits as well (This is only an issue on M1 macs).
|
||||
You can find the path of udunits by executing the following command:
|
||||
|
||||
```
|
||||
```bash
|
||||
brew info udunits
|
||||
```
|
||||
Then enter the path to llvm (and udunits) when you execute the configure command in place of the placeholders:
|
||||
```
|
||||
./configure --with-llvm=<enter path to llvm> --with-udunits=<path to udunits> <other configure flags (if any)>
|
||||
```bash
|
||||
./configure --with-llvm=<path to llvm> --with-udunits=<path to udunits> <other configure flags (if any)>
|
||||
```
|
||||
e.g.
|
||||
```
|
||||
./configure --with-llvm=/Users/trickguy/llvm13 --with-udunits=/usr/local/Cellar/udunits/2.2.28
|
||||
```bash
|
||||
# For Apple Silicon Macs, you may need to configure as following if Trick configure can't find packages:
|
||||
./configure --with-llvm=/opt/homebrew/opt/llvm --with-udunits=/opt/homebrew --with-hdf5==/opt/homebrew
|
||||
```
|
||||
|
||||
OPTIONAL: Trick uses google test (gtest) version 1.8 for unit testing. To install gtest:
|
||||
|
||||
OPTIONAL: To install gtest for Trick unit testing:
|
||||
|
||||
`brew install googletest`
|
||||
|
||||
For your reference, a particular googletest release can be installed as following:
|
||||
|
||||
```
|
||||
brew install cmake wget
|
||||
wget https://github.com/google/googletest/archive/release-1.8.0.tar.gz
|
||||
@ -256,6 +276,48 @@ proceed to [Install Trick](#install) section of the install guide
|
||||
|
||||
---
|
||||
|
||||
<a name="apple_silicon_mac"></a>
|
||||
### Apple Silicon Mac
|
||||
### The following is obtained from user notes for fresh Trick installation on macOS Sonoma for your reference. Thanks to Zack Crues!
|
||||
|
||||
```bash
|
||||
1. Install Xcode
|
||||
a. Install the Xcode development tools from the Apple App Store.
|
||||
b. Install command line tools. (xcode-select --install)
|
||||
|
||||
2. Install Homebrew
|
||||
a. Install the Homebrew package manager (https://brew.sh)
|
||||
b. brew install swig maven udunits openmotif llvm
|
||||
c. brew install cmake
|
||||
d. Optional: brew install gsl hdf5 googletest
|
||||
|
||||
3. Install XQuartz.
|
||||
a. Option 1: brew install xquartz
|
||||
b. Option 2: Get XQuartz from www.quartz.org
|
||||
|
||||
4. Install Java from Self Service.
|
||||
a. Option 1: brew install java
|
||||
b. Option 2: Get Java from the NASA Self Service app.
|
||||
|
||||
5. Setup environment
|
||||
|
||||
setenv PYTHON_VERSION 3
|
||||
setenv TRICK_CXXFLAGS "-g -I/opt/homebrew/include -L/opt/homebrew/lib -Wno-unused-command-line-argument"
|
||||
setenv TRICK_CFLAGS "-g -I/opt/homebrew/include -L/opt/homebrew/lib -Wno-unused-command-line-argument"
|
||||
setenv TRICK_LDFLAGS "-L/opt/homebrew/lib"
|
||||
setenv TRICK_EXCLUDE "/opt/homebrew"
|
||||
|
||||
6. Build Trick
|
||||
a. Follow the direction in the Trick installation documentation for Mac.
|
||||
b. I add in support for GSL, HDF5, and Google Test.
|
||||
|
||||
./configure --with-llvm=/opt/homebrew/opt/llvm --with-udunits=/opt/homebrew/opt/udunits --with-gsl=/opt/homebrew --with-hdf5=/opt/homebrew --with-gtest=/opt/homebrew PYTHON_VERSION=3
|
||||
```
|
||||
|
||||
proceed to [Install Trick](#install) section of the install guide
|
||||
|
||||
---
|
||||
|
||||
<a name="windows10"></a>
|
||||
### Windows 10 (Linux Subsystem Only)
|
||||
|
||||
@ -281,6 +343,90 @@ sudo <edit_cmd> /etc/hosts
|
||||
|
||||
proceed to [Install Trick](#install) section of the install guide
|
||||
|
||||
---
|
||||
|
||||
|
||||
<a name="manual_build_clang_llvm"></a>
|
||||
### Build Clang and LLVM
|
||||
#### If you come to this section because Clang+LLVM installed by the package manager on your machine does not work for your environment, you need to manually build Clang and LLVM. Following instructions show steps on building a particular release of Clang and LLVM . `cmake` is required. CMake may support multiple native build systmes on certain platforms. A generator is responsible for generating a particular build system. Below lists two approaches for your reference. The 1st approach uses `Unix Makefiles` (one of Makefile generators) and the 2nd one uses `Ninja` (one of Ninja generators). For Mac Apple Silicon user, may want to go to the 2nd approach direcly.
|
||||
|
||||
#### Note: Remember to add `--with-llvm=<clang+llvm-17_path>` for Trick configure if using the Clang and LLVM built in this section.
|
||||
|
||||
1. Using `Unix Makefiles` generator
|
||||
|
||||
```bash
|
||||
# Go to a folder to checkout LLVM project
|
||||
a. cd <a_folder>
|
||||
|
||||
# Clone a particular project version
|
||||
b. git clone -b llvmorg-17.0.6 https://github.com/llvm/llvm-project.git
|
||||
|
||||
c. cd llvm-project
|
||||
|
||||
e. mkdir build
|
||||
|
||||
f. cmake -S llvm -B build -G "Unix Makefiles" -DLLVM_ENABLE_PROJECTS="clang" -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi" -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=<clang+llvm-17_path>
|
||||
|
||||
# Be patient, this step takes a bit time ...
|
||||
g. cmake --build build
|
||||
|
||||
h. cd build
|
||||
|
||||
# Install
|
||||
i. cmake -DCMAKE_INSTALL_PREFIX=<clang+llvm-17_path> -P cmake_install.cmake
|
||||
|
||||
|
||||
```
|
||||
|
||||
2. Using `Ninja` generator
|
||||
|
||||
```bash
|
||||
a. brew install ninja
|
||||
|
||||
b. cd <a_folder>
|
||||
|
||||
c. git clone -b llvmorg-17.0.6 https://github.com/llvm/llvm-project.git
|
||||
|
||||
d. cd llvm-project
|
||||
|
||||
e. mkdir build
|
||||
|
||||
# Apple Silicon
|
||||
g cmake -S llvm -B build -G Ninja -DLLVM_ENABLE_PROJECTS=clang -DCMAKE_BUILD_TYPE=Release -DLLVM_TARGETS_TO_BUILD=AArch64 -DCMAKE_INSTALL_PREFIX=<clang+llvm-17-arm64_path>
|
||||
|
||||
# Intel-based
|
||||
g. cmake -S llvm -B build -G Ninja -DLLVM_ENABLE_PROJECTS=clang -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi" -DCMAKE_BUILD_TYPE=Release -DLLVM_TARGETS_TO_BUILD=X86 -DCMAKE_INSTALL_PREFIX=<clang+llvm-17-x86_path>
|
||||
|
||||
# Build and install
|
||||
h. cmake --build build --target install
|
||||
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
<a name="build_swig"></a>
|
||||
### Build SWIG
|
||||
|
||||
```bash
|
||||
a. Download the desired source code version from https://github.com/swig/swig/tags
|
||||
|
||||
b. Go to the folder with uncompressed files
|
||||
|
||||
c. ./autogen.sh
|
||||
|
||||
# Default to /usr/local, swig command is in /usr/local/bin and swig installation is in /usr/local/share
|
||||
# Use --prefix for ./configure to install to a different location
|
||||
d. ./configure
|
||||
|
||||
e. make
|
||||
|
||||
# Uninstall previous installation using "make uninstall"
|
||||
f. make install
|
||||
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
<a name="install"></a>
|
||||
# Install Trick
|
||||
|
||||
@ -342,17 +488,17 @@ make install
|
||||
|
||||
### Offline Mode
|
||||
#### (No maven) (19.1 and up)
|
||||
Because java is virtual machine code and is portable, you can copy the java applications that have already been built on a different machine into your trick installation on the target machine. If trick is configured in this way, it no longer relies on maven or calls it (in the target environment only). If you know someone trustworthy who has built Trick already, they can provide the built java code to you (you can skip step 1 below).
|
||||
Because Java is virtual machine code and is portable, you can copy the Java applications that have already been built on a different machine into your Trick installation on the target machine. If Trick is configured in this way, it no longer relies on maven or calls it (in the target environment only). If you know someone trustworthy who has built Trick already, they can provide the built Java code to you (you can skip step 1 below).
|
||||
|
||||
Trick jars are all-in-one and contain everything they need to run. You will still need maven on the machine where you build the trick java jars.
|
||||
Trick jars are all-in-one and contain everything they need to run. You will still need maven on the machine where you build the Trick Java jars.
|
||||
|
||||
1. Pre-build your java code on a machine with trick dependencies, including maven and internet access.
|
||||
1. Pre-build your Java code on a machine with Trick dependencies, including maven and internet access.
|
||||
```
|
||||
# On source machine with trick dependencies, internet, and maven
|
||||
# On source machine with Trick dependencies, internet, and maven
|
||||
cd prebuiltTrick && ./configure && make java
|
||||
```
|
||||
|
||||
2. Copy the java jars to the environment that you need to build trick on. They are nested in the libexec directory as specified below. The directory should be at the top level of trick, called trick/trick-offline.
|
||||
2. Copy the Java jars to the environment that you need to build Trick on. They are nested in the libexec directory as specified below. The directory should be at the top level of Trick, called trick/trick-offline.
|
||||
|
||||
```
|
||||
mkdir trick/trick-offline
|
||||
|
@ -16,14 +16,27 @@ S_main_${TRICK_HOST_CPU}.exe [trick_version] [sie]
|
||||
[-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 '--read-only-sim' flag can be used to redirect all files written at simulation runtime into the output directory.
|
||||
- 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 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.
|
||||
- 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.
|
||||
- Data Products specification DP_xxx.xml files if generated such as for frame logging are saved in `DP_Product` directory.
|
||||
- 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.
|
||||
- Two subdirectories are automatically created in the designated `<output_file_path>`:
|
||||
- `DP_Product`
|
||||
- Data Products sepcification DP_xxx.xml files are saved in this folder.
|
||||
- `RUN_<name>`
|
||||
- All simulation output files, excluding DP_xxx.xml files, are saved in this folder. Additionally, the S_sie.resource file is copied to this directory.
|
||||
- The `--read-only-sim` flag can be used to redirect all files written at simulation runtime into the output directory.
|
||||
- The `--read-only-sim` flag requires either the `-O` or `-OO` option to be used.
|
||||
- When the `-O <output_file_path>` option is used and `trick.trick.sie_append_runtime_objs()` is called from the input file, the S_sie.resource file with appended runtime objects is saved in `<output_file_path>`.
|
||||
- When the `-OO <output_file_path>` option is used and `trick.trick.sie_append_runtime_objs()` is called from the input file, the S_sie.resource file with runtime objects appended is saved in `<output_file_path>/RUN_<name>`.
|
||||
- If `trick.trick.sie_append_runtime_objs()` is called from the input file, the S_sie.resource file is to be appended with runtime objects.
|
||||
- When neither the `-O` nor `-OO` option is used, the S_sie.resource file with runtime objects appended is saved in the current directory from which the simulation is executed.
|
||||
- When the `-O <output_file_path>` option is used without the `--read-only-sim` flag, the S_sie.resource file with runtime objects appended is saved in the current directory from which the simulation is executed.
|
||||
- When the `-OO <output_file_path>` option is used without the `--read-only-sim` flag, the S_sie.resource file with runtime objects appended is saved in `<output_file_path>/RUN_<name>`.
|
||||
- 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.
|
||||
|
||||
|
@ -102,9 +102,10 @@ By default these are all enabled. If you disable `file` at startup, the `send_hs
|
||||
That means you cannot then later try to enable and subscribe to file/device.
|
||||
|
||||
```cpp
|
||||
int message_cout_set_enabled(int yes_no) ;
|
||||
int message_file_set_enabled(int yes_no) ;
|
||||
int message_device_set_enabled(int yes_no) ;
|
||||
int set_enabled(bool yes_no)
|
||||
trick_message.mcout.set_enabled(bool yes_no);
|
||||
trick_message.mdevice.set_enabled(bool yes_no);
|
||||
trick_message.mfile.set_enabled(bool yes_no);
|
||||
```
|
||||
|
||||
To enable / disable showing colored messages in Trick's default subscribers:
|
||||
@ -112,9 +113,10 @@ To enable / disable showing colored messages in Trick's default subscribers:
|
||||
By default color is enabled for `cout` and `device`. Color is achieved by adding ANSI escape codes around the message.
|
||||
|
||||
```cpp
|
||||
int message_cout_set_color(int yes_no) ;
|
||||
int message_file_set_color(int yes_no) ;
|
||||
int message_device_set_color(int yes_no) ;
|
||||
int set_color(bool yes_no)
|
||||
trick_message.mcout.set_color(bool yes_no);
|
||||
trick_message.mdevice.set_color(bool yes_no);
|
||||
trick_message.mfile.set_color(bool yes_no);
|
||||
```
|
||||
|
||||
[Continue to Command Line Arguments](Command-Line-Arguments)
|
||||
|
@ -12,17 +12,17 @@ adding a web server to your simulation simply requires including the CivetServer
|
||||
|
||||
## Configuration of the Web Server
|
||||
|
||||
The following (input.py) parameters are available to configure your web server:
|
||||
The following (`input.py`) parameters are available to configure your web server:
|
||||
|
||||
|Parameter Name | Default Value | Description |
|
||||
|---------------------------|---------------------------|-----------------------------------------------------------------|
|
||||
|web.server.enable | False |Must be explicitly enabled |
|
||||
|web.server.port | "8888" |Web servers “listen” port |
|
||||
|web.server.document_root | "www" |Web servers document root |
|
||||
|web.server.debug | False |Print Client/Server Communication. |
|
||||
|web.server.ssl_enable | False |Encrypt traffic. Uses https instead of http. |
|
||||
|web.server.path_to_ssl_cert|"~/.ssl/server.pem" |Path to your certificate. This is only used if ssl_enable = True|
|
||||
|web.server.error_log_file | "civet_server_error.log" |CivetWeb error log file. |
|
||||
|Parameter Name | Default Value | Description |
|
||||
|---------------------------|---------------------------|-------------------------------------------------------------------|
|
||||
|web.server.enable | `False` |Must be explicitly enabled |
|
||||
|web.server.port | `8888` |Web servers “listen” port |
|
||||
|web.server.document_root | `"www"` |Web servers document root |
|
||||
|web.server.debug | `False` |Print Client/Server Communication. |
|
||||
|web.server.ssl_enable | `False` |Encrypt traffic. Uses https instead of http. |
|
||||
|web.server.path_to_ssl_cert|`"~/.ssl/server.pem"` |Path to your certificate. This is only used if `ssl_enable = True`|
|
||||
|web.server.error_log_file |`"civet_server_error.log"` |CivetWeb error log file. |
|
||||
|
||||
For your web server to be active, you must at least specify the following :
|
||||
|
||||
@ -31,10 +31,10 @@ web.server.enable = True
|
||||
|
||||
```
|
||||
|
||||
To have your web server listen on port 8890, rather than 8888, you would specify:
|
||||
To have your web server listen on port `8890`, rather than `8888`, you would specify:
|
||||
|
||||
```python
|
||||
web.server.port = "8890"
|
||||
web.server.port = 8890
|
||||
```
|
||||
|
||||
To serve files from a directory called ```my_document_root```, rather than ```www```:
|
||||
@ -50,11 +50,11 @@ web.server.debug = True
|
||||
```
|
||||
|
||||
## When the Web Server Starts
|
||||
The web server, if enabled, will start during sim initialization. When it does, it will look for the specified document root directory. By default that’s “www”. If root directory doesn’t exist, one will be created with a simple index.html file , a style sheet, and a couple of directories.
|
||||
The web server, if enabled, will start during sim initialization. When it does, it will look for the specified document root directory. By default that’s `“www”`. If root directory doesn’t exist, one will be created with a simple `index.html` file , a style sheet, and a couple of directories.
|
||||
|
||||
|
||||
## Connecting to Your Web Server
|
||||
Assuming that you accepted the default port, connect to ```http://localhost:8888/``` (```https://localhost:8888/``` if ssl_enable=True) from your web browser. This will display the index.html file in your root directory.
|
||||
Assuming that you accepted the default port, connect to ```http://localhost:8888/``` (```https://localhost:8888/``` if `ssl_enable=True`) from your web browser. This will display the `index.html` file in your root directory.
|
||||
|
||||
|
||||
## The Default Document Root Directory
|
||||
@ -69,7 +69,7 @@ www/
|
||||
images/
|
||||
```
|
||||
|
||||
**index.html** is the file that’s displayed when you connect to http://localhost:8888/.
|
||||
**index.html** is the file that’s displayed when you connect to `http://localhost:8888/`.
|
||||
|
||||
**style.css** is a CSS style-sheet that’s included by index.html to give it some pizzazz.
|
||||
|
||||
|
@ -11,3 +11,4 @@
|
||||
01. [How to Containerize Trick with Docker](How-To-Containerize-Trick-with-Docker)
|
||||
01. [How to Setup a Virtual Python Environment](How-To-Python-Virtual-Environment)
|
||||
01. [Checkpointing Best Practices](Checkpointing-Best-Practices)
|
||||
01. [Realtime Best Practices](Realtime-Best-Practices)
|
||||
|
539
docs/howto_guides/Realtime-Best-Practices.md
Normal file
@ -0,0 +1,539 @@
|
||||
# Trick Realtime Best Practices
|
||||
|
||||
**Contents**
|
||||
|
||||
* [Purpose](#Purpose)<br>
|
||||
* [Prerequisite Knowledge](#prerequisite-knowledge)<br>
|
||||
* [Do's, Don'ts and Wisdom](#guidelines)<br>
|
||||
|
||||
<a id= introduction></a>
|
||||
|
||||
---
|
||||
## Purpose
|
||||
The intention of this document is to compile and share practical knowledge, based on the experience of people in the Trick simulation community regarding the development of realtime computer simulations.
|
||||
|
||||
<a id=prerequisite-knowledge></a>
|
||||
## Prerequisite Knowledge
|
||||
(Assuming you've completed the [Trick Tutorial](https://nasa.github.io/trick/tutorial/Tutorial))
|
||||
|
||||
---
|
||||
|
||||
<a id=simulation-time-vs-realtime></a>
|
||||
### Simulation Time vs Realtime
|
||||
|
||||
Real world dynamic systems change in realtime (the time that you and I experience). A simulated dynamic system changes in simulation time. Simulation time begins at t=0, and runs until we stop it. Simulation time can elapse faster or slower than realtime.
|
||||
|
||||
If we want to interact with a simulation as if it were real, we need to synchronize simulation time to realtime. This requires that a simulation is capable of running at least as fast as realtime. If it is incapable, then it can not be made to run in realtime.
|
||||
|
||||
---
|
||||
|
||||
<a id=realtime-clock></a>
|
||||
### Realtime Clock
|
||||
* By default, the Trick realtime scheduler will synchronize to the system clock:
|
||||
* ```clock_gettime(CLOCK_REALTIME,…)``` [Linux]
|
||||
* ```gettimeofday()``` [Mac OS]
|
||||
|
||||
* The Trick realtime scheduler can also be configured to synchronize to a [custom realtime clock](https://nasa.github.io/trick/documentation/simulation_capabilities/Realtime-Clock).
|
||||
|
||||
---
|
||||
|
||||
<a id=enabling-realtime></a>
|
||||
### Enabling Realtime
|
||||
|
||||
Trick tries to consistently and repetitively execute its scheduled math models to completion within some predetermined realtime interval for an indefinite period. This realtime interval is called the **realtime software frame**.
|
||||
|
||||
To enable realtime synchronization, call ```trick.real_time_enable()``` in the input file.
|
||||
|
||||
[Ref: Realtime](https://nasa.github.io/trick/documentation/simulation_capabilities/Realtime)
|
||||
|
||||
---
|
||||
|
||||
<a id=realtime-software-frame></a>
|
||||
### Realtime Software Frame
|
||||
The realtime software frame determines how often Trick will synchronize simulation time to the realtime clock. Simulation time will run as fast as it can in the intervals between realtime synchronizations.
|
||||
|
||||
To set the realtime software frame, call the following in the input file:
|
||||
|
||||
```python
|
||||
trick.exec_set_software_frame(double time)
|
||||
```
|
||||
[Ref: Software Frame](https://nasa.github.io/trick/documentation/simulation_capabilities/Executive-Scheduler#software-frame)
|
||||
|
||||
---
|
||||
|
||||
<a id=under-runs-and-over-runs></a>
|
||||
### Under-runs and Over-runs
|
||||
|
||||
An **under-run** occurs when the Trick executive finishes running all of its scheduled jobs, between synchronizations to the realtime clock. This is a **good thing**. In this case the executive will enter a spin loop, waiting for the next realtime frame to start.
|
||||
|
||||
<a id=figure-realtime-under-run></a>
|
||||
![Realtime Under Run](images/RealtimeUnderRun.png)
|
||||
|
||||
An **over-run** occurs if the executive does not finish running all of its scheduled jobs. This is a **bad-thing**. In this case, the executive will immediately start the next frame in an attempt to catch up.
|
||||
|
||||
<a id=figure-realtime-over-run></a>
|
||||
![Realtime Over Run](images/RealtimeOverRun.png)
|
||||
|
||||
---
|
||||
|
||||
<a id=itimers></a>
|
||||
### Itimers ( Being Nice to Other Processes On Your System )
|
||||
|
||||
During real time under runs you may want to release the processor for other tasks to use instead of spinning waiting for the clock. Trick provides a realtime sleep timer based on itimers. You might think of it as a “snooze button”.
|
||||
|
||||
To enable itimers call ```trick.itimer_enable()``` from the input file.
|
||||
|
||||
With itimer_enabled, the simulation will sleep() after completing the jobs scheduled for the current frame. The itimer will then wake the sim 2ms before the realtime frame is to expire. The executive will spin for the final 2ms. The 2ms spin is there because an itimer interval is not guaranteed to be perfectly precise.
|
||||
|
||||
<a id=figure-Realtime-with_itimer></a>
|
||||
![Realtime with itimer](images/RealtimeWithItimer.png)
|
||||
|
||||
[Ref: Itimer](https://nasa.github.io/trick/documentation/simulation_capabilities/Realtime-Timer)
|
||||
|
||||
---
|
||||
|
||||
<a id=frame-logging></a>
|
||||
### Frame-Logging ( Critical For Improving Sim Performance )
|
||||
|
||||
The failure of a simulation to meet its scheduling requirements can have many causes. To aid in solving these problems, Trick can gather simulation performance data, called **frame-logging** by calling:
|
||||
|
||||
```trick.frame_log_on()```
|
||||
|
||||
in your sim's input file.
|
||||
|
||||
Note that frame logging will add some overhead to a simulation as each job is timed and recorded.
|
||||
|
||||
[Ref: Frame-Logging](https://nasa.github.io/trick/documentation/simulation_capabilities/Frame-Logging)
|
||||
|
||||
<a id=frame-log-files></a>
|
||||
#### Frame Log Files
|
||||
Frame logging records the following data files in your sim’s RUN_ directory:
|
||||
|
||||
* [```log_frame.trk```](#log-frame-trk)<br>
|
||||
* [```log_frame_trickjobs.trk```](#log-frame-trickjobs-trk)
|
||||
* [```log_frame_userjobs_main.trk```](#log-frame-userjobs-main-trk)
|
||||
* [```log_timeline.csv```](#log-timeline-csv)
|
||||
* [```log_timeline_init.csv```](#log-timeline-csv)
|
||||
|
||||
Note that **main** in this file name refers to the main thread.
|
||||
If child threads (for example: C1, C2, ...) have been specified in the sim then frame log files for those threads will also be created ( that is:```log_trick_frame_userjobs_C1.trk```, ```log_trick_frame_userjobs_C2.trk```, ```...```).
|
||||
|
||||
---
|
||||
|
||||
<a id=log-frame-trk></a>
|
||||
#### ```log_frame.trk```
|
||||
* Number of fields per record : 5
|
||||
|
||||
|# | Name | Type | Units | Description |
|
||||
|--:|:---- |:-----|:-----:|-------------|
|
||||
| 1| ```sys.exec.out.time``` | double | seconds |Simulation Time |
|
||||
| 2| ```trick_real_time.rt_sync.frame_time``` | double | seconds | This badly named parameter expresses the amount of time that the scheduled jobs in this frame took to execute. See: [figure](#figure-realtime-under-run)|
|
||||
|3| ```trick_real_time.rt_sync.frame_overrun ``` | double | seconds | The magnitude of the current overrun. See: [figure](#figure-realtime-over-run) |
|
||||
|4| ```JOB_data_record_group_frame_userjobs.data_record...``` | double | s | How long the write job for the user Jobs data recording group took. |
|
||||
|5| ```JOB_data_record_group.trickjobs...``` | double | seconds | How long did the write job for the Trick Jobs data recording group take. |
|
||||
|
||||
---
|
||||
|
||||
<a id=log-frame-userjobs-main-trk></a>
|
||||
#### ```log_frame_userjobs_main.trk```
|
||||
* Number of fields per record : 1 + *#user-jobs*
|
||||
|
||||
|# | Name | Type | Units | Description |
|
||||
|--:|:---- |:-----|:-----:|-------------|
|
||||
| 1| ```sys.exec.out.time``` | double | seconds |Simulation Time |
|
||||
| n| *user-job-name* | double | seconds |How long the user-job took to execute. |
|
||||
|
||||
---
|
||||
|
||||
<a id=log-frame-trickjobs-trk></a>
|
||||
#### ```log_frame_trickjobs.trk```
|
||||
* Number of fields per record : 1 + *#trick-jobs*
|
||||
|
||||
|# | Name | Type | Units | Description |
|
||||
|--:|:---- |:-----|:-----:|-------------|
|
||||
| 1| ```sys.exec.out.time``` | double | seconds |Simulation Time |
|
||||
| n| *trick-job-name* | double | seconds |How long the trick-job took to execute. |
|
||||
|
||||
<a id=log-timeline-csv></a>
|
||||
#### ```log_timeline.csv``` & ```log_timeline_init.csv```
|
||||
These files contain start and stop times for each of the jobs executed in a trick sim.
|
||||
```log_timeline.csv``` contains times for jobs run during run-time. ```log_timeline_init.csv``` contains times for jobs run at initialization time.
|
||||
|
||||
Frankly this format is **weird**, but it contains useful information.
|
||||
It's weird because of its redundancy, and that each job timing "record" consists of four CSV lines.
|
||||
|
||||
Both files have the same format. They contain three columns, of ```float``` formatted numbers representing (in order, left to right):
|
||||
|
||||
1. time-stamp
|
||||
2. trick job ID
|
||||
3. user job ID
|
||||
|
||||
Each record consists of four rows in the CSV file representing the start and stop times of a job.
|
||||
|
||||
|row#|time-stamp|trick-job-id|user-job-id|
|
||||
|---:|---:|---:|---:|
|
||||
|4xRecord#+0|start-job-time|0|0|
|
||||
|4xRecord#+1|start-job-time|trick job id|user-job-id|
|
||||
|4xRecord#+2|stop-job-time|trick-job-id|user-job-id|
|
||||
|4xRecord#+3|stop-job-time|0|0|
|
||||
|
||||
If **trick** job ID is non-zero, then the **user** job ID will be zero, and vice versa.
|
||||
Within any four line record the job-ID will be recorded twice.
|
||||
|
||||
##### Example
|
||||
|
||||
The following is one four-line record from a ```log_timeline.csv``` file.
|
||||
|
||||
```
|
||||
...
|
||||
0.000026,0,0
|
||||
0.000026,16.010000,0
|
||||
0.000027,16.010000,0
|
||||
0.000027,0,0
|
||||
...
|
||||
```
|
||||
The first line of the record indicates that **some** job started at time=0.000026 seconds. It's not until the second line of the record that you find that the start time (0.000026) refers to the job with ID=16.01. The third line in the record indicates that the job with ID=16.01 stopped at 0.000027. The fourth line redundantly conveys that **some** job stopped at 0.000027. (I told you it was weird.)
|
||||
|
||||
To match the job ID's with the job names, see the ```S_job_execution``` file.
|
||||
|
||||
### Analyzing the Frame Log Files
|
||||
There are several ways we can examine/ analyze the data logged in these files.
|
||||
|
||||
#### [trick-DP](https://nasa.github.io/trick/tutorial/ATutPlottingData)
|
||||
When you build your Trick sim, the following data-product files are created for you to plot your sim's frame log data.
|
||||
|
||||
* ```DP_rt_frame.xml```
|
||||
* ```DP_rt_timeline.xml```
|
||||
* ```DP_rt_timeline_init.xml```
|
||||
* ```DP_rt_trickjobs.xml```
|
||||
* ```DP_rt_userjobs.xml```
|
||||
|
||||
#### [koviz](https://github.com/nasa/koviz)
|
||||
**koviz** Is an open-source project for plotting Trick data-recording files. It's particularly good for Monte Carlo data plotting. It also has a nifty feature for processing frame-log files. Not only can it plot them, but ```% koviz -rt RUN_directory``` will generate a report that will list the top 10 spikes in your frame log.
|
||||
|
||||
**TIP:**`` ```trick_real_time.rt_sync.rt_monitor``` (the Trick realtime monitor) should show the max job time. If not, you might have problems to solve.
|
||||
|
||||
---
|
||||
|
||||
### Other Useful Files Generated by a Trick Sim Run
|
||||
|
||||
| Name | Desscription|
|
||||
|:-----|:------------|
|
||||
|```RUN_*/S_job_execution```| Lists the simulation jobs by Name, Job ID, Trick Thread ID (PID) Job class, Phase, Start time, Stop time, Cycle, and whether the job is enabled.|
|
||||
|```RUN_*/S_run_summary ```|(Should be called build_summary) - Documents the name and path of the executable and the input file, the build time of the simulation executable, and the Trick version. It also contains the list of environment variables used when the simulation was built and the model versions.|
|
||||
|```RUN_*/send_hs ```|the end of this file contains run statistics that may be useful.|
|
||||
|
||||
---
|
||||
|
||||
### Trick Executive Scheduler
|
||||
|
||||
The
|
||||
[Executive Scheduler](https://nasa.github.io/trick/documentation/simulation_capabilities/Executive-Scheduler) determines how, when, and where (which CPU) the jobs in your Trick sim are executed.
|
||||
|
||||
|
||||
* [Job Control](https://nasa.github.io/trick/documentation/simulation_capabilities/Executive-Scheduler#job-control) - describes the Trick job control interface.
|
||||
* [Thread Control](https://nasa.github.io/trick/documentation/simulation_capabilities/Executive-Scheduler#thread-control) - describes the attributes and behaviors of different Trick thread types.
|
||||
|
||||
Thread control will in some cases require that you isolate CPUs at boot-time. This is usualy done with the **isolcpus** boot parameter:
|
||||
|
||||
```isolcpus= cpu_number[, cpu_number,...]```
|
||||
|
||||
Ref: [RedHat: Isolating CPUs Using tuned-profiles-realtime](https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux_for_real_time/7/html/tuning_guide/isolating_cpus_using_tuned-profiles-realtime)
|
||||
|
||||
|
||||
<a id=guidelines></a>
|
||||
## Do's, Don'ts, and Wisdom
|
||||
|
||||
---
|
||||
### 1 Trick
|
||||
---
|
||||
|
||||
#### 1.1 Trick events are computationally expensive. Use them judiciously.
|
||||
|
||||
Trick events can provide a quick and easy way to customize the behavior of a sim, based on some condition. But, because they require Python interpretation, they are slow. They are not intended for implementation of permanent sim functionality. If they are over used, they can seriously degrade simulation performance. So, take it easy with the events.
|
||||
|
||||
See [Event Manager](https://nasa.github.io/trick/documentation/simulation_capabilities/Event-Manager).
|
||||
|
||||
#### 1.2 Disable Trick run-time components that your sim doesn't need.
|
||||
|
||||
```default_trick_sys.sm```, the file included at the top of any Trick ```S_define``` file defines numerous "modules" that provide functionality to a Trick sim. Whereas some of these modules ( like the Executive, MemoryManager, CommandLineArguments) are required for any Trick Simulation to function, many are optional. If the modules are not needed, then disabling them can improve simulation performance.
|
||||
|
||||
Inserting one or more of the ```#define``` statements listed below to the top of the ```S_define```, just before the inclusion of ```default_trick_sys.sm``` will disable those modules.
|
||||
|
||||
```
|
||||
#define TRICK_NO_EXECUTIVE
|
||||
#define TRICK_NO_MONTE_CARLO
|
||||
#define TRICK_NO_MEMORY_MANAGER
|
||||
#define TRICK_NO_CHECKPOINT_RESTART
|
||||
#define TRICK_NO_SIE
|
||||
#define TRICK_NO_COMMANDLINEARGUMENTS
|
||||
#define TRICK_NO_MESSAGE
|
||||
#define TRICK_NO_INPUTPROCESSOR
|
||||
#define TRICK_NO_VARIABLE_SERVER
|
||||
#define TRICK_NO_DATA_RECORD
|
||||
#define TRICK_NO_REALTIME
|
||||
#define TRICK_NO_FRAMELOG
|
||||
#define TRICK_NO_MASTERSLAVE
|
||||
#define TRICK_NO_INSTRUMENTATION
|
||||
#define TRICK_NO_INTEGRATE
|
||||
#define TRICK_NO_REALTIMEINJECTOR
|
||||
#define TRICK_NO_ZEROCONF
|
||||
#define TRICK_NO_UNITTEST
|
||||
```
|
||||
##### Example
|
||||
Using "SIM_submarine" as an example, the following demonstrates disabling unneeded ```default_trick_sys.sm``` modules.
|
||||
|
||||
```
|
||||
/************************************************************
|
||||
PURPOSE:
|
||||
( Simulate a submarine. )
|
||||
LIBRARY DEPENDENCIES:
|
||||
((submarine/src/Submarine.cpp))
|
||||
*************************************************************/
|
||||
#define TRICK_NO_MONTE_CARLO
|
||||
#define TRICK_NO_MASTERSLAVE
|
||||
#define TRICK_NO_INSTRUMENTATION
|
||||
#define TRICK_NO_REALTIMEINJECTOR
|
||||
#define TRICK_NO_ZEROCONF
|
||||
#define TRICK_NO_UNITTEST
|
||||
#include "sim_objects/default_trick_sys.sm"
|
||||
|
||||
##include "submarine/include/Submarine.hh"
|
||||
|
||||
class SubmarineSimObject : public Trick::SimObject {
|
||||
public:
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
#### 1.3 Consider running Trick variable server clients and Sims on different machines.
|
||||
Trick variable server clients communicate with a simulation via a TCP/IP connection.
|
||||
The client process may, but isn't required to, run on the same machine as your simulation process. On the same machine, both will competing for the same resources. This can degrade sim performance, especially when clients are rendering high-definition graphics.
|
||||
|
||||
|
||||
#### 1.4 Compile Trick and Trick sims with optimizations turned on
|
||||
|
||||
Example :
|
||||
In my ```S_overrides.mk``` file, I'll add the "-O2" optimization flag.
|
||||
|
||||
```
|
||||
TRICK_CFLAGS += -Imodels -O2
|
||||
TRICK_CXXFLAGS += -Imodels -O2
|
||||
```
|
||||
|
||||
See:
|
||||
|
||||
* [GCC Optimization Options](https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html)
|
||||
* [Clang Optimization Options](https://clang.llvm.org/docs/CommandGuide/clang.html#code-generation-options)
|
||||
|
||||
|
||||
#### 1.5 Disable unused jobs in Trick sims
|
||||
|
||||
Jobs can be enabled and disabled from the input file with the following commands:
|
||||
|
||||
```
|
||||
trick.exec_get_job(<job_name>, <instance_num>).enable()
|
||||
trick.exec_get_job(<job_name>, <instance_num>).disable()
|
||||
```
|
||||
|
||||
Alternatively, we can use:
|
||||
|
||||
```
|
||||
trick.exec_set_job_onoff(<job_name>, <instance_num>, True|False)
|
||||
```
|
||||
|
||||
If a job isn't necessary for a particular RUN scenario, consider disabling it. But, make sure that it doesn’t impact the rest of the sim.
|
||||
|
||||
##### Example:
|
||||
|
||||
Suppose ```SIM_submarine```'s S_define file contains the job ```submarine.diagnostics```:
|
||||
|
||||
```
|
||||
...
|
||||
(0.1, "scheduled") submarine.diagnostics();
|
||||
...
|
||||
};
|
||||
SubmarineSimObject dyn;
|
||||
...
|
||||
```
|
||||
This job only transmits information. It doesn't affect the simulation, but does degrade realtime performance slightly. To disable it, we'll add the following to our input file:
|
||||
|
||||
```trick.exec_get_job("dyn.submarine.diagnostics", 0).disable()```
|
||||
|
||||
|
||||
#### 1.6 Name the child threads in your Trick sim
|
||||
Do this for easier identification of time spikes.
|
||||
|
||||
```trick.exec_get_thread(<thread_id>).set_name(<name>)```
|
||||
|
||||
##### Example:
|
||||
|
||||
In ```SIM_lander's``` ```S_define```, suppose we specify that ```lander.control()``` job is to run in thread 1 (C1):
|
||||
|
||||
``` C1 (0.1, "scheduled") lander.control() ;```
|
||||
|
||||
Then in the input file, we add:
|
||||
|
||||
```trick.exec_get_thread(1).set_name("LanderControl")```
|
||||
|
||||
to name the C1 thread "LanderControl".
|
||||
|
||||
|
||||
#### 1.7 Use ```default_data``` jobs to specify the default sim state. Customize it with the input file.
|
||||
|
||||
Prefer ```default_data``` jobs as the **primary** means of initializing your sim. Then, **customize** the default for different scenarios, with an input file. Try to make your sim capable of initializing to a valid state with an empty input file.
|
||||
|
||||
Doing this has several benefits.
|
||||
|
||||
1. The sim will initialize faster because ```default_data``` jobs are compiled rather that interpreted.
|
||||
|
||||
2. If you can test and confirm that your base, default, "empty input file" sim is initialized to a valid state, then it will be easier to identify errors when the sim is customized for different scenarios, via an input file. It saves time and reduces pain.
|
||||
|
||||
---
|
||||
### 2. User Simulation Software
|
||||
---
|
||||
|
||||
#### 2.1 Don't read from the disk during run-time.
|
||||
Disk access is slow. If you need to read from disk, do it in a ```default_data```, or ```initialization``` job.
|
||||
|
||||
|
||||
#### 2.2 Try to reduce variation in job cycle times.
|
||||
Realtime performance is largely about minimizing the worst case, rather than the average case.
|
||||
The most well behaved job takes the same amount of time, every time.
|
||||
|
||||
|
||||
#### 2.3 Minimize dynamic memory allocation during run-time
|
||||
The time to dynamically allocate memory can vary, and in the worst-case is unbounded. This is bad for realtime performance.
|
||||
|
||||
|
||||
#### 2.4 Allow the compiler to help you find problems
|
||||
|
||||
Modern compilers have gotten very helpful, and can check for a lot of potential problems.
|
||||
Many people are familiar with the compiler warning options like ```-Wall```, ```-Wextra```, and ```-Wshadow```. Be aware that there are a lot more, to help you find problems:
|
||||
|
||||
* [GCC Warning Options](https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html)
|
||||
* [CLANG Warning Options](https://clang.llvm.org/docs/DiagnosticsReference.html)
|
||||
|
||||
|
||||
#### 2.5 Fix All Compiler Warnings And Errors
|
||||
Many a time the necessary clue needed to solve an intractable problem was there all along, in the form of an unheeded warning that scrolled by unseen.
|
||||
|
||||
Don't ignore the messages.
|
||||
|
||||
When Trick builds a sim, it generates the files, ```MAKE_out``` and ```MAKE_err``` in the ```build``` directory. These files contain the makefile output of the sim build. It's a good idea to check these for warnings on a big sim build.
|
||||
|
||||
---
|
||||
### 3. Hardware
|
||||
---
|
||||
|
||||
#### 3.1 Know Your Simulation Machine Architecture
|
||||
Getting the best performance from a simulation on a multi-CPU machine requires understanding of the machine's hardware architecture. Particularly important is data transfer delay from memory to the CPU (latency). Depending on the machine architecture, and how data processing is allocated across CPUs, the time used for memory access, and therefore simulation performance can very significantly.
|
||||
|
||||
##### Uniform Memory Access (UMA)
|
||||
Uniform memory access (UMA) is a multi-processor model in which all processors share the physical memory uniformly. All memory accesses have the same latency.
|
||||
|
||||
![Realtime with itimer](images/UMA_Arch.png)
|
||||
|
||||
In an UMA architecture, as the number of CPUs increases, the higher the chance that the system bus will become a bottle-neck.
|
||||
|
||||
##### Non Uniform Memory Access (NUMA)
|
||||
Non-Uniform Memory Access (NUMA) is a multiprocessor model in which each processor is connected to dedicated memory but may access memory attached to other processors in the system. A NUMA architecture is one in which accesses to different addresses may have different latencies depending on where the data is stored. NUMA essentially connects UMA elements via a data-transfer interconnect. For best performance, applications should be “NUMA aware”.
|
||||
|
||||
![Realtime with itimer](images/NUMA_Arch.png)
|
||||
|
||||
On a Linux system the following will display the available nodes, CPUs, memory, and a normalized measure of access latency between nodes.
|
||||
|
||||
```% numactl --hardware```
|
||||
|
||||
##### Example 1
|
||||
```
|
||||
available: 1 nodes (0)
|
||||
node 0 cpus: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
||||
node 0 size: 63986 MB
|
||||
node 0 free: 54389 MB
|
||||
node distances:
|
||||
node 0
|
||||
0: 10
|
||||
```
|
||||
This computer has one NUMA node with 20 CPUs, and 64 Gigabytes.
|
||||
|
||||
##### Example 2
|
||||
```
|
||||
available: 2 nodes (0-1)
|
||||
node 0 cpus: 0 1 2 3 4 5 6 7 8 9 10 11 24 25 26 27 28 29 30 31 32 33 34 35
|
||||
node 0 size: 15371 MB
|
||||
node 0 free: 3926 MB
|
||||
node 1 cpus: 12 13 14 15 16 17 18 19 20 21 22 23 36 37 38 39 40 41 42 43 44 45 46 47
|
||||
node 1 size: 16120 MB
|
||||
node 1 free: 4504 MB
|
||||
node distances:
|
||||
node 0 1
|
||||
0: 10 21
|
||||
1: 21 10
|
||||
```
|
||||
This computer has two NUMA nodes, each with 24 CPUs, and each with about 16 gigabytes of local memory, for a total of 32 Gigabytes. The "distances" matrix at the bottom tells us that memory access latency between the nodes is (21/10) = 2.1 times the latency within a node.
|
||||
|
||||
|
||||
#### 3.2 Turn Off Any Energy-Efficiency Settings
|
||||
Energy efficiency and performance are usually trade-offs. Turn off any energy-efficiency settings the computer may have enabled, usually in the BIOS.
|
||||
|
||||
|
||||
#### 3.3 Fewer, Faster Cores Are Preferable to More, Slower Cores
|
||||
For simulation hosts, fewer but faster cores is usually preferable to more but slower cores
|
||||
|
||||
* **Server-class** machines are designed for throughput.
|
||||
* **Performance** machines are designed for low latency, high-speed computing.
|
||||
|
||||
|
||||
#### 3.4 Buy More Memory
|
||||
Insufficient random access memory (RAM) leads to virtual memory page swapping, which degrades realtime performance. More RAM is one of the easiest and cheapest ways of boosting machine performance.
|
||||
|
||||
|
||||
#### 3.5 Avoid Intel “Efficiency” Cores
|
||||
Intel "efficiency" cores aren’t currently recognized by most Linux OS’s and will cause a lot of problems. They are more energy efficient, but slower, the opposite of what hard realtime needs. RHEL8 is unable to determine which cores are “E” (Efficiency) and which are “P” (Performance). Did I mention you should buy more memory?
|
||||
|
||||
---
|
||||
### 4. Network
|
||||
---
|
||||
|
||||
#### 4.1 Have Multiple Network Interface Jacks On Sim Machines
|
||||
Isolate all sim-to-sim traffic to one network interface. Leave the other for connections to the box and OS traffic.
|
||||
|
||||
|
||||
#### 4.2 Use One Master Clock For All Machines On The Network
|
||||
All clocks will drift apart unless periodically synchronized. Synchronization means that one of the clocks must be the reference, or "master". Multiple unsynchronized clocks in a realtime system is nightmare fuel.
|
||||
|
||||
---
|
||||
### 5. Miscellaneous
|
||||
---
|
||||
|
||||
#### 5.1 Maintain a history of simulation performance.
|
||||
|
||||
Maintain a performance history of your sim as development procedes. This can be very useful evidence in solving problems. Begin frame logging the sim even before implementing realtime.
|
||||
|
||||
|
||||
#### 5.2 Take care when "tuning" operating system behavior
|
||||
Overriding the OS by isolating CPUs, assigning threads to CPUs, redirecting interrupts, changing priorities, and so forth can be powerful techniques to improve performance, but with the same power they can degrade it. Modern operating systems are pretty good at managing performance. If you decide to "help" the OS, you’ll need to know what you’re doing. Take the time to study up first.
|
||||
|
||||
Some useful learning material:
|
||||
|
||||
* [Challenges Using Linux as a Real-Time Operating System](https://ntrs.nasa.gov/api/citations/20200002390/downloads/20200002390.pdf)
|
||||
* [Optimizing RHEL 8 for Real Time for low latency operation](https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux_for_real_time/8/html-single/optimizing_rhel_8_for_real_time_for_low_latency_operation/index)
|
||||
|
||||
#### 5.3 Don’t isolate CPU 0
|
||||
Nothing good can come from this.
|
||||
|
||||
|
||||
#### 5.4 Best Performance Requires Root Privileges
|
||||
|
||||
Ways to give root privilege to sim:
|
||||
|
||||
1. Run as root ( Don't )
|
||||
2. Change owner of executable to root and set user id bit
|
||||
|
||||
Use ```sudo``` command to give root privileges to the simulation executable using ```chown``` and ```chmod``` commands.
|
||||
|
||||
```
|
||||
chown root S_main_${TRICK_HOST_CPU}.exe
|
||||
chmod 4775 S_main_${TRICK_HOST_CPU}.exe
|
||||
```
|
BIN
docs/howto_guides/images/NUMA_Arch.png
Normal file
After Width: | Height: | Size: 138 KiB |
BIN
docs/howto_guides/images/RealtimeOverRun.png
Normal file
After Width: | Height: | Size: 121 KiB |
BIN
docs/howto_guides/images/RealtimeUnderRun.png
Normal file
After Width: | Height: | Size: 152 KiB |
BIN
docs/howto_guides/images/RealtimeWithItimer.png
Normal file
After Width: | Height: | Size: 183 KiB |
BIN
docs/howto_guides/images/UMA_Arch.png
Normal file
After Width: | Height: | Size: 56 KiB |
@ -61,7 +61,7 @@ namespace Trick {
|
||||
*/
|
||||
void print_nonzero_diffs() {
|
||||
std::map<std::string, ClassSizeDiffInfo>::iterator it ;
|
||||
for ( it = name_to_diff.begin() ; it != name_to_diff.end() ; it++ ) {
|
||||
for ( it = name_to_diff.begin() ; it != name_to_diff.end() ; ++it ) {
|
||||
int curr_diff = it->second.diff ;
|
||||
ATTRIBUTES * attr = Trick::AttributesMap::attributes_map()->get_attr(it->first) ;
|
||||
unsigned int ii ;
|
||||
|
@ -65,11 +65,11 @@ namespace Trick {
|
||||
/** Thread start time */
|
||||
long long start_time ;
|
||||
|
||||
/** Thread total frame scheduled time in tics*/
|
||||
/** Thread total frame scheduled time in tics */
|
||||
long long frame_sched_time ;
|
||||
|
||||
/** Thread total frame scheduled time in seconds*/
|
||||
double frame_time ;
|
||||
/** Thread total frame scheduled time in seconds */
|
||||
double frame_time ; // trick_units(s)
|
||||
|
||||
} ;
|
||||
|
||||
|
@ -17,7 +17,6 @@
|
||||
#define IPPYTHON_HH
|
||||
|
||||
#include <string>
|
||||
#include <pthread.h>
|
||||
#include "trick/InputProcessor.hh"
|
||||
|
||||
namespace Trick {
|
||||
@ -36,9 +35,6 @@ namespace Trick {
|
||||
/** Returned value from event condition evaluation.\n */
|
||||
int return_val ; /**< trick_io(**) trick_units(--) */
|
||||
|
||||
/** Input processor mutex for protection for var server and event processing.\n */
|
||||
pthread_mutex_t ip_mutex; /**< trick_io(**) trick_units(--) */
|
||||
|
||||
/**
|
||||
@brief Constructor.
|
||||
*/
|
||||
|
@ -92,7 +92,7 @@ namespace Trick {
|
||||
long long frame_time ; /**< trick_io(**) */
|
||||
|
||||
/** Cumulative time in seconds used for job in frame (rt_stop_time - rt_start_time) / time_tic_value */
|
||||
double frame_time_seconds; /**< trick_io(s) */
|
||||
double frame_time_seconds; /**< trick_io(**) trick_units(s) */
|
||||
|
||||
/** Sim_object_id.id (for job identification in timeline logging) */
|
||||
double frame_id; /**< trick_io(**) */
|
||||
|
@ -309,7 +309,7 @@ namespace Trick {
|
||||
@param var_name - the address of the variable.
|
||||
@return 0 = SUCCESS, 1 = FAILURE
|
||||
*/
|
||||
int delete_var(const char* var_name);
|
||||
int delete_var(std::string var_name);
|
||||
|
||||
/**
|
||||
Forget about the external variable at the given address. DOES NOT attempt to deallocate the
|
||||
@ -325,7 +325,7 @@ namespace Trick {
|
||||
@param var_name - the address of the external variable.
|
||||
@return 0 = SUCCESS, 1 = FAILURE
|
||||
*/
|
||||
int delete_extern_var(const char* var_name);
|
||||
int delete_extern_var(std::string var_name);
|
||||
|
||||
/**
|
||||
Checkpoint all allocations known to the MemoryManager to the given stream.
|
||||
|
@ -66,6 +66,8 @@ namespace Trick {
|
||||
*/
|
||||
int freeze_init() ;
|
||||
|
||||
void shutdownConnections();
|
||||
|
||||
/**
|
||||
@brief Shutdown the variable server
|
||||
@return always 0
|
||||
|
@ -58,6 +58,8 @@ namespace Trick {
|
||||
|
||||
virtual void dump( std::ostream & oss = std::cout ) ;
|
||||
|
||||
void shutdownConnections();
|
||||
|
||||
protected:
|
||||
void initializeMulticast();
|
||||
|
||||
@ -82,9 +84,13 @@ namespace Trick {
|
||||
/* Multicast broadcaster */
|
||||
MulticastGroup * _multicast; /**< trick_io(**) trick_units(--) */
|
||||
|
||||
bool allowConnections; /**< trick_io(**) trick_units(--) */
|
||||
unsigned int pendingConnections; /**< trick_io(**) trick_units(--) */
|
||||
pthread_mutex_t connectionMutex; /**< trick_io(**) trick_units(--) */
|
||||
pthread_cond_t noPendingConnections_cv; /**< trick_io(**) trick_units(--) */
|
||||
|
||||
} ;
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -64,7 +64,7 @@ int checkpoint_sequence_i(STL & in_stl , std::string object_name , std::string v
|
||||
//message_publish(1, "CHECKPOINT_SEQUENCE_STL with %s\n", var_declare) ;
|
||||
|
||||
/* copy the contents of the stl */
|
||||
for ( ii = 0 , it = in_stl.begin() , end = in_stl.end() ; it != end ; it++ , ii++ ) {
|
||||
for ( ii = 0 , it = in_stl.begin() , end = in_stl.end() ; it != end ; ++it , ii++ ) {
|
||||
items[ii] = *it ;
|
||||
}
|
||||
}
|
||||
@ -103,7 +103,7 @@ int checkpoint_sequence_s(STL & in_stl , std::string object_name , std::string v
|
||||
//message_publish(1, "CHECKPOINT_SEQUENCE_STL_STL with %s\n", temp_str.c_str()) ;
|
||||
|
||||
/* create the names of the sub stl checkpoint names we're going to be using */
|
||||
for ( ii = 0 , it = in_stl.begin() , end = in_stl.end() ; it != end ; it++ , ii++ ) {
|
||||
for ( ii = 0 , it = in_stl.begin() , end = in_stl.end() ; it != end ; ++it , ii++ ) {
|
||||
std::ostringstream sub_elements ;
|
||||
sub_elements << object_name << "_" << var_name << "_" << ii ;
|
||||
items[ii] = sub_elements.str() ;
|
||||
|
@ -9,6 +9,9 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int message_add_subscriber( void * in_ms ) ;
|
||||
int message_remove_subscriber( void * in_ms ) ;
|
||||
void * message_get_subscriber( const char * sub_name) ;
|
||||
int message_publish(int level, const char *format_msg, ...) ;
|
||||
int message_publish_standalone(int level, const char *format_msg, ...) ;
|
||||
int send_hs(FILE * fp, const char *format_msg, ...) ;
|
||||
|
@ -51,7 +51,15 @@
|
||||
// TYPE *
|
||||
void * temp_ptr ;
|
||||
|
||||
if ( SWIG_IsOK(SWIG_ConvertPtr($input, &temp_ptr,$1_descriptor, SWIG_POINTER_DISOWN)) ) {
|
||||
SwigPyObject *sobj = SWIG_Python_GetSwigThis($input) ;
|
||||
// isDisown is set to SWIG_POINTER_DISOWN by default
|
||||
int isDisown = SWIG_POINTER_DISOWN ;
|
||||
if (sobj) {
|
||||
// isDisown is re-set based on whether the Python processor owns the input object
|
||||
isDisown = !sobj->own ;
|
||||
}
|
||||
|
||||
if ( SWIG_IsOK(SWIG_ConvertPtr($input, &temp_ptr,$1_descriptor, isDisown)) ) {
|
||||
$1 = reinterpret_cast< $1_ltype >(temp_ptr) ;
|
||||
} else if ( SWIG_IsOK(SWIG_ConvertPtr($input, &temp_ptr,SWIG_TypeQuery("_p_swig_ref"), 0)) ) {
|
||||
// Array to pointer assignment
|
||||
|
@ -97,7 +97,7 @@ my $template_def = qr/template\s* # keyword template
|
||||
\s+[_A-Za-z]\w*\s* # class name
|
||||
/sx ;
|
||||
my $template_var_def = qr/(?:\:\:)?[_A-Za-z][:\w]*\s* # template name
|
||||
<[\w\s\*,:<>]*>\s* # template parameters
|
||||
<[\w\s\*,:<>\[\]]*>\s* # template parameters
|
||||
[_A-Za-z]\w*\s*(?:[{=].*?)?; # var name ;
|
||||
/sx ;
|
||||
|
||||
@ -337,6 +337,24 @@ sub process_file() {
|
||||
print OUT "\n$new_contents" ;
|
||||
print OUT "$contents\n" ;
|
||||
print OUT $global_template_typedefs ;
|
||||
|
||||
# Add _swig_setattr_nondynamic_instance_variable function for raising AttributeError for improper non-class attribute assingment in input processor.
|
||||
# _swig_setattr_nondynamic_instance_variable function is added for each class in process_class subroutine.
|
||||
foreach my $c ( @class_names ) {
|
||||
if ( ! exists $class_typemap_printed{$c} ) {
|
||||
my $c_ = $c ;
|
||||
$c_ =~ s/\:/_/g ;
|
||||
if ( $c !~ /::/ ) {
|
||||
print OUT "\n#if SWIG_VERSION > 0x040000\n";
|
||||
print OUT "%pythoncode %{\n" ;
|
||||
print OUT " if '$c' in globals():\n";
|
||||
print OUT " $c.__setattr__ = _swig_setattr_nondynamic_instance_variable(object.__setattr__)\n" ;
|
||||
print OUT "%}\n" ;
|
||||
print OUT "#endif\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Add a trick_cast_as macro line for each class parsed in the file. These lines must appear at the bottom of the
|
||||
# file to ensure they are not in a namespace directive and they are after the #define statements they depend on.
|
||||
undef %class_typemap_printed ;
|
||||
@ -479,6 +497,9 @@ sub process_template($$) {
|
||||
my ( $contents_ref , $new_contents_ref ) = @_ ;
|
||||
my $extracted ;
|
||||
|
||||
# Add _swig_setattr_nondynamic_instance_variable function for raising AttributeError for improper class attribute assingment in input processor
|
||||
# The function call is inserted after the 1st { of the class template so it is placed at the top
|
||||
$$contents_ref=~s/{\n/{\n\n#if SWIG_VERSION > 0x040000\n\%pythoncode \%{\n __setattr__ = _swig_setattr_nondynamic_instance_variable(object.__setattr__)\n\%}\n#endif\n/m;
|
||||
if ( $$contents_ref =~ s/^(\s*;)//s ) {
|
||||
$$new_contents_ref .= $1 ;
|
||||
} else {
|
||||
@ -590,20 +611,22 @@ sub process_class($$$$$) {
|
||||
my ($class_name) ;
|
||||
my $template_typedefs ;
|
||||
|
||||
|
||||
## Extract the class_name from the class_string
|
||||
$class_string =~ /^(?:class|struct)\s+ # keyword class or struct
|
||||
([_A-Za-z]\w*) # class name
|
||||
\s*[\{\:]$
|
||||
/sx or die "Internal error" ;
|
||||
$class_name = $1 ;
|
||||
$$new_contents_ref .= $class_string ;
|
||||
my $my_class_contents = $class_string ;
|
||||
|
||||
if ( $class_string !~ /\{$/ ) {
|
||||
$$contents_ref =~ s/^(.*?\s*\{)//s ;
|
||||
$$new_contents_ref .= $1 ;
|
||||
$my_class_contents .= $1 ;
|
||||
}
|
||||
|
||||
# Add _swig_setattr_nondynamic_instance_variable function for raising AttributeError for improper class attribute assingment in input processor
|
||||
$my_class_contents .= "\n#if SWIG_VERSION > 0x040000\n\%pythoncode \%{\n __setattr__ = _swig_setattr_nondynamic_instance_variable(object.__setattr__)\n\%}\n#endif\n" ;
|
||||
|
||||
($extracted, $$contents_ref) = extract_bracketed( "{" . $$contents_ref , "{}") ;
|
||||
|
||||
# remove the trailing semicolon because we may append text to the class.
|
||||
@ -618,6 +641,8 @@ sub process_class($$$$$) {
|
||||
# SWIG doesn't like "const static". Change it to "static const"
|
||||
$extracted =~ s/const\s+static/static const/g ;
|
||||
|
||||
my $isSwigExcludeBlock = 0 ;
|
||||
|
||||
# templated variables need to be declared with the SWIG %template directive.
|
||||
# This loop looks for any templated variables and creates the %template lines.
|
||||
while ( $extracted =~ s/^(.*?)(?:($template_var_def))//sx ) {
|
||||
@ -626,7 +651,27 @@ sub process_class($$$$$) {
|
||||
|
||||
if ( $non_var ne "" ) {
|
||||
#print "*** non_var = $non_var ***\n" ;
|
||||
$$new_contents_ref .= $non_var ;
|
||||
$my_class_contents .= $non_var ;
|
||||
my $ifndefSwig = $non_var;
|
||||
my $moreNonVar = 1 ;
|
||||
# search for all instances of #ifndef SWIG, #if !defined(SWIG), and #endif prior to template variable
|
||||
# update $isSwigExcludeBlock to the last instance*
|
||||
# exit when no match is found
|
||||
# * this script does not track preprocessor scope, so any #endif will set $isSwigExcludeBlock to 0
|
||||
# in other words we don't support SWIGing nested preprocessor if statements, use at your peril
|
||||
while ($moreNonVar == 1) {
|
||||
if ($ifndefSwig =~ s/(#\s*ifndef\s*SWIG)|(#\s*if\s*!\s*defined\s*\(\s*SWIG\s*\))|(#\s*endif\s*)// ) {
|
||||
if($1 ne "" or $2 ne "") {
|
||||
$isSwigExcludeBlock = 1 ;
|
||||
}
|
||||
elsif($3 ne "") {
|
||||
$isSwigExcludeBlock = 0 ;
|
||||
}
|
||||
}
|
||||
else {
|
||||
$moreNonVar = 0 ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( $template_var_def_str ne "" ) {
|
||||
@ -635,7 +680,7 @@ sub process_class($$$$$) {
|
||||
$template_var_def_str =~ /(.*?>)\s*([_A-Za-z]\w*).*?;/s ;
|
||||
my ($template_full_type) = $1 ;
|
||||
my ($var_name) = $2 ;
|
||||
$$new_contents_ref .= $template_var_def_str ;
|
||||
$my_class_contents .= $template_var_def_str ;
|
||||
|
||||
$template_full_type =~ /([_A-Za-z][:\w]*)\s*</ ;
|
||||
my ($template_type) = $1 ;
|
||||
@ -658,17 +703,29 @@ sub process_class($$$$$) {
|
||||
my $identifier = "${sanitized_namespace}${class_name}_${var_name}" ;
|
||||
my $trick_swig_template = "TRICK_SWIG_TEMPLATE_$identifier" ;
|
||||
|
||||
$$new_contents_ref .= "\n#define $trick_swig_template\n" ;
|
||||
|
||||
my $typedef = "\n#ifdef $trick_swig_template\n" ;
|
||||
# Insert template directive immediately before intsance
|
||||
# This is required as of SWIG 4
|
||||
my $typedef = "\n#ifndef $trick_swig_template\n" ;
|
||||
$typedef .= "#define $trick_swig_template\n" ;
|
||||
$typedef .= "\%template($identifier) $template_full_type;\n" ;
|
||||
$typedef .= "#undef $trick_swig_template\n" ;
|
||||
$typedef .= "#endif\n" ;
|
||||
|
||||
if ($qualified) {
|
||||
$global_template_typedefs .= $typedef
|
||||
} else {
|
||||
$template_typedefs .= $typedef
|
||||
# SWIG namespace resolution for template directives starts at the local space
|
||||
# Therefore, if the type is qualified, assume it's fully qualified and put the
|
||||
# %template directive in the global namespace by escaping the current namespace
|
||||
if ($curr_namespace ne "") {
|
||||
my $in_same_namespace = 1 ;
|
||||
if ($template_full_type =~ /^\w*(::)\w+</) {
|
||||
$in_same_namespace = 0 ;
|
||||
}
|
||||
if ($in_same_namespace eq 0) {
|
||||
$curr_namespace =~ /(.*)::/ ;
|
||||
$typedef = "\n}" . $typedef . "namespace " . $1 . " {" ;
|
||||
}
|
||||
}
|
||||
|
||||
if ($isSwigExcludeBlock == 0) {
|
||||
$template_typedefs .= $typedef ;
|
||||
}
|
||||
|
||||
$processed_templates{$template_type_no_sp} = 1 ;
|
||||
@ -681,11 +738,12 @@ sub process_class($$$$$) {
|
||||
|
||||
push @$class_names_ref , "$curr_namespace$class_name" ;
|
||||
|
||||
# write the class contents and semicolon to ensure any template declarations below are after the semicolon.
|
||||
$$new_contents_ref .= "\n#if SWIG_VERSION > 0x040000\n\%pythoncode \%{\n __setattr__ = _swig_setattr_nondynamic_instance_variable(object.__setattr__)\n\%}\n#endif\n" ;
|
||||
$$new_contents_ref .= $extracted . ";\n" ;
|
||||
# write out the templated variable declaration lines found in this class.
|
||||
$$new_contents_ref .= $template_typedefs ;
|
||||
$$new_contents_ref .= $template_typedefs."\n" ;
|
||||
|
||||
$$new_contents_ref .= $my_class_contents ;
|
||||
# write the class contents and semicolon to ensure any template declarations below are after the semicolon.
|
||||
$$new_contents_ref .= $extracted . ";\n" ;
|
||||
|
||||
my $c_ = "$curr_namespace$class_name" ;
|
||||
$c_ =~ s/\:/_/g ;
|
||||
@ -727,7 +785,7 @@ sub process_typedef_struct($$$$) {
|
||||
my ($typedef_struct_string , $contents_ref, $new_contents_ref , $class_names_ref) = @_ ;
|
||||
|
||||
my $extracted ;
|
||||
my ($begin, $tail , $struct_names, @struct_names) ;
|
||||
my ($tail , $struct_names, @struct_names) ;
|
||||
|
||||
#print "*** typedef_struct_string = $typedef_struct_string ***\n" ;
|
||||
|
||||
@ -736,7 +794,6 @@ sub process_typedef_struct($$$$) {
|
||||
$typedef_struct_string =~ s/((?:typedef\s+)?(struct|union)\s* # the words typedef struct|union
|
||||
([_A-Za-z]\w*)?\s* # optional name
|
||||
{)//sx ;
|
||||
$begin = $3 ;
|
||||
|
||||
($extracted, $$contents_ref) = extract_bracketed( "{" . $$contents_ref , "{}") ;
|
||||
#print "*** extracted = $extracted ***\n" ;
|
||||
@ -751,9 +808,6 @@ sub process_typedef_struct($$$$) {
|
||||
$struct_names =~ s/\s//g ;
|
||||
@struct_names = split /,/ , $struct_names ;
|
||||
|
||||
if ( $begin ne "" ) {
|
||||
push @$class_names_ref , $begin ;
|
||||
}
|
||||
foreach my $s ( @struct_names ) {
|
||||
if ( $s !~ /\*/ ) {
|
||||
push @$class_names_ref , $s ;
|
||||
|
@ -1,6 +1,13 @@
|
||||
#!/usr/bin/perl
|
||||
package sie_concat;
|
||||
|
||||
use File::Basename ;
|
||||
use FindBin qw($RealBin);
|
||||
use lib "$RealBin/pm" ;
|
||||
use get_paths ;
|
||||
|
||||
my @trick_python_paths = get_paths( "TRICK_PYTHON_PATH") ;
|
||||
|
||||
open(my $S_sie_resource, ">", "./S_sie.resource")
|
||||
or die "cannot open S_sie.resource $!";
|
||||
print $S_sie_resource "<?xml version=\"1.0\"?>\n\n<sie>\n\n";
|
||||
@ -14,6 +21,17 @@ while(my $line = <$classes_resource>) {
|
||||
|
||||
close($classes_resource);
|
||||
|
||||
# Add trickified classes.resource if available
|
||||
foreach my $path ( @trick_python_paths ) {
|
||||
my $trickified_dir = dirname($path);
|
||||
if (open(my $classes_resource, "<", "$trickified_dir/build/classes.resource")) {
|
||||
while(my $line = <$classes_resource>) {
|
||||
print $S_sie_resource $line;
|
||||
}
|
||||
close($classes_resource);
|
||||
}
|
||||
}
|
||||
|
||||
open(my $top_level_objects_resource, "<", "build/top_level_objects.resource")
|
||||
or die "cannot open build/top_level_objects.resource";
|
||||
while(my $line = <$top_level_objects_resource>) {
|
||||
|
@ -1284,8 +1284,11 @@ class TrickWorkflow(WorkflowCommon):
|
||||
self.status = Job.Status.FAILED
|
||||
if self.missing:
|
||||
return self.status
|
||||
if (hashlib.md5(open(self.test_data,'rb').read(), usedforsecurity=False).hexdigest() !=
|
||||
hashlib.md5(open(self.baseline_data,'rb').read(), usedforsecurity=False).hexdigest()):
|
||||
td = hashlib.new('md5', usedforsecurity=False)
|
||||
bd = hashlib.new('md5', usedforsecurity=False)
|
||||
td.update(open(self.test_data,'rb').read())
|
||||
bd.update(open(self.baseline_data,'rb').read())
|
||||
if (td.hexdigest() != bd.hexdigest()):
|
||||
self.status = Job.Status.FAILED
|
||||
else:
|
||||
self.status = Job.Status.SUCCESS
|
||||
|
@ -146,12 +146,12 @@ SIM_test_templates:
|
||||
- unit_test
|
||||
runs:
|
||||
RUN_test/unit_test.py:
|
||||
# SIM_test_varserv:
|
||||
# path: test/SIM_test_varserv
|
||||
# labels:
|
||||
# - unit_test
|
||||
# runs:
|
||||
# RUN_test/unit_test.py:
|
||||
SIM_test_varserv:
|
||||
path: test/SIM_test_varserv
|
||||
labels:
|
||||
- unit_test
|
||||
runs:
|
||||
RUN_test/unit_test.py:
|
||||
SIM_threads:
|
||||
path: test/SIM_threads
|
||||
labels:
|
||||
@ -189,8 +189,8 @@ SIM_ball_L2:
|
||||
runs:
|
||||
SIM_ball_L3:
|
||||
path: trick_sims/Ball/SIM_ball_L3
|
||||
# SIM_amoeba:
|
||||
# path: trick_sims/Cannon/SIM_amoeba
|
||||
SIM_amoeba:
|
||||
path: trick_sims/Cannon/SIM_amoeba
|
||||
SIM_cannon_aero:
|
||||
path: trick_sims/Cannon/SIM_cannon_aero
|
||||
SIM_cannon_analytic:
|
||||
|
@ -19,7 +19,7 @@ int Trick::SegmentedExecutive::add_segment( Trick::Segment * ps ) {
|
||||
|
||||
// Gets the job class to job queue map for this segment and adds the job classes to the executive.
|
||||
std::map < std::string , Trick::ScheduledJobQueue * >::iterator it ;
|
||||
for ( it = ps->get_job_queues().begin() ; it != ps->get_job_queues().end() ; it++ ) {
|
||||
for ( it = ps->get_job_queues().begin() ; it != ps->get_job_queues().end() ; ++it ) {
|
||||
class_map[(*it).first] = num_classes ;
|
||||
class_to_queue[num_classes++] = (*it).second ;
|
||||
}
|
||||
@ -41,7 +41,7 @@ int Trick::SegmentedExecutive::gather_segmented_jobs() {
|
||||
std::map < std::string , Trick::Segment * >::iterator mit ;
|
||||
std::set< std::string > segment_tags ;
|
||||
|
||||
for ( mit = segment_map.begin() ; mit != segment_map.end() ; mit++ ) {
|
||||
for ( mit = segment_map.begin() ; mit != segment_map.end() ; ++mit ) {
|
||||
segment_tags.insert((*mit).first) ;
|
||||
}
|
||||
|
||||
@ -129,7 +129,7 @@ int Trick::SegmentedExecutive::segment_set_jobs_onoff() {
|
||||
Trick::JobData * job ;
|
||||
std::set < Trick::JobData * >::iterator it ;
|
||||
|
||||
for ( it = all_segmented_jobs.begin() ; it != all_segmented_jobs.end() ; it++ ) {
|
||||
for ( it = all_segmented_jobs.begin() ; it != all_segmented_jobs.end() ; ++it ) {
|
||||
job = *it ;
|
||||
// Test to see if the next segment is present in the job tags.
|
||||
// Set the disabled flag to the negation of the tag's presence
|
||||
@ -164,10 +164,10 @@ int Trick::SegmentedExecutive::write_s_job_execution(FILE *fp) {
|
||||
fprintf(fp, "Segment Jobs:\n") ;
|
||||
|
||||
std::map < std::string , Trick::Segment * >::iterator pmit ;
|
||||
for ( pmit = segment_map.begin() ; pmit != segment_map.end() ; pmit++ ) {
|
||||
for ( pmit = segment_map.begin() ; pmit != segment_map.end() ; ++pmit ) {
|
||||
Trick::Segment * pb = (*pmit).second ;
|
||||
std::map < std::string , Trick::ScheduledJobQueue * >::iterator jqit ;
|
||||
for ( jqit = pb->get_job_queues().begin() ; jqit != pb->get_job_queues().end() ; jqit++ ) {
|
||||
for ( jqit = pb->get_job_queues().begin() ; jqit != pb->get_job_queues().end() ; ++jqit ) {
|
||||
(*jqit).second->write_non_sched_queue(fp) ;
|
||||
}
|
||||
}
|
||||
@ -187,10 +187,10 @@ int Trick::SegmentedExecutive::instrument_job_before( Trick::JobData * instrumen
|
||||
|
||||
//go through all of the segmented jobs and instrument them.
|
||||
std::map < std::string , Trick::Segment * >::iterator pmit ;
|
||||
for ( pmit = segment_map.begin() ; pmit != segment_map.end() ; pmit++ ) {
|
||||
for ( pmit = segment_map.begin() ; pmit != segment_map.end() ; ++pmit ) {
|
||||
Trick::Segment * pb = (*pmit).second ;
|
||||
std::map < std::string , Trick::ScheduledJobQueue * >::iterator jqit ;
|
||||
for ( jqit = pb->get_job_queues().begin() ; jqit != pb->get_job_queues().end() ; jqit++ ) {
|
||||
for ( jqit = pb->get_job_queues().begin() ; jqit != pb->get_job_queues().end() ; ++jqit ) {
|
||||
(*jqit).second->instrument_before(instrument_job) ;
|
||||
}
|
||||
}
|
||||
@ -209,10 +209,10 @@ int Trick::SegmentedExecutive::instrument_job_after( Trick::JobData * instrument
|
||||
|
||||
//go through all of the segmented jobs and instrument them.
|
||||
std::map < std::string , Trick::Segment * >::iterator pmit ;
|
||||
for ( pmit = segment_map.begin() ; pmit != segment_map.end() ; pmit++ ) {
|
||||
for ( pmit = segment_map.begin() ; pmit != segment_map.end() ; ++pmit ) {
|
||||
Trick::Segment * pb = (*pmit).second ;
|
||||
std::map < std::string , Trick::ScheduledJobQueue * >::iterator jqit ;
|
||||
for ( jqit = pb->get_job_queues().begin() ; jqit != pb->get_job_queues().end() ; jqit++ ) {
|
||||
for ( jqit = pb->get_job_queues().begin() ; jqit != pb->get_job_queues().end() ; ++jqit ) {
|
||||
(*jqit).second->instrument_after(instrument_job) ;
|
||||
}
|
||||
}
|
||||
@ -226,10 +226,10 @@ int Trick::SegmentedExecutive::instrument_job_remove(std::string in_job) {
|
||||
Trick::Executive::instrument_job_remove( in_job ) ;
|
||||
|
||||
std::map < std::string , Trick::Segment * >::iterator pmit ;
|
||||
for ( pmit = segment_map.begin() ; pmit != segment_map.end() ; pmit++ ) {
|
||||
for ( pmit = segment_map.begin() ; pmit != segment_map.end() ; ++pmit ) {
|
||||
Trick::Segment * pb = (*pmit).second ;
|
||||
std::map < std::string , Trick::ScheduledJobQueue * >::iterator jqit ;
|
||||
for ( jqit = pb->get_job_queues().begin() ; jqit != pb->get_job_queues().end() ; jqit++ ) {
|
||||
for ( jqit = pb->get_job_queues().begin() ; jqit != pb->get_job_queues().end() ; ++jqit ) {
|
||||
(*jqit).second->instrument_remove(in_job) ;
|
||||
}
|
||||
}
|
||||
|
@ -2781,12 +2781,16 @@ def main():
|
||||
# Polymorphic assignments and access
|
||||
test_suite = "polymorphism"
|
||||
|
||||
test_so.a = trick.Cat()
|
||||
#test_so.a = trick.Cat()
|
||||
# use MM to allocate memory for a pointer declared in S_define
|
||||
test_so.a = trick.TMM_declare_var_s("Cat")
|
||||
TRICK_EXPECT_EQ( test_so.a.id , 1, test_suite , "single abstract ptr" )
|
||||
trick.trick_test_add_parent( test_suite , "single abstract ptr" , "1770735610")
|
||||
#test_so.a.speak()
|
||||
#test_so.a[0].speak()
|
||||
test_so.a = trick.Dog()
|
||||
#test_so.a = trick.Dog()
|
||||
# use MM to allocate memory for a pointer declared in S_define
|
||||
test_so.a = trick.TMM_declare_var_s("Dog")
|
||||
TRICK_EXPECT_EQ( test_so.a.id , 2, test_suite , "single abstract ptr" )
|
||||
|
||||
test_so.aarray[0] = trick.Cat()
|
||||
@ -2991,6 +2995,24 @@ def main():
|
||||
TRICK_EXPECT_TRUE( test_so.test_true(), test_suite , "boolean function return" )
|
||||
TRICK_EXPECT_FALSE( test_so.test_false(), test_suite , "boolean function return" )
|
||||
|
||||
######################################################################################################################
|
||||
|
||||
test_suite = "SWIG Templates"
|
||||
|
||||
test_so.obj.class_no_ns.tnns.x = 1
|
||||
test_so.obj.class_no_ns.tns.y = 2
|
||||
test_so.obj.class_ns.tnns.x = 3
|
||||
test_so.obj.class_ns.tns.y = 4
|
||||
test_so.obj.foo1.bar.z = 5
|
||||
test_so.obj.foo2.bar.z = 6
|
||||
|
||||
TRICK_EXPECT_EQ( test_so.obj.class_no_ns.tnns.x, 1, test_suite , "template member access" )
|
||||
TRICK_EXPECT_EQ( test_so.obj.class_no_ns.tns.y, 2, test_suite , "template member access" )
|
||||
TRICK_EXPECT_EQ( test_so.obj.class_ns.tnns.x, 3, test_suite , "template member access" )
|
||||
TRICK_EXPECT_EQ( test_so.obj.class_ns.tns.y, 4, test_suite , "template member access" )
|
||||
TRICK_EXPECT_EQ( test_so.obj.foo1.bar.z, 5, test_suite , "template member access" )
|
||||
TRICK_EXPECT_EQ( test_so.obj.foo2.bar.z, 6, test_suite , "template member access" )
|
||||
|
||||
######################################################################################################################
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
@ -9,8 +9,25 @@ LIBRARY DEPENDENCIES:
|
||||
#include "sim_objects/default_trick_sys.sm"
|
||||
|
||||
##include "test_ip/include/ClassOfEverything.hh"
|
||||
##include "test_ip/include/ArrayTemplate.hh"
|
||||
##include "test_ip/include/OverloadedVariable.hh"
|
||||
|
||||
class ArrayTemplateSimObject : public Trick::SimObject
|
||||
{
|
||||
public:
|
||||
ArrayTemplateSimObject(const ArrayTemplateSimObject&) = delete;
|
||||
ArrayTemplateSimObject& operator=(const ArrayTemplateSimObject&) = delete;
|
||||
|
||||
double a[3];
|
||||
ArrayTemplate<double[3]> arryTemp;
|
||||
|
||||
ArrayTemplateSimObject()
|
||||
: arryTemp(a)
|
||||
{
|
||||
}
|
||||
};
|
||||
ArrayTemplateSimObject arry_temp_object;
|
||||
|
||||
class testSimObject : public Trick::SimObject {
|
||||
|
||||
public:
|
||||
|
37
test/SIM_test_ip/models/test_ip/include/ArrayTemplate.hh
Normal file
@ -0,0 +1,37 @@
|
||||
/**
|
||||
@file
|
||||
|
||||
@verbatim
|
||||
PURPOSE:
|
||||
(Test if we can build with arrays as template parameters)
|
||||
@endverbatim
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef ARRAY_TEMPLATE_TESTS_HH
|
||||
#define ARRAY_TEMPLATE_TESTS_HH
|
||||
|
||||
// System include files.
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
|
||||
template <class SourceType>
|
||||
class ArrayTemplate
|
||||
{
|
||||
public:
|
||||
ArrayTemplate(const SourceType& source)
|
||||
: source(source)
|
||||
{
|
||||
}
|
||||
|
||||
ArrayTemplate(const ArrayTemplate&) = delete;
|
||||
ArrayTemplate& operator=(const ArrayTemplate&) = delete;
|
||||
|
||||
private:
|
||||
const SourceType& source;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -28,6 +28,8 @@ LIBRARY DEPENDENCY:
|
||||
#include "test_ip/include/NoICG.hh"
|
||||
#include "exclude_me/include/exclude_me.hh"
|
||||
#include "test_ip/include/Namespace_tests.hh"
|
||||
#include "test_ip/include/TemplateTest.hh"
|
||||
#include "test_ip/include/IfndefSwigTest.hh"
|
||||
|
||||
/** @class Ball
|
||||
@brief ball in C++
|
||||
@ -441,6 +443,12 @@ class ClassOfEverything {
|
||||
std::map < std::string , int > msi ;
|
||||
std::list < std::string > ls ;
|
||||
|
||||
ClassNoNS class_no_ns ;
|
||||
NS2::ClassNS class_ns ;
|
||||
|
||||
a::Foo foo1;
|
||||
b::Foo2 foo2;
|
||||
|
||||
private:
|
||||
ClassOfEverything (const ClassOfEverything &);
|
||||
ClassOfEverything & operator= (const ClassOfEverything &);
|
||||
|
35
test/SIM_test_ip/models/test_ip/include/FooB.hh
Normal file
@ -0,0 +1,35 @@
|
||||
/********************************* TRICK HEADER *******************************
|
||||
PURPOSE:
|
||||
()
|
||||
LIBRARY DEPENDENCY:
|
||||
()
|
||||
PROGRAMMERS:
|
||||
(((Your Name) (Company Name) (Date) (Trick tutorial)))
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef FOOB_HH_
|
||||
#define FOOB_HH_
|
||||
|
||||
namespace FooNamespace
|
||||
{
|
||||
|
||||
// RestartableStateIntegrator
|
||||
template<int T>
|
||||
class FooA
|
||||
{
|
||||
public:
|
||||
|
||||
int A = T;
|
||||
};
|
||||
|
||||
// RestartableFirstOrderODEIntegrator
|
||||
template<int T>
|
||||
class FooB : public FooA<3>
|
||||
{
|
||||
public:
|
||||
int B = T;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
36
test/SIM_test_ip/models/test_ip/include/FooD.hh
Normal file
@ -0,0 +1,36 @@
|
||||
/********************************* TRICK HEADER *******************************
|
||||
PURPOSE:
|
||||
()
|
||||
LIBRARY DEPENDENCY:
|
||||
()
|
||||
PROGRAMMERS:
|
||||
(((Your Name) (Company Name) (Date) (Trick tutorial)))
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef FOOD_HH_
|
||||
#define FOOD_HH_
|
||||
|
||||
#include "FooB.hh"
|
||||
|
||||
namespace FooNamespace
|
||||
{
|
||||
|
||||
// RestartableSecondOrderODEIntegrator
|
||||
class FooC : public FooA<1>
|
||||
{
|
||||
public:
|
||||
int C;
|
||||
};
|
||||
|
||||
// RestartableSimpleSecondOrderODEIntegrator
|
||||
template<int T>
|
||||
class FooD : public FooC
|
||||
{
|
||||
public:
|
||||
int D = T;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
62
test/SIM_test_ip/models/test_ip/include/IfndefSwigTest.hh
Normal file
@ -0,0 +1,62 @@
|
||||
/********************************* TRICK HEADER *******************************
|
||||
PURPOSE:
|
||||
()
|
||||
LIBRARY DEPENDENCY:
|
||||
()
|
||||
PROGRAMMERS:
|
||||
(((Your Name) (Company Name) (Date) (Trick tutorial)))
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef FOO_HH_
|
||||
#define FOO_HH_
|
||||
|
||||
#include "FooB.hh"
|
||||
#include "FooD.hh"
|
||||
|
||||
namespace FooNamespace
|
||||
{
|
||||
|
||||
// RestartableScalarFirstOrderODEIntegrator
|
||||
class FooContB {
|
||||
public:
|
||||
FooContB() : d(12.0) {}
|
||||
|
||||
// RestartableFirstOrderODEIntegrator
|
||||
FooB<2> fooB;
|
||||
|
||||
FooB<2> fooB2;
|
||||
|
||||
double d;
|
||||
};
|
||||
|
||||
|
||||
// RestartableT3SecondOrderODEIntegrator
|
||||
class FooContD {
|
||||
public:
|
||||
FooContD() : d(12.0) {}
|
||||
|
||||
// RestartableSimpleSecondOrderODEIntegrator
|
||||
#ifndef TESTING_SWIG
|
||||
# ifndef SWIG
|
||||
// THIS SHOULD PREVENT SWIG FROM MAKING ANY TEMPLATE REFERENCES TO EXCLUDED FooD TYPE
|
||||
FooD<1> fooD;
|
||||
|
||||
FooD<2> fooD2;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
int spacer;
|
||||
|
||||
#if ! defined ( SWIG )
|
||||
// THIS SHOULD PREVENT SWIG FROM MAKING ANY TEMPLATE REFERENCES TO EXCLUDED FooD TYPE
|
||||
FooD<3> fooD3;
|
||||
|
||||
FooD<4> fooD4;
|
||||
#endif
|
||||
|
||||
double d;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -54,8 +54,12 @@ namespace NS2 {
|
||||
class B {
|
||||
public :
|
||||
//TODO: in the clang based convert_swig, we can use NS1 without the leading ::
|
||||
//NS1::A< int > m ;
|
||||
//Since swig 4.2.0, leading :: causes error.
|
||||
#if SWIG_VERSION >= 0x040200
|
||||
NS1::A< int > m ;
|
||||
#else
|
||||
::NS1::A< int > m ;
|
||||
#endif
|
||||
} ;
|
||||
}
|
||||
#endif
|
||||
|
@ -11,10 +11,10 @@ PURPOSE:
|
||||
#define TEMPLATETEST_HH
|
||||
|
||||
template <class A, class B>
|
||||
class TTT {
|
||||
class TTT_test {
|
||||
public:
|
||||
|
||||
TTT() {
|
||||
TTT_test() {
|
||||
aa = 0 ;
|
||||
bb = 0 ;
|
||||
cc = NULL ;
|
||||
@ -22,11 +22,11 @@ class TTT {
|
||||
} ;
|
||||
A aa ;
|
||||
B bb ;
|
||||
TTT<A,B> * ttt ;
|
||||
TTT_test<A,B> * ttt ;
|
||||
|
||||
typedef TTT<A,B> C ;
|
||||
typedef TTT_test<A,B> C ;
|
||||
C * cc ;
|
||||
typedef TTT<B,A> D ;
|
||||
typedef TTT_test<B,A> D ;
|
||||
D * dd ;
|
||||
} ;
|
||||
|
||||
@ -36,7 +36,7 @@ class TemplateTest {
|
||||
friend void init_attrTemplateTest() ;
|
||||
|
||||
public:
|
||||
TTT< int , double > TTT_var ;
|
||||
TTT_test< int , double > TTT_var ;
|
||||
|
||||
};
|
||||
|
||||
@ -44,5 +44,55 @@ class TemplateTest {
|
||||
%struct_str(TemplateTest)
|
||||
#endif
|
||||
|
||||
//Verify we can build templates/intsantiations defined in different combinations of namespaces
|
||||
template <class T>
|
||||
struct TemplateNoNS {T x;};
|
||||
|
||||
namespace NS1 {
|
||||
template <class T>
|
||||
struct TemplateNS {T y;};
|
||||
}
|
||||
|
||||
class ClassNoNS {
|
||||
public:
|
||||
TemplateNoNS<int> tnns;
|
||||
NS1::TemplateNS<int> tns;
|
||||
};
|
||||
|
||||
namespace NS2 {
|
||||
class ClassNS {
|
||||
public:
|
||||
TemplateNoNS<int> tnns;
|
||||
NS1::TemplateNS<int> tns;
|
||||
};
|
||||
}
|
||||
|
||||
//Verify we can build templates/intsantiations defined in the same namespace
|
||||
namespace a {
|
||||
|
||||
template <class T>
|
||||
struct Bar {T z;};
|
||||
|
||||
class Foo {
|
||||
public:
|
||||
Bar<int> bar;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
//Verify we can build templates/intsantiations defined in different namespaces
|
||||
namespace b {
|
||||
|
||||
class Foo2 {
|
||||
public:
|
||||
a::Bar<int> bar;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
//Verify we can build with templated functions (isn't actually SWIG-ified, but should be ignored)
|
||||
template <typename T> void templated_function() {}
|
||||
|
||||
|
||||
#endif /* _BALL_HH_ */
|
||||
|
||||
|
@ -304,7 +304,7 @@ SIM_test_output_dir:
|
||||
RUN_test/input.py -OO sim_output --read-only-sim:
|
||||
returns: 0
|
||||
analyze: 'python3 test/SIM_test_output_dir/ref_files/check_file_endings.py test/SIM_test_output_dir/ref_files/ref_compiletime_S_sie.resource test/SIM_test_output_dir/S_sie.resource'
|
||||
analyze: 'python3 test/SIM_test_output_dir/ref_files/check_file_endings.py test/SIM_test_output_dir/ref_files/ref_runtime_S_sie.resource test/SIM_test_output_dir/sim_output/S_sie.resource'
|
||||
analyze: 'python3 test/SIM_test_output_dir/ref_files/check_file_endings.py test/SIM_test_output_dir/ref_files/ref_runtime_S_sie.resource test/SIM_test_output_dir/sim_output/RUN_test/S_sie.resource'
|
||||
|
||||
|
||||
# The variable server client and SIM_amoeba sometimes fail to connect and need to be retried
|
||||
|
@ -13,14 +13,14 @@ void DrawStuff::start() {
|
||||
|
||||
void DrawStuff::step(int) {
|
||||
std::vector<DrawStuffObject *>::iterator it ;
|
||||
for( it = objects.begin() ; it != objects.end() ; it++ ) {
|
||||
for( it = objects.begin() ; it != objects.end() ; ++it ) {
|
||||
(*it)->draw() ;
|
||||
}
|
||||
}
|
||||
|
||||
void DrawStuff::command(int cmd) {
|
||||
std::vector<DrawStuffObject *>::iterator it ;
|
||||
for( it = objects.begin() ; it != objects.end() ; it++ ) {
|
||||
for( it = objects.begin() ; it != objects.end() ; ++it ) {
|
||||
(*it)->command(cmd) ;
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,13 @@ LIBRARY DEPENDENCIES:
|
||||
(Aircraft/src/Waypoint.cpp)
|
||||
)
|
||||
**************************************************************************/
|
||||
#define TRICK_NO_MONTE_CARLO
|
||||
#define TRICK_NO_MASTERSLAVE
|
||||
#define TRICK_NO_INSTRUMENTATION
|
||||
#define TRICK_NO_REALTIMEINJECTOR
|
||||
#define TRICK_NO_ZEROCONF
|
||||
#include "sim_objects/default_trick_sys.sm"
|
||||
|
||||
##include "Aircraft/include/Aircraft.hh"
|
||||
##include "Aircraft/include/Waypoint.hh"
|
||||
|
||||
|
@ -5,7 +5,13 @@ LIBRARY DEPENDENCIES:
|
||||
((balloon/src/Balloon.cpp)
|
||||
(atmosphere/src/atmosphere.c))
|
||||
*************************************************************/
|
||||
#define TRICK_NO_MONTE_CARLO
|
||||
#define TRICK_NO_MASTERSLAVE
|
||||
#define TRICK_NO_INSTRUMENTATION
|
||||
#define TRICK_NO_REALTIMEINJECTOR
|
||||
#define TRICK_NO_ZEROCONF
|
||||
#include "sim_objects/default_trick_sys.sm"
|
||||
|
||||
##include "balloon/include/Balloon.hh"
|
||||
|
||||
class BalloonSimObject : public Trick::SimObject {
|
||||
|
@ -4,7 +4,13 @@ PURPOSE:
|
||||
LIBRARY DEPENDENCIES:
|
||||
((pool_table/src/pool_table.cpp))
|
||||
*************************************************************/
|
||||
#define TRICK_NO_MONTE_CARLO
|
||||
#define TRICK_NO_MASTERSLAVE
|
||||
#define TRICK_NO_INSTRUMENTATION
|
||||
#define TRICK_NO_REALTIMEINJECTOR
|
||||
#define TRICK_NO_ZEROCONF
|
||||
#include "sim_objects/default_trick_sys.sm"
|
||||
|
||||
##include "pool_table/include/pool_table.hh"
|
||||
|
||||
class PoolTableSimObject : public Trick::SimObject {
|
||||
|
@ -4,7 +4,13 @@ PURPOSE:
|
||||
LIBRARY DEPENDENCIES:
|
||||
((contact/src/Contact.cpp))
|
||||
*************************************************************/
|
||||
#define TRICK_NO_MONTE_CARLO
|
||||
#define TRICK_NO_MASTERSLAVE
|
||||
#define TRICK_NO_INSTRUMENTATION
|
||||
#define TRICK_NO_REALTIMEINJECTOR
|
||||
#define TRICK_NO_ZEROCONF
|
||||
#include "sim_objects/default_trick_sys.sm"
|
||||
|
||||
##include "contact/include/Contact.hh"
|
||||
class ContactSimObject : public Trick::SimObject {
|
||||
public:
|
||||
|
@ -4,8 +4,6 @@ dyn.lander.pos[0] = 0
|
||||
dyn.lander.pos[1] = 1.8
|
||||
dyn.lander.vel[0] = 0.0
|
||||
dyn.lander.vel[1] = 0.0
|
||||
dyn.lander.angleDot = 0.0
|
||||
dyn.lander.angle = 0.0
|
||||
|
||||
trick.TMM_set_debug_level(1)
|
||||
#==========================================
|
||||
|
@ -5,7 +5,13 @@ LIBRARY DEPENDENCIES:
|
||||
((lander/src/Lander.cpp)
|
||||
(PIDController/src/PIDController.cpp))
|
||||
*************************************************************/
|
||||
#define TRICK_NO_MONTE_CARLO
|
||||
#define TRICK_NO_MASTERSLAVE
|
||||
#define TRICK_NO_INSTRUMENTATION
|
||||
#define TRICK_NO_REALTIMEINJECTOR
|
||||
#define TRICK_NO_ZEROCONF
|
||||
#include "sim_objects/default_trick_sys.sm"
|
||||
|
||||
##include "lander/include/Lander.hh"
|
||||
class LanderSimObject : public Trick::SimObject {
|
||||
public:
|
||||
|
@ -11,8 +11,13 @@ LIBRARY DEPENDENCIES:
|
||||
(msd/src/msd_shutdown.cpp)
|
||||
)
|
||||
*************************************************************/
|
||||
|
||||
#define TRICK_NO_MONTE_CARLO
|
||||
#define TRICK_NO_MASTERSLAVE
|
||||
#define TRICK_NO_INSTRUMENTATION
|
||||
#define TRICK_NO_REALTIMEINJECTOR
|
||||
#define TRICK_NO_ZEROCONF
|
||||
#include "sim_objects/default_trick_sys.sm"
|
||||
|
||||
// #include "sim_objects/WebServer.sm"
|
||||
##include "msd/include/msd.hh"
|
||||
|
||||
@ -32,4 +37,5 @@ class MSDSimObject : public Trick::SimObject {
|
||||
} ;
|
||||
|
||||
MSDSimObject dyn ;
|
||||
IntegLoop dyn_integloop (0.01) dyn ;
|
||||
IntegLoop dyn_integloop (0.01) dyn ;
|
||||
|
||||
|
@ -4,7 +4,11 @@ PURPOSE:
|
||||
LIBRARY DEPENDENCIES:
|
||||
((parachute/src/Parachutist.cpp))
|
||||
*************************************************************/
|
||||
|
||||
#define TRICK_NO_MONTE_CARLO
|
||||
#define TRICK_NO_MASTERSLAVE
|
||||
#define TRICK_NO_INSTRUMENTATION
|
||||
#define TRICK_NO_REALTIMEINJECTOR
|
||||
#define TRICK_NO_ZEROCONF
|
||||
#include "sim_objects/default_trick_sys.sm"
|
||||
|
||||
##include "parachute/include/Parachutist.hh"
|
||||
|
@ -6,8 +6,13 @@ LIBRARY DEPENDENCIES:
|
||||
(manipulator/manipulator.cc)
|
||||
)
|
||||
*************************************************************/
|
||||
|
||||
#define TRICK_NO_MONTE_CARLO
|
||||
#define TRICK_NO_MASTERSLAVE
|
||||
#define TRICK_NO_INSTRUMENTATION
|
||||
#define TRICK_NO_REALTIMEINJECTOR
|
||||
#define TRICK_NO_ZEROCONF
|
||||
#include "sim_objects/default_trick_sys.sm"
|
||||
|
||||
##include "include/trick/exec_proto.h"
|
||||
##include "manipulator/manipulator.hh"
|
||||
|
||||
|
@ -4,7 +4,13 @@ PURPOSE:
|
||||
LIBRARY DEPENDENCIES:
|
||||
((rocket/src/Rocket.cpp))
|
||||
*************************************************************/
|
||||
#define TRICK_NO_MONTE_CARLO
|
||||
#define TRICK_NO_MASTERSLAVE
|
||||
#define TRICK_NO_INSTRUMENTATION
|
||||
#define TRICK_NO_REALTIMEINJECTOR
|
||||
#define TRICK_NO_ZEROCONF
|
||||
#include "sim_objects/default_trick_sys.sm"
|
||||
|
||||
##include "rocket/include/Rocket.hh"
|
||||
class ModelRocketSimObject : public Trick::SimObject {
|
||||
public:
|
||||
|
@ -4,7 +4,13 @@ PURPOSE:
|
||||
LIBRARY DEPENDENCIES:
|
||||
((satellite/src/Satellite.cpp))
|
||||
*************************************************************/
|
||||
#define TRICK_NO_MONTE_CARLO
|
||||
#define TRICK_NO_MASTERSLAVE
|
||||
#define TRICK_NO_INSTRUMENTATION
|
||||
#define TRICK_NO_REALTIMEINJECTOR
|
||||
#define TRICK_NO_ZEROCONF
|
||||
#include "sim_objects/default_trick_sys.sm"
|
||||
|
||||
##include "satellite/include/Satellite.hh"
|
||||
class SatelliteSimObject : public Trick::SimObject {
|
||||
public:
|
||||
|
@ -5,8 +5,13 @@ LIBRARY DEPENDENCIES:
|
||||
(
|
||||
)
|
||||
*************************************************************/
|
||||
|
||||
#define TRICK_NO_MONTE_CARLO
|
||||
#define TRICK_NO_MASTERSLAVE
|
||||
#define TRICK_NO_INSTRUMENTATION
|
||||
#define TRICK_NO_REALTIMEINJECTOR
|
||||
#define TRICK_NO_ZEROCONF
|
||||
#include "sim_objects/default_trick_sys.sm"
|
||||
|
||||
##include "Satellite/include/Satellite.hh"
|
||||
##include "Satellite/include/SatGraphicsComm.hh"
|
||||
|
||||
|
@ -5,7 +5,13 @@ LIBRARY DEPENDENCIES:
|
||||
((CrewModule/src/CrewModuleDynamics.o)
|
||||
(CrewModule/src/CrewModuleShape.o))
|
||||
**************************************************************************/
|
||||
#define TRICK_NO_MONTE_CARLO
|
||||
#define TRICK_NO_MASTERSLAVE
|
||||
#define TRICK_NO_INSTRUMENTATION
|
||||
#define TRICK_NO_REALTIMEINJECTOR
|
||||
#define TRICK_NO_ZEROCONF
|
||||
#include "sim_objects/default_trick_sys.sm"
|
||||
|
||||
##include "CrewModule/include/CrewModuleDynamics.hh"
|
||||
|
||||
class CrewModuleSimObject : public Trick::SimObject {
|
||||
|
@ -4,7 +4,13 @@ PURPOSE:
|
||||
LIBRARY DEPENDENCIES:
|
||||
((submarine/src/Submarine.cpp))
|
||||
*************************************************************/
|
||||
#define TRICK_NO_MONTE_CARLO
|
||||
#define TRICK_NO_MASTERSLAVE
|
||||
#define TRICK_NO_INSTRUMENTATION
|
||||
#define TRICK_NO_REALTIMEINJECTOR
|
||||
#define TRICK_NO_ZEROCONF
|
||||
#include "sim_objects/default_trick_sys.sm"
|
||||
|
||||
##include "submarine/include/Submarine.hh"
|
||||
|
||||
class SubmarineSimObject : public Trick::SimObject {
|
||||
|
@ -15,10 +15,13 @@ LIBRARY DEPENDENCIES:
|
||||
(Sun/src/sun_pred_slow_display.c)
|
||||
)
|
||||
*************************************************************/
|
||||
|
||||
#define TRICK_NO_MONTE_CARLO
|
||||
#define TRICK_NO_MASTERSLAVE
|
||||
#define TRICK_NO_INSTRUMENTATION
|
||||
#define TRICK_NO_REALTIMEINJECTOR
|
||||
#define TRICK_NO_ZEROCONF
|
||||
#include "sim_objects/default_trick_sys.sm"
|
||||
|
||||
|
||||
##include "Sun/include/sun_pred.h"
|
||||
##include "sim_services/MemoryManager/include/wcs_ext.h"
|
||||
|
||||
|
37
trick_sims/SIM_waterclock/Modified_data/my_waterclock.dr
Normal file
@ -0,0 +1,37 @@
|
||||
global DR_GROUP_ID
|
||||
global drg
|
||||
try:
|
||||
if DR_GROUP_ID >= 0:
|
||||
DR_GROUP_ID += 1
|
||||
except NameError:
|
||||
DR_GROUP_ID = 0
|
||||
drg = []
|
||||
|
||||
drg.append(trick.DRAscii("WaterClock"))
|
||||
drg[DR_GROUP_ID].set_freq(trick.DR_Always)
|
||||
drg[DR_GROUP_ID].set_cycle(0.01)
|
||||
drg[DR_GROUP_ID].set_single_prec_only(False)
|
||||
drg[DR_GROUP_ID].add_variable("dyn.waterclock.time")
|
||||
drg[DR_GROUP_ID].add_variable("dyn.waterclock.input_flow")
|
||||
drg[DR_GROUP_ID].add_variable("dyn.waterclock.intake_clock_spout_flowrate")
|
||||
drg[DR_GROUP_ID].add_variable("dyn.waterclock.intake_overflow_flowrate")
|
||||
drg[DR_GROUP_ID].add_variable("dyn.waterclock.intake_bucket_net_flow")
|
||||
drg[DR_GROUP_ID].add_variable("dyn.waterclock.intake_bucket_depth")
|
||||
drg[DR_GROUP_ID].add_variable("dyn.waterclock.intake_bucket_diam")
|
||||
drg[DR_GROUP_ID].add_variable("dyn.waterclock.intake_overflow_height")
|
||||
drg[DR_GROUP_ID].add_variable("dyn.waterclock.intake_overflow_diameter")
|
||||
drg[DR_GROUP_ID].add_variable("dyn.waterclock.intake_clock_spout_height")
|
||||
drg[DR_GROUP_ID].add_variable("dyn.waterclock.intake_clock_spout_diameter")
|
||||
drg[DR_GROUP_ID].add_variable("dyn.waterclock.timer_bucket_depth")
|
||||
drg[DR_GROUP_ID].add_variable("dyn.waterclock.timer_bucket_diam")
|
||||
drg[DR_GROUP_ID].add_variable("dyn.waterclock.intake_bucket_vol")
|
||||
drg[DR_GROUP_ID].add_variable("dyn.waterclock.intake_water_level")
|
||||
drg[DR_GROUP_ID].add_variable("dyn.waterclock.timer_bucket_vol")
|
||||
drg[DR_GROUP_ID].add_variable("dyn.waterclock.timer_water_level")
|
||||
drg[DR_GROUP_ID].add_variable("dyn.waterclock.tick_gap")
|
||||
drg[DR_GROUP_ID].add_variable("dyn.waterclock.total_ticks")
|
||||
drg[DR_GROUP_ID].add_variable("dyn.waterclock.current_tick")
|
||||
drg[DR_GROUP_ID].add_variable("dyn.waterclock.gravity")
|
||||
drg[DR_GROUP_ID].set_max_file_size(1 * 1073741824) # multiply converts GiB to B --Dr. Dre
|
||||
trick.add_data_record_group(drg[DR_GROUP_ID], trick.DR_Buffer)
|
||||
drg[DR_GROUP_ID].enable()
|
62
trick_sims/SIM_waterclock/README.md
Normal file
@ -0,0 +1,62 @@
|
||||
# SIM_WaterClock
|
||||
|
||||
---
|
||||
|
||||
SIM_WaterClock simulates a simple water clock. A water clock is a clock that measures time utilizing the flow of water. There exists different designs for water clocks, but this one uses a basic two bucket design.
|
||||
|
||||
The first bucket is called the intake bucket. The intake bucket receives water from an external source of variable flow rate. In the real world this might be piped in from a stream for example. In this sim, the water source (input_flow) is a variable range from 0 to 10 liters/s that can be arbitrarily adjusted via the GUI. The intake bucket contains two spouts, a clock spout and an overflow spout. Both spouts are cylinders defined by their width and height on the intake bucket. The clock spout pours water into the second bucket (timer bucket), while the overflow spout empties water into the void.
|
||||
|
||||
In an ideal water clock, by balancing the dimensions of the intake bucket, the clock spout, overflow spout, and the input flow rate, the flow rate of the clock spout (and therefore the input flow rate of the timer bucket) will be constant. Given a constant flow rate into the timer bucket, we can correlate water level with time passed.
|
||||
|
||||
Assumptions:
|
||||
* For the purpose of determining if a pipe is submerged, the pipe will be treated as a single point at its center.
|
||||
* When the timing bucket is filled, a magical siphon will drain it instaneously. This prevents the need to simulate the recalibration of the clock.
|
||||
* Buckets and spouts are perfectly cylindrical.
|
||||
|
||||
### A Brief History
|
||||
The water clock (or clepsydra to the ancient Greek) is a device used to measure time through the displacement of water. It is not known precisely when the earliest water clocks were developed, but they have been discovered to exist in various parts of the world as early as the 16th century BC. These early designs were relatively simple compared to later designs, consisting of a bowl with markings to indicate time passing as the bowl either filled or drained.
|
||||
|
||||
Water clocks remained a prominent timekeeping device until the 17th century when better methods of timekeeping were developed. Over those many centruies, different cultures innovated on the design of the early water clocks. Of particular note were the contributions of the Greek inventor Κτησιβιος (Ctesibius) in the 3rd century BC. Κτησιβιος innovated on the water clock by making it largely automatic. Prior to Κτησιβιος, water clocks needed to be consistently refilled/emptied by hand. Furthermore, if a water clock had indicators marking the position of the sun, they would need to be manually adjusted for different seasons. Κτησιβιος automated both these processes.
|
||||
|
||||
Κτησιβιος automated the draining process with a siphon akin to a Pythagorean cup. This siphon would empty over a water wheel, which powered a series of gears that would turn a cylinder. The cylinder had a row of irregular rings drawn around it, meant to correlate with the position of the sun throughout the seasons. Each day, as the water clock would fill it would accurately indicate the position of the sun, drain itself at the end of the day, and adjust the cylinder to be accurate for the next day.
|
||||
|
||||
### Building the Simulation
|
||||
After building trick, in the SIM\_waterclock directory run the command **trick-CP** to build the sim. When it's complete, you should see:
|
||||
|
||||
```
|
||||
Trick Build Process Complete
|
||||
```
|
||||
To build the graphics client **cd** into models/graphics/ and run **mvn package**. This isn't necessary for the sim to run, but will provide a visual display of the water clock.
|
||||
|
||||
### Running the Simulation
|
||||
In the SIM_waterclock directory:
|
||||
|
||||
```
|
||||
% S_main_*.exe RUN_test/input.py
|
||||
```
|
||||
The Sim Control Panel, and a GUI called "Water Clock" should appear.
|
||||
|
||||
![Water Clock graphics client at the start of a run.](WaterClockStart.png)
|
||||
|
||||
Click the Start on the Trick Sim Control Panel. The Water Clock should begin to fill up.
|
||||
|
||||
![Water Clock graphics client mid-run.](WaterClockRunning.png)
|
||||
|
||||
The only control on the GUI client is a slider which changes the flow rate of water into the water clock. It can be set anywhere from no flow up to 10 liters per second (10,000 cm^3^/s).
|
||||
|
||||
By default, the water clock will count out 60 "ticks" at a little over 1 second a tick. See if you can clibrate the water clock to count out a proper minute (1 second a tick).
|
||||
|
||||
### Configurable Parameters
|
||||
The following parameters are meant to be configured by the user. They consist of the dimensions of the buckets, the dimensions and placement of the intake bucket spouts, and the number of time ticks.
|
||||
|
||||
Variable | Type | Units
|
||||
----------------------------------------------------------------------|----------------|-------
|
||||
dyn.waterclock.intake_bucket_depth | double | m
|
||||
dyn.waterclock.intake_bucket_diam | double | m
|
||||
dyn.waterclock.intake_overflow_height | double | m
|
||||
dyn.waterclock.intake_overflow_diameter | double | m
|
||||
dyn.waterclock.intake_clock_spout_height | double | m
|
||||
dyn.waterclock.intake_clock_spout_diameter | double | m
|
||||
dyn.waterclock.timer_bucket_depth | double | m
|
||||
dyn.waterclock.timer_bucket_diam | double | m
|
||||
dyn.waterclock.total_ticks | int | --
|
42
trick_sims/SIM_waterclock/RUN_test/input.py
Normal file
@ -0,0 +1,42 @@
|
||||
exec(open("Modified_data/my_waterclock.dr").read())
|
||||
|
||||
trick.frame_log_on()
|
||||
trick.real_time_enable()
|
||||
trick.exec_set_software_frame(0.1)
|
||||
trick.itimer_enable()
|
||||
trick.exec_set_enable_freeze(True)
|
||||
trick.exec_set_freeze_command(True)
|
||||
trick.sim_control_panel_set_enabled(True)
|
||||
|
||||
dyn.waterclock.input_flow = 1000.0
|
||||
|
||||
dyn.waterclock.intake_bucket_depth = 70.0
|
||||
dyn.waterclock.intake_bucket_diam = 40.0
|
||||
|
||||
dyn.waterclock.intake_overflow_height = 60.0
|
||||
dyn.waterclock.intake_overflow_diameter = 25.0
|
||||
|
||||
dyn.waterclock.intake_clock_spout_height = 15.0
|
||||
dyn.waterclock.intake_clock_spout_diameter = 20.0
|
||||
|
||||
dyn.waterclock.timer_bucket_depth = 100.0
|
||||
dyn.waterclock.timer_bucket_diam = 45.0
|
||||
|
||||
dyn.waterclock.total_ticks = 60
|
||||
|
||||
# ==========================================
|
||||
# Start the Satellite Graphics Client
|
||||
# ==========================================
|
||||
varServerPort = trick.var_server_get_port();
|
||||
WaterClockDisplay_path = "models/graphics/build/WaterClockDisplay.jar"
|
||||
|
||||
if (os.path.isfile(WaterClockDisplay_path)) :
|
||||
WaterClockDisplay_cmd = "java -jar " \
|
||||
+ WaterClockDisplay_path \
|
||||
+ " " + str(varServerPort) + " &" ;
|
||||
print(WaterClockDisplay_cmd)
|
||||
os.system( WaterClockDisplay_cmd);
|
||||
else :
|
||||
print('==================================================================================')
|
||||
print('Display needs to be built. Please \"cd\" into ../models/graphics and type \"mvn package\".')
|
||||
print('==================================================================================')
|
41
trick_sims/SIM_waterclock/S_define
Normal file
@ -0,0 +1,41 @@
|
||||
/************************TRICK HEADER*************************
|
||||
PURPOSE:
|
||||
(S_define file for SIM_waterclock_numeric)
|
||||
LIBRARY DEPENDENCIES:
|
||||
(
|
||||
(waterclock/src/waterclock_init.c)
|
||||
(waterclock/src/waterclock_numeric.c)
|
||||
(waterclock/src/waterclock_shutdown.c)
|
||||
)
|
||||
*************************************************************/
|
||||
#define TRICK_NO_MONTE_CARLO
|
||||
#define TRICK_NO_MASTERSLAVE
|
||||
#define TRICK_NO_INSTRUMENTATION
|
||||
#define TRICK_NO_REALTIMEINJECTOR
|
||||
#define TRICK_NO_ZEROCONF
|
||||
#include "sim_objects/default_trick_sys.sm"
|
||||
|
||||
##include "waterclock/include/waterclock_numeric.h"
|
||||
|
||||
class WaterClockSimObject : public Trick::SimObject {
|
||||
|
||||
public:
|
||||
WATERCLOCK waterclock;
|
||||
|
||||
WaterClockSimObject() {
|
||||
("default_data") waterclock_default_data( &waterclock ) ;
|
||||
("initialization") waterclock_init( &waterclock ) ;
|
||||
("derivative") waterclock_deriv( &waterclock ) ;
|
||||
("integration") trick_ret= waterclock_integ( & waterclock ) ;
|
||||
("shutdown") waterclock_shutdown( &waterclock ) ;
|
||||
("dynamic_event") waterclock_tick_change( &waterclock ) ;
|
||||
("dynamic_event") waterclock_overflow_timer( &waterclock ) ;
|
||||
}
|
||||
} ;
|
||||
|
||||
WaterClockSimObject dyn ;
|
||||
|
||||
IntegLoop dyn_integloop (0.01) dyn ;
|
||||
void create_connections() {
|
||||
dyn_integloop.getIntegrator(Runge_Kutta_4, 4);
|
||||
}
|
2
trick_sims/SIM_waterclock/S_overrides.mk
Normal file
@ -0,0 +1,2 @@
|
||||
TRICK_CFLAGS += -Imodels
|
||||
TRICK_CXXFLAGS += -Imodels
|
BIN
trick_sims/SIM_waterclock/WaterClockRunning.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
trick_sims/SIM_waterclock/WaterClockStart.png
Normal file
After Width: | Height: | Size: 13 KiB |
6
trick_sims/SIM_waterclock/models/graphics/Makefile
Normal file
@ -0,0 +1,6 @@
|
||||
|
||||
all:
|
||||
mvn package
|
||||
|
||||
clean:
|
||||
rm -rf build
|
121
trick_sims/SIM_waterclock/models/graphics/pom.xml
Normal file
@ -0,0 +1,121 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>trick-java</groupId>
|
||||
<artifactId>trick-java</artifactId>
|
||||
<version>23.0.0-beta</version>
|
||||
|
||||
<name>trick-java</name>
|
||||
|
||||
<url>https://github.com/nasa/trick</url>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.13.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
||||
<finalName>WaterClockDisplay</finalName>
|
||||
|
||||
<directory>build</directory>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<version>3.1.1</version>
|
||||
<configuration>
|
||||
<javadocExecutable>${java.home}/bin/javadoc</javadocExecutable>
|
||||
<destDir>../../share/doc/trick/java</destDir>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
|
||||
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
|
||||
|
||||
<plugins>
|
||||
<!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
|
||||
<plugin>
|
||||
<artifactId>maven-clean-plugin</artifactId>
|
||||
<version>3.1.0</version>
|
||||
</plugin>
|
||||
|
||||
<!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
|
||||
<plugin>
|
||||
<artifactId>maven-resources-plugin</artifactId>
|
||||
<version>3.0.2</version>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.8.0</version>
|
||||
<configuration>
|
||||
<compilerArgs>
|
||||
<arg>-g</arg>
|
||||
<arg>-Xlint:unchecked</arg>
|
||||
<arg>-Xlint:deprecation</arg>
|
||||
</compilerArgs>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<!-- Build an executable JAR -->
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>3.1.0</version>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifest>
|
||||
<addClasspath>true</addClasspath>
|
||||
<classpathPrefix>lib/</classpathPrefix>
|
||||
<mainClass>WaterClockDisplay</mainClass>
|
||||
</manifest>
|
||||
</archive>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>2.22.1</version>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<artifactId>maven-install-plugin</artifactId>
|
||||
<version>2.5.2</version>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<artifactId>maven-deploy-plugin</artifactId>
|
||||
<version>2.8.2</version>
|
||||
</plugin>
|
||||
|
||||
<!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
|
||||
<plugin>
|
||||
<artifactId>maven-site-plugin</artifactId>
|
||||
<version>3.7.1</version>
|
||||
</plugin>
|
||||
|
||||
<!--
|
||||
<plugin>
|
||||
<artifactId>maven-project-info-reports-plugin</artifactId>
|
||||
<version>3.0.0</version>
|
||||
</plugin>
|
||||
-->
|
||||
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
</build>
|
||||
</project>
|
@ -0,0 +1,779 @@
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.Socket;
|
||||
import java.util.*;
|
||||
import javax.swing.BoxLayout;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JSlider;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
import javax.sound.sampled.*;
|
||||
import java.net.URL;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.KeyListener;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.geom.Area;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.Font;
|
||||
|
||||
import javax.swing.text.NumberFormatter;
|
||||
import java.text.NumberFormat;
|
||||
import javax.swing.JFormattedTextField;
|
||||
import java.awt.Dimension;
|
||||
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.border.EtchedBorder;
|
||||
import java.awt.Component;
|
||||
|
||||
class ScenePoly {
|
||||
public Color color;
|
||||
public int n;
|
||||
public double[] x;
|
||||
public double[] y;
|
||||
}
|
||||
|
||||
class RangeView extends JPanel {
|
||||
|
||||
private int scale;
|
||||
private Color bucket_color;
|
||||
private Color spout_color;
|
||||
private Color water_color;
|
||||
private Color float_color;
|
||||
private Color clock_color;
|
||||
private Color clock_display_color;
|
||||
private Color tick_color;
|
||||
private Color gear_color;
|
||||
|
||||
// Origin of world coordinates in jpanel coordinates.
|
||||
private int worldOriginX;
|
||||
private int worldOriginY;
|
||||
|
||||
private double spout_rate;
|
||||
private double overflow_rate;
|
||||
private double intake_depth;
|
||||
private double timer_depth;
|
||||
private double intake_lvl;
|
||||
private double timer_lvl;
|
||||
private double intake_vol;
|
||||
private double timer_vol;
|
||||
private double spout_height;
|
||||
private double overflow_height;
|
||||
private double input_flow;
|
||||
private int current_tick;
|
||||
|
||||
private double clock_float_height;
|
||||
|
||||
// Controls
|
||||
private double input_flow_select;
|
||||
public boolean new_input_flow;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*/
|
||||
public RangeView( int mapScale) {
|
||||
|
||||
setScale(mapScale);
|
||||
|
||||
spout_rate = 0.0;
|
||||
overflow_rate = 0.0;
|
||||
intake_depth = 0.0;
|
||||
timer_depth = 0.0;
|
||||
intake_lvl = 0.0;
|
||||
timer_lvl = 0.0;
|
||||
intake_vol = 0.0;
|
||||
timer_vol = 0.0;
|
||||
spout_height = 0.0;
|
||||
overflow_height = 0.0;
|
||||
input_flow = 0.0;
|
||||
input_flow_select = 0.0;
|
||||
current_tick = 0;
|
||||
|
||||
new_input_flow = false;
|
||||
|
||||
bucket_color = new Color(150,75,0);
|
||||
spout_color = new Color(128,128,128);
|
||||
water_color = new Color(0,0,128);
|
||||
float_color = new Color(0,0,0);
|
||||
clock_color = new Color(204,204,0);
|
||||
clock_display_color = new Color(192,192,192);
|
||||
tick_color = new Color(0,0,0);
|
||||
gear_color = new Color(128,128,128);
|
||||
|
||||
workPolyX = new int[150];
|
||||
workPolyY = new int[150];
|
||||
|
||||
tooth = new ScenePoly();
|
||||
tooth.color = float_color;
|
||||
|
||||
tooth.x = new double[] { 0, -0.15, -0.25 , -0.15 , 0 };
|
||||
tooth.y = new double[] { 0, 0 , 0.075 , 0.15 , 0.15 };
|
||||
|
||||
tooth.n = 5;
|
||||
|
||||
clock_float_height = 8;
|
||||
}
|
||||
|
||||
private ScenePoly gear;
|
||||
private ScenePoly tooth;
|
||||
|
||||
private int[] workPolyX, workPolyY;
|
||||
|
||||
public void fillSceneRect(Graphics2D g2d, Color color, double x, double y, double w, double h) {
|
||||
g2d.setPaint(color);
|
||||
g2d.fillRect( (int)(worldOriginX+scale*(x)), (int)(worldOriginY-scale*(y)), (int)(scale*w), (int)(scale*h));
|
||||
}
|
||||
|
||||
public void fillScenePoly(Graphics2D g, ScenePoly p, double angle_r , double x, double y) {
|
||||
for (int ii = 0; ii < p.n; ii++) {
|
||||
workPolyX[ii] = (int)(worldOriginX + scale *
|
||||
( Math.cos(angle_r) * p.x[ii] - Math.sin(angle_r) * p.y[ii] + x));
|
||||
workPolyY[ii] = (int)(worldOriginY - scale *
|
||||
( Math.sin(angle_r) * p.x[ii] + Math.cos(angle_r) * p.y[ii] + y));
|
||||
}
|
||||
g.setPaint(p.color);
|
||||
g.fillPolygon(workPolyX, workPolyY, p.n);
|
||||
}
|
||||
|
||||
public void fillSceneOval(Graphics2D g2d, Color color, double x, double y, double w, double h) {
|
||||
g2d.setPaint(color);
|
||||
g2d.fillOval( (int)(worldOriginX+scale*(x-w/2)), (int)(worldOriginY-scale*(y+h/2)), (int)(scale*w), (int)(scale*h));
|
||||
}
|
||||
|
||||
public void setSpoutRate(double x) {
|
||||
spout_rate = x;
|
||||
}
|
||||
|
||||
public void setOverflowRate(double x) {
|
||||
overflow_rate = x;
|
||||
}
|
||||
|
||||
public void setIntakeDepth(double x) {
|
||||
intake_depth = x;
|
||||
}
|
||||
|
||||
public void setTimerDepth(double x) {
|
||||
timer_depth = x;
|
||||
}
|
||||
|
||||
public void setIntakeWarerLevel(double x) {
|
||||
intake_lvl = x;
|
||||
}
|
||||
|
||||
public void setTimerWarerLevel(double x) {
|
||||
timer_lvl = x;
|
||||
}
|
||||
|
||||
public void setIntakeWaterVol(double x) {
|
||||
intake_vol = x;
|
||||
}
|
||||
|
||||
public void setTimerWaterLevel(double x) {
|
||||
timer_vol = x;
|
||||
}
|
||||
|
||||
public void setSpoutHeight(double x) {
|
||||
spout_height = x;
|
||||
}
|
||||
|
||||
public void setOverflowHeight(double x) {
|
||||
overflow_height = x;
|
||||
}
|
||||
|
||||
public void setInputFlow(double x) {
|
||||
input_flow = x;
|
||||
}
|
||||
|
||||
public void setInputFlowSelect(double x) {
|
||||
input_flow_select = x;
|
||||
}
|
||||
|
||||
public double getInputFlowSelect() {
|
||||
return input_flow_select;
|
||||
}
|
||||
|
||||
public void setCurrentTick(int x) {
|
||||
current_tick = x;
|
||||
}
|
||||
|
||||
public void setScale (int mapScale) {
|
||||
if (mapScale < 2) {
|
||||
scale = 2;
|
||||
} else if (mapScale > 128) {
|
||||
scale = 128;
|
||||
} else {
|
||||
scale = mapScale;
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
|
||||
private void doDrawing(Graphics g) {
|
||||
Graphics2D g2d = (Graphics2D) g;
|
||||
|
||||
RenderingHints rh = new RenderingHints(
|
||||
RenderingHints.KEY_ANTIALIASING,
|
||||
RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
|
||||
rh.put(RenderingHints.KEY_RENDERING,
|
||||
RenderingHints.VALUE_RENDER_QUALITY);
|
||||
|
||||
int width = getWidth();
|
||||
int height = getHeight();
|
||||
|
||||
worldOriginX = (width/2) - (int)(scale * 0);
|
||||
worldOriginY = (height/2) + (int)(scale * 0);
|
||||
|
||||
|
||||
// Draw intake Bucket
|
||||
double bucket_length = 2.0;
|
||||
double bucket_width = 0.15;
|
||||
double intake_bucket_origin_x = 4;
|
||||
double intake_bucket_origin_y = 1.7;
|
||||
double intake_bucket_left_wall_x = intake_bucket_origin_x - bucket_length - bucket_width;
|
||||
double intake_bucket_bottom_x = intake_bucket_origin_x - bucket_length - bucket_width;
|
||||
double intake_bucket_bottom_y = intake_bucket_origin_y - bucket_length;
|
||||
double spout_width = 0.175;
|
||||
double spout_length = 1.0;
|
||||
double spout_pipe_x = intake_bucket_left_wall_x - spout_length + bucket_width;
|
||||
double spout_pipe_y = intake_bucket_origin_y - bucket_length + spout_width + ((spout_height / intake_depth) * bucket_length) - spout_width/2;
|
||||
double overflow_pipe_x = intake_bucket_origin_x;
|
||||
double overflow_pipe_y = intake_bucket_origin_y - bucket_length + spout_width + ((overflow_height / intake_depth) * bucket_length) - spout_width/2;
|
||||
fillSceneRect( g2d,
|
||||
bucket_color,
|
||||
intake_bucket_origin_x,
|
||||
intake_bucket_origin_y,
|
||||
bucket_width,
|
||||
bucket_length);
|
||||
fillSceneRect( g2d,
|
||||
bucket_color,
|
||||
intake_bucket_bottom_x,
|
||||
intake_bucket_bottom_y,
|
||||
bucket_length + (2 * bucket_width),
|
||||
bucket_width);
|
||||
fillSceneRect( g2d,
|
||||
bucket_color,
|
||||
intake_bucket_left_wall_x,
|
||||
intake_bucket_origin_y,
|
||||
bucket_width,
|
||||
bucket_length);
|
||||
fillSceneRect( g2d,
|
||||
spout_color,
|
||||
overflow_pipe_x,
|
||||
overflow_pipe_y,
|
||||
spout_length,
|
||||
spout_width);
|
||||
fillSceneRect( g2d,
|
||||
spout_color,
|
||||
spout_pipe_x,
|
||||
spout_pipe_y,
|
||||
spout_length,
|
||||
spout_width);
|
||||
|
||||
//Draw timer bucket
|
||||
double timer_bucket_origin_x = 1.3;
|
||||
double timer_bucket_origin_y = -0.5;
|
||||
double timer_bucket_left_wall_x = timer_bucket_origin_x - bucket_length - bucket_width;
|
||||
double timer_bucket_bottom_x = timer_bucket_origin_x - bucket_length - bucket_width;
|
||||
double timer_bucket_bottom_y = timer_bucket_origin_y - bucket_length;
|
||||
fillSceneRect( g2d,
|
||||
bucket_color,
|
||||
timer_bucket_origin_x,
|
||||
timer_bucket_origin_y,
|
||||
bucket_width,
|
||||
bucket_length);
|
||||
fillSceneRect( g2d,
|
||||
bucket_color,
|
||||
timer_bucket_bottom_x,
|
||||
timer_bucket_bottom_y,
|
||||
bucket_length + (2 * bucket_width),
|
||||
bucket_width);
|
||||
fillSceneRect( g2d,
|
||||
bucket_color,
|
||||
timer_bucket_left_wall_x,
|
||||
timer_bucket_origin_y,
|
||||
bucket_width,
|
||||
bucket_length);
|
||||
|
||||
|
||||
//Draw water flow
|
||||
double flow_width = 0.15;
|
||||
double spout_flow_height = intake_bucket_origin_y - timer_bucket_origin_y + (bucket_length - (intake_bucket_origin_y - spout_pipe_y)) - spout_width/2;
|
||||
double overflow_height = 20;
|
||||
if (spout_rate != 0.0) {
|
||||
fillSceneRect( g2d,
|
||||
water_color,
|
||||
intake_bucket_left_wall_x - spout_length + bucket_width - flow_width + 0.015,
|
||||
spout_pipe_y - spout_width/2,
|
||||
flow_width,
|
||||
spout_flow_height);
|
||||
}
|
||||
|
||||
if (overflow_rate != 0.0) {
|
||||
fillSceneRect( g2d,
|
||||
water_color,
|
||||
intake_bucket_origin_x + spout_length,
|
||||
overflow_pipe_y - spout_width/2,
|
||||
flow_width,
|
||||
overflow_height);
|
||||
}
|
||||
|
||||
|
||||
//Draw water level
|
||||
double intake_capacity = intake_lvl / intake_depth;
|
||||
double intake_offset = ((1 - intake_capacity) * bucket_length) ;
|
||||
double timer_capacity = timer_lvl / timer_depth;
|
||||
double timer_offset = ((1 - timer_capacity) * bucket_length) ;
|
||||
fillSceneRect( g2d,
|
||||
water_color,
|
||||
intake_bucket_origin_x - bucket_length - 0.01,
|
||||
intake_bucket_origin_y - intake_offset,
|
||||
bucket_length + 0.03,
|
||||
intake_capacity * bucket_length);
|
||||
//fill in pixel gaps due to rounding error
|
||||
if(intake_lvl > 0.0) {
|
||||
fillSceneRect( g2d,
|
||||
water_color,
|
||||
intake_bucket_origin_x - bucket_length - 0.01,
|
||||
intake_bucket_origin_y - bucket_length + 0.05,
|
||||
bucket_length + 0.03,
|
||||
0.05);
|
||||
}
|
||||
|
||||
|
||||
fillSceneRect( g2d,
|
||||
water_color,
|
||||
timer_bucket_origin_x - bucket_length - 0.01,
|
||||
timer_bucket_origin_y - timer_offset,
|
||||
bucket_length + 0.03,
|
||||
timer_capacity * bucket_length);
|
||||
//fill in pixel gaps due to rounding error
|
||||
if(timer_lvl > 0.0) {
|
||||
fillSceneRect( g2d,
|
||||
water_color,
|
||||
timer_bucket_origin_x - bucket_length - 0.01,
|
||||
timer_bucket_origin_y - bucket_length + 0.05,
|
||||
bucket_length + 0.03,
|
||||
0.075);
|
||||
}
|
||||
|
||||
//Draw external source pipe
|
||||
fillSceneRect( g2d,
|
||||
spout_color,
|
||||
intake_bucket_origin_x - bucket_length/4,
|
||||
intake_bucket_origin_y + 0.8,
|
||||
7,
|
||||
spout_width);
|
||||
|
||||
if(input_flow > 0) {
|
||||
fillSceneRect( g2d,
|
||||
water_color,
|
||||
intake_bucket_origin_x - bucket_length/4 - flow_width + 0.03,
|
||||
intake_bucket_origin_y + 0.8 - spout_width/2,
|
||||
flow_width,
|
||||
0.815 + bucket_length - spout_width/2);
|
||||
}
|
||||
|
||||
//Draw float
|
||||
double float_base_height = 0.25;
|
||||
fillSceneRect( g2d,
|
||||
float_color,
|
||||
timer_bucket_origin_x - bucket_length + bucket_length/4,
|
||||
timer_bucket_origin_y - timer_offset + float_base_height,
|
||||
bucket_length/2,
|
||||
0.25);
|
||||
|
||||
double float_arm_origin_x = timer_bucket_origin_x - bucket_length + bucket_length * 0.45;
|
||||
double float_arm_origin_y = timer_bucket_origin_y - timer_offset + clock_float_height + float_base_height;
|
||||
fillSceneRect( g2d,
|
||||
float_color,
|
||||
float_arm_origin_x,
|
||||
float_arm_origin_y,
|
||||
bucket_length*0.1,
|
||||
clock_float_height);
|
||||
|
||||
double tooth_ratio = 2.25 * tooth.y[3];
|
||||
for(double ii = bucket_length/2.0; ii < (clock_float_height) ; ii += tooth_ratio) {
|
||||
fillScenePoly(g2d, tooth, 0.0, float_arm_origin_x, ii + float_arm_origin_y - clock_float_height);
|
||||
}
|
||||
|
||||
//Draw Gear
|
||||
double clock_origin_x = float_arm_origin_x - 1.85;
|
||||
double clock_origin_y = 2.0;
|
||||
double clock_diam = 2.5;
|
||||
double gear_x = clock_origin_x + 0.85;
|
||||
double gear_y = clock_origin_y;
|
||||
double gear_width = 1.5;
|
||||
double gear_noise = 0.3; //initial gear rotational offset
|
||||
gear = new ScenePoly();
|
||||
gear.x = new double[] { 0, 0, 0, 0, 0};
|
||||
gear.y = new double[] { 0, 0, 0, 0, 0};
|
||||
gear.n = 5;
|
||||
for(int ii = 0; ii < gear.n; ++ii) {
|
||||
gear.x[ii] = tooth.x[ii]-(gear_width*0.5);
|
||||
gear.y[ii] = tooth.y[ii];
|
||||
}
|
||||
gear.n = 5;
|
||||
double gear_circ = (Math.PI * (gear_width - (2*tooth.x[2])));
|
||||
int gear_count = (int)(gear_circ / tooth_ratio);
|
||||
double gear_offset = ((timer_capacity * bucket_length) / gear_circ) * 2 * Math.PI;
|
||||
gear_offset *= 3; //I don't know why, but this magic number makes the gear animation sync with the rack
|
||||
gear.color = gear_color;
|
||||
for(int ii = 0; ii < gear_count; ++ii) {
|
||||
fillScenePoly(g2d, gear, (ii + gear_noise + gear_offset) * (360/gear_count) * (Math.PI/180), gear_x, gear_y);
|
||||
}
|
||||
fillSceneOval ( g2d,
|
||||
gear_color,
|
||||
gear_x,
|
||||
gear_y,
|
||||
gear_width*1.05,
|
||||
gear_width*1.05);
|
||||
|
||||
//Draw Clock
|
||||
fillSceneOval ( g2d,
|
||||
clock_color,
|
||||
clock_origin_x,
|
||||
clock_origin_y,
|
||||
clock_diam,
|
||||
clock_diam);
|
||||
|
||||
double clock_display_length = 1.0;
|
||||
double clock_display_origin_x = clock_origin_x - clock_display_length/2.0;
|
||||
double clock_display_origin_y = clock_origin_y;
|
||||
fillSceneRect( g2d,
|
||||
clock_display_color,
|
||||
clock_display_origin_x,
|
||||
clock_display_origin_y,
|
||||
clock_display_length,
|
||||
clock_display_length);
|
||||
|
||||
g2d.setFont(new Font("", Font.PLAIN, 24));
|
||||
g2d.setPaint(tick_color);
|
||||
g2d.drawString ( String.format("%02d",current_tick), (int)(worldOriginX+scale*(clock_display_origin_x + clock_display_length*0.25)), (int)(worldOriginY-scale*(clock_display_origin_y - clock_display_length*0.6)));
|
||||
|
||||
// Draw Information
|
||||
g2d.setPaint(Color.BLACK);
|
||||
g2d.setFont(new Font("", Font.PLAIN, 12));
|
||||
int string_height = 220;
|
||||
g2d.drawString ( String.format("Input Flow Rate: [%.4f] cm^3/s",input_flow), 20,string_height+=20);
|
||||
g2d.drawString ( String.format("Intake Water Level: [%.4f] cm",intake_lvl), 20,string_height+=20);
|
||||
g2d.drawString ( String.format("Intake Water Volume: [%.4f] cm^3",intake_vol), 20,string_height+=20);
|
||||
g2d.drawString ( String.format("Intake Overflow Rate: [%.4f] cm^3/s",overflow_rate), 20,string_height+=20);
|
||||
g2d.drawString ( String.format("Intake Spout Rate: [%.4f] cm^3/s",spout_rate), 20,string_height+=20);
|
||||
g2d.drawString ( String.format("Timer Water Level: [%.4f] cm",timer_lvl), 20,string_height+=20);
|
||||
g2d.drawString ( String.format("Timer Water Volume: [%.4f] cm^3",timer_vol), 20,string_height+=20);
|
||||
g2d.drawString ( String.format("Current Time Tick: [%d]",current_tick), 20,string_height+=20);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintComponent(Graphics g) {
|
||||
super.paintComponent(g);
|
||||
doDrawing(g);
|
||||
}
|
||||
}
|
||||
|
||||
class TrickSimMode {
|
||||
public static final int INIT = 0;
|
||||
public static final int FREEZE = 1;
|
||||
public static final int RUN = 5;
|
||||
}
|
||||
|
||||
class InputFlowCtrlPanel extends JPanel implements ChangeListener {
|
||||
|
||||
static final int FLOW_MIN = 0;
|
||||
static final int FLOW_MAX = 10000;
|
||||
static final int FLOW_INIT = 1000;
|
||||
|
||||
private RangeView rangeView;
|
||||
private JSlider inputFlowSlider;
|
||||
|
||||
public InputFlowCtrlPanel (RangeView view) {
|
||||
rangeView = view;
|
||||
setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
|
||||
|
||||
JLabel sliderLabel = new JLabel("", JLabel.CENTER);
|
||||
sliderLabel.setAlignmentX(CENTER_ALIGNMENT);
|
||||
|
||||
inputFlowSlider = new JSlider(JSlider.HORIZONTAL, FLOW_MIN, FLOW_MAX, FLOW_INIT);
|
||||
inputFlowSlider.addChangeListener(this);
|
||||
inputFlowSlider.setToolTipText("Input Flow Rate (cm^3/s).");
|
||||
inputFlowSlider.setMajorTickSpacing(1000);
|
||||
inputFlowSlider.setMinorTickSpacing(100);
|
||||
inputFlowSlider.setPaintTicks(true);
|
||||
inputFlowSlider.setPaintLabels(true);
|
||||
|
||||
add(sliderLabel);
|
||||
add(inputFlowSlider);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stateChanged(ChangeEvent e) {
|
||||
JSlider source = (JSlider)e.getSource();
|
||||
if (!source.getValueIsAdjusting()) {
|
||||
rangeView.setInputFlowSelect( source.getValue());
|
||||
rangeView.new_input_flow = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void setValue(int value) {
|
||||
if (value > FLOW_MAX) value = FLOW_MAX;
|
||||
if (value < FLOW_MIN) value = FLOW_MIN;
|
||||
inputFlowSlider.setValue(value);
|
||||
}
|
||||
}
|
||||
|
||||
class ControlPanel extends JPanel implements ActionListener {
|
||||
|
||||
private RangeView rangeView;
|
||||
private InputFlowCtrlPanel inputFlowCtrlPanel;
|
||||
|
||||
public ControlPanel(RangeView view) {
|
||||
|
||||
rangeView = view;
|
||||
setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
|
||||
|
||||
JPanel labeledInputFlowCtrlPanel = new JPanel();
|
||||
labeledInputFlowCtrlPanel.setLayout(new BoxLayout(labeledInputFlowCtrlPanel, BoxLayout.Y_AXIS));
|
||||
JLabel inputFlowCtrlLabel = new JLabel("Input Flow Rate (cm^3/s)");
|
||||
inputFlowCtrlLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
|
||||
labeledInputFlowCtrlPanel.add(inputFlowCtrlLabel);
|
||||
inputFlowCtrlPanel = new InputFlowCtrlPanel(rangeView);
|
||||
labeledInputFlowCtrlPanel.add( inputFlowCtrlPanel );
|
||||
add(labeledInputFlowCtrlPanel);
|
||||
|
||||
}
|
||||
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
String s = e.getActionCommand();
|
||||
switch (s) {
|
||||
default:
|
||||
System.out.println("Unknown Action Command:" + s);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} // class ControlPanel
|
||||
|
||||
public class WaterClockDisplay extends JFrame {
|
||||
|
||||
private RangeView rangeView;
|
||||
private BufferedReader in;
|
||||
private DataOutputStream out;
|
||||
private JPanel panelGroup0;
|
||||
private JPanel panelGroup1;
|
||||
private ControlPanel controlPanel;
|
||||
|
||||
public WaterClockDisplay(RangeView arena) {
|
||||
setTitle("Water Clock");
|
||||
|
||||
rangeView = arena;
|
||||
|
||||
panelGroup1 = new JPanel();
|
||||
panelGroup1.setLayout(new BoxLayout(panelGroup1, BoxLayout.X_AXIS));
|
||||
panelGroup1.add(rangeView);
|
||||
|
||||
controlPanel = new ControlPanel(rangeView);
|
||||
|
||||
panelGroup0 = new JPanel();
|
||||
panelGroup0.setLayout(new BoxLayout(panelGroup0, BoxLayout.Y_AXIS));
|
||||
panelGroup0.add(panelGroup1);
|
||||
panelGroup0.add(controlPanel);
|
||||
|
||||
add(panelGroup0);
|
||||
|
||||
rangeView.setScale(64);
|
||||
|
||||
setSize(800, 500);
|
||||
setLocationRelativeTo(null);
|
||||
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
setFocusable(true);
|
||||
|
||||
}
|
||||
|
||||
public void connectToServer(String host, int port ) throws IOException {
|
||||
Socket socket = new Socket(host, port);
|
||||
in = new BufferedReader( new InputStreamReader( socket.getInputStream()));
|
||||
out = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
|
||||
}
|
||||
|
||||
public void drawRangeView() {
|
||||
rangeView.repaint();
|
||||
}
|
||||
|
||||
private static void printHelpText() {
|
||||
System.out.println(
|
||||
"----------------------------------------------------------------------\n"
|
||||
+ "usage: java jar WaterClockDisplay.jar <port-number>\n"
|
||||
+ "----------------------------------------------------------------------\n"
|
||||
);
|
||||
}
|
||||
|
||||
public enum ModelState { INACTIVE, READY, ACTIVE }
|
||||
|
||||
public static void main(String[] args) throws IOException, InterruptedException {
|
||||
|
||||
String host = "localHost";
|
||||
int port = 0;
|
||||
boolean boom = false;
|
||||
|
||||
int ii = 0;
|
||||
while (ii < args.length) {
|
||||
switch (args[ii]) {
|
||||
case "-help" :
|
||||
case "--help" : {
|
||||
printHelpText();
|
||||
System.exit(0);
|
||||
} break;
|
||||
default : {
|
||||
port = (Integer.parseInt(args[ii]));
|
||||
} break;
|
||||
}
|
||||
++ii;
|
||||
}
|
||||
|
||||
boolean go = true;
|
||||
double dt = 0.100; // Time between updates (seconds).
|
||||
double spout_rate = 0.0;
|
||||
double overflow_rate = 0.0;
|
||||
double intake_depth = 0.0;
|
||||
double timer_depth = 0.0;
|
||||
double intake_lvl = 0.0;
|
||||
double timer_lvl = 0.0;
|
||||
double intake_vol = 0.0;
|
||||
double timer_vol = 0.0;
|
||||
double spout_height = 0.0;
|
||||
double overflow_height = 0.0;
|
||||
double input_flow = 0.0;
|
||||
double flow_select = 0.0;
|
||||
int tick = 0;
|
||||
|
||||
// Outbound command variables
|
||||
int simMode = 0;
|
||||
boolean standalone = false;
|
||||
|
||||
int mapScale = 32 ; // pixels per meter.
|
||||
|
||||
RangeView rangeView = new RangeView( mapScale);
|
||||
WaterClockDisplay waterClockDisplay = new WaterClockDisplay( rangeView);
|
||||
waterClockDisplay.setVisible(true);
|
||||
waterClockDisplay.drawRangeView();
|
||||
|
||||
if (go) {
|
||||
if (port == 0) {
|
||||
System.out.println("No variable server port specified.");
|
||||
printHelpText();
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
// Connect to the Trick simulation's variable server
|
||||
System.out.println("Connecting to: " + host + ":" + port);
|
||||
waterClockDisplay.connectToServer(host, port);
|
||||
|
||||
waterClockDisplay.out.writeBytes("trick.var_set_client_tag(\"WaterClockDisplay\") \n");
|
||||
waterClockDisplay.out.flush();
|
||||
|
||||
// Have the Variable Server send us the simulation mode ONCE.
|
||||
waterClockDisplay.out.writeBytes( "trick.var_add(\"trick_sys.sched.mode\")\n" +
|
||||
"trick.var_send() \n" +
|
||||
"trick.var_clear() \n");
|
||||
waterClockDisplay.out.flush();
|
||||
|
||||
// Read the response and extract the simulation mode.
|
||||
try {
|
||||
String line;
|
||||
String field[];
|
||||
line = waterClockDisplay.in.readLine();
|
||||
field = line.split("\t");
|
||||
simMode = Integer.parseInt( field[1]);
|
||||
} catch (IOException | NullPointerException e ) {
|
||||
go = false;
|
||||
}
|
||||
|
||||
// Configure the Variable Server to cyclically send us the following varibales.
|
||||
// Tell the variable server:
|
||||
// 1) We want the values of the following variables:
|
||||
waterClockDisplay.out.writeBytes( "trick.var_pause() \n" +
|
||||
"trick.var_add(\"dyn.waterclock.intake_clock_spout_flowrate\")\n" +
|
||||
"trick.var_add(\"dyn.waterclock.intake_overflow_flowrate\")\n" +
|
||||
"trick.var_add(\"dyn.waterclock.intake_bucket_depth\")\n" +
|
||||
"trick.var_add(\"dyn.waterclock.timer_bucket_depth\")\n" +
|
||||
"trick.var_add(\"dyn.waterclock.intake_water_level\")\n" +
|
||||
"trick.var_add(\"dyn.waterclock.timer_water_level\")\n" +
|
||||
"trick.var_add(\"dyn.waterclock.intake_bucket_vol\")\n" +
|
||||
"trick.var_add(\"dyn.waterclock.timer_bucket_vol\")\n" +
|
||||
"trick.var_add(\"dyn.waterclock.intake_clock_spout_height\")\n" +
|
||||
"trick.var_add(\"dyn.waterclock.intake_overflow_height\")\n" +
|
||||
"trick.var_add(\"dyn.waterclock.input_flow\")\n" +
|
||||
"trick.var_add(\"dyn.waterclock.current_tick\")\n" +
|
||||
"trick.var_add(\"trick_sys.sched.mode\")\n" +
|
||||
// 2) We want the responses in ASCII:
|
||||
"trick.var_ascii() \n" +
|
||||
// 3) We want values to be updated at the specified rate:
|
||||
String.format("trick.var_cycle(%.3f)\n", dt) +
|
||||
// 4) Start sending values as specified.
|
||||
"trick.var_unpause() \n" );
|
||||
waterClockDisplay.out.flush();
|
||||
} // if go
|
||||
|
||||
while (go) {
|
||||
|
||||
// Recieve and parse periodic data response from the variable server.
|
||||
try {
|
||||
String line;
|
||||
String field[];
|
||||
line = waterClockDisplay.in.readLine();
|
||||
field = line.split("\t");
|
||||
spout_rate = Double.parseDouble( field[1]);
|
||||
overflow_rate = Double.parseDouble( field[2]);
|
||||
intake_depth = Double.parseDouble( field[3]);
|
||||
timer_depth = Double.parseDouble( field[4]);
|
||||
intake_lvl = Double.parseDouble( field[5]);
|
||||
timer_lvl = Double.parseDouble( field[6]);
|
||||
intake_vol = Double.parseDouble( field[7]);
|
||||
timer_vol = Double.parseDouble( field[8]);
|
||||
spout_height = Double.parseDouble( field[9]);
|
||||
overflow_height = Double.parseDouble( field[10]);
|
||||
input_flow = Double.parseDouble( field[11]);
|
||||
tick = Integer.parseInt( field[12]);
|
||||
simMode = Integer.parseInt( field[13]);
|
||||
} catch (IOException | NullPointerException e ) {
|
||||
go = false;
|
||||
}
|
||||
|
||||
// Update the display data.
|
||||
rangeView.setSpoutRate(spout_rate);
|
||||
rangeView.setOverflowRate(overflow_rate);
|
||||
rangeView.setIntakeDepth(intake_depth);
|
||||
rangeView.setTimerDepth(timer_depth);
|
||||
rangeView.setIntakeWarerLevel(intake_lvl);
|
||||
rangeView.setTimerWarerLevel(timer_lvl);
|
||||
rangeView.setIntakeWaterVol(intake_vol);
|
||||
rangeView.setTimerWaterLevel(timer_vol);
|
||||
rangeView.setSpoutHeight(spout_height);
|
||||
rangeView.setOverflowHeight(overflow_height);
|
||||
rangeView.setInputFlow(input_flow);
|
||||
rangeView.setCurrentTick(tick);
|
||||
|
||||
if(rangeView.new_input_flow) {
|
||||
flow_select = rangeView.getInputFlowSelect();
|
||||
waterClockDisplay.out.writeBytes( String.format("dyn.waterclock.input_flow = %f ;\n", flow_select ));
|
||||
rangeView.new_input_flow = false;
|
||||
}
|
||||
|
||||
waterClockDisplay.out.flush();
|
||||
|
||||
// Update the scene.
|
||||
waterClockDisplay.drawRangeView();
|
||||
|
||||
} // while
|
||||
} // main
|
||||
} // class
|
@ -0,0 +1,76 @@
|
||||
/*************************************************************************
|
||||
PURPOSE: (Represent the state and initial conditions of the water clock)
|
||||
**************************************************************************/
|
||||
#ifndef WATERCLOCK_H
|
||||
#define WATERCLOCK_H
|
||||
|
||||
#include "trick/regula_falsi.h"
|
||||
|
||||
typedef struct {
|
||||
|
||||
|
||||
//////////////////////////
|
||||
|
||||
/* ASSUMPTIONS
|
||||
* 1) For the purpose of determining if a pipe is submerged, it will be treated as a single point at the center of the pipe
|
||||
* 2) When the timing bucket is filled, a siphon will drain it instaneously
|
||||
* 3) Buckets are cylindrical
|
||||
*/
|
||||
|
||||
/* DESCRIPTION
|
||||
* This is a simulation of a simple water clock. The clock consists of two cylinders (buckets).
|
||||
* The first bucket is known as the intake bucket. It receives water from an unspecified external source (like a stream).
|
||||
* The intake bucket has two cylindrical spouts extending from its sides, one known as an overflow spout and the other the clock spout.
|
||||
* The overflow spout is simply for maintaing an equilibrium of the water level. It keeps the intake bucket from exceeding a certain water level, thus ensuring it's water level is consistent.
|
||||
* The clock spout pours water into the second bucket (timer bucket). In an ideal clock, the water level of the intake bucket will remain consistent, meaning the clock spout will output at a constant rate and operate as an accurate clock.
|
||||
* The timer bucket receives water from the clock spout. The timer bucket has no spouts, it fills until it is full, upon which a siphon instantaneously drains it.
|
||||
* There exists a float in the timer bucket, connected to an arrow which will point to vertical tick marks. As the timer bucket fills, the arrow will move vertically along these ticks, indicating how much time has passed.
|
||||
* Depending on the configuration of the clock (size of the buckets, size of the spouts, external water source rate, and the number/spacing of ticks) you can create a clock that tracks a variety of times.
|
||||
*/
|
||||
|
||||
double time; /* s Model time */
|
||||
|
||||
double input_flow; /* cm^3/s Flow rate of the external water source to the water clock */
|
||||
double intake_clock_spout_flowrate; /* cm^3/s Intake bucket output spout pipe flow rate */
|
||||
double intake_overflow_flowrate; /* cm^3/s Intake bucket overflow pipe flow rate */
|
||||
double intake_bucket_net_flow; /* cm^3/s Intake bucket net flow rate */
|
||||
|
||||
double intake_bucket_depth; /* cm Intake bucket depth */
|
||||
double intake_bucket_diam; /* cm Intake bucket diameter */
|
||||
|
||||
double intake_overflow_height; /* cm Intake bucket overflow pipe height of center */
|
||||
double intake_overflow_diameter; /* cm Intake bucket overflow pipe diameter */
|
||||
|
||||
double intake_clock_spout_height; /* cm Intake bucket output spout pipe height of center */
|
||||
double intake_clock_spout_diameter; /* cm Intake bucket output spout pipe diameter */
|
||||
|
||||
double timer_bucket_depth; /* cm Timer bucket depth */
|
||||
double timer_bucket_diam; /* cm Timer bucket diameter */
|
||||
|
||||
double intake_bucket_vol; /* cm^3 Intake bucket water volume */
|
||||
double intake_water_level; /* cm Intake bucket water level */
|
||||
double timer_bucket_vol; /* cm^3 Timer bucket water volume */
|
||||
double timer_water_level; /* cm Timer bucket water level */
|
||||
|
||||
double tick_gap; /* cm Distance between tick marks */
|
||||
int total_ticks; /* -- Total number of ticks on the timer */
|
||||
int current_tick; /* -- The current timer tick to have crossed the threshold*/
|
||||
|
||||
double gravity; /* m/s^2 Gravity constant */
|
||||
|
||||
REGULA_FALSI rf1 ;
|
||||
REGULA_FALSI rf2 ;
|
||||
|
||||
} WATERCLOCK ;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
int waterclock_default_data(WATERCLOCK*) ;
|
||||
int waterclock_init(WATERCLOCK*) ;
|
||||
int waterclock_shutdown(WATERCLOCK*) ;
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -0,0 +1,21 @@
|
||||
/*************************************************************************
|
||||
PURPOSE: ( Water Clock Numeric Model )
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef WATERCLOCK_NUMERIC_H
|
||||
#define WATERCLOCK_NUMERIC_H
|
||||
|
||||
#include "waterclock.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
int waterclock_integ(WATERCLOCK* WC);
|
||||
int waterclock_deriv(WATERCLOCK* WC);
|
||||
double waterclock_tick_change(WATERCLOCK* WC);
|
||||
double waterclock_overflow_timer(WATERCLOCK* WC);
|
||||
void waterclock_update_water_level(WATERCLOCK* WC);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
@ -0,0 +1,59 @@
|
||||
/******************************* TRICK HEADER ****************************
|
||||
PURPOSE: (Set the initial data values)
|
||||
*************************************************************************/
|
||||
|
||||
/* Model Include files */
|
||||
#include <math.h>
|
||||
#include "../include/waterclock.h"
|
||||
|
||||
/* default data job */
|
||||
int waterclock_default_data( WATERCLOCK* WC ) {
|
||||
|
||||
WC->time = 0.0 ;
|
||||
|
||||
WC->input_flow = 1000;
|
||||
WC->intake_clock_spout_flowrate = 0.0;
|
||||
WC->intake_overflow_flowrate = 0.0;
|
||||
|
||||
WC->intake_bucket_depth = 100.0;
|
||||
WC->intake_bucket_diam = 500.0;
|
||||
|
||||
WC->intake_overflow_height = 080.0 * WC->intake_bucket_depth;
|
||||
WC->intake_overflow_diameter = 100.0;
|
||||
|
||||
WC->intake_clock_spout_height = 010.0;
|
||||
WC->intake_clock_spout_diameter = 005.0;
|
||||
|
||||
WC->timer_bucket_depth = 120.0;
|
||||
WC->timer_bucket_diam = 050.0;
|
||||
|
||||
WC->intake_bucket_vol = 0.0;
|
||||
WC->timer_bucket_vol = 0.0;
|
||||
|
||||
WC->total_ticks = 5;
|
||||
WC->current_tick = 0;
|
||||
|
||||
WC->gravity = 9.81;
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
/* initialization job */
|
||||
int waterclock_init( WATERCLOCK* WC) {
|
||||
|
||||
if (WC->intake_overflow_height > WC->intake_bucket_depth) {
|
||||
WC->intake_overflow_height = WC->intake_bucket_depth;
|
||||
}
|
||||
if (WC->intake_clock_spout_height > WC->intake_bucket_depth) {
|
||||
WC->intake_clock_spout_height = WC->intake_bucket_depth;
|
||||
}
|
||||
if (WC->intake_overflow_height < 0) {
|
||||
WC->intake_overflow_height = 0;
|
||||
}
|
||||
if (WC->intake_clock_spout_height < 0) {
|
||||
WC->intake_clock_spout_height = 0;
|
||||
}
|
||||
WC->tick_gap = WC->timer_bucket_depth / WC->total_ticks ;
|
||||
|
||||
return 0 ;
|
||||
}
|
@ -0,0 +1,127 @@
|
||||
/*********************************************************************
|
||||
PURPOSE: ( Trick numeric )
|
||||
*********************************************************************/
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include "trick/integrator_c_intf.h"
|
||||
#include "../include/waterclock_numeric.h"
|
||||
#include "trick/exec_proto.h"
|
||||
#include "trick/message_proto.h"
|
||||
#include <math.h>
|
||||
|
||||
int waterclock_deriv(WATERCLOCK* WC) {
|
||||
|
||||
//Make sure water level is up to date
|
||||
waterclock_update_water_level(WC);
|
||||
|
||||
//Clock spout area
|
||||
double spout_radius = WC->intake_clock_spout_diameter / 2;
|
||||
double spout_area = M_PI * spout_radius * spout_radius;
|
||||
|
||||
//Overflow spout area
|
||||
double overflow_radius = WC->intake_overflow_diameter / 2;
|
||||
double overflow_area = M_PI * overflow_radius * overflow_radius;
|
||||
|
||||
//Calculate flow rate using Torricelli's equation ( V = sqrt(2gh) ) to find water velocity. Multiple velocity by spout area to find flow rate.
|
||||
//Calculate input bucket spout flow rate.
|
||||
if(WC->intake_water_level > WC->intake_clock_spout_height)
|
||||
WC->intake_clock_spout_flowrate = spout_area * sqrt(2 * WC->gravity * (WC->intake_water_level - WC->intake_clock_spout_height) );
|
||||
else
|
||||
WC->intake_clock_spout_flowrate = 0.0;
|
||||
|
||||
//Calculate input bucket over flow rate
|
||||
if(WC->intake_water_level > WC->intake_overflow_height)
|
||||
WC->intake_overflow_flowrate = overflow_area * sqrt(2 * WC->gravity * (WC->intake_water_level - WC->intake_overflow_height) );
|
||||
else
|
||||
WC->intake_overflow_flowrate = 0.0;
|
||||
|
||||
//Need to know net flow of the source, overflow spout, and clock spout for integration
|
||||
WC->intake_bucket_net_flow = WC->input_flow - WC->intake_clock_spout_flowrate - WC->intake_overflow_flowrate;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
int waterclock_integ(WATERCLOCK* WC) {
|
||||
int ipass;
|
||||
|
||||
load_state(
|
||||
&WC->intake_bucket_vol,
|
||||
&WC->timer_bucket_vol,
|
||||
NULL);
|
||||
|
||||
load_deriv(
|
||||
&WC->intake_bucket_net_flow,
|
||||
&WC->intake_clock_spout_flowrate,
|
||||
NULL);
|
||||
|
||||
ipass = integrate();
|
||||
|
||||
unload_state(
|
||||
&WC->intake_bucket_vol,
|
||||
&WC->timer_bucket_vol,
|
||||
NULL );
|
||||
|
||||
waterclock_update_water_level(WC);
|
||||
|
||||
return(ipass);
|
||||
}
|
||||
|
||||
//Since we are inetgrating over water volume, we must convert volume to water level in order to track how quickly the timer bucket is filling up.
|
||||
void waterclock_update_water_level(WATERCLOCK* WC)
|
||||
{
|
||||
//Calculate Input bucket water level
|
||||
double intake_bucket_radius = WC->intake_bucket_diam / 2;
|
||||
double intake_bucket_base = M_PI * intake_bucket_radius * intake_bucket_radius;
|
||||
WC->intake_water_level = WC->intake_bucket_vol / intake_bucket_base;
|
||||
|
||||
//Calculate Timer bucket water level
|
||||
double timer_bucket_radius = WC->timer_bucket_diam / 2;
|
||||
double timer_bucket_base = M_PI * timer_bucket_radius * timer_bucket_radius;
|
||||
WC->timer_water_level = WC->timer_bucket_vol / timer_bucket_base;
|
||||
|
||||
}
|
||||
|
||||
//When timer bucket fills, drain it instantly (we have a magic siphon)
|
||||
double waterclock_overflow_timer( WATERCLOCK* WC ) {
|
||||
double tgo;
|
||||
double now;
|
||||
|
||||
WC->rf1.error = WC->timer_bucket_depth - WC->timer_water_level;
|
||||
now = get_integ_time();
|
||||
tgo = regula_falsi( now, &(WC->rf1) );
|
||||
if (tgo == 0.0) {
|
||||
now = get_integ_time() ;
|
||||
reset_regula_falsi( now, &(WC->rf1) ) ;
|
||||
WC->timer_water_level = 0; //Instantly drains
|
||||
WC->timer_bucket_vol = 0; //Instantly drains
|
||||
WC->current_tick = 0;
|
||||
message_publish(MSG_NORMAL, "WATER CLOCK RESET\n" ) ;
|
||||
}
|
||||
return (tgo) ;
|
||||
}
|
||||
|
||||
//Detect when the arrow has passed a new tick, print some diagnostics.
|
||||
double waterclock_tick_change( WATERCLOCK* WC ) {
|
||||
double tgo;
|
||||
double now;
|
||||
|
||||
WC->rf2.error = WC->tick_gap - (WC->timer_water_level - ( WC->current_tick * WC->tick_gap ));
|
||||
now = get_integ_time();
|
||||
tgo = regula_falsi( now, &(WC->rf2) );
|
||||
if (tgo == 0.0) {
|
||||
now = get_integ_time() ;
|
||||
reset_regula_falsi( now, &(WC->rf2) ) ;
|
||||
if( (WC->current_tick < WC->total_ticks) && (WC->current_tick >= 0) )
|
||||
{
|
||||
WC->current_tick += 1;
|
||||
void * sub_ptr = message_get_subscriber("cout");
|
||||
message_remove_subscriber(sub_ptr);
|
||||
message_publish(MSG_NORMAL, "Tick %d, Sim Time %f, Water Level %f\n", WC->current_tick, exec_get_sim_time(), WC->timer_water_level) ;
|
||||
message_add_subscriber(sub_ptr);
|
||||
}
|
||||
else
|
||||
fprintf(stderr, "ERROR, SOMETHING WENT VERY WRONG!\n" ) ;
|
||||
}
|
||||
return (tgo) ;
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
/************************************************************************
|
||||
PURPOSE: (Shutdown the sim)
|
||||
*************************************************************************/
|
||||
#include <stdio.h>
|
||||
#include "../include/waterclock.h"
|
||||
#include "trick/exec_proto.h"
|
||||
|
||||
int waterclock_shutdown( WATERCLOCK* WC) {
|
||||
printf( "========================================\n");
|
||||
printf( " Water Clock Shutdown \n");
|
||||
printf( "========================================\n");
|
||||
return 0 ;
|
||||
}
|
96
trick_sims/SIM_waterclock/waterclock.tv
Normal file
@ -0,0 +1,96 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<trickView>
|
||||
<cyclePeriod>0.5</cyclePeriod>
|
||||
<variable>
|
||||
<name>dyn.waterclock.intake_overflow_flowrate</name>
|
||||
<tvDouble>
|
||||
<value xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:double">0.0</value>
|
||||
<format>Decimal</format>
|
||||
</tvDouble>
|
||||
<state>Valid</state>
|
||||
<units>m^3/s</units>
|
||||
</variable>
|
||||
<variable>
|
||||
<name>dyn.waterclock.intake_clock_spout_flowrate</name>
|
||||
<tvDouble>
|
||||
<value xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:double">0.0</value>
|
||||
<format>Decimal</format>
|
||||
</tvDouble>
|
||||
<state>Valid</state>
|
||||
<units>m^3/s</units>
|
||||
</variable>
|
||||
<variable>
|
||||
<name>dyn.waterclock.intake_bucket_depth</name>
|
||||
<tvDouble>
|
||||
<value xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:double">5.0</value>
|
||||
<format>Decimal</format>
|
||||
</tvDouble>
|
||||
<state>Valid</state>
|
||||
<units>m</units>
|
||||
</variable>
|
||||
<variable>
|
||||
<name>dyn.waterclock.intake_overflow_height</name>
|
||||
<tvDouble>
|
||||
<value xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:double">4.0</value>
|
||||
<format>Decimal</format>
|
||||
</tvDouble>
|
||||
<state>Valid</state>
|
||||
<units>m</units>
|
||||
</variable>
|
||||
<variable>
|
||||
<name>dyn.waterclock.intake_clock_spout_height</name>
|
||||
<tvDouble>
|
||||
<value xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:double">0.25</value>
|
||||
<format>Decimal</format>
|
||||
</tvDouble>
|
||||
<state>Valid</state>
|
||||
<units>m</units>
|
||||
</variable>
|
||||
<variable>
|
||||
<name>dyn.waterclock.intake_water_level</name>
|
||||
<tvDouble>
|
||||
<value xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:double">0.0</value>
|
||||
<format>Decimal</format>
|
||||
</tvDouble>
|
||||
<state>Valid</state>
|
||||
<units>m</units>
|
||||
</variable>
|
||||
<variable>
|
||||
<name>dyn.waterclock.total_ticks</name>
|
||||
<tvInteger>
|
||||
<value xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:int">60</value>
|
||||
<unsigned>false</unsigned>
|
||||
<format>Decimal</format>
|
||||
</tvInteger>
|
||||
<state>Valid</state>
|
||||
<units>--</units>
|
||||
</variable>
|
||||
<variable>
|
||||
<name>dyn.waterclock.current_tick</name>
|
||||
<tvInteger>
|
||||
<value xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:int">0</value>
|
||||
<unsigned>false</unsigned>
|
||||
<format>Decimal</format>
|
||||
</tvInteger>
|
||||
<state>Valid</state>
|
||||
<units>--</units>
|
||||
</variable>
|
||||
<variable>
|
||||
<name>dyn.waterclock.timer_bucket_depth</name>
|
||||
<tvDouble>
|
||||
<value xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:double">5.133689839572193</value>
|
||||
<format>Decimal</format>
|
||||
</tvDouble>
|
||||
<state>Valid</state>
|
||||
<units>m</units>
|
||||
</variable>
|
||||
<variable>
|
||||
<name>dyn.waterclock.timer_water_level</name>
|
||||
<tvDouble>
|
||||
<value xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:double">0.0</value>
|
||||
<format>Decimal</format>
|
||||
</tvDouble>
|
||||
<state>Valid</state>
|
||||
<units>m</units>
|
||||
</variable>
|
||||
</trickView>
|
141
trick_sims/SIM_waterclock/waterclock_debug.tv
Normal file
@ -0,0 +1,141 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<trickView>
|
||||
<cyclePeriod>0.5</cyclePeriod>
|
||||
<variable>
|
||||
<name>dyn.waterclock.intake_overflow_flowrate</name>
|
||||
<tvDouble>
|
||||
<value xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:double">0.0</value>
|
||||
<format>Decimal</format>
|
||||
</tvDouble>
|
||||
<state>Valid</state>
|
||||
<units>m^3/s</units>
|
||||
</variable>
|
||||
<variable>
|
||||
<name>dyn.waterclock.intake_clock_spout_flowrate</name>
|
||||
<tvDouble>
|
||||
<value xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:double">0.0</value>
|
||||
<format>Decimal</format>
|
||||
</tvDouble>
|
||||
<state>Valid</state>
|
||||
<units>m^3/s</units>
|
||||
</variable>
|
||||
<variable>
|
||||
<name>dyn.waterclock.intake_bucket_depth</name>
|
||||
<tvDouble>
|
||||
<value xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:double">1.0</value>
|
||||
<format>Decimal</format>
|
||||
</tvDouble>
|
||||
<state>Valid</state>
|
||||
<units>m</units>
|
||||
</variable>
|
||||
<variable>
|
||||
<name>dyn.waterclock.intake_overflow_height</name>
|
||||
<tvDouble>
|
||||
<value xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:double">0.8</value>
|
||||
<format>Decimal</format>
|
||||
</tvDouble>
|
||||
<state>Valid</state>
|
||||
<units>m</units>
|
||||
</variable>
|
||||
<variable>
|
||||
<name>dyn.waterclock.intake_clock_spout_height</name>
|
||||
<tvDouble>
|
||||
<value xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:double">0.1</value>
|
||||
<format>Decimal</format>
|
||||
</tvDouble>
|
||||
<state>Valid</state>
|
||||
<units>m</units>
|
||||
</variable>
|
||||
<variable>
|
||||
<name>dyn.waterclock.intake_water_level</name>
|
||||
<tvDouble>
|
||||
<value xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:double">0.0</value>
|
||||
<format>Decimal</format>
|
||||
</tvDouble>
|
||||
<state>Valid</state>
|
||||
<units>m</units>
|
||||
</variable>
|
||||
<variable>
|
||||
<name>dyn.waterclock.intake_bucket_vol</name>
|
||||
<tvDouble>
|
||||
<value xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:double">0.0</value>
|
||||
<format>Decimal</format>
|
||||
</tvDouble>
|
||||
<state>Valid</state>
|
||||
<units>m^3</units>
|
||||
</variable>
|
||||
<variable>
|
||||
<name>dyn.waterclock.timer_bucket_depth</name>
|
||||
<tvDouble>
|
||||
<value xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:double">2.3077</value>
|
||||
<format>Decimal</format>
|
||||
</tvDouble>
|
||||
<state>Valid</state>
|
||||
<units>m</units>
|
||||
</variable>
|
||||
<variable>
|
||||
<name>dyn.waterclock.timer_water_level</name>
|
||||
<tvDouble>
|
||||
<value xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:double">0.0</value>
|
||||
<format>Decimal</format>
|
||||
</tvDouble>
|
||||
<state>Valid</state>
|
||||
<units>m</units>
|
||||
</variable>
|
||||
<variable>
|
||||
<name>dyn.waterclock.timer_bucket_vol</name>
|
||||
<tvDouble>
|
||||
<value xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:double">0.0</value>
|
||||
<format>Decimal</format>
|
||||
</tvDouble>
|
||||
<state>Valid</state>
|
||||
<units>m^3</units>
|
||||
</variable>
|
||||
<variable>
|
||||
<name>dyn.waterclock.rf1.error</name>
|
||||
<tvDouble>
|
||||
<value xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:double">0.0</value>
|
||||
<format>Decimal</format>
|
||||
</tvDouble>
|
||||
<state>Valid</state>
|
||||
<units>--</units>
|
||||
</variable>
|
||||
<variable>
|
||||
<name>dyn.waterclock.rf2.error</name>
|
||||
<tvDouble>
|
||||
<value xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:double">0.0</value>
|
||||
<format>Decimal</format>
|
||||
</tvDouble>
|
||||
<state>Valid</state>
|
||||
<units>--</units>
|
||||
</variable>
|
||||
<variable>
|
||||
<name>dyn.waterclock.tick_gap</name>
|
||||
<tvDouble>
|
||||
<value xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:double">0.03846166666666666</value>
|
||||
<format>Decimal</format>
|
||||
</tvDouble>
|
||||
<state>Valid</state>
|
||||
<units>m</units>
|
||||
</variable>
|
||||
<variable>
|
||||
<name>dyn.waterclock.total_ticks</name>
|
||||
<tvInteger>
|
||||
<value xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:int">60</value>
|
||||
<unsigned>false</unsigned>
|
||||
<format>Decimal</format>
|
||||
</tvInteger>
|
||||
<state>Valid</state>
|
||||
<units>--</units>
|
||||
</variable>
|
||||
<variable>
|
||||
<name>dyn.waterclock.current_tick</name>
|
||||
<tvInteger>
|
||||
<value xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:int">0</value>
|
||||
<unsigned>false</unsigned>
|
||||
<format>Decimal</format>
|
||||
</tvInteger>
|
||||
<state>Valid</state>
|
||||
<units>--</units>
|
||||
</variable>
|
||||
</trickView>
|
@ -5,7 +5,11 @@ LIBRARY DEPENDENCIES:
|
||||
((Vehicle/src/vehicleOne.cpp)
|
||||
(Control/src/PIDController.cpp))
|
||||
*************************************************************/
|
||||
|
||||
#define TRICK_NO_MONTE_CARLO
|
||||
#define TRICK_NO_MASTERSLAVE
|
||||
#define TRICK_NO_INSTRUMENTATION
|
||||
#define TRICK_NO_REALTIMEINJECTOR
|
||||
#define TRICK_NO_ZEROCONF
|
||||
#include "sim_objects/default_trick_sys.sm"
|
||||
|
||||
##include "Vehicle/include/vehicleOne.hh"
|
||||
|
@ -22,7 +22,7 @@ ClassValues::ClassValues() :
|
||||
|
||||
ClassValues::~ClassValues() {
|
||||
std::vector<FieldDescription *>::iterator fdit ;
|
||||
for ( fdit = field_descripts.begin() ; fdit != field_descripts.end() ; fdit++ ) {
|
||||
for ( fdit = field_descripts.begin() ; fdit != field_descripts.end() ; ++fdit ) {
|
||||
delete (*fdit) ;
|
||||
}
|
||||
}
|
||||
@ -57,7 +57,7 @@ void ClassValues::addInheritedFieldDescriptions(std::vector<FieldDescription *>
|
||||
|
||||
std::vector<FieldDescription *>::iterator fdit ;
|
||||
// Loop through the incoming inherited variable names
|
||||
for ( fdit = in_fdes.begin() ; fdit != in_fdes.end() ; fdit++ ) {
|
||||
for ( fdit = in_fdes.begin() ; fdit != in_fdes.end() ; ++fdit ) {
|
||||
|
||||
(*fdit)->setBaseClassOffset( class_offset ) ;
|
||||
(*fdit)->setInherited( true ) ;
|
||||
@ -72,7 +72,7 @@ void ClassValues::addInheritedFieldDescriptions(std::vector<FieldDescription *>
|
||||
#else
|
||||
{
|
||||
#endif
|
||||
for ( fdit = in_fdes.begin() ; fdit != in_fdes.end() ; fdit++ ) {
|
||||
for ( fdit = in_fdes.begin() ; fdit != in_fdes.end() ; ++fdit ) {
|
||||
|
||||
std::string in_name = (*fdit)->getName() ;
|
||||
// search existing names for incoming inherited variable name.
|
||||
@ -113,7 +113,7 @@ void ClassValues::addInheritedFieldDescriptions(std::vector<FieldDescription *>
|
||||
void ClassValues::saveInheritAncestry( ClassValues * in_cv ) {
|
||||
|
||||
std::map< std::string , unsigned int >::iterator mit ;
|
||||
for ( mit = in_cv->all_inherited_class_names_map.begin() ; mit != in_cv->all_inherited_class_names_map.end() ; mit++ ) {
|
||||
for ( mit = in_cv->all_inherited_class_names_map.begin() ; mit != in_cv->all_inherited_class_names_map.end() ; ++mit ) {
|
||||
all_inherited_class_names_map[(*mit).first] += (*mit).second ;
|
||||
}
|
||||
|
||||
@ -123,7 +123,7 @@ void ClassValues::saveInheritAncestry( ClassValues * in_cv ) {
|
||||
void ClassValues::setContainerClassForFields() {
|
||||
std::vector<FieldDescription *>::iterator fdit ;
|
||||
// Loop through all fields
|
||||
for ( fdit = field_descripts.begin() ; fdit != field_descripts.end() ; fdit++ ) {
|
||||
for ( fdit = field_descripts.begin() ; fdit != field_descripts.end() ; ++fdit ) {
|
||||
// Prepend the field container class with the current class name.
|
||||
(*fdit)->setContainerClass( name + "::" + (*fdit)->getContainerClass() ) ;
|
||||
}
|
||||
@ -134,13 +134,13 @@ void ClassValues::clearAmbiguousVariables() {
|
||||
std::map< std::string , unsigned int >::iterator mit ;
|
||||
std::vector<FieldDescription *>::iterator fdit ;
|
||||
|
||||
for ( mit = all_inherited_class_names_map.begin() ; mit != all_inherited_class_names_map.end() ; mit++ ) {
|
||||
for ( mit = all_inherited_class_names_map.begin() ; mit != all_inherited_class_names_map.end() ; ++mit ) {
|
||||
// If a class in inherited more than once we have a diamond. We'll need to modify variables that were
|
||||
// inherited from that class.
|
||||
if ( (*mit).second > 1 ) {
|
||||
std::string str = (*mit).first + "::" ;
|
||||
// Loop through all fields testing for the diamond inherited class in the name.
|
||||
for ( fdit = field_descripts.begin() ; fdit != field_descripts.end() ; fdit++ ) {
|
||||
for ( fdit = field_descripts.begin() ; fdit != field_descripts.end() ; ++fdit ) {
|
||||
std::string fdit_name = (*fdit)->getName() ;
|
||||
size_t f = fdit_name.find(str) ;
|
||||
// If the variable contains the diamond class string, remove the diamond class qualification.
|
||||
|
@ -210,7 +210,7 @@ bool CXXRecordVisitor::VisitCXXRecordDecl( clang::CXXRecordDecl *rec ) {
|
||||
} else {
|
||||
// Test all constructors to see if any of those are the default and public
|
||||
clang::CXXRecordDecl::ctor_iterator cit ;
|
||||
for ( cit = rec->ctor_begin() ; cit != rec->ctor_end() ; cit++ ) {
|
||||
for ( cit = rec->ctor_begin() ; cit != rec->ctor_end() ; ++cit ) {
|
||||
if ( ( !(*cit)->isDeleted() ) and (*cit)->isDefaultConstructor() and (*cit)->getAccess() == clang::AS_public ) {
|
||||
cval.setHasDefaultConstructor(true) ;
|
||||
}
|
||||
@ -234,7 +234,7 @@ bool CXXRecordVisitor::VisitCXXRecordDecl( clang::CXXRecordDecl *rec ) {
|
||||
//std::cout << "parsing " << cval.getName() << std::endl ;
|
||||
//std::cout << " [34mprocessing inheritance " << rec->getNumBases() << " " << rec->getNumVBases() << "[00m" << std::endl ;
|
||||
clang::CXXRecordDecl::base_class_iterator bcii ;
|
||||
for ( bcii = rec->bases_begin() ; bcii != rec->bases_end() ; bcii++ ) {
|
||||
for ( bcii = rec->bases_begin() ; bcii != rec->bases_end() ; ++bcii ) {
|
||||
if ( !bcii->isVirtual() ) {
|
||||
const clang::Type * temp = bcii->getType().getTypePtr() ;
|
||||
//std::cout << "\n[33minherited Type = " << temp->getTypeClassName() << "[00m" << std::endl ;
|
||||
@ -282,7 +282,7 @@ bool CXXRecordVisitor::VisitCXXRecordDecl( clang::CXXRecordDecl *rec ) {
|
||||
// When processing inherited classes include_virtual_base will be set to true
|
||||
// so we don't process virtual inherited classes multiple times.
|
||||
if ( include_virtual_base ) {
|
||||
for ( bcii = rec->vbases_begin() ; bcii != rec->vbases_end() ; bcii++ ) {
|
||||
for ( bcii = rec->vbases_begin() ; bcii != rec->vbases_end() ; ++bcii ) {
|
||||
const clang::Type * temp = bcii->getType().getTypePtr() ;
|
||||
//std::cout << "\n[33minherited Type = " << temp->getTypeClassName() << "[00m" << std::endl ;
|
||||
const clang::RecordType * rt = temp->getAs<clang::RecordType>() ;
|
||||
|
@ -60,7 +60,7 @@ std::string CommentSaver::getTrickHeaderComment( std::string file_name ) {
|
||||
if ( resolved_path != NULL ) {
|
||||
if ( trick_header_comments.find(resolved_path) == trick_header_comments.end() ) {
|
||||
trick_header_comments[resolved_path] = std::string() ;
|
||||
for ( cit = comment_map[resolved_path].begin() ; cit != comment_map[resolved_path].end() ; cit++ ) {
|
||||
for ( cit = comment_map[resolved_path].begin() ; cit != comment_map[resolved_path].end() ; ++cit ) {
|
||||
std::string comment_str = getComment((*cit).second) ;
|
||||
if ( comment_str.find("@trick_parse") != std::string::npos or
|
||||
comment_str.find("\\trick_parse") != std::string::npos ) {
|
||||
|
@ -304,7 +304,7 @@ void FieldDescription::parseComment(std::string comment) {
|
||||
// escape special characters, convert tabs and newlines to spaces, remove multiple spaces.
|
||||
std::ostringstream ss ;
|
||||
bool is_space = false ;
|
||||
for (std::string::iterator it = comment.begin(); it != comment.end(); it++) {
|
||||
for (std::string::iterator it = comment.begin(); it != comment.end(); ++it) {
|
||||
switch (*it) {
|
||||
case '\\': ss << "\\\\"; is_space = false ; break;
|
||||
case '"': ss << "\\\""; is_space = false ; break;
|
||||
|
@ -442,7 +442,7 @@ bool FieldVisitor::VisitRecordType(clang::RecordType *rt) {
|
||||
// Test if we have some type from STL.
|
||||
if (!tst_string.compare( 0 , 5 , "std::")) {
|
||||
// If we have some type from std, figure out if it is one we support.
|
||||
for ( std::map<std::string, bool>::iterator it = stl_classes.begin() ; it != stl_classes.end() ; it++ ) {
|
||||
for ( std::map<std::string, bool>::iterator it = stl_classes.begin() ; it != stl_classes.end() ; ++it ) {
|
||||
/* Mark STL types that are not strings and exit */
|
||||
if (!tst_string.compare( 0 , (*it).first.size() , (*it).first)) {
|
||||
|
||||
|
@ -80,7 +80,7 @@ void FindTrickICG::If(clang::SourceLocation Loc, clang::SourceRange ConditionRan
|
||||
if ( ref.str().find("TRICK_ICG") != std::string::npos ) {
|
||||
// for each header in the stack, mark them as being exposed to TRICK_ICG
|
||||
std::vector<std::string>::iterator it ;
|
||||
for ( it = included_files.begin() ; it != included_files.end() ; it++ ) {
|
||||
for ( it = included_files.begin() ; it != included_files.end() ; ++it ) {
|
||||
hsd.addTrickICGFoundFile(*it) ;
|
||||
}
|
||||
// print warning messages.
|
||||
@ -124,7 +124,7 @@ void FindTrickICG::Ifdef(clang::SourceLocation Loc, const clang::Token &MacroNam
|
||||
if ( (loc_str.find("S_source.hh") == std::string::npos) ) {
|
||||
// for each header in the stack, mark them as being exposed to TRICK_ICG
|
||||
std::vector<std::string>::iterator it ;
|
||||
for ( it = included_files.begin() ; it != included_files.end() ; it++ ) {
|
||||
for ( it = included_files.begin() ; it != included_files.end() ; ++it ) {
|
||||
hsd.addTrickICGFoundFile(*it) ;
|
||||
}
|
||||
// print warning messages.
|
||||
@ -149,7 +149,7 @@ void FindTrickICG::Ifndef(clang::SourceLocation Loc, const clang::Token &MacroNa
|
||||
std::string loc_str = Loc.printToString(ci.getSourceManager()) ;
|
||||
// for each header in the stack, mark them as being exposed to TRICK_ICG
|
||||
std::vector<std::string>::iterator it ;
|
||||
for ( it = included_files.begin() ; it != included_files.end() ; it++ ) {
|
||||
for ( it = included_files.begin() ; it != included_files.end() ; ++it ) {
|
||||
hsd.addTrickICGFoundFile(*it) ;
|
||||
}
|
||||
// print warning messages.
|
||||
|
@ -186,13 +186,13 @@ void HeaderSearchDirs::ApplyHeaderSearchOptions () {
|
||||
clang::ApplyHeaderSearchOptions( hs , hso , pp.getLangOpts() , pp.getTargetInfo().getTriple() ) ;
|
||||
//clang::HeaderSearch::search_dir_iterator sdi ;
|
||||
/*
|
||||
for ( sdi = hs.quoted_dir_begin() ; sdi != hs.quoted_dir_end() ; sdi++ ) {
|
||||
for ( sdi = hs.quoted_dir_begin() ; sdi != hs.quoted_dir_end() ; ++sdi ) {
|
||||
std::cout << "quoted dir " << (*sdi).getName() << std::endl ;
|
||||
}
|
||||
for ( sdi = hs.angled_dir_begin() ; sdi != hs.angled_dir_end() ; sdi++ ) {
|
||||
for ( sdi = hs.angled_dir_begin() ; sdi != hs.angled_dir_end() ; ++sdi ) {
|
||||
std::cout << "angled dir " << (*sdi).getName() << std::endl ;
|
||||
}
|
||||
for ( sdi = hs.system_dir_begin() ; sdi != hs.system_dir_end() ; sdi++ ) {
|
||||
for ( sdi = hs.system_dir_begin() ; sdi != hs.system_dir_end() ; ++sdi ) {
|
||||
std::cout << "system dir " << (*sdi).getName() << std::endl ;
|
||||
}
|
||||
*/
|
||||
@ -229,7 +229,7 @@ bool HeaderSearchDirs::isPathInUserDir (const std::string& in_dir ) {
|
||||
for ( clang::ConstSearchDirIterator sdi = hs.system_dir_begin() ; sdi != hs.system_dir_end() ; sdi = std::next(sdi) )
|
||||
#else
|
||||
clang::HeaderSearch::search_dir_iterator sdi ;
|
||||
for ( sdi = hs.system_dir_begin() ; sdi != hs.system_dir_end() ; sdi++ )
|
||||
for ( sdi = hs.system_dir_begin() ; sdi != hs.system_dir_end() ; ++sdi )
|
||||
#endif
|
||||
{
|
||||
#if (LIBCLANG_MAJOR < 4) // TODO delete when RHEL 7 no longer supported
|
||||
@ -261,7 +261,7 @@ bool HeaderSearchDirs::isPathInUserOrTrickDir (const std::string& in_dir ) {
|
||||
for ( clang::ConstSearchDirIterator sdi = hs.system_dir_begin() ; sdi != hs.system_dir_end() ; sdi = std::next(sdi) )
|
||||
#else
|
||||
clang::HeaderSearch::search_dir_iterator sdi ;
|
||||
for ( sdi = hs.system_dir_begin() ; sdi != hs.system_dir_end() ; sdi++ )
|
||||
for ( sdi = hs.system_dir_begin() ; sdi != hs.system_dir_end() ; ++sdi )
|
||||
#endif
|
||||
{
|
||||
#if (LIBCLANG_MAJOR < 4) // TODO delete when RHEL 7 no longer supported
|
||||
@ -279,7 +279,7 @@ bool HeaderSearchDirs::isPathInUserOrTrickDir (const std::string& in_dir ) {
|
||||
bool HeaderSearchDirs::isPathInExclude (const std::string& in_dir ) {
|
||||
|
||||
std::vector<std::string>::iterator vit ;
|
||||
for ( vit = exclude_dirs.begin() ; vit != exclude_dirs.end() ; vit++ ) {
|
||||
for ( vit = exclude_dirs.begin() ; vit != exclude_dirs.end() ; ++vit ) {
|
||||
if ( ! in_dir.compare(0, (*vit).size(), (*vit))) {
|
||||
return true ;
|
||||
}
|
||||
@ -291,7 +291,7 @@ bool HeaderSearchDirs::isPathInExclude (const std::string& in_dir ) {
|
||||
bool HeaderSearchDirs::isPathInICGExclude (const std::string& in_dir ) {
|
||||
|
||||
std::vector<std::string>::iterator vit ;
|
||||
for ( vit = icg_exclude_dirs.begin() ; vit != icg_exclude_dirs.end() ; vit++ ) {
|
||||
for ( vit = icg_exclude_dirs.begin() ; vit != icg_exclude_dirs.end() ; ++vit ) {
|
||||
if ( ! in_dir.compare(0, (*vit).size(), (*vit))) {
|
||||
return true ;
|
||||
}
|
||||
@ -303,7 +303,7 @@ bool HeaderSearchDirs::isPathInICGExclude (const std::string& in_dir ) {
|
||||
bool HeaderSearchDirs::isPathInExtLib (const std::string& in_dir ) {
|
||||
|
||||
std::vector<std::string>::iterator vit ;
|
||||
for ( vit = ext_lib_dirs.begin() ; vit != ext_lib_dirs.end() ; vit++ ) {
|
||||
for ( vit = ext_lib_dirs.begin() ; vit != ext_lib_dirs.end() ; ++vit ) {
|
||||
if ( ! in_dir.compare(0, (*vit).size(), (*vit))) {
|
||||
return true ;
|
||||
}
|
||||
@ -318,7 +318,7 @@ bool HeaderSearchDirs::isPathInICGNoComment (const std::string& in_dir ) {
|
||||
}
|
||||
else {
|
||||
std::vector<std::string>::iterator vit ;
|
||||
for ( vit = icg_nocomment_dirs.begin() ; vit != icg_nocomment_dirs.end() ; vit++ ) {
|
||||
for ( vit = icg_nocomment_dirs.begin() ; vit != icg_nocomment_dirs.end() ; ++vit ) {
|
||||
if ( ! in_dir.compare(0, (*vit).size(), (*vit))) {
|
||||
icg_nocomment_files[in_dir] = true ;
|
||||
return true;
|
||||
@ -332,7 +332,7 @@ bool HeaderSearchDirs::isPathInICGNoComment (const std::string& in_dir ) {
|
||||
bool HeaderSearchDirs::isPathInCompat15 (const std::string& in_dir ) {
|
||||
|
||||
std::vector<std::string>::iterator vit ;
|
||||
for ( vit = compat15_dirs.begin() ; vit != compat15_dirs.end() ; vit++ ) {
|
||||
for ( vit = compat15_dirs.begin() ; vit != compat15_dirs.end() ; ++vit ) {
|
||||
if ( ! in_dir.compare(0, (*vit).size(), (*vit))) {
|
||||
return true ;
|
||||
}
|
||||
@ -347,7 +347,7 @@ bool HeaderSearchDirs::isPathInCompat15 (const std::string& in_dir ) {
|
||||
std::string HeaderSearchDirs::getPathInExclude (const std::string& in_dir ) {
|
||||
|
||||
std::vector<std::string>::iterator vit ;
|
||||
for ( vit = exclude_dirs.begin() ; vit != exclude_dirs.end() ; vit++ ) {
|
||||
for ( vit = exclude_dirs.begin() ; vit != exclude_dirs.end() ; ++vit ) {
|
||||
if ( ! in_dir.compare(0, (*vit).size(), (*vit))) {
|
||||
return (*vit) ;
|
||||
}
|
||||
@ -359,7 +359,7 @@ std::string HeaderSearchDirs::getPathInExclude (const std::string& in_dir ) {
|
||||
std::string HeaderSearchDirs::getPathInICGExclude (const std::string& in_dir ) {
|
||||
|
||||
std::vector<std::string>::iterator vit ;
|
||||
for ( vit = icg_exclude_dirs.begin() ; vit != icg_exclude_dirs.end() ; vit++ ) {
|
||||
for ( vit = icg_exclude_dirs.begin() ; vit != icg_exclude_dirs.end() ; ++vit ) {
|
||||
if ( ! in_dir.compare(0, (*vit).size(), (*vit))) {
|
||||
return (*vit) ;
|
||||
}
|
||||
@ -371,7 +371,7 @@ std::string HeaderSearchDirs::getPathInICGExclude (const std::string& in_dir ) {
|
||||
std::string HeaderSearchDirs::getPathInExtLib (const std::string& in_dir ) {
|
||||
|
||||
std::vector<std::string>::iterator vit ;
|
||||
for ( vit = ext_lib_dirs.begin() ; vit != ext_lib_dirs.end() ; vit++ ) {
|
||||
for ( vit = ext_lib_dirs.begin() ; vit != ext_lib_dirs.end() ; ++vit ) {
|
||||
if ( ! in_dir.compare(0, (*vit).size(), (*vit))) {
|
||||
return (*vit) ;
|
||||
}
|
||||
|
@ -0,0 +1,39 @@
|
||||
#include <iostream>
|
||||
#include "clang/Basic/SourceManager.h"
|
||||
#include "clang/Basic/SourceLocation.h"
|
||||
|
||||
#include "ICGDiagnosticConsumer.hh"
|
||||
#include "HeaderSearchDirs.hh"
|
||||
#include "Utilities.hh"
|
||||
|
||||
|
||||
ICGDiagnosticConsumer::ICGDiagnosticConsumer(llvm::raw_ostream &os, clang::DiagnosticOptions *diags, clang::CompilerInstance &in_ci, HeaderSearchDirs &in_hsd)
|
||||
: clang::TextDiagnosticPrinter(os, diags), ci(in_ci), hsd(in_hsd) {
|
||||
error_in_user_code = false;
|
||||
};
|
||||
ICGDiagnosticConsumer::~ICGDiagnosticConsumer() {
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @details
|
||||
* -# Check the diagnostic level to see if an error is from user code.
|
||||
* -# Terminate the build if yes, continue otherwise.
|
||||
*/
|
||||
void ICGDiagnosticConsumer::HandleDiagnostic(clang::DiagnosticsEngine::Level DiagLevel, const clang::Diagnostic &Info) {
|
||||
// Use TextDiagnosticPrinter to handle diagnostic if the code is user code.
|
||||
// Otherwise use base DiagnosticConsumer to handle diagnostic for system code.
|
||||
if (isInUserCode(ci , Info.getLocation(), hsd)) {
|
||||
// Parent class implementation for handling diagnostic
|
||||
clang::TextDiagnosticPrinter::HandleDiagnostic(DiagLevel, Info);
|
||||
|
||||
// Flag it if an error is from user code
|
||||
if (DiagLevel == clang::DiagnosticsEngine::Level::Fatal || DiagLevel == clang::DiagnosticsEngine::Level::Error) {
|
||||
error_in_user_code = true;
|
||||
}
|
||||
} else {
|
||||
// Base class implementation for handling diagnostic
|
||||
clang::DiagnosticConsumer::HandleDiagnostic(DiagLevel, Info);
|
||||
}
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
#ifndef ICG_DIAGNOSTICCONSUMER_HH
|
||||
#define ICG_DIAGNOSTICCONSUMER_HH
|
||||
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "clang/Basic/Diagnostic.h"
|
||||
#include "clang/Frontend/CompilerInstance.h"
|
||||
#include "clang/Frontend/TextDiagnosticPrinter.h"
|
||||
|
||||
|
||||
class HeaderSearchDirs;
|
||||
|
||||
/**
|
||||
|
||||
This class is passed to the clang parser as a DiagnosticConsumer.
|
||||
It will terminate the trick build if an error found is from user code.
|
||||
|
||||
@date May 2024
|
||||
|
||||
*/
|
||||
|
||||
|
||||
class ICGDiagnosticConsumer : public clang::TextDiagnosticPrinter {
|
||||
public:
|
||||
ICGDiagnosticConsumer(llvm::raw_ostream &os, clang::DiagnosticOptions *diags, clang::CompilerInstance &in_ci, HeaderSearchDirs &in_hsd);
|
||||
~ICGDiagnosticConsumer() override;
|
||||
|
||||
void HandleDiagnostic(clang::DiagnosticsEngine::Level DiagLevel,
|
||||
const clang::Diagnostic &Info) override;
|
||||
|
||||
/** Flag for if any error found in user code. */
|
||||
bool error_in_user_code;
|
||||
|
||||
protected:
|
||||
/** The compiler instance. */
|
||||
clang::CompilerInstance &ci ;
|
||||
|
||||
/** The header search directories. */
|
||||
HeaderSearchDirs &hsd ;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
@ -449,7 +449,7 @@ void PrintAttributes::printIOMakefile() {
|
||||
<< "IO_OBJECTS =" ;
|
||||
|
||||
std::map< std::string , std::string >::iterator mit ;
|
||||
for ( mit = all_io_files.begin() ; mit != all_io_files.end() ; mit++ ) {
|
||||
for ( mit = all_io_files.begin() ; mit != all_io_files.end() ; ++mit ) {
|
||||
size_t found ;
|
||||
found = (*mit).second.find_last_of(".") ;
|
||||
makefile_io_src << " \\\n " << (*mit).second.substr(0,found) << ".o" ;
|
||||
@ -487,7 +487,7 @@ void PrintAttributes::printIOMakefile() {
|
||||
ICG_processed.open("build/ICG_processed") ;
|
||||
|
||||
makefile_ICG << "build/Makefile_io_src:" ;
|
||||
for ( mit = all_io_files.begin() ; mit != all_io_files.end() ; mit++ ) {
|
||||
for ( mit = all_io_files.begin() ; mit != all_io_files.end() ; ++mit ) {
|
||||
makefile_ICG << " \\\n " << (*mit).first ;
|
||||
size_t found ;
|
||||
found = (*mit).second.find_last_of(".") ;
|
||||
@ -518,7 +518,7 @@ void PrintAttributes::printICGNoFiles() {
|
||||
if ( ! sim_services_flag ) {
|
||||
std::vector< std::string >::iterator it ;
|
||||
std::ofstream icg_no_outfile("build/ICG_no_found") ;
|
||||
for ( it = icg_no_files.begin() ; it != icg_no_files.end() ; it++ ) {
|
||||
for ( it = icg_no_files.begin() ; it != icg_no_files.end() ; ++it ) {
|
||||
icg_no_outfile << (*it) << std::endl ;
|
||||
}
|
||||
icg_no_outfile.close() ;
|
||||
|
@ -6,7 +6,12 @@
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
// `llvm/Support/Host.h` is deprecated in favour of `llvm/TargetParser/Host.h` since clang 17
|
||||
#if LIBCLANG_MAJOR > 16
|
||||
#include "llvm/TargetParser/Host.h"
|
||||
#else
|
||||
#include "llvm/Support/Host.h"
|
||||
#endif
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
@ -20,6 +25,7 @@
|
||||
#include "clang/Basic/Diagnostic.h"
|
||||
#include "clang/Parse/ParseAST.h"
|
||||
|
||||
#include "ICGDiagnosticConsumer.hh"
|
||||
#include "ICGASTConsumer.hh"
|
||||
#include "HeaderSearchDirs.hh"
|
||||
#include "CommentSaver.hh"
|
||||
@ -239,8 +245,10 @@ int main(int argc, char * argv[]) {
|
||||
#endif
|
||||
clang::Preprocessor& pp = ci.getPreprocessor();
|
||||
|
||||
#if (LIBCLANG_MAJOR >= 10)
|
||||
#if (LIBCLANG_MAJOR >= 10) && (LIBCLANG_MAJOR < 18)
|
||||
clang::InitializePreprocessor(pp, ppo, ci.getPCHContainerReader(), ci.getFrontendOpts());
|
||||
#elif (LIBCLANG_MAJOR >= 18)
|
||||
clang::InitializePreprocessor(pp, ppo, ci.getPCHContainerReader(), ci.getFrontendOpts(), ci.getCodeGenOpts());
|
||||
#endif
|
||||
|
||||
// Add all of the include directories to the preprocessor
|
||||
@ -301,17 +309,23 @@ int main(int argc, char * argv[]) {
|
||||
exit(-1);
|
||||
}
|
||||
// Open up the input file and parse it
|
||||
#if (LIBCLANG_MAJOR >= 10)
|
||||
#if (LIBCLANG_MAJOR >= 10 && LIBCLANG_MAJOR < 18)
|
||||
const clang::FileEntry* fileEntry = ci.getFileManager().getFile(inputFilePath).get();
|
||||
#elif (LIBCLANG_MAJOR >= 18)
|
||||
clang::FileEntryRef fileEntryRef = llvm::cantFail(ci.getFileManager().getFileRef(inputFilePath));
|
||||
#else
|
||||
const clang::FileEntry* fileEntry = ci.getFileManager().getFile(inputFilePath);
|
||||
#endif
|
||||
free(inputFilePath);
|
||||
#if (LIBCLANG_MAJOR > 3) || ((LIBCLANG_MAJOR == 3) && (LIBCLANG_MINOR >= 5))
|
||||
#if ((LIBCLANG_MAJOR > 3 && LIBCLANG_MAJOR < 18)) || ((LIBCLANG_MAJOR == 3) && (LIBCLANG_MINOR >= 5))
|
||||
ci.getSourceManager().setMainFileID(ci.getSourceManager().createFileID(fileEntry, clang::SourceLocation(), clang::SrcMgr::C_User));
|
||||
#elif (LIBCLANG_MAJOR >= 18)
|
||||
ci.getSourceManager().setMainFileID(ci.getSourceManager().createFileID(fileEntryRef, clang::SourceLocation(), clang::SrcMgr::C_User));
|
||||
#else
|
||||
ci.getSourceManager().createMainFileID(fileEntry);
|
||||
#endif
|
||||
ICGDiagnosticConsumer *icgDiagConsumer = new ICGDiagnosticConsumer(llvm::errs(), &ci.getDiagnosticOpts(), ci, hsd);
|
||||
ci.getDiagnostics().setClient(icgDiagConsumer);
|
||||
ci.getDiagnosticClient().BeginSourceFile(ci.getLangOpts(), &ci.getPreprocessor());
|
||||
clang::ParseAST(ci.getSema());
|
||||
ci.getDiagnosticClient().EndSourceFile();
|
||||
@ -326,5 +340,10 @@ int main(int argc, char * argv[]) {
|
||||
// Print the list of headers that have the ICG:(No) comment
|
||||
printAttributes.printICGNoFiles();
|
||||
|
||||
if (icgDiagConsumer->error_in_user_code) {
|
||||
std::cout << color(ERROR, "Trick build was terminated due to error in user code!") << std::endl;
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -7,7 +7,11 @@ import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.net.SocketTimeoutException;
|
||||
|
||||
|
||||
/**
|
||||
* a generic variable server client that provides for sending commands and
|
||||
@ -54,12 +58,30 @@ public class VariableServerConnection implements AutoCloseable {
|
||||
* @throws IOException IOException
|
||||
* @throws SecurityException SecurityException
|
||||
*/
|
||||
public VariableServerConnection(String host, int port) throws UnknownHostException, IOException, SecurityException {
|
||||
public VariableServerConnection(String host, int port) throws UnknownHostException, IOException, SecurityException, SocketTimeoutException {
|
||||
socket = new Socket(host, port);
|
||||
inputStream = new BufferedReader(new InputStreamReader(socket.getInputStream()));
|
||||
outputStream = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
|
||||
}
|
||||
|
||||
/**
|
||||
* attempts to connect to the Variable Server on the given host and port with a timeout
|
||||
*
|
||||
* @param host Variable Server machine name
|
||||
* @param port Variable Server port number
|
||||
* @param timeout Time out in milliseconds
|
||||
* @throws UnknownHostException UnknownHostException
|
||||
* @throws IOException IOException
|
||||
* @throws SecurityException SecurityException
|
||||
*/
|
||||
public VariableServerConnection(String host, int port, int timeout) throws UnknownHostException, IOException, SecurityException, SocketTimeoutException {
|
||||
socket = new Socket();
|
||||
SocketAddress addr = new InetSocketAddress(host, port);
|
||||
socket.connect(addr, timeout);
|
||||
inputStream = new BufferedReader(new InputStreamReader(socket.getInputStream()));
|
||||
outputStream = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
|
||||
}
|
||||
|
||||
/**
|
||||
* sends the given command and any commands in the output stream's buffer
|
||||
* to the Variable Server. The command is written to the output stream,
|
||||
|
@ -29,6 +29,7 @@ import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.MulticastSocket;
|
||||
import java.net.UnknownHostException;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.CharBuffer;
|
||||
import java.nio.channels.NotYetConnectedException;
|
||||
@ -171,6 +172,10 @@ public class SimControlApplication extends TrickApplication implements PropertyC
|
||||
private static String host;
|
||||
private static int port = -1;
|
||||
private static boolean isRestartOptionOn;
|
||||
//True if an error was encountered during the attempt to connect to Variable Server during intialize()
|
||||
private boolean errOnInitConnect = false;
|
||||
//Time out when attempting to establish connection with Variable Server in milliseconds
|
||||
private int varServerTimeout = 5000;
|
||||
|
||||
// The object of SimState that has Sim state data.
|
||||
private SimState simState;
|
||||
@ -405,22 +410,30 @@ public class SimControlApplication extends TrickApplication implements PropertyC
|
||||
String errMsg = "Error: SimControlApplication:getInitializationPacket()";
|
||||
try {
|
||||
if (host != null && port != -1) {
|
||||
commandSimcom = new VariableServerConnection(host, port);
|
||||
commandSimcom = new VariableServerConnection(host, port, varServerTimeout);
|
||||
} else {
|
||||
commandSimcom = null;
|
||||
}
|
||||
} catch (UnknownHostException host_exception) {
|
||||
/** The IP address of the host could not be determined. */
|
||||
errMsg += "\n Unknown host \""+host+"\"";
|
||||
errMsg += "\n Please use a valid host name (e.g. localhost)";
|
||||
printErrorMessage(errMsg);
|
||||
errMsg += "\n Please use a valid host name (e.g. localhost)";
|
||||
errOnInitConnect = true;
|
||||
printErrorMessage(errMsg);
|
||||
} catch (SocketTimeoutException ste) {
|
||||
/** Connection attempt timed out. */
|
||||
errMsg += "\n Connection Timeout \""+host+"\"";
|
||||
errMsg += "\n Please try a different host name (e.g. localhost)";
|
||||
errOnInitConnect = true;
|
||||
printErrorMessage(errMsg);
|
||||
} catch (IOException ioe) {
|
||||
/** Port number is unavailable, or there is no connection, etc. */
|
||||
errMsg += "\n Invalid TCP/IP port number \""+port+"\"";
|
||||
errMsg += "\n Please check the server and enter a proper port number!";
|
||||
errMsg += "\n IOException ..." + ioe;
|
||||
errMsg += "\n If there is no connection, please make sure SIM is up running properly!";
|
||||
printErrorMessage(errMsg);
|
||||
errOnInitConnect = true;
|
||||
printErrorMessage(errMsg);
|
||||
}
|
||||
|
||||
if (commandSimcom == null) {
|
||||
@ -644,6 +657,10 @@ public class SimControlApplication extends TrickApplication implements PropertyC
|
||||
view.setToolBar(createToolBar());
|
||||
view.setStatusBar(createStatusBar());
|
||||
|
||||
if(errOnInitConnect && (runningSimList != null) ) {
|
||||
runningSimList.addItem("localhost : " + port);
|
||||
}
|
||||
|
||||
show(view);
|
||||
}
|
||||
|
||||
@ -1396,7 +1413,7 @@ public class SimControlApplication extends TrickApplication implements PropertyC
|
||||
// Reset the packet length or future messages will be clipped.
|
||||
packet.setLength(buffer.length);
|
||||
// version Trick 10 or later
|
||||
if (info[7] != null && info[7].startsWith("10.")) {
|
||||
if (info[7] != null) {
|
||||
if (runningSimList != null) {
|
||||
String hostPort = info[0] + " : " + info[1] + " (" + info[5] + " " + info[6] + ")";
|
||||
if (!UIUtils.comboBoxContains((DefaultComboBoxModel)runningSimList.getModel(), hostPort)) {
|
||||
|
@ -9,7 +9,7 @@ include $(dir $(lastword $(MAKEFILE_LIST)))../../../../share/trick/makefiles/Mak
|
||||
|
||||
# Flags passed to the preprocessor.
|
||||
TRICK_CPPFLAGS += -I$(GTEST_HOME)/include -I$(TRICK_HOME)/include -g -Wall -Wextra ${TRICK_SYSTEM_CXXFLAGS} ${TRICK_TEST_FLAGS}
|
||||
|
||||
TRICK_LIBS = -L${TRICK_LIB_DIR} -ltrick -ltrick_units -ltrick_mm -ltrick_pyip -ltrick_connection_handlers -ltrick_comm
|
||||
LIBS = -L${GTEST_HOME}/lib64 -L${GTEST_HOME}/lib -lgtest -lgtest_main
|
||||
|
||||
|
||||
@ -41,7 +41,7 @@ GetTimeOfDayClock_test.o : GetTimeOfDayClock_test.cpp
|
||||
$(TRICK_CXX) $(TRICK_CPPFLAGS) -c $<
|
||||
|
||||
GetTimeOfDayClock_test : ${GETTIMEOFDAY_CLOCK_OBJECTS}
|
||||
$(TRICK_CXX) $(TRICK_SYSTEM_LDFLAGS) $(TRICK_CPPFLAGS) -o $@ $^ ${LIBS}
|
||||
$(TRICK_CXX) $(TRICK_SYSTEM_LDFLAGS) $(TRICK_CPPFLAGS) -o $@ $^ $(TRICK_LIBS) ${LIBS}
|
||||
|
||||
exec_get_rt_nap_stub.o : exec_get_rt_nap_stub.cpp
|
||||
$(TRICK_CXX) $(TRICK_CPPFLAGS) -c $<
|
||||
|
@ -253,8 +253,9 @@ int Trick::CommandLineArguments::process_sim_args(int nargs , char **args) {
|
||||
}
|
||||
/* Output data directory */
|
||||
output_dir = user_output_dir = argv[++ii];
|
||||
|
||||
|
||||
if (!strncmp("-OO", argv[ii-1], (size_t) 3)) {
|
||||
output_dir = output_dir + "/" + run_dir;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,7 @@ TRICK_CXXFLAGS += -I$(GTEST_HOME)/include -I$(TRICK_HOME)/include -g -Wall -Wext
|
||||
MM_OBJECTS = $(TRICK_HOME)/trick_source/sim_services/MemoryManager/object_${TRICK_HOST_CPU}/extract_bitfield.o \
|
||||
$(TRICK_HOME)/trick_source/sim_services/MemoryManager/object_${TRICK_HOST_CPU}/extract_unsigned_bitfield.o
|
||||
|
||||
TRICK_LIBS = -L${TRICK_LIB_DIR} -ltrick_mm -ltrick_units -ltrick -ltrick_mm -ltrick_units -ltrick
|
||||
TRICK_LIBS = -L${TRICK_LIB_DIR} -ltrick_mm -ltrick_units -ltrick -ltrick_mm -ltrick_units -ltrick -ltrick_pyip -ltrick_connection_handlers -ltrick_comm -ltrick_mm -ltrick_units -ltrick
|
||||
TRICK_EXEC_LINK_LIBS += -L${GTEST_HOME}/lib64 -L${GTEST_HOME}/lib -lgtest -lgtest_main -lpthread
|
||||
|
||||
|
||||
|
@ -182,7 +182,7 @@ void Trick::DataRecordDispatcher::remove_all_groups() {
|
||||
|
||||
Trick::DataRecordGroup * Trick::DataRecordDispatcher::get_group(std::string in_name) {
|
||||
std::vector <Trick::DataRecordGroup *>::iterator it ;
|
||||
for ( it = groups.begin() ; it != groups.end() ; it++ ) {
|
||||
for ( it = groups.begin() ; it != groups.end() ; ++it ) {
|
||||
if ( ! (*it)->get_group_name().compare(in_name) )
|
||||
return *it ;
|
||||
}
|
||||
|
@ -512,7 +512,7 @@ int Trick::DataRecordGroup::restart() {
|
||||
std::vector <Trick::DataRecordBuffer *>::iterator drb_it ;
|
||||
|
||||
/* delete the current rec_buffer */
|
||||
for ( drb_it = rec_buffer.begin() ; drb_it != rec_buffer.end() ; drb_it++ ) {
|
||||
for ( drb_it = rec_buffer.begin() ; drb_it != rec_buffer.end() ; ++drb_it ) {
|
||||
delete *drb_it ;
|
||||
}
|
||||
rec_buffer.clear() ;
|
||||
@ -520,7 +520,7 @@ int Trick::DataRecordGroup::restart() {
|
||||
add_time_variable() ;
|
||||
|
||||
/* delete the current change_buffer contents */
|
||||
for ( drb_it = change_buffer.begin() ; drb_it != change_buffer.end() ; drb_it++ ) {
|
||||
for ( drb_it = change_buffer.begin() ; drb_it != change_buffer.end() ; ++drb_it ) {
|
||||
delete *drb_it ;
|
||||
}
|
||||
change_buffer.clear() ;
|
||||
|
@ -44,7 +44,7 @@ int Trick::Environment::print_vars( FILE * fp ) {
|
||||
|
||||
std::map<std::string, std::string >::iterator it ;
|
||||
|
||||
for ( it = local_env.begin() ; it != local_env.end() ; it++ ) {
|
||||
for ( it = local_env.begin() ; it != local_env.end() ; ++it ) {
|
||||
fprintf(fp, "%s = %s\n", it->first.c_str(), it->second.c_str());
|
||||
}
|
||||
|
||||
|
@ -30,7 +30,7 @@ void Trick::EventProcessor::add_event(Trick::Event * in_event) {
|
||||
*/
|
||||
void Trick::EventProcessor::remove_event(Trick::Event * in_event) {
|
||||
std::multiset< Trick::Event *, CompareEventPtrs >::iterator sit = event_set.begin() ;
|
||||
for (sit=event_set.begin(); sit!=event_set.end(); sit++) {
|
||||
for (sit=event_set.begin(); sit!=event_set.end(); ++sit) {
|
||||
if ((*sit) == in_event) {
|
||||
event_set.erase(sit) ;
|
||||
break;
|
||||
|
@ -148,7 +148,7 @@ int Trick::Executive::add_job_to_queue( Trick::JobData * job ) {
|
||||
/* Add job to convienience constructs for easy retrival */
|
||||
all_jobs.insert(std::pair<std::string, JobData *>(job->name,job)) ;
|
||||
all_jobs_vector.push_back(job) ;
|
||||
for ( it = job->tags_begin() ; it != job->tags_end() ; it++ ) {
|
||||
for ( it = job->tags_begin() ; it != job->tags_end() ; ++it ) {
|
||||
all_tagged_jobs.insert(std::pair<std::string, JobData *>(*it,job)) ;
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,7 @@ Trick::JobData * Trick::Executive::get_job(std::string job_name, unsigned int j_
|
||||
range = all_jobs.equal_range(job_name) ;
|
||||
|
||||
/** @li Move to the j_instance-th item in the list */
|
||||
for ( it = range.first , ii = 1 ; (it != range.second) && (ii < j_instance) ; it++ , ii++ ) ;
|
||||
for ( it = range.first , ii = 1 ; (it != range.second) && (ii < j_instance) ; ++it , ii++ ) ;
|
||||
|
||||
/** @li If the j_instance-th item doesn't exist return NULL */
|
||||
if ( it == range.second ) {
|
||||
|
@ -40,7 +40,7 @@ int Trick::Executive::remove_jobs( Trick::SimObject * in_sim_object ) {
|
||||
}
|
||||
|
||||
/* search the executive queues for the job and remove it if found */
|
||||
for ( std::vector <Trick::JobData *>::iterator jit = in_sim_object->jobs.begin() ; jit != in_sim_object->jobs.end() ; jit++ ) {
|
||||
for ( std::vector <Trick::JobData *>::iterator jit = in_sim_object->jobs.begin() ; jit != in_sim_object->jobs.end() ; ++jit ) {
|
||||
std::map<std::string, int>::iterator class_id_it ;
|
||||
std::map<int, Trick::ScheduledJobQueue *>::iterator queue_it ;
|
||||
Trick::ScheduledJobQueue * curr_queue ;
|
||||
|
@ -17,7 +17,7 @@ int Trick::Executive::delete_sim_object( Trick::SimObject * in_object ) {
|
||||
std::vector <Trick::SimObject *>::iterator so_it ;
|
||||
std::vector <Trick::Scheduler *>::iterator sched_it ;
|
||||
|
||||
for ( so_it = in_object->pre_component_objects.begin() ; so_it != in_object->pre_component_objects.end() ; so_it++ ) {
|
||||
for ( so_it = in_object->pre_component_objects.begin() ; so_it != in_object->pre_component_objects.end() ; ++so_it ) {
|
||||
delete_sim_object((*so_it)) ;
|
||||
}
|
||||
|
||||
@ -31,11 +31,11 @@ int Trick::Executive::delete_sim_object( Trick::SimObject * in_object ) {
|
||||
|
||||
remove_jobs( in_object ) ;
|
||||
|
||||
for ( sched_it = other_schedulers.begin() ; sched_it != other_schedulers.end() ; sched_it++ ) {
|
||||
for ( sched_it = other_schedulers.begin() ; sched_it != other_schedulers.end() ; ++sched_it ) {
|
||||
(*sched_it)->delete_sim_object(in_object) ;
|
||||
}
|
||||
|
||||
for ( so_it = in_object->post_component_objects.begin() ; so_it != in_object->post_component_objects.end() ; so_it++ ) {
|
||||
for ( so_it = in_object->post_component_objects.begin() ; so_it != in_object->post_component_objects.end() ; ++so_it ) {
|
||||
delete_sim_object((*so_it)) ;
|
||||
}
|
||||
|
||||
|