Fast Forward Configure GUI Branch (#1275)

Fast Forward
This commit is contained in:
Scott Fennell 2022-06-01 14:20:49 -05:00 committed by GitHub
parent b2c12b34fe
commit fdd2b9a674
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
83 changed files with 4222 additions and 4891 deletions

32
.github/workflows/report_linux.yml vendored Normal file
View File

@ -0,0 +1,32 @@
name: 'Report'
on:
workflow_run:
workflows: ['Linux'] # runs after CI workflow
types:
- completed
jobs:
report:
strategy:
fail-fast: false
matrix:
cfg:
#-------- Operating Systems ----------------
- { os: ubuntu, tag: 18.04, arch: debian, arch_ver: 10 }
- { os: ubuntu, tag: 20.04, arch: debian, arch_ver: 11 }
- { os: debian, tag: 10, arch: debian, arch_ver: 10 }
- { os: debian, tag: 11, arch: debian, arch_ver: 11 }
- { os: centos, tag: 7, arch: rhel, arch_ver: 7 }
- { os: rockylinux, tag: 8, arch: rhel, arch_ver: 8 }
- { os: oraclelinux, tag: 8, arch: rhel, arch_ver: 8 }
- { os: almalinux, tag: 8, arch: rhel, arch_ver: 8 }
python: [2, 3]
runs-on: ubuntu-latest
steps:
- uses: dorny/test-reporter@v1
with:
artifact: Trick_${{matrix.cfg.os}}${{matrix.cfg.tag}}_py${{matrix.python}} # artifact name
name: Results_Trick_${{matrix.cfg.os}}${{matrix.cfg.tag}}_py${{matrix.python}} # Name of the check run which will be created
path: '*.xml' # Path to test results (inside artifact .zip)
reporter: java-junit # Format of test results

View File

@ -7,6 +7,7 @@ on:
- '.github/workflows/**'
- '!.github/workflows/test_linux.yml'
pull_request:
workflow_dispatch:
jobs:
build:
@ -15,15 +16,15 @@ jobs:
matrix:
cfg:
#-------- Operating Systems ----------------
- { os: ubuntu, tag: 18.04, arch: debian } # EOL April 2023
- { os: ubuntu, tag: 20.04, arch: debian } # EOL April 2025
- { os: debian, tag: 10, arch: debian } # EOL 2024
- { os: centos, tag: 7, arch: rhel } # EOL June 2024
# - { os: centos, tag: 8, arch: rhel } # 8 as of April 2020
- { os: rockylinux, tag: latest, arch: rhel}
# - { os: fedora, tag: latest, arch: rhel } # 31 as of April 2020
# - { os: fedora, tag: 33, arch: rhel } # feeling confident?
# - { os: fedora, tag: rawhide, arch: rhel } # for thrill-seekers only
- { os: ubuntu, tag: 18.04, arch: debian, arch_ver: 10 }
- { os: ubuntu, tag: 20.04, arch: debian, arch_ver: 11 }
- { os: debian, tag: 10, arch: debian, arch_ver: 10 }
- { os: debian, tag: 11, arch: debian, arch_ver: 11 }
- { os: centos, tag: 7, arch: rhel, arch_ver: 7 }
- { os: rockylinux, tag: 8, arch: rhel, arch_ver: 8 }
- { os: oraclelinux, tag: 8, arch: rhel, arch_ver: 8 }
- { os: almalinux, tag: 8, arch: rhel, arch_ver: 8 }
python: [2, 3]
#-------- Defaults --------------------------
include:
@ -54,13 +55,14 @@ jobs:
libxt-dev
libmotif-common
libmotif-dev
python2.7-dev
zlib1g-dev
llvm-dev
libclang-dev
libudunits2-dev
libgtest-dev
install_gtest: cd /usr/src/gtest && cmake . && make && cp libgtest* /usr/lib/
default-jdk
python2.7-dev
python3-dev
#-------- RHEL Dependencies ----------------
- cfg: { arch: rhel }
arch_deps: >-
@ -80,78 +82,129 @@ jobs:
udunits2-devel
which
zlib-devel
gtest-devel
#-------- Ubuntu Only Dependencies ----------------
- cfg: { os: ubuntu }
os_deps: >-
openjdk-11-jdk
#-------- Debian OS Only Dependencies ----------------
- cfg: { os: debian }
os_deps: >-
openjdk-11-jdk
#-------- CentOS Only Dependencies ----------------
- cfg: { os: centos }
python2-devel
python3-devel
#-------- RHEL 7-based Only Dependencies ----------------
- cfg: { arch: rhel, arch_ver: 7 }
pkg_mgr: yum
conf_pkg: yum -y install epel-release && yum -y update
conf_pkg: |
yum -y install epel-release
yum -y update
os_deps: >-
libX11-devel
libXt-devel
#-------- Fedora Only Dependencies ----------------
# - cfg: { os: fedora }
# pkg_mgr: dnf
# os_deps: >-
# swig
# perl-Text-Balanced
# python-devel
# diffutils
#-------- Version Specific Dependencies ----------------
- cfg: { os: ubuntu, tag: 20.04 }
conf_pkg: DEBIAN_FRONTEND=noninteractive && apt-get update && apt-get install -y tzdata
install_gtest: cd /usr/src/gtest && cmake . && make && cp lib/libgtest* /usr/lib/
tag_deps: >-
python3.8-dev
- cfg: { os: centos, tag: 7 }
tag_deps: >-
swig3
python-devel
# - cfg: { os: centos, tag: 8 }
# pkg_mgr: dnf
# 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-Linux-* &&
# dnf -y install epel-release &&
# dnf -y update &&
# dnf install -y 'dnf-command(config-manager)' &&
# dnf config-manager --enable powertools
# tag_deps: >-
# swig
# python3-devel diffutils
- cfg: { os: rockylinux }
gtest-devel
#-------- RHEL 8-based Only Dependencies ----------------
- cfg: { arch: rhel, arch_ver: 8 }
pkg_mgr: dnf
conf_pkg: >
dnf -y install epel-release &&
dnf -y update &&
dnf install -y 'dnf-command(config-manager)' &&
dnf config-manager --enable powertools
tag_deps: >-
swig
python3-devel diffutils
diffutils
conf_pkg: |
dnf -y install epel-release
dnf -y update
dnf install -y 'dnf-command(config-manager)'
install_gtest: |
dnf config-manager --enable powertools
dnf install -y gtest-devel
#-------- Debian 10-based Only Dependencies ----------------
- cfg: { arch: debian, arch_ver: 10 }
install_gtest: |
apt-get install -y libgtest-dev
cd /usr/src/gtest
cmake .
make
cp libgtest* /usr/lib/
#-------- Debian 11-based Only Dependencies ----------------
- cfg: { arch: debian, arch_ver: 11 }
conf_pkg: |
export DEBIAN_FRONTEND=noninteractive
apt-get update
apt-get install -y tzdata
install_gtest: |
apt-get install -y libgtest-dev
cd /usr/src/gtest
cmake .
make
cp lib/libgtest* /usr/lib/
#-------- OS and Version Specific Dependencies ----------------
- cfg: { os: oraclelinux }
install_gtest: |
dnf config-manager --enable ol8_codeready_builder
dnf install -y gtest-devel
#-------- Job definition ----------------
runs-on: ubuntu-18.04
runs-on: ubuntu-latest
container: docker://${{matrix.cfg.os}}:${{matrix.cfg.tag}}
steps:
- name: Update Package Manager
run: ${{matrix.conf_pkg}}
- name: Install Dependencies
run: |
${{matrix.pkg_mgr}} ${{matrix.install_cmd}} ${{matrix.deps}} ${{matrix.arch_deps}} ${{matrix.os_deps}} ${{matrix.tag_deps}}
run: >
${{matrix.pkg_mgr}}
${{matrix.install_cmd}}
${{matrix.deps}}
${{matrix.arch_deps}}
${{matrix.os_deps}}
${{matrix.tag_deps}}
- name: Install GTest
run: ${{matrix.install_gtest}}
- name: Checkout repository
uses: actions/checkout@master
- name: Build trick
- name: Configure Trick
run: |
export MAKEFLAGS=-j`nproc`
export PYTHON_VERSION=${{matrix.python}}
./configure
- name: Build Trick
run: |
export MAKEFLAGS=-j`nproc`
make
- name: Test
run: make test
- name: Upload Tests
uses: actions/upload-artifact@v3.0.0
if: success() || failure() # run this step even if previous step failed
with:
name: Trick_${{matrix.cfg.os}}${{matrix.cfg.tag}}_py${{matrix.python}}
path: trick_test/*.xml
retention-days: 1
# Uncomment for build artifacts
# - name: Upload Trick Build
# uses: actions/upload-artifact@v3.0.0
# with:
# name: Trick_${{matrix.cfg.os}}${{matrix.cfg.tag}}_py${{matrix.python}}
# path: |
# bin
# include
# lib
# share
# libexec
# retention-days: 1
# report:
# needs: [build]
# strategy:
# fail-fast: false
# matrix:
# cfg:
# #-------- Operating Systems ----------------
# - { os: ubuntu, tag: 18.04, arch: debian, arch_ver: 10 }
# - { os: ubuntu, tag: 20.04, arch: debian, arch_ver: 11 }
# - { os: debian, tag: 10, arch: debian, arch_ver: 10 }
# - { os: debian, tag: 11, arch: debian, arch_ver: 11 }
# - { os: centos, tag: 7, arch: rhel, arch_ver: 7 }
# - { os: rockylinux, tag: 8, arch: rhel, arch_ver: 8 }
# - { os: oraclelinux, tag: 8, arch: rhel, arch_ver: 8 }
# - { os: almalinux, tag: 8, arch: rhel, arch_ver: 8 }
# python: [2, 3]
# runs-on: ubuntu-latest
# steps:
# - uses: dorny/test-reporter@v1
# with:
# artifact: Trick_${{matrix.cfg.os}}${{matrix.cfg.tag}}_py${{matrix.python}} # artifact name
# name: Results_Trick_${{matrix.cfg.os}}${{matrix.cfg.tag}}_py${{matrix.python}} # Name of the check run which will be created
# path: '*.xml' # Path to test results (inside artifact .zip)
# reporter: java-junit # Format of test results

View File

@ -28,11 +28,10 @@ jobs:
# sudo installer -pkg /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.15.pkg -target /
brew install --cask xquartz
brew install llvm@11 swig udunits openmotif maven
brew link llvm llvm@11
- name: Build Trick
run: |
export MAKEFLAGS=-j4
./configure
./configure --with-llvm=/usr/local/opt/llvm@11
make
- name: Run tests
run: |

View File

@ -420,7 +420,7 @@ AC_ARG_WITH(
PYTHON_HOME="$withval"
AC_PATH_PROGS(PYTHON, python${PYTHON_VERSION} python python3, nopython, "$PYTHON_HOME")
AS_IF(
[test "$ac_cv_path_PYTHON" = "nopython"],
[test "$ac_cv_path_PYTHON" = "" || test "$ac_cv_path_PYTHON" = "nopython"],
AC_MSG_ERROR([could not find python<version> python or python3 in the specefied path. Please install the python development package]),
[]
)
@ -428,7 +428,7 @@ AC_ARG_WITH(
PYTHON_MAJOR=`${PYTHON} -c 'import sys; print(str(sys.version_info[[0]]))'`
AC_PATH_PROGS(PYTHON_CONFIG, python${PYTHON_MAJORMINOR}-config python${PYTHON_MAJOR}-config python${PYTHON_VERSION}-config python-config, nopython-config, "$PYTHON_HOME")
AS_IF(
[test "$ac_cv_path_PYTHON_CONFIG" = "nopython-config"],
[test "$ac_cv_path_PYTHON_CONFIG" = "" || test "$ac_cv_path_PYTHON_CONFIG" = "nopython-config"],
AC_MSG_ERROR([could not find python<major>-config python<major.minor>-config or python-config in the specified path. Please install the python development package]),
[]
)
@ -436,7 +436,7 @@ AC_ARG_WITH(
[
AC_PATH_PROGS(PYTHON, python${PYTHON_VERSION} python python3, nopython)
AS_IF(
[test "$ac_cv_path_PYTHON" = "nopython"],
[test {"$ac_cv_path_PYTHON" = "" || test "${ac_cv_path_PYTHON}" = "nopython"}],
AC_MSG_ERROR([could not find python<version> python or python3. Please install the python development package]),
[]
)
@ -444,7 +444,7 @@ AC_ARG_WITH(
PYTHON_MAJOR=`${PYTHON} -c 'import sys; print(str(sys.version_info[[0]]))'`
AC_PATH_PROGS(PYTHON_CONFIG, python${PYTHON_MAJORMINOR}-config python${PYTHON_MAJOR}-config python${PYTHON_VERSION}-config python-config, nopython-config)
AS_IF(
[test "$ac_cv_path_PYTHON_CONFIG" = "nopython-config"],
[test "$ac_cv_path_PYTHON_CONFIG" = "" || test "$ac_cv_path_PYTHON_CONFIG" = "nopython-config"],
AC_MSG_ERROR([could not find python<major>-config python<major.minor>-config or python-config. Please install the python development package]),
[]
)

7216
configure generated vendored

File diff suppressed because it is too large Load Diff

View File

@ -10,7 +10,7 @@ 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] | 3.4.2+ (<=11 on mac) | C/C++ Compiler | Utilized by the interface code generator. | |
| [clang]/[llvm] | <=13 (14 not currently supported) | C/C++ Compiler | Utilized by the interface code generator. | |
| [python] | 2.7+ | Programming Language | Lets the user interact with a simulation. | Trick has been tested up to python 3.9 as of 02/21 |
| [perl] | 5.6+ | Programming Language | Allows executable scripts in the bin directory to run. | |
| [java] | 11+ | Programming Language | Necessary for Trick GUIs. | |
@ -53,7 +53,7 @@ Trick runs on GNU/Linux and MacOSX, though any System V/POSIX compatible UNIX wo
|[CentOS 7](#redhat7)|
|[Fedora](#fedora)|
|[Ubuntu](#ubuntu)|
|[MacOS](#macos)|
|[macOS](#macos)|
|[Windows 10 (Linux Subsystem Only)](#windows10)|
---
@ -169,107 +169,55 @@ export PYTHON_VERSION=3
proceed to [Install Trick](#install) section of the install guide
<a name="macos"></a>
### macOS BigSur
### macOS Monterey, Big Sur, Catalina
1. Install XCode from the App Store.
1. Install the latest Xcode. I recommend installing Xcode through the App Store.
2. Download and install Command Line Tools for macOS by opening a terminal and running the following command.
2. Download and install Xcode Command Line Tools for macOS. The following command in the terminal should do the job:
```bash
xcode-select --install
```
3. Install Homebrew, macOS's unofficial package manager.
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/
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).
```bash
# bash
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
```
4. Install the remaining dependencies. Currently llvm 12 with homebrew is not supported, so we need to treat it specially by installing v11 and configuring trick to use it. Also when installing java (defaults to openjdk) with homebrew, we need to add it to our path.
```bash
brew install java xquartz llvm@11 swig maven udunits openmotif
brew install java xquartz swig maven udunits openmotif
```
IMPORTANT: Make sure to follow the instructions for adding java to your path provided by brew. If you missed them, you can see them again by using `brew info java`.
5. Download and un-compress the latest pre-built clang+llvm 13 from llvm-project github. Go to https://github.com/llvm/llvm-project/releases
and download the latest version of 13 from the release assets. 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.
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.
You can find the path of udunits by executing the following command:
IMPORTANT: when doing the configure step in the install trick section, you need to point trick to llvm@11. 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.
You can find the path of llvm and udunits by executing the following commands:
```
brew info llvm@11
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)>
```
IMPORTANT: Add java and javac from openjdk to your path.
e.g.
```
# temporarily for this terminal session:
export PATH="/usr/local/opt/openjdk/bin:$PATH"
# OR we can add it to .zshrc so it is always added to path when opening a new terminal:
echo 'export PATH="/usr/local/opt/openjdk/bin:$PATH"' >> ~/.zshrc
```
Openmotif may install dependent packages that conflict with other installations, fontconfig and freetype. Use the following command to skip installing these packages if you encounter conflicts.
```bash
brew install --ignore-dependencies openmotif
```
---
### macOS Catelina/Mojave
1. Install XCode from the App Store.
2. Download and install Command Line Tools for MacOSX by opening a terminal and running the following command.
```bash
xcode-select --install
```
3. Install system header files into /usr/include
```bash
### Catalina Only
sudo installer -pkg /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.15.pkg -target /
### Mojave Only
sudo installer -pkg /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg -target /
```
4. Install Homebrew, macOS's unofficial package manager.
```bash
# bash
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
```
or
```csh
# csh
curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install | ruby
```
5. Install the remaining dependencies. Currently llvm 12 with homebrew is not supported, so we need to treat it specially by installing v11 and linking it.
```bash
brew install java xquartz llvm@11 swig maven udunits openmotif
```
IMPORTANT: when doing the configure step in the install trick section, you need to point trick to llvm@11.
```
./configure --with-llvm=/usr/local/opt/llvm@11 <other configure flags>
Openmotif may install dependent packages that conflict with other installations, fontconfig and freetype. Use the following command to skip installing these packages if you encounter conflicts.
```bash
brew install --ignore-dependencies openmotif
./configure --with-llvm=/Users/trickguy/llvm13 --with-udunits=/usr/local/Cellar/udunits/2.2.28
```
proceed to [Install Trick](#install) section of the install guide
---
<a name="windows10"></a>
### Windows 10 (Linux Subsystem Only)
@ -315,7 +263,7 @@ cd ${HOME}/trick
./configure
```
The *configure* script will generate makefiles and locate project dependencies automatically. It may be necessary to specify dependency paths manually. Run the following command to see the possible options *configure* will accept.
The *configure* script will generate makefiles and locate project dependencies automatically. It may be necessary to specify dependency paths manually. Run the following command to see the possible options *configure* will accept. If you are having trouble with this step, make sure there were not details in the OS section of this document that you missed.
```bash
./configure --help

View File

@ -36,7 +36,7 @@ Note: drg is just an example name. Any name may be used.
### Adding a Variable To Be Recorded
To add variables to the recording group call the <tt>drg.add_variable("<string_of_variable_name">)</tt> method of the recording group.
To add variables to the recording group call the <tt>drg.add_variable("<string_of_variable_name>")</tt> method of the recording group.
For example:
```python
@ -44,7 +44,7 @@ drg.add_variable("ball.obj.state.output.position[0]")
drg.add_variable("ball.obj.state.output.position[1]")
```
An optional alias may also be specified in the method as <tt>drg.add_variable("<string_of_variable_name"> [, "<alias>"])</tt>.
An optional alias may also be specified in the method as <tt>drg.add_variable("<string_of_variable_name>" [, "<alias>"])</tt>.
If an alias is present as a second argument, the alias name will be used in the data recording file instead of the actual variable name.
For example:
@ -121,18 +121,18 @@ recording groups as well as record a single point of data.
```c++
/* C code */
dr_enable_group("<group_name">) ;
dr_disable_group("<group_name">) ;
dr_record_now_group("<group_name">) ;
dr_enable_group("<group_name>") ;
dr_disable_group("<group_name>") ;
dr_record_now_group("<group_name>") ;
```
This is the Python input file version:
```python
# Python code
trick.dr_enable_group("<group_name">) ; # same as <group_name>.enable()
trick.dr_disable_group("<group_name">) ; # same as <group_name>.disable()
trick.dr_record_now_group("<group_name">) ;
trick.dr_enable_group("<group_name>") ; # same as <group_name>.enable()
trick.dr_disable_group("<group_name>") ; # same as <group_name>.disable()
trick.dr_record_now_group("<group_name>") ;
```
### Changing the thread Data Recording runs on.

View File

@ -9,9 +9,8 @@ To configure Trick to support the civetweb web server, you'll need to
### Building the Civetweb Library
```bash
cd $(CIVETWEB_HOME)
make build
make WITH_ALL=1
mv $(CIVETWEB_HOME)/output/build/src/libcivetweb.a $(CIVETWEB_HOME)/lib
mkdir lib
make install-lib PREFIX=. CAN_INSTALL=1 WITH_WEBSOCKET=1
```
### Configuring Trick with Civetweb
```bash

View File

@ -540,40 +540,9 @@ that provide standard Trick Simulation functionality.
* `##include "cannon/include/cannon_analytic.h"` The S_define must `##include`
type definitions for all of the classes and structures that it uses. It also
needs to include prototypes for all of the functions that it calls. You may also
put the prototypes in the `S_define` block as shown below. But if you need to
call any of the C functions from the input file then you must include the
put the prototypes in the `S_define` block using ([user code blocks](/trick/documentation/building_a_simulation/Simulation-Definition-File#user-code-block)), but if you need to call any of the C functions from the input file then you must include the
prototypes in a header file (the preferred method).
```c++
/*********************************************************************
PURPOSE: (S_define Header)
LIBRARY_DEPENDENCY: ((cannon/src/cannon_analytic.c)
(cannon/src/cannon_init.c)
(cannon/src/cannon_shutdown.c))
*********************************************************************/
#include "sim_objects/default_trick_sys.sm"
##include "cannon/include/cannon.h"
%{
extern "C" {
extern int cannon_analytic(CANNON*) ;
}
%}
class CannonSimObject : public Trick::SimObject {
public:
CANNON cannon ;
CannonSimObject() {
("initialization") cannon_init( &cannon ) ;
("default_data") cannon_default_data( &cannon ) ;
(0.01, "scheduled") cannon_analytic( &cannon ) ;
("shutdown") cannon_shutdown( &cannon) ;
}
} ;
CannonSimObject dyn ;
```
**Listing 7a - `Alternate Way of Adding Prototypes to S_define`**
### Data Lines
`Class CannonSimObject : public Trick::SimObject`
@ -741,16 +710,14 @@ You should, ultimately see :
![Simulation Make Complete](images/SimMakeComplete.png)
Now, take a look at the sim directory. Is there an `S_main*.exe` file ??? If so,
cool deal. If not, scream!, then take a look at the next section "Troubleshooting A
Bad Build". If all went well, you will notice several other files now resident in
the `SIM_cannon_analytic` directory.
Now, take a look at the sim directory. Is there an `S_main*.exe` file?? (* is a wildcard, instead of * you will see the name of your platform). If so, cool deal. If not, scream!, then take a look at the next section "Troubleshooting A Bad Build". If all went well, you will notice several other files now resident in the `SIM_cannon_analytic` directory.
```bash
% ls
S_default.dat S_overrides.mk build
S_define S_sie.resource makefile
S_main_Darwin_13.exe S_source.hh trick
Modified_data S_overrides.mk makefile
RUN_test S_sie.resource trick.zip
S_define S_source.hh
S_main_<your_platform_name_here>.exe build
```
#### Troubleshooting A Bad Build

View File

@ -74,8 +74,7 @@ you installed Trick in your home directory, and you used the default name for
the repository, which is **trick**. If you named it something different, then
use that name instead in the scripts below.
If you are using **bash**, then add the following lines to your **.profile**
file.
If you are using **bash or ksh**, then add the following lines to the file that is automatically sourced by your terminal. Based on your platform this could be **.profile, .bash_profile, .bashrc, .zshrc** or others. Google "How to edit PATH variable" on google to find a wealth of information on this subject.
```bash
export TRICK_HOME="${HOME}/trick"

View File

@ -264,7 +264,7 @@ int cannon_deriv(CANNON* C) {
return(0);
}
```
:point_right: **Add cannon\_deriv() to cannon\_numeric.c.**
👉 **Add cannon\_deriv() to cannon\_numeric.c.**
<a id=creating-an-integration-class-job></a>
#### Creating an Integration Class Job
@ -320,7 +320,7 @@ int cannon_integ(CANNON* C) {
```
:point_right: **Add cannon\_integ() to cannon\_numeric.c.**
👉 **Add cannon\_integ() to cannon\_numeric.c.**
<a id=updating-the-s_define-file></a>
## Updating the S_define File
@ -373,7 +373,7 @@ void create_connections() {
The first line here defines an integration scheduler called `dyn_integloop` that executes `derivative` and `integration` jobs in the *dyn* SimObject. The integration rate is specified in parentheses.
`create_connections` is a special function-like construct whose code is copied into S_source.cpp and is executed directly after SimObject instantiations. Common uses are to 1) instanciate integrators, and 2) connect data structures between SimObjects.
`create_connections` is a special function-like construct whose code is copied into S_source.cpp and is executed directly after SimObject instantiations. Common uses are to 1) instantiate integrators, and 2) connect data structures between SimObjects.
`dyn_integloop.getIntegrator` configures our integration scheduler. Its first argument specifies the integration algorithm to be used. In the case `Runge_Kutta_4`. The second argument is the number of variables that are to be integrated. There are four variables for this simulation (pos[0], pos[1], vel[0], vel[1]).

View File

@ -62,8 +62,8 @@ The `realtime.py` file must be included in the RUN_test/input.py file. When
finished, the latest version of the input file should look like the following:
```python
execfile("Modified_data/realtime.py")
execfile("Modified_data/cannon.dr")
exec(open("Modified_data/realtime.py").read())
exec(open("Modified_data/cannon.dr").read())
trick.stop(5.2)
```

View File

@ -79,7 +79,7 @@ TV_cannon file we saved off in the last step. There are two ways to do this.
```bash
% cd $HOME/trick_sims/SIM_cannon_analytic
% S_main*exe RUN_test/input.py
% ./S_main*exe RUN_test/input.py &
```
1. Choose "Actions->Start Trick View" from sim control panel.

View File

@ -64,10 +64,9 @@ is to configure the sessions.
## Approach
Calling functions and setting simulation variables using the variable server is
done as in the input file. That is, the client sends Python code to the variable
server where it's executed, to call functions, set variables, or both. In the
following sections we'll see examples of these. We'll also learn how to use the
Calling functions and setting simulation variables with the variable server client is a similar process to doing the same with the input file. The client sends Python code to the variable
server, where it's executed to call functions, set variables, or both. In the
following sections, we'll see examples of these. We'll also learn how to use the
variable server API to get data back to the client.
<a id=a-simple-variable-server-client></a>
@ -81,7 +80,7 @@ position data, and prints the periodic responses to the screen.
**Listing - CannonDisplay_Rev1.py**
```python
#!/usr/bin/python
#!/usr/bin/python2
import sys
import socket
@ -89,7 +88,7 @@ import socket
if ( len(sys.argv) == 2) :
trick_varserver_port = int(sys.argv[1])
else :
print( "Usage: vsclient <port_number>")
print( "Usage: python<version_number> CannonDisplay_Rev1.py <port_number>")
sys.exit()
# 2.0 Connect to the variable server.
@ -178,7 +177,7 @@ send messages using an ASCII encoding (rather than binary).
The two [**var_add**](#api-var-add) commands add "dyn.cannon.pos[0]"
and "dyn.cannon.pos[1]" to the session variable list.
:warning: Please notice that the quotes around the variable names must be
⚠️ Please notice that the quotes around the variable names must be
escaped with the '\' (backslash) character.
```
@ -235,7 +234,7 @@ two ways. We can 1) call [**var_clear**](#api-var-clear) to clear the the list,
or 2) we can call [**var_remove**](#api-var-remove). Specifically we could do
the following:
```client_socket.send("trick.var_remove(\"dyn.cannon.init_angle\")\n )```
```client_socket.send("trick.var_remove(\"dyn.cannon.init_angle\")\n")```
So, when we run the modified client, the first three lines of the output should
look something like the following.
@ -275,7 +274,7 @@ The listing below implements a GUI client using **Python** and
**Listing - CannonDisplay_Rev2.py**
```python
#!/usr/bin/python
#!/usr/bin/python2
import sys
import socket
import math

View File

@ -29,6 +29,7 @@ namespace Trick {
void set_port(unsigned short in_port) ;
std::string get_user_tag() ;
const std::string& get_user_tag_ref() ;
void set_user_tag(std::string in_tag) ;
void set_source_address(const char * address) ;

View File

@ -1,4 +1,4 @@
#!/usr/bin/python
#!/usr/bin/env python3
import sys
import xml.etree.ElementTree as ET

View File

@ -1,4 +1,4 @@
#!/usr/bin/python
#!/usr/bin/env python3
import os

View File

@ -0,0 +1,5 @@
trick.stop(15.0);
trick.real_time_enable()
trick.sim_control_panel_set_enabled(True)

View File

@ -0,0 +1,21 @@
/************************TRICK HEADER*************************
PURPOSE:
()
LIBRARY DEPENDENCIES:
*************************************************************/
#include "sim_objects/default_trick_sys.sm"
##include "starter.h"
class StarterSimObject : public Trick::SimObject {
public:
Starter starter;
StarterSimObject() {
}
};
StarterSimObject starterSimObject;

View File

@ -0,0 +1,3 @@
TRICK_CFLAGS += -I./models
TRICK_CXXFLAGS += -I./models

View File

@ -0,0 +1,5 @@
#include "starter.h"
Starter::Starter() {
}

View File

@ -0,0 +1,14 @@
/*************************************************************************
PURPOSE: (Starter class)
LIBRARY DEPENDENCY:
(
(starter.cpp)
)
**************************************************************************/
class Starter {
public:
Starter();
public:
enum {VAR = 6};
};

View File

@ -7,6 +7,7 @@ unexport TRICK_PYTHON_PATH
SIMS_TO_COMPILE_ONLY = \
SIM_alloc_test \
SIM_anon_enum \
SIM_default_member_initializer \
SIM_delete_default_constructor \
SIM_demo_inputfile \

0
trick_sims/SIM_balloon/Modified_data/realtime.py Executable file → Normal file
View File

View File

View File

0
trick_sims/SIM_balloon/models/balloon/src/Balloon.cpp Executable file → Normal file
View File

View File

0
trick_sims/SIM_contact/Modified_data/realtime.py Executable file → Normal file
View File

0
trick_sims/SIM_contact/RUN_Newtons_cradle/input.py Executable file → Normal file
View File

0
trick_sims/SIM_contact/RUN_ball_line/input.py Executable file → Normal file
View File

0
trick_sims/SIM_contact/RUN_multi_collision/input.py Executable file → Normal file
View File

0
trick_sims/SIM_contact/RUN_pool_break/input.py Executable file → Normal file
View File

0
trick_sims/SIM_contact/RUN_simple_collision/input.py Executable file → Normal file
View File

0
trick_sims/SIM_contact/RUN_test5/input.py Executable file → Normal file
View File

0
trick_sims/SIM_contact/S_define Executable file → Normal file
View File

0
trick_sims/SIM_contact/S_overrides.mk Executable file → Normal file
View File

View File

0
trick_sims/SIM_contact/models/contact/src/Contact.cpp Executable file → Normal file
View File

0
trick_sims/SIM_contact/models/graphics/Makefile Executable file → Normal file
View File

View File

0
trick_sims/SIM_lander/Modified_data/realtime.py Executable file → Normal file
View File

0
trick_sims/SIM_lander/RUN_test/input.py Executable file → Normal file
View File

0
trick_sims/SIM_lander/S_define Executable file → Normal file
View File

0
trick_sims/SIM_lander/S_overrides.mk Executable file → Normal file
View File

0
trick_sims/SIM_lander/models/graphics/Makefile Executable file → Normal file
View File

View File

0
trick_sims/SIM_lander/models/lander/include/Lander.hh Executable file → Normal file
View File

0
trick_sims/SIM_lander/models/lander/src/Lander.cpp Executable file → Normal file
View File

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
import matplotlib.pyplot as plt
import numpy as np

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
import matplotlib.pyplot as plt
import numpy as np

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
import matplotlib.pyplot as plt
import numpy as np

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
import matplotlib.pyplot as plt
import numpy as np

View File

@ -0,0 +1,10 @@
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)
simControlPanel = trick.SimControlPanel()
trick.add_external_application(simControlPanel)

View File

@ -0,0 +1,37 @@
import math
exec(open("Modified_data/realtime.py").read())
crewModule.dyn.position[0] = 0.0;
crewModule.dyn.position[1] = 0.0;
crewModule.dyn.position[2] = 3.0;
crewModule.dyn.mass_vehicle = 9300.0;
# crewModule.dyn.mass_vehicle = 20000.0;
xrot = math.radians(60.0);
crewModule.dyn.R[0][0] = 1.000000;
crewModule.dyn.R[0][1] = 0.000000;
crewModule.dyn.R[0][2] = 0.000000;
crewModule.dyn.R[1][0] = 0.000000;
crewModule.dyn.R[1][1] = math.cos(xrot);
crewModule.dyn.R[1][2] = -math.sin(xrot);
crewModule.dyn.R[2][0] = 0.000000;
crewModule.dyn.R[2][1] = math.sin(xrot);
crewModule.dyn.R[2][2] = math.cos(xrot);
# ==========================================
# Start the CM Display Graphics Client
#==========================================
varServerPort = trick.var_server_get_port();
CMDisplay_path = "models/CrewModuleGraphics/build/CrewModuleDisplay.jar"
if (os.path.isfile(CMDisplay_path)) :
CMDisplay_cmd = "java -jar " \
+ CMDisplay_path \
+ " " + str(varServerPort) + " &" ;
print(CMDisplay_cmd)
os.system( CMDisplay_cmd);
else :
print('==================================================================================')
print('CrewModuleDisplay needs to be built. Please \"cd\" into ../models/CrewModuleGraphics and type \"mvn package\".')
print('==================================================================================')

View File

@ -0,0 +1,27 @@
/************************************************************
PURPOSE:
( Simulate a Crew Module. )
LIBRARY DEPENDENCIES:
((CrewModule/src/CrewModuleDynamics.o)
(CrewModule/src/CrewModuleShape.o))
**************************************************************************/
#include "sim_objects/default_trick_sys.sm"
##include "CrewModule/include/CrewModuleDynamics.hh"
class CrewModuleSimObject : public Trick::SimObject {
public:
CrewModuleDynamics dyn;
CrewModuleSimObject() {
("default_data") dyn.init_defaults() ;
("derivative") dyn.calc_derivatives() ;
("integration") trick_ret = dyn.calc_state() ;
}
};
CrewModuleSimObject crewModule;
IntegLoop dyn_integloop(0.1) crewModule;
void create_connections() {
dyn_integloop.getIntegrator(Runge_Kutta_4, 18);
}

View File

@ -0,0 +1,2 @@
TRICK_CFLAGS += -Imodels
TRICK_CXXFLAGS += -Imodels

View File

@ -0,0 +1,66 @@
/************************************************************************
PURPOSE: (Simulate a ... .)
LIBRARY DEPENDENCIES:
((CrewModule/src/CrewModuleDynamics.o)((CrewModule/src/CrewModuleShape.o)))
**************************************************************************/
#ifndef CREW_MODULE_DYNAMICS_HH
#define CREW_MODULE_DYNAMICS_HH
#include "../include/CrewModuleShape.hh"
class CrewModuleDynamics {
public:
double R[3][3]; /* (--) Vehicle body to World rotation matrix. */
double Rdot[3][3];
double angular_velocity[3];
double I_body[3][3]; /* (kg*m2) Inertia Tensor in Body frame. */
double I_body_inverse[3][3];
double momentum[3]; /* (kg*m/s) Linear Momentum */
double force_total[3];
double force_gravity[3];
double force_buoyancy[3];
double force_drag[3];
double position[3]; // (m) Position (world coordinates).
double velocity[3]; // (m/s) Velocity (world coordinates).
double mass_vehicle; // (kg) Vehicle mass
double angular_momentum[3]; /* (kg*m2/s) Angular Momentum */
double torque_buoyancy[3];
double torque_drag[3];
double torque_total[3];
double center_of_buoyancy[3];
double volume_displaced;
double mass_displaced;
CrewModuleShape crewModuleShape;
CrewModuleDynamics();
void init_defaults();
void calcVolumeAndCenterOfBuoyancy();
void calcVelocity();
void calcRDot();
void calcAngularVelocity();
void calcTotalTorque();
void calcBuoyancyTorque();
void calcDragTorque();
void calcMassDisplaced();
void calcTotalForce();
void calcBuoyancyForce();
void calcGravityForce();
void calcDragForce();
int calc_derivatives();
int calc_state();
};
#endif

View File

@ -0,0 +1,33 @@
/************************************************************************
PURPOSE: (Simulate a ... .)
LIBRARY DEPENDENCIES:
((CrewModule/src/CrewModuleShape.o))
**************************************************************************/
#ifndef CREW_MODULE_SHAPE_HH
#define CREW_MODULE_SHAPE_HH
class CrewModuleShape {
public:
double sphere_radius;
double cone_angle;
double sphere_center_base[3];
double cone_point_base[3];
double plane_point_base[3];
double sphere_center_trans[3];
double cone_point_trans[3];
double plane_point_trans[3];
// Work variables
double cone_vector_trans[3];
double plane_vector_trans[3];
CrewModuleShape ();
bool containsPoint(double (&test_point)[3] );
void transformCoordinates( double (&rotation)[3][3], double (&position)[3]);
void transformPoint( double (&rotation)[3][3], double (&translation)[3], double (&in_point)[3], double (&out_point)[3]);
};
#endif

View File

@ -0,0 +1,40 @@
#ifndef ROTATION_MATRIX_MACROS_H
#define ROTATION_MATRIX_MACROS_H
#define SET_X_ROTATION_MATRIX( matrix, angle ) { \
matrix[0][0] = 1.0; \
matrix[0][1] = 0.0; \
matrix[0][2] = 0.0; \
matrix[1][0] = 0.0; \
matrix[1][1] = cos((angle)); \
matrix[1][2] = -sin((angle)); \
matrix[2][0] = 0.0; \
matrix[2][1] = sin((angle)); \
matrix[2][2] = cos((angle)); \
}
#define SET_Y_ROTATION_MATRIX( matrix, angle ) { \
matrix[0][0] = cos((angle)); \
matrix[0][1] = 0.0; \
matrix[0][2] = sin((angle)); \
matrix[1][0] = 0.0; \
matrix[1][1] = 1.0; \
matrix[1][2] = 0.0; \
matrix[2][0] = -sin((angle)); \
matrix[2][1] = 0.0; \
matrix[2][2] = cos((angle)); \
}
#define SET_Z_ROTATION_MATRIX( matrix, angle ) { \
matrix[0][0] = cos((angle)); \
matrix[0][1] = -sin((angle)); \
matrix[0][2] = 0.0; \
matrix[1][0] = sin((angle)); \
matrix[1][1] = cos((angle)); \
matrix[1][2] = 0.0; \
matrix[2][0] = 0.0; \
matrix[2][1] = 0.0; \
matrix[2][2] = 1.0; \
}
#endif

View File

@ -0,0 +1,187 @@
#include <math.h>
#include <stdio.h>
#include "trick/integrator_c_intf.h"
#include "trick/vector_macros.h"
#include "trick/matrix_macros.h"
#include "../include/CrewModuleDynamics.hh"
#include "trick/trick_math_proto.h"
const double acceleration_of_gravity[3] = {0.0, 0.0, -9.81};
const double density_of_water = 1025.0; // kg/m^3 Density of sea water.
CrewModuleDynamics::CrewModuleDynamics() {
init_defaults();
}
void CrewModuleDynamics::init_defaults() {
M_IDENT(R);
M_INIT(Rdot);
mass_vehicle = 9300.0;
momentum[0] = 0.0;
momentum[1] = 0.0;
momentum[2] = 0.0;
position[0] = 0.0;
position[1] = 0.0;
position[2] = 0.0;
angular_momentum[0] = 0.0;
angular_momentum[1] = 0.0;
angular_momentum[2] = 0.0;
crewModuleShape.transformCoordinates(R, position);
double A=1, B=1, C=1;
I_body[0][0] = mass_vehicle * (B*B + C*C);
I_body[0][1] = 0.0;
I_body[0][2] = 0.0;
I_body[1][0] = 0.0;
I_body[1][1] = mass_vehicle * (A*A + C*C);
I_body[1][2] = 0.0;
I_body[2][0] = 0.0;
I_body[2][1] = 0.0;
I_body[2][2] = mass_vehicle * (A*A + B*B);
dm_invert(I_body_inverse, I_body);
}
void CrewModuleDynamics::calcVolumeAndCenterOfBuoyancy() {
double x_start = position[0] - 2.6;
double x_end = position[0] + 2.6;
double y_start = position[1] - 2.6;
double y_end = position[1] + 2.6;
double z_start = position[2] - 2.6;
double z_end = position[2] + 2.6;
double sum_r_dv[3] = {0.0, 0.0, 0.0};
volume_displaced = 0.0;
double P[3];
double dx = 0.1;
double dy = 0.1;
double dz = 0.1;
double dv = dx * dy * dz;
for (double x = x_start; x < x_end ; x+= dx ) {
for (double y = y_start; y < y_end ; y+= dy ) {
for (double z = z_start; z < z_end ; z+= dz ) {
P[0]=x; P[1]=y; P[2]=z;
if ( crewModuleShape.containsPoint(P) ) {
if (P[2] < 0.0) { // Below the water level.
sum_r_dv[0] += x * dv;
sum_r_dv[1] += y * dv;
sum_r_dv[2] += z * dv;
volume_displaced += dv;
}
}
}
}
}
if (volume_displaced > 0.0) {
center_of_buoyancy[0] = sum_r_dv[0] / volume_displaced;
center_of_buoyancy[1] = sum_r_dv[1] / volume_displaced;
center_of_buoyancy[2] = sum_r_dv[2] / volume_displaced;
} else {
center_of_buoyancy[0] = position[0];
center_of_buoyancy[1] = position[1];
center_of_buoyancy[2] = position[2];
}
}
void CrewModuleDynamics::calcVelocity() {
double mass_reciprocal = (1.0/mass_vehicle);
V_SCALE(velocity, momentum, mass_reciprocal);
}
void CrewModuleDynamics::calcRDot() {
double omega_skew[3][3];
calcAngularVelocity();
V_SKEW(omega_skew, angular_velocity);
MxM(Rdot, omega_skew, R);
}
void CrewModuleDynamics::calcAngularVelocity() {
double R_transpose[3][3];
double R_I_body_inverse[3][3];
double I_world_inverse[3][3];
MxM(R_I_body_inverse, R, I_body_inverse);
M_TRANS(R_transpose, R);
MxM(I_world_inverse, R_I_body_inverse, R_transpose);
MxV(angular_velocity, I_world_inverse, angular_momentum);
}
void CrewModuleDynamics::calcBuoyancyTorque() {
double lever[3];
V_SUB(lever, center_of_buoyancy, position);
V_CROSS(torque_buoyancy, lever, force_buoyancy);
}
void CrewModuleDynamics::calcDragTorque() {
V_SCALE(torque_drag, angular_velocity, -5000.0);
}
void CrewModuleDynamics::calcTotalTorque() {
calcBuoyancyTorque();
calcDragTorque();
V_ADD(torque_total, torque_buoyancy, torque_drag);
}
void CrewModuleDynamics::calcMassDisplaced() {
mass_displaced = density_of_water * volume_displaced;
}
void CrewModuleDynamics::calcBuoyancyForce() {
calcMassDisplaced();
V_SCALE(force_buoyancy, -acceleration_of_gravity, mass_displaced);
}
void CrewModuleDynamics::calcGravityForce() {
V_SCALE(force_gravity, acceleration_of_gravity, mass_vehicle);
}
void CrewModuleDynamics::calcDragForce() {
V_SCALE(force_drag, velocity, -2000.0);
}
void CrewModuleDynamics::calcTotalForce() {
calcGravityForce();
calcDragForce();
/* force_buoyancy is calculated in calc_derivatives() because two different derivative calculations depend on it. */
V_ADD(force_total, force_gravity, force_buoyancy);
V_ADD(force_total, force_total, force_drag);
}
int CrewModuleDynamics::calc_derivatives() {
crewModuleShape.transformCoordinates(R, position);
calcVolumeAndCenterOfBuoyancy ();
calcBuoyancyForce();
calcTotalForce();
calcVelocity();
calcTotalTorque();
calcRDot();
return 0;
}
int CrewModuleDynamics::calc_state() {
int ipass;
load_state(
&momentum[0], &momentum[1], &momentum[2],
&position[0], &position[1], &position[2],
&angular_momentum[0], &angular_momentum[1], &angular_momentum[2],
&R[0][0],&R[0][1],&R[0][2],
&R[1][0],&R[1][1],&R[1][2],
&R[2][0],&R[2][1],&R[2][2],
NULL);
load_deriv(
&force_total[0], &force_total[1], &force_total[2],
&velocity[0], &velocity[1], &velocity[2],
&torque_total[0], &torque_total[1], &torque_total[2],
&Rdot[0][0],&Rdot[0][1],&Rdot[0][2],
&Rdot[1][0],&Rdot[1][1],&Rdot[1][2],
&Rdot[2][0],&Rdot[2][1],&Rdot[2][2],
NULL);
ipass = integrate();
unload_state(
&momentum[0], &momentum[1], &momentum[2],
&position[0], &position[1], &position[2],
&angular_momentum[0], &angular_momentum[1], &angular_momentum[2],
&R[0][0],&R[0][1],&R[0][2],
&R[1][0],&R[1][1],&R[1][2],
&R[2][0],&R[2][1],&R[2][2],
NULL);
int axis = 0;
dm_orthonormal(R, &axis); // Square up the rotation matrix.
return(ipass);
}

View File

@ -0,0 +1,69 @@
#include "../include/CrewModuleShape.hh"
#include "trick/vector_macros.h"
#include "trick/matrix_macros.h"
CrewModuleShape::CrewModuleShape () {
sphere_radius = 6.04;
cone_angle = (M_PI/180.0) * 32.5;
sphere_center_base[0] = 0.00;
sphere_center_base[1] = 0.00;
sphere_center_base[2] = 5.14;
cone_point_base[0] = 0.00;
cone_point_base[1] = 0.00;
cone_point_base[2] = 3.82;
plane_point_base[0] = 0.00;
plane_point_base[1] = 0.00;
plane_point_base[2] = 2.40;
double M[3][3] = {{1.0, 0.0, 0.0},
{0.0, 1.0, 0.0},
{0.0, 0.0, 1.0}};
double P[3] = {0.0, 0.0, 0.0};
transformCoordinates(M, P);
}
bool CrewModuleShape::containsPoint(double (&test_point)[3]) {
double sdiff[3];
V_SUB(sdiff, test_point, sphere_center_trans);
if ( V_MAG(sdiff) <= sphere_radius) { // The point is in the sphere.
double cdiff[3];
V_SUB(cdiff, test_point, cone_point_trans);
double test_angle = acos ( V_DOT(cdiff, cone_vector_trans) / V_MAG(cdiff) );
if ( test_angle < cone_angle ) { // The point is in the cone.
double pdiff[3];
V_SUB(pdiff, test_point, plane_point_trans);
return ( V_DOT(pdiff, plane_vector_trans) > 0.0); // The point is on the correct side of the plane.
}
}
return false;
}
void CrewModuleShape::transformCoordinates( double (&rotation)[3][3], double (&position)[3]) {
transformPoint(rotation, position, sphere_center_base, sphere_center_trans );
transformPoint(rotation, position, cone_point_base, cone_point_trans );
transformPoint(rotation, position, plane_point_base, plane_point_trans );
/*
Calculate these unit vectors so they dont have to be calculated everytime we test a point.
*/
double scale;
V_SUB(cone_vector_trans, position, cone_point_trans);
scale = 1.0/V_MAG(cone_vector_trans);
V_SCALE(cone_vector_trans, cone_vector_trans, scale);
V_SUB(plane_vector_trans, position, plane_point_trans);
scale = 1.0/V_MAG(plane_vector_trans);
V_SCALE(plane_vector_trans, plane_vector_trans, scale);
}
void CrewModuleShape::transformPoint(double (&rotation)[3][3], double (&translation)[3], double (&in_point)[3], double (&out_point)[3] ) {
double work[3];
MxV(work, rotation, in_point);
V_ADD(out_point, work, translation);
}

View 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>CrewModuleDisplay</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>trick.CMDisplay</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>

View File

@ -0,0 +1,476 @@
package trick;
import java.awt.Graphics2D;
import java.awt.Graphics;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.FileReader;
import java.net.Socket;
import java.util.*;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.Color;
import java.awt.event.MouseEvent;
import javax.swing.event.MouseInputAdapter;
import trick.matrixOps.MatrixOps;
/**
* @author penn
*/
class CrewModuleView extends JPanel {
private Color waterColor;
private Color vehicleColor;
private double[] vehiclePos;
private double[] centerOfBuoyancy;
private double bodyToWorldRotation[][];
private double vantageAzimuth;
private double vantageElevation;
private double vantageRotation[][];
private double vantageDistance;
private double beta;
private int screen_half_width;
private int screen_half_height;
private double veh_vrtx_body[][];
private double veh_vrtx_world[][];
private int veh_vrtx_screen[][];
private int veh_edges[][];
private double water_vrtx_world[][];
public CrewModuleView() {
ViewListener viewListener = new ViewListener();
addMouseListener(viewListener);
addMouseMotionListener(viewListener);
waterColor = new Color(220,220,250,180);
vehicleColor = new Color(100,100,100);
vehiclePos = new double[] {0.0, 0.0, 0.0};
centerOfBuoyancy = new double[] {0.0, 0.0, 0.0};
bodyToWorldRotation = new double[][] {{1.0, 0.0, 0.0},
{0.0, 1.0, 0.0},
{0.0, 0.0, 1.0}};
vantageAzimuth = Math.toRadians(45.0);
vantageElevation = Math.toRadians(20.0);
vantageRotation = new double[][] {{1.0, 0.0, 0.0},
{0.0, 1.0, 0.0},
{0.0, 0.0, 1.0}};
updateVantageRotation();
vantageDistance = 15.0;
beta = Math.toRadians(30.0);
veh_vrtx_body = new double[][]
{ { 0.000, 0.000, 2.400}, /* 0 top point*/
{ 0.900, 0.000, 2.400}, /* 1 Upper ring */
{ 0.779, 0.450, 2.400}, /* 2 */
{ 0.450, 0.779, 2.400}, /* 3 */
{ 0.000, 0.900, 2.400}, /* 4 */
{-0.450, 0.779, 2.400}, /* 5 */
{-0.779, 0.450, 2.400}, /* 6 */
{-0.900, 0.000, 2.400}, /* 7 */
{-0.779,-0.450, 2.400}, /* 8 */
{-0.450,-0.779, 2.400}, /* 9 */
{ 0.000,-0.900, 2.400}, /* 10 */
{ 0.450,-0.779, 2.400}, /* 11 */
{ 0.779,-0.450, 2.400}, /* 12 */
{ 2.500, 0.000,-0.100}, /* 13 Middle ring */
{ 2.166, 1.250,-0.100}, /* 14 */
{ 1.250, 2.166,-0.100}, /* 15 */
{ 0.000, 2.500,-0.100}, /* 16 */
{-1.250, 2.166,-0.100}, /* 17 */
{-2.166, 1.250,-0.100}, /* 18 */
{-2.500, 0.000,-0.100}, /* 19 */
{-2.166,-1.250,-0.100}, /* 20 */
{-1.250,-2.166,-0.100}, /* 21 */
{ 0.000,-2.500,-0.100}, /* 22 */
{ 1.250,-2.166,-0.100}, /* 23 */
{ 2.166,-1.250,-0.100}, /* 24 */
{ 2.500, 0.000,-0.300}, /* 25 Lower ring */
{ 2.166, 1.250,-0.300}, /* 26 */
{ 1.250, 2.166,-0.300}, /* 27 */
{ 0.000, 2.500,-0.300}, /* 28 */
{-1.250, 2.166,-0.300}, /* 29 */
{-2.166, 1.250,-0.300}, /* 30 */
{-2.500, 0.000,-0.300}, /* 31 */
{-2.166,-1.250,-0.300}, /* 32 */
{-1.250,-2.166,-0.300}, /* 33 */
{ 0.000,-2.500,-0.300}, /* 34 */
{ 1.250,-2.166,-0.300}, /* 35 */
{ 2.166,-1.250,-0.300}, /* 36 */
{ 0.000, 0.000,-0.900} /* 37 bottom point */
};
veh_vrtx_world = new double[veh_vrtx_body.length][3];
veh_vrtx_screen = new int[veh_vrtx_body.length][2];
veh_edges = new int[][]
{ /* connect top-center and upper ring */
{ 0, 1},{ 0, 2},{ 0, 3},{ 0, 4},{ 0, 5},{ 0, 6},{ 0, 7},{ 0, 8},{ 0, 9},{ 0,10},{ 0,11},{ 0,12},
/* connect upper ring points */
{ 1, 2},{ 2, 3},{ 3, 4},{ 4, 5},{ 5, 6},{ 6, 7},{ 7, 8},{ 8, 9},{ 9,10},{10,11},{11,12},{12, 1},
/* connect upper and middle rings */
{ 1,13},{ 2,14},{ 3,15},{ 4,16},{ 5,17},{ 6,18},{ 7,19},{ 8,20},{ 9,21},{10,22},{11,23},{12,24},
/* connect middle ring points */
{13,14},{14,15},{15,16},{16,17},{17,18},{18,19},{19,20},{20,21},{21,22},{22,23},{23,24},{24,13},
/* connect middle and lower rings */
{13,25},{14,26},{15,27},{16,28},{17,29},{18,30},{19,31},{20,32},{21,33},{22,34},{23,35},{24,36},
/* connect lower ring points */
{25,26},{26,27},{27,28},{28,29},{29,30},{30,31},{31,32},{32,33},{33,34},{34,35},{35,36},{36,25},
/* connect lower points to bottom-center */
{25,37},{26,37},{27,37},{28,37},{29,37},{30,37},{31,37},{32,37},{33,37},{34,37},{35,37},{36,37}
};
water_vrtx_world = new double[][]
{
{ 5.000, 5.000, 0.000},
{ 5.000,-5.000, 0.000},
{-5.000,-5.000, 0.000},
{-5.000, 5.000, 0.000}
};
}
private class ViewListener extends MouseInputAdapter {
private int start_x;
private int start_y;
public void mousePressed(MouseEvent e) {
start_x = e.getX();
start_y = e.getY();
}
public void mouseDragged(MouseEvent e) {
int dx = ( e.getX() - start_x );
int dy = ( start_y - e.getY());
start_x = e.getX();
start_y = e.getY();
mouseVantage( dx, dy);
}
}
public void setVantageRange( double range) {
vantageDistance = range;
}
public void setBodyToWorldRotation( double xx, double xy, double xz,
double yx, double yy, double yz,
double zx, double zy, double zz ) {
bodyToWorldRotation[0][0] = xx;
bodyToWorldRotation[0][1] = xy;
bodyToWorldRotation[0][2] = xz;
bodyToWorldRotation[1][0] = yx;
bodyToWorldRotation[1][1] = yy;
bodyToWorldRotation[1][2] = yz;
bodyToWorldRotation[2][0] = zx;
bodyToWorldRotation[2][1] = zy;
bodyToWorldRotation[2][2] = zz;
}
public void mouseVantage(int dx, int dy) {
vantageAzimuth += (dx * Math.PI) / getWidth();
if (vantageAzimuth > Math.PI) vantageAzimuth -= Math.PI;
if (vantageAzimuth < -Math.PI) vantageAzimuth += Math.PI;
vantageElevation += (dy * Math.PI) / getHeight();
if (vantageElevation > Math.toRadians( 89.0)) vantageElevation = Math.toRadians( 89.0);
if (vantageElevation < Math.toRadians(-89.0)) vantageElevation = Math.toRadians(-89.0);
updateVantageRotation();
repaint();
}
public void updateVantageRotation() {
double Rotation_about_Y[][] = {
{ Math.cos(vantageElevation), 0.0, Math.sin(vantageElevation)},
{ 0.0, 1.0, 0.0},
{-Math.sin(vantageElevation), 0.0, Math.cos(vantageElevation)}
};
double Rotation_about_Z[][] = {
{Math.cos(vantageAzimuth), -Math.sin(vantageAzimuth), 0.0},
{Math.sin(vantageAzimuth), Math.cos(vantageAzimuth), 0.0},
{ 0.0, 0.0, 1.0}
};
MatrixOps.MtimesM( vantageRotation, Rotation_about_Y, Rotation_about_Z);
}
public void worldToScreenPoint( int result[], double X_world[]) {
// X_world to X_vantage
double x_vantage[] = new double[3];
MatrixOps.MtimesV(x_vantage, vantageRotation, X_world);
// X_vantage to screen
double perspective_scale = screen_half_width/(Math.tan(beta)*(vantageDistance-x_vantage[0]));
result[0] = (int)(perspective_scale * x_vantage[1] + screen_half_width);
result[1] = (int)(screen_half_height - perspective_scale * x_vantage[2]);
}
public void setVehPos( double x, double y, double z) {
vehiclePos[0] = x;
vehiclePos[1] = y;
vehiclePos[2] = z;
}
public void setCB(double CBx, double CBy, double CBz) {
centerOfBuoyancy[0] = CBx;
centerOfBuoyancy[1] = CBy;
centerOfBuoyancy[2] = CBz;
}
private void doDrawing( Graphics g) {
Graphics2D g2d = (Graphics2D) g;
int width = getWidth();
int height = getHeight();
screen_half_width = (width/2);
screen_half_height = (height/2);
g2d.setPaint(Color.WHITE);
g2d.fillRect(0, 0, width, height);
// ======================
// Draw Water
// ======================
g2d.setPaint( waterColor);
int pt[] = {0, 0};
int wx[] = {0, 0, 0, 0};
int wy[] = {0, 0, 0, 0};
for (int i=0; i<water_vrtx_world.length ; i++) {
worldToScreenPoint( pt, water_vrtx_world[i]);
wx[i] = pt[0];
wy[i] = pt[1];
}
g2d.fillPolygon(wx, wy, 4);
g2d.setPaint( Color.BLUE);
g2d.drawPolygon(wx, wy, 4);
// =============================
// Draw Center of Buoyancy Point
// =============================
int CB_screen[] = {0, 0};
int CB_symbol_size = 15;
worldToScreenPoint( CB_screen, centerOfBuoyancy);
g2d.setPaint( Color.WHITE);
g2d.fillOval(CB_screen[0]-CB_symbol_size/2, CB_screen[1]-CB_symbol_size/2, CB_symbol_size, CB_symbol_size);
g2d.setPaint( Color.BLUE);
g2d.fillArc( CB_screen[0]-CB_symbol_size/2, CB_screen[1]-CB_symbol_size/2, CB_symbol_size, CB_symbol_size, 0, 90 );
g2d.fillArc( CB_screen[0]-CB_symbol_size/2, CB_screen[1]-CB_symbol_size/2, CB_symbol_size, CB_symbol_size, 180, 90);
// ============================
// Draw Center of Gravity Point
// ============================
int CG_screen[] = {0, 0};
int CG_symbol_size = 15;
worldToScreenPoint( CG_screen, vehiclePos);
g2d.setPaint( Color.WHITE);
g2d.fillOval(CG_screen[0]-CG_symbol_size/2, CG_screen[1]-CG_symbol_size/2, CG_symbol_size, CG_symbol_size);
g2d.setPaint( Color.BLACK);
g2d.fillArc( CG_screen[0]-CG_symbol_size/2, CG_screen[1]-CG_symbol_size/2, CG_symbol_size, CG_symbol_size, 0, 90 );
g2d.fillArc( CG_screen[0]-CG_symbol_size/2, CG_screen[1]-CG_symbol_size/2, CG_symbol_size, CG_symbol_size, 180, 90);
// ======================
// Draw Vehicle
// ======================
g2d.setPaint( vehicleColor);
for (int i=0; i<veh_vrtx_body.length ; i++) {
MatrixOps.MtimesV(veh_vrtx_world[i], bodyToWorldRotation, veh_vrtx_body[i]);
MatrixOps.VplusV(veh_vrtx_world[i], veh_vrtx_world[i], vehiclePos);
worldToScreenPoint (veh_vrtx_screen[i], veh_vrtx_world[i]);
}
for (int i=0; i<veh_edges.length; i++) {
int point0[] = veh_vrtx_screen[ veh_edges[i][0] ];
int point1[] = veh_vrtx_screen[ veh_edges[i][1] ];
g2d.drawLine( point0[0], point0[1], point1[0], point1[1]);
}
// ==========================
// Draw World Coordinate Axes
// ==========================
double origin_world[] = {0.0, 0.0, 0.0};
int origin_screen[] = {0, 0};
worldToScreenPoint( origin_screen, origin_world);
g2d.setPaint(Color.RED);
double x_axis_world[] = {5.0, 0.0, 0.0};
int x_axis_screen[] = {0, 0};
worldToScreenPoint( x_axis_screen, x_axis_world);
g2d.drawLine( origin_screen[0], origin_screen[1], x_axis_screen[0], x_axis_screen[1]);
g2d.drawString ( "X", x_axis_screen[0],x_axis_screen[1]);
g2d.setPaint(Color.GREEN);
double y_axis_world[] = {0.0, 5.0, 0.0};
int y_axis_screen[] = {0, 0};
worldToScreenPoint( y_axis_screen, y_axis_world);
g2d.drawLine( origin_screen[0], origin_screen[1], y_axis_screen[0], y_axis_screen[1]);
g2d.drawString ( "Y", y_axis_screen[0],y_axis_screen[1]);
g2d.setPaint(Color.BLUE);
double z_axis_world[] = {0.0, 0.0, 5.0};
int z_axis_screen[] = {0, 0};
worldToScreenPoint( z_axis_screen, z_axis_world);
g2d.drawLine( origin_screen[0], origin_screen[1], z_axis_screen[0], z_axis_screen[1]);
g2d.drawString ( "Z", z_axis_screen[0],z_axis_screen[1]);
}
@Override
public void paintComponent( Graphics g) {
super.paintComponent(g);
doDrawing(g);
}
}
public class CMDisplay extends JFrame {
private CrewModuleView crewModuleView;
private BufferedReader in;
private DataOutputStream out;
public CMDisplay( CrewModuleView cmv) {
crewModuleView = cmv;
add( crewModuleView);
setTitle("CM Display");
setSize(1597, 987);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
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 drawCrewModuleView() {
crewModuleView.repaint();
}
private static void printHelpText() {
System.out.println(
"----------------------------------------------------------------------\n"
+ "usage: java jar CMDisplay.jar <port-number>\n"
+ "----------------------------------------------------------------------\n"
);
}
public static void main(String[] args) throws IOException {
String host = "localHost";
int port = 0;
String vehicleImageFile = null;
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;
}
if (port == 0) {
System.out.println("No variable server port specified.");
printHelpText();
System.exit(0);
}
CrewModuleView crewModuleView = new CrewModuleView();
CMDisplay sd = new CMDisplay(crewModuleView);
sd.setVisible(true);
double vehX = 0.0;
double vehY = 0.0;
double vehZ = 0.0;
double Rxx = 0.0;
double Rxy = 0.0;
double Rxz = 0.0;
double Ryx = 0.0;
double Ryy = 0.0;
double Ryz = 0.0;
double Rzx = 0.0;
double Rzy = 0.0;
double Rzz = 0.0;
double CBx = 0.0;
double CBy = 0.0;
double CBz = 0.0;
System.out.println("Connecting to: " + host + ":" + port);
sd.connectToServer(host, port);
sd.out.writeBytes("trick.var_set_client_tag(\"CMDisplay\") \n" +
"trick.var_pause() \n" +
"trick.var_add(\"crewModule.dyn.position[0]\") \n" +
"trick.var_add(\"crewModule.dyn.position[1]\") \n" +
"trick.var_add(\"crewModule.dyn.position[2]\") \n" +
"trick.var_add(\"crewModule.dyn.R[0][0]\") \n" +
"trick.var_add(\"crewModule.dyn.R[0][1]\") \n" +
"trick.var_add(\"crewModule.dyn.R[0][2]\") \n" +
"trick.var_add(\"crewModule.dyn.R[1][0]\") \n" +
"trick.var_add(\"crewModule.dyn.R[1][1]\") \n" +
"trick.var_add(\"crewModule.dyn.R[1][2]\") \n" +
"trick.var_add(\"crewModule.dyn.R[2][0]\") \n" +
"trick.var_add(\"crewModule.dyn.R[2][1]\") \n" +
"trick.var_add(\"crewModule.dyn.R[2][2]\") \n" +
"trick.var_add(\"crewModule.dyn.center_of_buoyancy[0]\") \n" +
"trick.var_add(\"crewModule.dyn.center_of_buoyancy[1]\") \n" +
"trick.var_add(\"crewModule.dyn.center_of_buoyancy[2]\") \n" +
"trick.var_ascii() \n" +
"trick.var_cycle(0.1) \n" +
"trick.var_unpause()\n" );
sd.out.flush();
sd.drawCrewModuleView();
Boolean go = true;
while (go) {
String field[];
try {
String line;
line = sd.in.readLine();
field = line.split("\t");
vehX = Double.parseDouble( field[1] );
vehY = Double.parseDouble( field[2] );
vehZ = Double.parseDouble( field[3] );
Rxx = Double.parseDouble( field[4] );
Rxy = Double.parseDouble( field[5] );
Rxz = Double.parseDouble( field[6] );
Ryx = Double.parseDouble( field[7] );
Ryy = Double.parseDouble( field[8] );
Ryz = Double.parseDouble( field[9] );
Rzx = Double.parseDouble( field[10] );
Rzy = Double.parseDouble( field[11] );
Rzz = Double.parseDouble( field[12] );
CBx = Double.parseDouble( field[13] );
CBy = Double.parseDouble( field[14] );
CBz = Double.parseDouble( field[15] );
// Set the Vehicle position
crewModuleView.setVehPos(vehX, vehY, vehZ);
crewModuleView.setBodyToWorldRotation( Rxx, Rxy, Rxz,
Ryx, Ryy, Ryz,
Rzx, Rzy, Rzz );
crewModuleView.setCB(CBx, CBy, CBz);
} catch (IOException | NullPointerException e ) {
go = false;
}
sd.drawCrewModuleView();
}
}
}

View File

@ -0,0 +1,109 @@
package trick.matrixOps;
import java.io.*;
public class MatrixOps {
public static void printMatrix(double M[][]) {
int M_rows = M.length;
int M_cols = M[0].length;
for (int i = 0; i < M_rows; i++) {
for (int j = 0; j < M_cols; j++)
System.out.print(" " + M[i][j]);
System.out.println();
}
}
public static void printDVector(double V[]) {
System.out.print("(");
for (int i = 0; i < V.length; i++) {
System.out.print(" " + V[i]);
}
System.out.println(")");
}
public static void printIVector(int V[]) {
System.out.print("(");
for (int i = 0; i < V.length; i++) {
System.out.print(" " + V[i]);
}
System.out.println(")");
}
public static void MtimesM( double R[][], double A[][], double B[][]) {
int A_rows = A.length;
int A_cols = A[0].length;
int B_rows = B.length;
int B_cols = B[0].length;
int R_rows = R.length;
int R_cols = R[0].length;
if (A_cols != B_rows) {
System.out.println( "\nNot possible to multiply matrixes,");
System.out.println("where the first has " + A_cols + " columns,");
System.out.println("and the second has " + B_rows + "rows.");
return;
}
if ((R_rows != A_rows) || (R_cols != B_cols)) {
System.out.println( "\n Result matrix is wrong size.");
return;
}
for (int i = 0; i < A_rows; i++) {
for (int j = 0; j < B_cols; j++) {
R[i][j] = 0.0;
for (int k = 0; k < B_rows; k++)
R[i][j] += A[i][k] * B[k][j];
}
}
}
public static void MtimesV( double R[], double M[][], double V[]) {
int M_rows = M.length;
int M_cols = M[0].length;
int V_rows = V.length;
if (M_cols != V_rows) {
System.out.println( "\nNot possible to multiply matrix and vector,");
System.out.println( "where the matrix has " + M_cols + " columns,");
System.out.println("and the vector has " + V_rows + " elements.");
return;
}
if (R.length != M.length) {
System.out.println( "\n Result vector is wrong size.");
return;
}
for (int i =0; i < M_rows ; i++) {
R[i] = 0.0;
for (int j =0; j < M_cols ; j++) {
R[i] += M[i][j] * V[j];
}
}
return;
}
public static void VplusV(double R[], double A[], double B[]) {
int A_rows = A.length;
int B_rows = B.length;
int R_rows = R.length;
if ((A_rows != B_rows) || (A_rows != R_rows)) {
System.out.println( "\n vector are wrong size.");
}
for (int i=0; i<A_rows ; i++) {
R[i] = A[i] + B[i];
}
}
public static double vector_magnitude (double V[]) {
double S = 0;
for (int i =0; i < V.length ; i++) {
S += V[i]*V[i];
}
return Math.sqrt(S);
}
}

View File

@ -46,7 +46,9 @@ bool EnumVisitor::VisitEnumType(clang::EnumType *et) {
size_t pos ;
// If this enumeration is anonymous return an error condition
if ((pos = enum_type_name.find("<anonymous")) != std::string::npos or
(pos = enum_type_name.find("(anonymous")) != std::string::npos) {
//(pos = enum_type_name.find("(anonymous")) != std::string::npos) {
(pos = enum_type_name.find("(anonymous")) != std::string::npos or
(pos = enum_type_name.find("(unnamed")) != std::string::npos) {
eval.setName("") ;
return false ;
}

View File

@ -11,6 +11,10 @@ std::string sanitize(const std::string& text) {
for (char c : {'<', '>', ' ', ',', ':', '*', '[', ']'}) {
std::replace(result.begin(), result.end(), c, '_');
}
// Catches templates with negative default values (iss #660)
for (char c : {'-'}) {
std::replace(result.begin(), result.end(), c, 'n');
}
return result ;
}

View File

@ -55,6 +55,10 @@ all: $(ICG)
$(ICG): $(OBJECTS) $(UDUNITS_OBJS)
$(CXX) -o $@ $(OBJECTS) $(UDUNITS_OBJS) $(CLANGLIBS) $(LLVMLDFLAGS)
ifeq ($(TRICK_HOST_TYPE),Darwin)
@install_name_tool -add_rpath `$(LLVM_HOME)/bin/llvm-config --libdir` $(ICG)
endif
# Only FieldDescription.cpp includes the units conversion header.
$(OBJ_DIR)/FieldDescription.o : CXXFLAGS += -I$(TRICK_HOME)/include
$(OBJ_DIR)/HeaderSearchDirs.o : CXXFLAGS += -DLLVM_HOME=\"${LLVM_HOME}\"

View File

@ -134,7 +134,11 @@ int Trick::JITInputFile::compile(std::string file_name) {
outfile << std::endl << std::endl ;
// rule to link shared library
outfile << library_fullpath_name << ": " << object_fullpath_name << std::endl ;
outfile << "\t" << get_trick_env((char *)"TRICK_CXX") << " -shared -o $@ $<" << std::endl << std::endl ;
#ifdef __APPLE__
outfile << "\t" << get_trick_env((char *)"TRICK_CXX") << " -shared -undefined dynamic_lookup -o $@ $< " << std::endl << std::endl ;
#else
outfile << "\t" << get_trick_env((char *)"TRICK_CXX") << " -shared -o $@ $< " << std::endl << std::endl ;
#endif
// rule to compile cpp file
outfile << object_fullpath_name << ": " << file_name << std::endl ;
outfile << "\t" << get_trick_env((char *)"TRICK_CXX") << " " << get_trick_env((char *)"TRICK_CXXFLAGS") ;

View File

@ -47,6 +47,10 @@ std::string Trick::VariableServerListenThread::get_user_tag() {
return user_tag ;
}
const std::string& Trick::VariableServerListenThread::get_user_tag_ref() {
return user_tag ;
}
void Trick::VariableServerListenThread::set_user_tag(std::string in_tag) {
user_tag = in_tag ;
}

View File

@ -434,7 +434,7 @@ extern "C" void var_server_set_source_address(const char * source_address) {
* C wrapper Trick::VariableServer::get_user_tag
*/
extern "C" const char * var_server_get_user_tag(void) {
return(the_vs->get_listen_thread().get_user_tag().c_str()) ;
return(the_vs->get_listen_thread().get_user_tag_ref().c_str()) ;
}
/**

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
import matplotlib.pyplot as plt
import numpy as np

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
import matplotlib.pyplot as plt
import numpy as np

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
import matplotlib.pyplot as plt
import numpy as np

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
import matplotlib.pyplot as plt
import numpy as np

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
import matplotlib.pyplot as plt
import numpy as np

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
import matplotlib.pyplot as plt
import numpy as np

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
import matplotlib.pyplot as plt
import numpy as np

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
import matplotlib.pyplot as plt
import numpy as np

View File

@ -0,0 +1,186 @@
# Trick::Interpolator
The Trick::Interpolator class provides a means of estimating the values of a function within a set of points sampled from that function.
## Header
```C
#include "trick/Interpolator.hh"
```
## Constructor
```C
Trick::Interpolator (double* Table,
double** BreakPointArrays,
unsigned int* BreakPointArraySizes,
unsigned int NParams)
```
* Table - array of function (output) values. The size of this array is the product of the BreakPointArraySizes.
* BreakPointArrays - an array of pointers to the breakpoint arrays. One breakpoint array per independent variable.
* BreakPointArraySizes - an array of the sizes of each of the breakpoint arrays.
* NParams - number of independent variables.
## Member Function
```
double Trick::Interpolator::eval (double param1, ...)
```
This member function returns an estimate of the function represented by the interpolator.
If the arguments are out side the bounds the interpolator break points, a ```std::logic_error```
exception will be thrown.
# Examples
---
## One Independent Variable Example
Suppose we have a set of points that represent the thrust vs. time function of an Estes E9 model rocket engine as shown below, and we want to be able to estimate the thrust for times anywhere between the minimum and maximum sample times.
![](images/Estes_E9.png)
Since these points represent thrust as a function of time, time is the independent variable.
The values of the independent variable where points have been sampled are called **breakpoints**.
### Setting Up Data for the Interpolator
```
/* Number of independent Variables. [Constructor Arg#4] */
#define E9_INDEPENDENT_VAR_COUNT 1
/* Number of elements in the breakpoint array */
#define E9_BP_SIZE 28
/* The one Breakpoint array */
double E9_sample_times[E9_BP_SIZE] = {
0.000, 0.010, 0.020, 0.030, 0.040, 0.050, 0.100, 0.110, 0.120, 0.130,
0.140, 0.155, 0.165, 0.180, 0.190, 0.200, 0.215, 0.230, 0.250, 0.275,
0.300, 0.400, 0.500, 2.600, 2.700, 2.725, 2.750, 2.800 };
/* Thrust values at the breakpoints. [Constructor Arg #1] */
double E9_thrust_array[E9_BP_SIZE] = {
0.0, 0.1, 0.3, 0.5, 0.8, 1.5, 10.0, 12.6, 15.2, 17.8,
20.4, 23.0, 24.6, 25.0, 24.8, 24.4, 22.0, 17.0, 13.7, 12.6,
11.9, 10.7, 10.6, 10.5, 10.3, 10.0, 9.7, 0.0 };
/* BreakPointArrays. [Constructor Arg#2] */
double* break_point_arrays[E9_INDEPENDENT_VAR_COUNT] = { E9_sample_times };
/* BreakPointArraySizes. [Constructor Arg #3] */
unsigned int break_point_array_sizes[E9_INDEPENDENT_VAR_COUNT] = { E9_BP_SIZE };
```
### Constructing the Interpolator
Using the data structures from above, we can construct an interpolator.
```
Trick::Interpolator* motor_thrust_interpolator =
new Trick::Interpolator( E9_thrust_array,
break_point_arrays,
break_point_array_sizes,
E9_INDEPENDENT_VAR_COUNT);
```
### Using the Interpolator
To use the interpolator, we simply call the **```eval()```** member function as follows, assuming that ```time``` and ```thrust``` are of type ```double```.
```
try {
thrust = motor_thrust_interpolator->eval( time );
} catch (std::logic_error e) {
thrust = 0.0;
}
```
---
## Two Independent Variable Example
Suppose we have a table of body-mass-index (BMI) values that have been sampled at each of the heights and weights as shown below, and that we want to estimate BMI between where the samples were measured. For example: What's the BMI for 1.82 meters, and 67 kg?
![](images/bmi.png)
In this situation we have two independent variables. Therefore we have two breakpoint arrays, one for weight, and one for height. The size of the weight, and weight breakpoint sets (arrays) are 13, and 6 respectively.
```
/* Number of independent Variables. [Constructor Arg#4] */
#define BMI_INDEPENDENT_VAR_COUNT 2
/* Number of elements in the weight breakpoint array */
#define WEIGHT_BP_SIZE 13
/* Number of elements in the height breakpoint array */
#define HEIGHT_BP_SIZE 6
/* ---------------------------------------------------------------------------------*/
/* NOTICE that we've converted kg to lb, and m to inches in the breakpoint arrays. */
/* This just demonstrates a units conversion trick in breakpoint arrays. */
/* ---------------------------------------------------------------------------------*/
double weight_lb[WEIGHT_BP_SIZE] = { 88.2, 110.25, 132.3, 154.35, 176.4, 198.45,
220.5, 242.55, 264.65, 286.65, 308.6, 330.75, 352.7 };
double height_inches[HEIGHT_BP_SIZE] = { 59.0, 63.0, 67.0, 71.0, 75.0, 78.0 };
/* BreakPointArrays. [Constructor Arg#2] */
double* bmi_break_point_arrays[BMI_INDEPENDENT_VAR_COUNT] =
{ weight_lb, height_inches };
/* BreakPointArraySizes. [Constructor Arg #3] */
unsigned int bmi_break_point_array_sizes[BMI_INDEPENDENT_VAR_COUNT] =
{ WEIGHT_BP_SIZE, HEIGHT_BP_SIZE};
[Constructor Arg #1]
double bmi_table[] = {
/* 1.5m 1.6m 1.7m 1.8m 1.9m 2.0m */
/* ================================================= */
/* 40kg */ 17.78, 15.62, 13.84, 12.35, 11.08, 10.00,
/* 50kg */ 22.22, 19.53, 17.30, 15.43, 13.85, 12.50,
/* 60kg */ 26.67, 23.44, 20.76, 18.52, 16.62, 15.00,
/* 70kg */ 31.11, 27.34, 24.22, 21.60, 19.39, 17.50,
/* 80kg */ 35.56, 31.25, 27.68, 24.69, 22.16, 20.00,
/* 90kg */ 40.00, 35.16, 31.14, 27.78, 24.93, 22.50,
/* 100kg */ 44.44, 39.06, 34.60, 30.86, 27.70, 25.00,
/* 110kg */ 48.89, 42.97, 38.06, 33.95, 30.47, 27.50,
/* 120kg */ 53.33, 46.87, 41.52, 37.04, 33.24, 30.00,
/* 130kg */ 57.78, 50.78, 44.98, 40.12, 36.01, 32.50,
/* 140kg */ 62.22, 54.69, 48.44, 43.21, 38.78, 35.00,
/* 150kg */ 66.67, 58.59, 51.90, 46.30, 41.55, 37.50,
/* 160kg */ 71.11, 62.50, 55.36, 49.38, 44.32, 40.00
};
```
### Constructing the Interpolator
Using the data structures from above, we can construct an interpolator.
```
Trick::Interpolator* bmi_interpolator =
new Trick::Interpolator( bmi_table,
bmi_break_point_arrays,
bmi_break_point_array_sizes,
BMI_INDEPENDENT_VAR_COUNT);
```
### Using the Interpolator
To use the interpolator, we simply call the **```eval()```** member function as follows, assuming that ```bmi```, ```weight```, and ```height``` are of type ```double```.
```
try {
bmi = bmi_interpolator->eval( weight, height );
} catch (std::logic_error e) {
std::cerr << "Arguments beyond the limits of the BMI interpolation table." << std::endl;
}
```

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@ -10136,9 +10136,9 @@
}
},
"lodash": {
"version": "4.17.14",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.14.tgz",
"integrity": "sha512-mmKYbW3GLuJeX+iGP+Y7Gp1AiGHGbXHCOh/jZmrawMmsE7MS4znI3RL2FsjbqOyMayHInjOeykW7PEajUk1/xw=="
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
},
"lodash._reinterpolate": {
"version": "3.0.0",