Merge branch 'master' into AssertJ_Swing_Tests
2
.github/workflows/docker.yml
vendored
@ -10,7 +10,7 @@ jobs:
|
||||
container: docker://nasatrick/${{matrix.container}}:latest
|
||||
strategy:
|
||||
matrix:
|
||||
container: [trick_centos7, trick_centos8, trick_ubuntu1804]
|
||||
container: [trick_ubuntu1804]
|
||||
steps:
|
||||
- name: run tests
|
||||
run: |
|
||||
|
86
.github/workflows/python_tests_32.yml
vendored
@ -1,86 +0,0 @@
|
||||
name: Python Tests 32-bit
|
||||
|
||||
on:
|
||||
push:
|
||||
# Temporarily disable all tests for Issue #1188.
|
||||
branches-ignore:
|
||||
- '**'
|
||||
paths-ignore:
|
||||
- 'docs/**'
|
||||
- '.github/workflows/**'
|
||||
- '!.github/workflows/python_tests_32.yml'
|
||||
pull_request:
|
||||
# Temporarily disable all tests for Issue #1188.
|
||||
branches-ignore:
|
||||
- '**'
|
||||
|
||||
jobs:
|
||||
trick_32bit:
|
||||
runs-on: ubuntu-18.04
|
||||
container: docker://centos:7
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@master
|
||||
- name: Add yum repo
|
||||
run: yum -y install epel-release.noarch && yum -y update
|
||||
- name: Install python dependencies
|
||||
run: yum install -y python3-venv python3 python3-pip python3-devel gcc
|
||||
- name: Info
|
||||
run: |
|
||||
python3 --version
|
||||
- name: Build Python environment
|
||||
run: |
|
||||
cd share/trick/pymods/trick
|
||||
python3 -m venv .venv && . .venv/bin/activate && pip3 install -r requirements.txt
|
||||
- name: Install dependency group
|
||||
run: yum -y groupinstall "Development tools" && yum -y update
|
||||
- name: Install other dependencies
|
||||
run: >
|
||||
yum remove -y swig && yum install -y llvm llvm-devel llvm-static clang clang-devel
|
||||
bison flex gcc gcc-c++ libxml2-devel make cmake wget
|
||||
ncurses-devel openmotif openmotif-devel python-devel perl
|
||||
perl-Digest-MD5 swig3 zlib-devel glibc.x86_64 libxml2-devel.i686
|
||||
ncurses-devel.i686 zlib-devel.i686 python-libs.i686
|
||||
expat-2.1.0-10.el7_3.i686 glibc-devel-2.17-196.el7.i686
|
||||
glibc.i686 glibc-devel.i686 udunits2 udunits2-devel gtest-devel.i686
|
||||
java-11-openjdk java-11-openjdk-devel expat-devel.i686
|
||||
which gcc-gfortran git wget gsl-devel gtest-devel gsl-devel.i686
|
||||
maven udunits2 udunits2-devel zip python3-tkinter xorg-x11-server-Xvfb
|
||||
- name: Symlink python
|
||||
run: |
|
||||
cd /usr/lib
|
||||
ln -s ./libpython2.7.so.1.0 libpython2.7.so
|
||||
- name: Install Udunits (32 bit)
|
||||
run: |
|
||||
cd /
|
||||
curl --retry 4 -O https://artifacts.unidata.ucar.edu/repository/downloads-udunits/udunits-2.2.28.tar.gz
|
||||
tar xfvz udunits-2.2.28.tar.gz
|
||||
rm -rf udunits-2.2.28.tar.gz
|
||||
cd udunits-2.2.28
|
||||
export CFLAGS="-m32"
|
||||
./configure
|
||||
make
|
||||
make install
|
||||
- name: Install GTest (32 bit)
|
||||
run: |
|
||||
wget https://github.com/google/googletest/archive/release-1.8.0.tar.gz
|
||||
tar xfvz release-1.8.0.tar.gz
|
||||
cd googletest-release-1.8.0/googletest
|
||||
export CFLAGS="-m32"
|
||||
export CXXFLAGS="-m32"
|
||||
cmake .
|
||||
make
|
||||
make install
|
||||
- name: Build Trick
|
||||
run: |
|
||||
yum -y update && yum clean all
|
||||
export MAKEFLAGS=-j`nproc`
|
||||
./configure --without-hdf5 --enable-32bit
|
||||
make
|
||||
- name: Run civet tests
|
||||
run: |
|
||||
cd share/trick/pymods/trick/
|
||||
. .venv/bin/activate
|
||||
./run_tests.py
|
||||
env:
|
||||
TRICK_HOME: "${{ github.workspace }}"
|
24
.github/workflows/python_tests_linux.yml
vendored
@ -24,8 +24,6 @@ jobs:
|
||||
- { 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: latest, arch: rhel } # 8 as of April 2020
|
||||
# - { 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
|
||||
@ -102,13 +100,6 @@ jobs:
|
||||
- cfg: { os: debian }
|
||||
os_deps: >-
|
||||
openjdk-11-jdk
|
||||
#-------- CentOS Only Dependencies ----------------
|
||||
- cfg: { os: centos }
|
||||
pkg_mgr: yum
|
||||
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
|
||||
@ -123,21 +114,6 @@ jobs:
|
||||
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: latest }
|
||||
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
|
||||
#-------- Job definition ----------------
|
||||
runs-on: ubuntu-18.04
|
||||
container: docker://${{matrix.cfg.os}}:${{matrix.cfg.tag}}
|
||||
|
1
.github/workflows/report_linux.yml
vendored
@ -13,7 +13,6 @@ jobs:
|
||||
cfg:
|
||||
#-------- Operating Systems ----------------
|
||||
- { os: ubuntu, tag: 22.04, arch: debian, arch_ver: 12 }
|
||||
- { 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 }
|
||||
python: [3]
|
||||
|
1
.github/workflows/report_linux_py2.yml
vendored
@ -13,7 +13,6 @@ jobs:
|
||||
cfg:
|
||||
#-------- Operating Systems ----------------
|
||||
- { os: ubuntu, tag: 22.04, arch: debian, arch_ver: 12 }
|
||||
- { 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 }
|
||||
python: [2]
|
||||
|
69
.github/workflows/test_32.yml
vendored
@ -1,69 +0,0 @@
|
||||
name: 32-bit
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 0 * * 0'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
trick_32bit:
|
||||
runs-on: ubuntu-latest
|
||||
container: docker://centos:7
|
||||
steps:
|
||||
- name: Add yum repo
|
||||
run: yum -y install epel-release.noarch && yum -y update
|
||||
- name: Install dependency group
|
||||
run: yum -y groupinstall "Development tools" && yum -y update
|
||||
- name: Install other dependencies
|
||||
run: >
|
||||
yum remove -y swig && yum install -y llvm llvm-devel llvm-static clang clang-devel
|
||||
bison flex gcc gcc-c++ libxml2-devel make cmake wget
|
||||
ncurses-devel openmotif openmotif-devel python-devel perl
|
||||
perl-Digest-MD5 swig3 zlib-devel glibc.x86_64 libxml2-devel.i686
|
||||
ncurses-devel.i686 zlib-devel.i686 python-libs.i686
|
||||
expat-2.1.0-10.el7_3.i686 glibc-devel-2.17-196.el7.i686
|
||||
glibc.i686 glibc-devel.i686 udunits2 udunits2-devel gtest-devel.i686
|
||||
java-11-openjdk java-11-openjdk-devel expat-devel.i686
|
||||
which gcc-gfortran git wget gsl-devel gtest-devel gsl-devel.i686
|
||||
maven udunits2 udunits2-devel zip libgcc*i686 libstdc++*i686 glibc*i686
|
||||
- name: Symlink python
|
||||
run: |
|
||||
cd /usr/lib
|
||||
ln -s ./libpython2.7.so.1.0 libpython2.7.so
|
||||
- name: Install Udunits (32 bit)
|
||||
run: |
|
||||
cd /
|
||||
curl --retry 4 -O https://artifacts.unidata.ucar.edu/repository/downloads-udunits/current/udunits-2.2.28.tar.gz
|
||||
tar xfvz udunits-2.2.28.tar.gz
|
||||
rm -rf udunits-2.2.28.tar.gz
|
||||
cd udunits-2.2.28
|
||||
export CFLAGS="-m32"
|
||||
./configure
|
||||
make
|
||||
make install
|
||||
- name: Install GTest (32 bit)
|
||||
run: |
|
||||
wget https://github.com/google/googletest/archive/release-1.8.0.tar.gz
|
||||
tar xfvz release-1.8.0.tar.gz
|
||||
cd googletest-release-1.8.0/googletest
|
||||
export CFLAGS="-m32"
|
||||
export CXXFLAGS="-m32"
|
||||
cmake .
|
||||
make
|
||||
make install
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
- name: Build Trick
|
||||
run: |
|
||||
yum -y update && yum clean all
|
||||
export MAKEFLAGS=-j`nproc`
|
||||
./configure --without-hdf5 --enable-32bit
|
||||
make
|
||||
- name: Run tests
|
||||
run: |
|
||||
cd share/trick/trickops/
|
||||
yum install -y python3-devel
|
||||
python3 -m venv .venv && . .venv/bin/activate && pip install --upgrade pip && pip3 install -r requirements.txt
|
||||
cd ../../../
|
||||
echo $MAKEFLAGS $CXXFLAGS $CFLAGS
|
||||
make test32
|
25
.github/workflows/test_linux.yml
vendored
@ -23,7 +23,6 @@ jobs:
|
||||
cfg:
|
||||
#-------- Operating Systems ----------------
|
||||
- { os: ubuntu, tag: 22.04, arch: debian, arch_ver: 12 }
|
||||
- { 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 }
|
||||
python: [3]
|
||||
@ -95,30 +94,6 @@ jobs:
|
||||
zlib-devel
|
||||
python2-devel
|
||||
python3-devel
|
||||
#-------- RHEL 7-based Only Dependencies ----------------
|
||||
- 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
|
||||
os_deps: >-
|
||||
libX11-devel
|
||||
libXt-devel
|
||||
swig3
|
||||
install_gtest: |
|
||||
cd /tmp
|
||||
wget https://github.com/google/googletest/archive/release-1.8.0.tar.gz
|
||||
tar xzvf release-1.8.0.tar.gz
|
||||
cd /tmp/googletest-release-1.8.0/googletest
|
||||
cmake .
|
||||
make
|
||||
make install
|
||||
cd /tmp/googletest-release-1.8.0/googlemock
|
||||
cmake .
|
||||
make
|
||||
make install
|
||||
#-------- RHEL 8-based Only Dependencies ----------------
|
||||
- cfg: { arch: rhel, arch_ver: 8 }
|
||||
pkg_mgr: dnf
|
||||
|
1
.github/workflows/test_linux_py2.yml
vendored
@ -13,7 +13,6 @@ jobs:
|
||||
cfg:
|
||||
#-------- Operating Systems ----------------
|
||||
- { os: ubuntu, tag: 22.04, arch: debian, arch_ver: 12 }
|
||||
- { 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 }
|
||||
python: [2]
|
||||
|
28
README.md
@ -6,7 +6,7 @@
|
||||
</picture>
|
||||
</p>
|
||||
|
||||
<p align=left>
|
||||
<p align=center>
|
||||
<a href="https://github.com/nasa/trick/actions?query=workflow%3ALinux">
|
||||
<img src="https://github.com/nasa/trick/workflows/Linux/badge.svg?branch=master" alt="Linux" height=30px>
|
||||
</a>
|
||||
@ -24,14 +24,14 @@ The Trick Simulation Environment, developed at the NASA Johnson Space Center, is
|
||||
</p>
|
||||
|
||||
<table>
|
||||
<col width="33%">
|
||||
<col width="33%">
|
||||
<col width="33%">
|
||||
<col>
|
||||
<col>
|
||||
<col>
|
||||
<thead>
|
||||
<tr>
|
||||
<th><a href="https://nasa.github.io/trick/documentation/install_guide/Install-Guide">Install Guide</a></th>
|
||||
<th><a href="https://nasa.github.io/trick/tutorial/Tutorial">Tutorial</a></th>
|
||||
<th><a href="https://nasa.github.io/trick/documentation/Documentation-Home">Documentation</a></th>
|
||||
<tr align="center">
|
||||
<th width="33%"><a href="https://nasa.github.io/trick/documentation/install_guide/Install-Guide">Install Guide</a></th>
|
||||
<th width="33%"><a href="https://nasa.github.io/trick/tutorial/Tutorial">Tutorial</a></th>
|
||||
<th width="33%"><a href="https://nasa.github.io/trick/documentation/Documentation-Home">Documentation</a></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@ -44,14 +44,14 @@ The Trick Simulation Environment, developed at the NASA Johnson Space Center, is
|
||||
</table>
|
||||
|
||||
<table>
|
||||
<col width="33%">
|
||||
<col width="33%">
|
||||
<col width="33%">
|
||||
<col>
|
||||
<col>
|
||||
<col>
|
||||
<thead>
|
||||
<tr>
|
||||
<th><a href="https://nasa.github.io/trick/related_projects/Related-Projects">Related Projects</a></th>
|
||||
<th><a href="https://nasa.github.io/trick/faq/FAQ">Frequently Asked Questions</a></th>
|
||||
<th><a href="https://nasa.github.io/trick/howto_guides/How-To-Guides">How-To Guides</a></th>
|
||||
<th width="33%"><a href="https://nasa.github.io/trick/related_projects/Related-Projects">Related Projects</a></th>
|
||||
<th width="33%"><a href="https://nasa.github.io/trick/faq/FAQ">Frequently Asked Questions</a></th>
|
||||
<th width="33%"><a href="https://nasa.github.io/trick/howto_guides/How-To-Guides">How-To Guides</a></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
@ -408,24 +408,51 @@ Trick may use model code with any type of inheritance. Some limitations are pres
|
||||
|
||||
### Namespaces
|
||||
|
||||
Currently one level of namespace is supported. Additional levels of namespaces are ignored. Similarly classes and enumerations embedded in other classes are ignored.
|
||||
ICG supports namespaces and nested scopes. Data recording and variable access via Trick View should work regardless of how many levels there are.
|
||||
|
||||
```C++
|
||||
namespace my_ns {
|
||||
// BB is processed
|
||||
class BB {
|
||||
public:
|
||||
std::string str;
|
||||
// Class CC is ignored.
|
||||
class CC {
|
||||
...
|
||||
Namespaces and nested scopes are similarly supported in Python contexts, such as the input file and variable server, with some caveats regarding templates.
|
||||
1. A template instantiation may be unqualified (have no use of the scope resolution operator `::`) only if its corresponding template is declared in the immediately-enclosing namespace.
|
||||
2. Otherwise, a template instantiation must be fully qualified, starting from the global namespace.
|
||||
3. Finally, instantiations of templates declared within the same class must be excluded from SWIG.
|
||||
|
||||
In the following examples, all template instantiations occur in `example::prime::Soup`. The immediately-enclosing namespace is `prime`, so only instantiations of templates declared directly in `prime` (only `Celery`) may be unqualified. All other template instantiations must be fully qualified, starting from the global namespace, even if the C++ name lookup process would find them with partial qualification.
|
||||
|
||||
```c++
|
||||
template <class T> class Potato {};
|
||||
|
||||
namespace example {
|
||||
|
||||
template <class T> class Onion {};
|
||||
|
||||
namespace peer {
|
||||
template <class T> class Raddish {};
|
||||
}
|
||||
|
||||
namespace prime {
|
||||
|
||||
namespace inner {
|
||||
template <class T> class Carrot {};
|
||||
}
|
||||
};
|
||||
// Everything enclosed in inner_ns is ignored.
|
||||
namespace inner_ns {
|
||||
...
|
||||
};
|
||||
};
|
||||
|
||||
template <class T> class Celery {};
|
||||
|
||||
class Soup {
|
||||
|
||||
public:
|
||||
template <class T> class Broth {};
|
||||
|
||||
::Potato<int> potato; // Rule 2
|
||||
example::Onion<int> onion; // Rule 2
|
||||
example::peer::Raddish<int> raddish; // Rule 2
|
||||
example::prime::inner::Carrot<int> carrot; // Rule 2
|
||||
Celery<int> celery; // Rule 1
|
||||
#ifndef SWIG
|
||||
Broth<int> broth; // Rule 3
|
||||
#endif
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
### Function Overloading
|
||||
|
@ -13,6 +13,7 @@ PROGRAMMERS:
|
||||
#include "trick/DataRecordGroup.hh"
|
||||
|
||||
#ifdef SWIG
|
||||
%feature("compactdefaultargs","0") ;
|
||||
%feature("shadow") Trick::DRAscii::DRAscii(std::string in_name) %{
|
||||
def __init__(self, *args):
|
||||
this = $action(*args)
|
||||
@ -68,7 +69,7 @@ namespace Trick {
|
||||
@code <my_drg> = trick.DRAscii("<in_name>") @endcode
|
||||
@copydoc Trick::DataRecordGroup::DataRecordGroup(string in_name)
|
||||
*/
|
||||
DRAscii( std::string in_name) ;
|
||||
DRAscii( std::string in_name, Trick::DR_Type dr_type = Trick::DR_Type::DR_Type_Ascii ) ;
|
||||
|
||||
/**
|
||||
@copybrief Trick::DataRecordGroup::format_specific_header
|
||||
|
@ -93,7 +93,7 @@ namespace Trick {
|
||||
@code <my_drg> = trick.DRBinary("<in_name>") @endcode
|
||||
@copydoc Trick::DataRecordGroup::DataRecordGroup(string in_name)
|
||||
*/
|
||||
DRBinary( std::string in_name, bool register_group = true ) ;
|
||||
DRBinary( std::string in_name, bool register_group = true, Trick::DR_Type dr_type = Trick::DR_Type::DR_Type_Binary ) ;
|
||||
|
||||
/**
|
||||
@copybrief Trick::DataRecordGroup::format_specific_header
|
||||
|
@ -24,6 +24,7 @@ PROGRAMMERS:
|
||||
#endif
|
||||
|
||||
#ifdef SWIG
|
||||
%feature("compactdefaultargs","0") ;
|
||||
%feature("shadow") Trick::DRHDF5::DRHDF5(std::string in_name) %{
|
||||
def __init__(self, *args):
|
||||
this = $action(*args)
|
||||
@ -101,7 +102,7 @@ GROUP "/" {
|
||||
@code <my_drg> = trick.DRHDF5("<in_name>") @endcode
|
||||
@copydoc Trick::DataRecordGroup::DataRecordGroup(string in_name)
|
||||
*/
|
||||
DRHDF5( std::string in_name) ;
|
||||
DRHDF5( std::string in_name, Trick::DR_Type dr_type = Trick::DR_Type::DR_Type_HDF5) ;
|
||||
|
||||
/**
|
||||
@copybrief Trick::DataRecordGroup::format_specific_header
|
||||
|
@ -75,9 +75,15 @@ namespace Trick {
|
||||
/** @brief Removes all data recording groups. */
|
||||
void remove_all_groups() ;
|
||||
|
||||
/** @brief Gets a data recording group. */
|
||||
/** @brief Gets a data recording group by its name. */
|
||||
Trick::DataRecordGroup * get_group(std::string group_name) ;
|
||||
|
||||
/** @brief Gets a data recording group by its id number */
|
||||
Trick::DataRecordGroup * get_group(int idx) ;
|
||||
|
||||
/** @brief Gets the size of all added data recroding groups */
|
||||
int get_groups_size() ;
|
||||
|
||||
/** @brief Signal the write thread to execute. */
|
||||
virtual int signal_thread() ;
|
||||
|
||||
|
@ -42,6 +42,14 @@ namespace Trick {
|
||||
DR_Not_Specified = 3 /**< Unknown type */
|
||||
} ;
|
||||
|
||||
enum DR_Type {
|
||||
DR_Type_None,
|
||||
DR_Type_Ascii,
|
||||
DR_Type_Binary,
|
||||
DR_Type_HDF5,
|
||||
DR_Type_FrameLogDataRecord
|
||||
} ;
|
||||
|
||||
class DataRecordBuffer {
|
||||
public:
|
||||
char *buffer; /* ** generic holding buffer for data */
|
||||
@ -149,7 +157,7 @@ namespace Trick {
|
||||
@brief Constructor that creates a new data recording group with the given @c in_name.
|
||||
@param in_name - the new data recording group name
|
||||
*/
|
||||
DataRecordGroup( std::string in_name = "" ) ;
|
||||
DataRecordGroup( std::string in_name = "", Trick::DR_Type dr_type = Trick::DR_Type::DR_Type_None ) ;
|
||||
|
||||
~DataRecordGroup() ;
|
||||
|
||||
@ -405,6 +413,12 @@ namespace Trick {
|
||||
*/
|
||||
virtual int add_time_variable() ;
|
||||
|
||||
/**
|
||||
@brief This function adds jobs to the DRG based on the dr type.
|
||||
@returns void
|
||||
*/
|
||||
void configure_jobs(DR_Type type) ;
|
||||
|
||||
/** Check that a variable is supported by data recording. */
|
||||
/** Variable must be a single primitive type - no STL, array, structured, string */
|
||||
bool isSupportedType(REF2 * ref2, std::string& message);
|
||||
|
@ -295,13 +295,6 @@ namespace Trick {
|
||||
/** Command to execute when starting this application. */
|
||||
std::string command;
|
||||
|
||||
/** Pointer to alloc'd command c str for use with external application c_intf */
|
||||
char * command_c_str;
|
||||
|
||||
/** alloc'd addresses to be deallocated during app destruction (currently only
|
||||
used by command_c_str) */
|
||||
std::vector<char*> allocations;
|
||||
|
||||
private:
|
||||
|
||||
/** Prevent SWIG from trying to invoke operator= on ostringstream. */
|
||||
|
@ -83,6 +83,9 @@ namespace Trick {
|
||||
to change to that directory before calling S_main_name.\n */
|
||||
std::string sim_path; /**< trick_units(--) */
|
||||
|
||||
/** @userdesc Optional shell environment setup config file for the slave shell.\n */
|
||||
std::string remote_shell_config_file; /**< trick_units(--) */
|
||||
|
||||
/** @userdesc Slave executable name, default is "./S_main_${TRICK_HOST_CPU}.exe".\n */
|
||||
std::string S_main_name; /**< trick_units(--) */
|
||||
|
||||
|
@ -23,6 +23,8 @@ int set_max_size_record_group (const char * in_name, uint64_t bytes ) ;
|
||||
int add_data_record_group( Trick::DataRecordGroup * in_group, Trick::DR_Buffering buffering = Trick::DR_Not_Specified ) ;
|
||||
int remove_data_record_group( Trick::DataRecordGroup * in_group ) ;
|
||||
Trick::DataRecordGroup * get_data_record_group( std::string in_name ) ;
|
||||
Trick::DataRecordGroup * get_data_record_group_by_idx( int idx ) ;
|
||||
int get_num_data_record_groups() ;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -57,7 +57,6 @@ my %sim ;
|
||||
my %out_of_date ;
|
||||
my ($version, $thread, $year) ;
|
||||
my %processed_templates ;
|
||||
my $global_template_typedefs ;
|
||||
|
||||
my $typedef_def = qr/typedef\s+ # the word typedef
|
||||
(?:[_A-Za-z][\s\w]*\s*) # resolved type
|
||||
@ -336,24 +335,6 @@ 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.
|
||||
@ -609,7 +590,8 @@ sub process_class($$$$$) {
|
||||
|
||||
my $extracted ;
|
||||
my ($class_name) ;
|
||||
my $template_typedefs ;
|
||||
my @qualified_template_typedefs ;
|
||||
my @unqualified_template_typedefs ;
|
||||
|
||||
## Extract the class_name from the class_string
|
||||
$class_string =~ /^(?:class|struct)\s+ # keyword class or struct
|
||||
@ -692,10 +674,6 @@ sub process_class($$$$$) {
|
||||
my ($template_type_no_sp) = $template_full_type ;
|
||||
$template_type_no_sp =~ s/\s//g ;
|
||||
|
||||
# If the type is qualified, assume it's fully qualified and put the
|
||||
# %template directive in the global namespace.
|
||||
# See https://github.com/nasa/trick/issues/768
|
||||
my $qualified = $template_type_no_sp =~ /^\w+(::)\w+</ ;
|
||||
#print "*** template_type_no_sp = $template_type_no_sp ***\n" ;
|
||||
if ( ! exists $processed_templates{$template_type_no_sp} ) {
|
||||
|
||||
@ -703,29 +681,48 @@ sub process_class($$$$$) {
|
||||
my $identifier = "${sanitized_namespace}${class_name}_${var_name}" ;
|
||||
my $trick_swig_template = "TRICK_SWIG_TEMPLATE_$identifier" ;
|
||||
|
||||
# Insert template directive immediately before intsance
|
||||
# Insert template directive immediately before instance
|
||||
# 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 .= "#endif\n" ;
|
||||
|
||||
# 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 . " {" ;
|
||||
}
|
||||
}
|
||||
# A SWIG %template directive must:
|
||||
# 1. Appear before each template instantiation
|
||||
# 2. Be in scope where the instantiation is declared
|
||||
# 3. Not be enclosed within a different namespace
|
||||
#
|
||||
# See https://www.swig.org/Doc4.2/SWIGPlus.html#SWIGPlus_template_scoping
|
||||
#
|
||||
# Generally, convert_swig is not smart enough to put all %template
|
||||
# directives in the right scope because:
|
||||
# 1. We do not keep track of what scope each type we encounter is
|
||||
# declared in.
|
||||
# 2. We cannot easily add %template directives to already-processed
|
||||
# scopes.
|
||||
#
|
||||
# As a compromise:
|
||||
# 1. For an unqualified template instantiation, the template declaration
|
||||
# is necessarily in the current or a containing scope. Hope it's in the
|
||||
# current namespace and put the %template directive there. This will
|
||||
# create invalid SWIG input code for templates declared in a containing
|
||||
# namespace and for member templates declared in this class.
|
||||
# 2. For a qualified template instantiation, the template declaration is
|
||||
# in a (possibly nested) scope contained by the current or a containing
|
||||
# scope. Assume the instantiation is fully qualified and put it in the
|
||||
# global namespace. This will create invalid SWIG code for partially-
|
||||
# qualified instantiations.
|
||||
#
|
||||
# See https://github.com/nasa/trick/issues/768
|
||||
|
||||
if ($isSwigExcludeBlock == 0) {
|
||||
$template_typedefs .= $typedef ;
|
||||
if ($template_full_type =~ /^\w*(::\w+)+</) {
|
||||
push @qualified_template_typedefs, $typedef ;
|
||||
}
|
||||
else {
|
||||
push @unqualified_template_typedefs, $typedef ;
|
||||
}
|
||||
}
|
||||
|
||||
$processed_templates{$template_type_no_sp} = 1 ;
|
||||
@ -738,12 +735,32 @@ sub process_class($$$$$) {
|
||||
|
||||
push @$class_names_ref , "$curr_namespace$class_name" ;
|
||||
|
||||
# write out the templated variable declaration lines found in this class.
|
||||
$$new_contents_ref .= $template_typedefs."\n" ;
|
||||
# Write out the %template directives for template instantiations found in
|
||||
# this class. Put the directives for unqualified instantiations in the
|
||||
# namespace containing this class, just before the class definition.
|
||||
foreach (@unqualified_template_typedefs) {
|
||||
$$new_contents_ref .= $_ ;
|
||||
}
|
||||
|
||||
# Assume qualified template instantiations are fully qualified and put
|
||||
# their %template directives in the global namespace.
|
||||
# 1. close all namespaces, returning to the global namespace
|
||||
# 2. add the %template directives
|
||||
# 3. open all namespaces, restoring the scope
|
||||
if (@qualified_template_typedefs) {
|
||||
my @namespaces = split(/::/, $curr_namespace) ;
|
||||
$$new_contents_ref .= "}" x @namespaces . "\n";
|
||||
foreach (@qualified_template_typedefs) {
|
||||
$$new_contents_ref .= $_ ;
|
||||
}
|
||||
$$new_contents_ref .= "\n";
|
||||
foreach (@namespaces) {
|
||||
$$new_contents_ref .= "namespace " . $_ . " { " ;
|
||||
}
|
||||
}
|
||||
|
||||
$$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" ;
|
||||
$$new_contents_ref .= "\n" . $my_class_contents . $extracted . ";\n" ;
|
||||
|
||||
my $c_ = "$curr_namespace$class_name" ;
|
||||
$c_ =~ s/\:/_/g ;
|
||||
@ -785,7 +802,7 @@ sub process_typedef_struct($$$$) {
|
||||
my ($typedef_struct_string , $contents_ref, $new_contents_ref , $class_names_ref) = @_ ;
|
||||
|
||||
my $extracted ;
|
||||
my ($tail , $struct_names, @struct_names) ;
|
||||
my ($tail , $my_struct_contents, $struct_names, @struct_names) ;
|
||||
|
||||
#print "*** typedef_struct_string = $typedef_struct_string ***\n" ;
|
||||
|
||||
@ -811,10 +828,12 @@ sub process_typedef_struct($$$$) {
|
||||
foreach my $s ( @struct_names ) {
|
||||
if ( $s !~ /\*/ ) {
|
||||
push @$class_names_ref , $s ;
|
||||
# Add _swig_setattr_nondynamic_instance_variable function for raising AttributeError for improper struct attribute assingment in input processor
|
||||
$my_struct_contents .= "\n#if SWIG_VERSION > 0x040000\n\%pythoncode \%{\n if '$s' in globals():\n $s.__setattr__ = _swig_setattr_nondynamic_instance_variable(object.__setattr__)\n\%}\n#endif\n" ;
|
||||
}
|
||||
}
|
||||
|
||||
$$new_contents_ref .= $extracted . $tail ;
|
||||
$$new_contents_ref .= $extracted . $tail . $my_struct_contents ;
|
||||
|
||||
}
|
||||
|
||||
|
@ -115,7 +115,7 @@ TRICK_CFLAGS += $(TRICKIFY_CXX_FLAGS)
|
||||
TRICK_CXXFLAGS += $(TRICKIFY_CXX_FLAGS)
|
||||
|
||||
# Ensure we can process all headers
|
||||
TRICK_EXT_LIB_DIRS :=
|
||||
TRICK_EXT_LIB_DIRS := $(TRICKIFY_EXT_LIB_DIRS)
|
||||
|
||||
.PHONY: all
|
||||
all: $(TRICKIFY_OBJECT_NAME) $(TRICKIFY_PYTHON_DIR)
|
||||
|
@ -1,3 +1,2 @@
|
||||
TRICK_CONVERT_SWIG_FLAGS := -s
|
||||
TRICK_CFLAGS += -Imodels
|
||||
TRICK_CXXFLAGS += -Imodels
|
||||
|
@ -1,93 +1,185 @@
|
||||
#include <vector>
|
||||
// @trick_parse{everything}
|
||||
|
||||
namespace a {
|
||||
template<class> class A {
|
||||
private:
|
||||
void operator=(const A&);
|
||||
#ifndef Classes_HH
|
||||
#define Classes_HH
|
||||
|
||||
template <class T>
|
||||
class Foo {};
|
||||
|
||||
namespace peer {
|
||||
template <class T>
|
||||
class Bar {};
|
||||
|
||||
struct Leek {
|
||||
template <class T>
|
||||
class Eggplant {};
|
||||
};
|
||||
|
||||
namespace nested {
|
||||
template <class T>
|
||||
class Broccoli {};
|
||||
|
||||
struct Carrot {
|
||||
template <class T>
|
||||
class Celery {};
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
namespace b {
|
||||
namespace prime {
|
||||
|
||||
template<class> class A {};
|
||||
template<class> class B {};
|
||||
template<class T>
|
||||
class Potato {};
|
||||
|
||||
class C {
|
||||
public:
|
||||
std::vector<int> v;
|
||||
a::A<int> a;
|
||||
a::A<int> a2;
|
||||
A<int> a3;
|
||||
A<int> a4;
|
||||
B<int> b;
|
||||
B<int> b2;
|
||||
b::B<int> b3;
|
||||
b::B<int> b4;
|
||||
B<a::A<int> > ba;
|
||||
B<a::A<int> > ba2;
|
||||
b::B<a::A<int> > ba3;
|
||||
b::B<a::A<int> > ba4;
|
||||
B<A<int> > ba5;
|
||||
B<A<int> > ba6;
|
||||
|
||||
// These don't work. Because the type is qualified, convert_swig assumes
|
||||
// it's fully qualified and puts the %template directive in the global
|
||||
// namespace. However, there is no A in the global namespace, so the wrapper
|
||||
// code fails to compile. Bonus points if you can fix this without breaking
|
||||
// something else.
|
||||
//b::B<A<int> > ba7;
|
||||
//b::B<A<int> > ba8;
|
||||
struct Turnip {
|
||||
template <class T>
|
||||
class Radish {};
|
||||
};
|
||||
|
||||
// This class is the same as the previous. Seems weird, but it reveals scoping
|
||||
// errors under SWIG 2. The replication is not necessary in SWIG 4, which has
|
||||
// better error detection.
|
||||
class D {
|
||||
public:
|
||||
std::vector<int> v;
|
||||
a::A<int> a;
|
||||
a::A<int> a2;
|
||||
A<int> a3;
|
||||
A<int> a4;
|
||||
B<int> b;
|
||||
B<int> b2;
|
||||
b::B<int> b3;
|
||||
b::B<int> b4;
|
||||
B<a::A<int> > ba;
|
||||
B<a::A<int> > ba2;
|
||||
b::B<a::A<int> > ba3;
|
||||
b::B<a::A<int> > ba4;
|
||||
B<A<int> > ba5;
|
||||
B<A<int> > ba6;
|
||||
//b::B<A<int> > ba7;
|
||||
//b::B<A<int> > ba8;
|
||||
namespace nested {
|
||||
template <class T>
|
||||
class Baz {};
|
||||
|
||||
struct Artichoke {
|
||||
template <class T>
|
||||
class Asparagus {};
|
||||
};
|
||||
}
|
||||
|
||||
struct Onion {
|
||||
// ======================= WORKING =============================================
|
||||
/**
|
||||
* We assume a qualified template instantiation is fully qualified
|
||||
* starting from the global namespace, and we put the corresponding
|
||||
* %template directive in the global namespace, which works if our
|
||||
* assumption is correct.
|
||||
*/
|
||||
::Foo<int> fooInt;
|
||||
|
||||
peer::Bar<int> barInt;
|
||||
::peer::Bar<double> barDouble;
|
||||
|
||||
peer::Leek::Eggplant<int> eggplantInt;
|
||||
::peer::Leek::Eggplant<double> eggplantDouble;
|
||||
|
||||
peer::nested::Broccoli<int> broccoliInt;
|
||||
::peer::nested::Broccoli<double> broccoliDouble;
|
||||
|
||||
peer::nested::Carrot::Celery<int> celeryInt;
|
||||
::peer::nested::Carrot::Celery<double> celeryDouble;
|
||||
|
||||
prime::Potato<int> potatoInt;
|
||||
::prime::Potato<double> potatoDouble;
|
||||
|
||||
prime::Turnip::Radish<int> radishInt;
|
||||
::prime::Turnip::Radish<double> radishDouble;
|
||||
|
||||
prime::nested::Baz<int> bazInt;
|
||||
::prime::nested::Baz<double> bazDouble;
|
||||
|
||||
prime::nested::Artichoke::Asparagus<int> asparagusint;
|
||||
::prime::nested::Artichoke::Asparagus<double> asparagusDouble;
|
||||
|
||||
/**
|
||||
* We put the %template directive for unqualified template
|
||||
* instantiations in the namespace containing the current class,
|
||||
* which only works if the template is defined in that namespace as
|
||||
* well.
|
||||
*/
|
||||
Potato<bool> potatoBool;
|
||||
|
||||
// ======================= BROKEN ==============================================
|
||||
/**
|
||||
* Because Foo is declared in the global namespace, its %template
|
||||
* directive must be in that scope as well. However, because the
|
||||
* template instation here is unqualified, we put the %template
|
||||
* directive in the containing namespace, which is an error.
|
||||
*
|
||||
* Error: 'Foo' resolves to '::Foo' and was incorrectly
|
||||
* instantiated in scope 'prime' instead of within scope ''.
|
||||
*/
|
||||
// Foo<double> fooDouble;
|
||||
|
||||
/**
|
||||
* Because these template instantiations are qualified, their %template
|
||||
* directives are placed in the global namespace. However, because they
|
||||
* are not _fully_ qualified, the generated SWIG input code is invalid.
|
||||
* For partially-qualified instantiations, the directive should either be:
|
||||
* 1. Declared in the global namespace and qualified with prime::
|
||||
* 2. Declared in the prime namespace
|
||||
*
|
||||
* We don't track enough information to do either.
|
||||
*
|
||||
* Error: Template 'Turnip::Radish' undefined.
|
||||
* Error: Template 'nested::Baz' undefined.
|
||||
* Error: Template 'nested::Artichoke::Asparagus' undefined.
|
||||
*/
|
||||
// Turnip::Radish<bool> radishBool;
|
||||
// nested::Baz<bool> bazBool;
|
||||
// nested::Artichoke::Asparagus<bool> asparagusBool;
|
||||
|
||||
template<class T>
|
||||
class InnerOnion {}; // onions have layers!
|
||||
|
||||
/**
|
||||
* All %template directives are placed before the class containing their
|
||||
* corresponding template instantiations. For member templates
|
||||
* (templates declared within the class being processed), this results
|
||||
* in the %template directive referencing the member template before it
|
||||
* has been declared, which is an error.
|
||||
*
|
||||
* Error: Template 'InnerOnion' undefined.
|
||||
* Error: Template 'Onion::InnerOnion' undefined.
|
||||
* Error: Template 'prime::Onion::InnerOnion' undefined.
|
||||
* Error: Template '::prime::Onion::InnerOnion' undefined.
|
||||
*/
|
||||
// InnerOnion<int> layer1;
|
||||
// Onion::InnerOnion<double> layer2;
|
||||
// prime::Onion::InnerOnion<bool> layer2;
|
||||
// ::prime::Onion::InnerOnion<short> layer4;
|
||||
};
|
||||
|
||||
// Same tests as above, but within a nested namespace.
|
||||
namespace nested {
|
||||
class Corn {
|
||||
::Foo<peer::Leek> fooLeek;
|
||||
|
||||
peer::Bar<Foo<long> > barFoo;
|
||||
::peer::Bar<peer::Leek> barLeek;
|
||||
|
||||
peer::Leek::Eggplant<long> eggplantLong;
|
||||
::peer::Leek::Eggplant<peer::Leek> eggplantLeek;
|
||||
|
||||
peer::nested::Broccoli<long> broccoliLong;
|
||||
::peer::nested::Broccoli<peer::Leek> broccoliLeek;
|
||||
|
||||
peer::nested::Carrot::Celery<long> celeryLong;
|
||||
::peer::nested::Carrot::Celery<peer::Leek> celeryLeek;
|
||||
|
||||
prime::Potato<long> potatoLong;
|
||||
::prime::Potato<peer::Leek> potatoLeek;
|
||||
|
||||
prime::Turnip::Radish<long> radishLong;
|
||||
::prime::Turnip::Radish<peer::Leek> radishLeek;
|
||||
|
||||
prime::nested::Baz<long> bazLong;
|
||||
::prime::nested::Baz<peer::Leek> bazLeek;
|
||||
|
||||
prime::nested::Artichoke::Asparagus<long> asparagusLong;
|
||||
::prime::nested::Artichoke::Asparagus<peer::Leek> asparagusLeek;
|
||||
|
||||
// These fail in Onion, but work here because Onion has already been processed.
|
||||
prime::Onion::InnerOnion<long> onionLong;
|
||||
::prime::Onion::InnerOnion<peer::Leek> onionLeek;
|
||||
|
||||
// These fail for the same reason as in Onion.
|
||||
// Foo<float> fooFloat;
|
||||
// Turnip::Radish<float> radishFloat;
|
||||
// nested::Baz<float> bazFloat;
|
||||
// nested::Artichoke::Asparagus<float> asparagusFloat;
|
||||
// Onion::InnerOnion<float> innerOnionFloat;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
class E {
|
||||
public:
|
||||
std::vector<int> v;
|
||||
a::A<int> a;
|
||||
a::A<int> a2;
|
||||
b::B<int> b3;
|
||||
b::B<int> b4;
|
||||
b::B<a::A<int> > ba3;
|
||||
b::B<a::A<int> > ba4;
|
||||
};
|
||||
|
||||
namespace a {
|
||||
class B {
|
||||
public:
|
||||
std::vector<int> v;
|
||||
a::A<int> a;
|
||||
a::A<int> a2;
|
||||
A<int> a3;
|
||||
A<int> a4;
|
||||
b::B<int> b3;
|
||||
b::B<int> b4;
|
||||
b::B<a::A<int> > ba3;
|
||||
b::B<a::A<int> > ba4;
|
||||
//b::B<A<int> > ba7;
|
||||
//b::B<A<int> > ba8;
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
@ -1,10 +1,59 @@
|
||||
exec(open("Modified_data/dr_typesASCII.dr").read())
|
||||
exec(open("Modified_data/dr_typesBINARY.dr").read())
|
||||
exec(open("Modified_data/dr_bitfASCII.dr").read())
|
||||
exec(open("Modified_data/dr_bitfBINARY.dr").read())
|
||||
from trick.unit_test import *
|
||||
|
||||
trick_utest.unit_tests.enable() ;
|
||||
trick_utest.unit_tests.set_file_name( os.getenv("TRICK_HOME") + "/trick_test/SIM_test_dr.xml" ) ;
|
||||
trick_utest.unit_tests.enable()
|
||||
trick_utest.unit_tests.set_file_name( os.getenv("TRICK_HOME") + "/trick_test/SIM_test_dr.xml" )
|
||||
|
||||
trick_utest.unit_tests.set_test_name( "DRTest" )
|
||||
|
||||
######################################################################################################################
|
||||
|
||||
test_suite = "drg api"
|
||||
|
||||
# Get the number of data recording groups before any drg is created
|
||||
num_drgs = trick.get_num_data_record_groups()
|
||||
|
||||
# Check the result of trick.get_num_data_record_groups()
|
||||
TRICK_EXPECT_EQ( num_drgs , 0 , test_suite , "0 drgs before any created" )
|
||||
|
||||
# The first item of each pair is the .dr file name and the second item of each pair is the drg name
|
||||
dr_file_name_drg_name_tuple = (('Modified_data/dr_typesASCII.dr', 'DR_typesASCII'),
|
||||
('Modified_data/dr_typesBINARY.dr', 'DR_typesBINARY'),
|
||||
('Modified_data/dr_bitfASCII.dr', 'DR_bitfieldsASCII'),
|
||||
('Modified_data/dr_bitfBINARY.dr', 'DR_bitfieldsBINARY'))
|
||||
|
||||
num_files = len(dr_file_name_drg_name_tuple)
|
||||
for i in range(num_files):
|
||||
exec(open(dr_file_name_drg_name_tuple[i][0]).read())
|
||||
|
||||
# Get the number of data recording groups created
|
||||
num_drgs = trick.get_num_data_record_groups()
|
||||
|
||||
# Check the result of trick.get_num_data_record_groups()
|
||||
TRICK_EXPECT_EQ( num_drgs , 4 , test_suite , "num of dr groups = 4" )
|
||||
|
||||
# Test trick.get_data_record_group(<drg_name>) for getting the drg pointer by its name
|
||||
# Check the name of the obtained drg instead of the drg pointer
|
||||
for i in range(num_drgs):
|
||||
TRICK_EXPECT_EQ( trick.get_data_record_group(dr_file_name_drg_name_tuple[i][1]).get_group_name(), dr_file_name_drg_name_tuple[i][1], test_suite , "get drg by name " + dr_file_name_drg_name_tuple[i][1] )
|
||||
|
||||
# Test trick.get_data_record_group_by_idx(<drg_idx) for getting the drg pointer by its id number
|
||||
# Check the name of the obtained drg instead of the drg pointer
|
||||
for i in range(num_drgs):
|
||||
TRICK_EXPECT_EQ( trick.get_data_record_group_by_idx(i).get_group_name(), dr_file_name_drg_name_tuple[i][1], test_suite , "get drg by drg id " + str(i) )
|
||||
|
||||
is_null = False
|
||||
if trick.get_data_record_group(dr_file_name_drg_name_tuple[0][1]+'test') is None :
|
||||
is_null = True
|
||||
TRICK_EXPECT_TRUE( is_null, test_suite , "null drg by nonexistent drg name" )
|
||||
|
||||
is_null = False
|
||||
if trick.get_data_record_group_by_idx(num_drgs+1) is None :
|
||||
is_null = True
|
||||
TRICK_EXPECT_TRUE( is_null, test_suite , "null drg by drg id 5" )
|
||||
|
||||
is_null = False
|
||||
if trick.get_data_record_group_by_idx(-1) is None :
|
||||
is_null = True
|
||||
TRICK_EXPECT_TRUE( is_null, test_suite , "null drg by drg id -1" )
|
||||
|
||||
trick.stop(1.0)
|
||||
|
@ -21,6 +21,8 @@ SIM_parse_s_define:
|
||||
path: test/SIM_parse_s_define
|
||||
SIM_target_specific_variables:
|
||||
path: test/SIM_target_specific_variables
|
||||
SIM_swig_template_scoping:
|
||||
path: test/SIM_swig_template_scoping
|
||||
SIM_test_abstract:
|
||||
path: test/SIM_test_abstract
|
||||
SIM_test_inherit:
|
||||
|
BIN
trick_sims/SIM_singlerigidbody/Images/AccOmega.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
trick_sims/SIM_singlerigidbody/Images/Angle.png
Normal file
After Width: | Height: | Size: 3.1 KiB |
BIN
trick_sims/SIM_singlerigidbody/Images/Angularvelocity.png
Normal file
After Width: | Height: | Size: 3.4 KiB |
BIN
trick_sims/SIM_singlerigidbody/Images/Centerofmass.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
trick_sims/SIM_singlerigidbody/Images/EquationsofMotion.png
Normal file
After Width: | Height: | Size: 6.9 KiB |
BIN
trick_sims/SIM_singlerigidbody/Images/Force.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
trick_sims/SIM_singlerigidbody/Images/ForceTorque.png
Normal file
After Width: | Height: | Size: 886 B |
BIN
trick_sims/SIM_singlerigidbody/Images/ForceTorqueRemain.png
Normal file
After Width: | Height: | Size: 3.3 KiB |
BIN
trick_sims/SIM_singlerigidbody/Images/Inertia.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
trick_sims/SIM_singlerigidbody/Images/Mass.png
Normal file
After Width: | Height: | Size: 2.0 KiB |
BIN
trick_sims/SIM_singlerigidbody/Images/MassMatrix.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
trick_sims/SIM_singlerigidbody/Images/Position.png
Normal file
After Width: | Height: | Size: 3.4 KiB |
BIN
trick_sims/SIM_singlerigidbody/Images/Radius.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
trick_sims/SIM_singlerigidbody/Images/Torque.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
trick_sims/SIM_singlerigidbody/Images/Vectora.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
trick_sims/SIM_singlerigidbody/Images/Velocity.png
Normal file
After Width: | Height: | Size: 3.2 KiB |
BIN
trick_sims/SIM_singlerigidbody/Images/koviz.png
Normal file
After Width: | Height: | Size: 157 KiB |
BIN
trick_sims/SIM_singlerigidbody/Images/trick-dp.png
Normal file
After Width: | Height: | Size: 88 KiB |
12
trick_sims/SIM_singlerigidbody/Modified_data/realtime.py
Normal file
@ -0,0 +1,12 @@
|
||||
|
||||
trick.frame_log_on()
|
||||
trick.real_time_enable()
|
||||
trick.exec_set_software_frame(0.033)
|
||||
trick.itimer_enable()
|
||||
|
||||
trick.exec_set_enable_freeze(True)
|
||||
#trick.exec_set_freeze_command(True)
|
||||
|
||||
#simControlPanel = trick.SimControlPanel()
|
||||
#trick.add_external_application(simControlPanel)
|
||||
|
54
trick_sims/SIM_singlerigidbody/Modified_data/state_data.dr
Normal file
@ -0,0 +1,54 @@
|
||||
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.DRBinary("StateData"))
|
||||
drg[DR_GROUP_ID].set_freq(trick.DR_Always)
|
||||
drg[DR_GROUP_ID].set_cycle(0.10)
|
||||
drg[DR_GROUP_ID].set_single_prec_only(False)
|
||||
drg[DR_GROUP_ID].add_variable("dyn.body.force[0]")
|
||||
drg[DR_GROUP_ID].add_variable("dyn.body.force[1]")
|
||||
drg[DR_GROUP_ID].add_variable("dyn.body.force[2]")
|
||||
drg[DR_GROUP_ID].add_variable("dyn.body.angle_force[0]")
|
||||
drg[DR_GROUP_ID].add_variable("dyn.body.angle_force[1]")
|
||||
drg[DR_GROUP_ID].add_variable("dyn.body.angle_force[2]")
|
||||
drg[DR_GROUP_ID].add_variable("dyn.body.rotate[0][0]")
|
||||
drg[DR_GROUP_ID].add_variable("dyn.body.rotate[0][1]")
|
||||
drg[DR_GROUP_ID].add_variable("dyn.body.rotate[0][2]")
|
||||
drg[DR_GROUP_ID].add_variable("dyn.body.rotate[1][0]")
|
||||
drg[DR_GROUP_ID].add_variable("dyn.body.rotate[1][1]")
|
||||
drg[DR_GROUP_ID].add_variable("dyn.body.rotate[1][2]")
|
||||
drg[DR_GROUP_ID].add_variable("dyn.body.rotate[2][0]")
|
||||
drg[DR_GROUP_ID].add_variable("dyn.body.rotate[2][1]")
|
||||
drg[DR_GROUP_ID].add_variable("dyn.body.rotate[2][2]")
|
||||
drg[DR_GROUP_ID].add_variable("dyn.body.pos[0]")
|
||||
drg[DR_GROUP_ID].add_variable("dyn.body.pos[1]")
|
||||
drg[DR_GROUP_ID].add_variable("dyn.body.pos[2]")
|
||||
drg[DR_GROUP_ID].add_variable("dyn.body.angle[0]")
|
||||
drg[DR_GROUP_ID].add_variable("dyn.body.angle[1]")
|
||||
drg[DR_GROUP_ID].add_variable("dyn.body.angle[2]")
|
||||
drg[DR_GROUP_ID].add_variable("dyn.body.vel[0]")
|
||||
drg[DR_GROUP_ID].add_variable("dyn.body.vel[1]")
|
||||
drg[DR_GROUP_ID].add_variable("dyn.body.vel[2]")
|
||||
drg[DR_GROUP_ID].add_variable("dyn.body.acc[0]")
|
||||
drg[DR_GROUP_ID].add_variable("dyn.body.acc[1]")
|
||||
drg[DR_GROUP_ID].add_variable("dyn.body.acc[2]")
|
||||
drg[DR_GROUP_ID].add_variable("dyn.body.omega[0]")
|
||||
drg[DR_GROUP_ID].add_variable("dyn.body.omega[1]")
|
||||
drg[DR_GROUP_ID].add_variable("dyn.body.omega[2]")
|
||||
drg[DR_GROUP_ID].add_variable("dyn.body.omegaDot[0]")
|
||||
drg[DR_GROUP_ID].add_variable("dyn.body.omegaDot[1]")
|
||||
drg[DR_GROUP_ID].add_variable("dyn.body.omegaDot[2]")
|
||||
drg[DR_GROUP_ID].add_variable("dyn.body.FORCE_INIT[0]")
|
||||
drg[DR_GROUP_ID].add_variable("dyn.body.FORCE_INIT[1]")
|
||||
drg[DR_GROUP_ID].add_variable("dyn.body.FORCE_INIT[2]")
|
||||
|
||||
|
||||
|
||||
trick.add_data_record_group(drg[DR_GROUP_ID], trick.DR_Buffer)
|
||||
drg[DR_GROUP_ID].enable()
|
122
trick_sims/SIM_singlerigidbody/README.md
Normal file
@ -0,0 +1,122 @@
|
||||
# Single Rigid Body
|
||||
``SIM_singlerigidbody`` is a simulation of the motion of a sphere that is a single rigid body with six degrees of freedom.
|
||||
|
||||
The motion of the sphere is found by using Euler's equations of motion, and can be controlled by changing several initial input values such as force, position, angle, angular velocity, velocity, and position of the force. The recorded data of the motion can then be viewed and analyzed.
|
||||
|
||||
## Dynamics model
|
||||
|
||||
### Equations of Motion
|
||||
To determine the sphere's motion, we will use Euler's equations of motion for a single rigid body. Euler's equations describe the combined translational and rotational dynamics of a rigid body in three-dimensional space.
|
||||
|
||||

|
||||
|
||||
Where,
|
||||
|
||||

|
||||
* is a 6x1 column vector.
|
||||
* F is the applied force.
|
||||
* τ is the torque.
|
||||
|
||||

|
||||
* is a 6x6 matrix.
|
||||
* m is the mass.
|
||||
* I <sub> 3x3 </sub> is the identity matrix.
|
||||
* I is the inertia.
|
||||
* C <sub> m </sub> is the center of mass.
|
||||
|
||||

|
||||
* is a 6x1 column vector.
|
||||
* a<sub> o </sub> is the acceleration.
|
||||
|
||||

|
||||
* is a 6x1 column vector.
|
||||
* ω <sup> A </sup> is the angular velocity.
|
||||
|
||||
|
||||
#### Force
|
||||
The force acting on the sphere is calculated by the cross product of the rotation matrix and initial force.
|
||||
|
||||

|
||||
|
||||
#### Torque
|
||||
Torque is found by the cross product of the rotation matrix and the cross product of the position of force and initial force.
|
||||
|
||||

|
||||
|
||||
#### Mass
|
||||
The default value of the mass of the sphere is:
|
||||
|
||||

|
||||
|
||||
#### Radius
|
||||
The default value of the radius is:
|
||||
|
||||

|
||||
|
||||
#### Center of mass
|
||||
The center of mass of a sphere is equal to its radius.
|
||||
|
||||

|
||||
|
||||
#### Inertia
|
||||
Inertia of a sphere is calculated by:
|
||||
|
||||

|
||||
|
||||
#### Acceleration and angular acceleration
|
||||
To determine the acceleration and angular acceleration, ```dLU_Choleski``` must be used. ```dLU_Choleski``` solves linear sets of equations in the form of [A]x = b and returns the vector x, which is the acceleration. It decomposes the symmetric, positive definite [A] matrix into a lower triangular form, where we can then substitute and our equation becomes:
|
||||
|
||||

|
||||
|
||||
The term 'a' is a 6x1 vector. Acceleration is equal to the first three values of vector a and angular acceleration is equal to the last three values of vector a.
|
||||
|
||||
### State Integration
|
||||
The state is defined by position, velocity, angle, and angular velocity. They are calculated by numerically integrating velocity, acceleration, angular velocity, and angular acceleration, respectively.
|
||||
|
||||
#### Position
|
||||
The position of the sphere is determined by integrating the velocity over time.
|
||||
|
||||

|
||||
|
||||
#### Velocity
|
||||
The velocity is determined by integrating the acceleration of the sphere over time.
|
||||
|
||||

|
||||
|
||||
#### Angle
|
||||
The angle is determined by integrating the angular velocity over time.
|
||||
|
||||

|
||||
|
||||
#### Angular velocity
|
||||
The angular velocity is determined by integrating the angular acceleration over time.
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
## Inputs
|
||||
|
||||
Variable |Type |Units
|
||||
----------------------------|-------------|---------
|
||||
dyn.body.POS_INIT |double[3] |m
|
||||
dyn.body.ANGLE_INIT |double[3] |rad
|
||||
dyn.body.OMEGA_INIT |double[3] |rad*s^-1
|
||||
dyn.body.FORCE_INIT |double[3] |N
|
||||
dyn.body.TORQUE_INIT |double[3] |N*m
|
||||
dyn.body.VEL_INIT |double[3] |m/s
|
||||
dyn.body.POS_FORCE |double[3] |m
|
||||
|
||||
## Outputs
|
||||
|
||||
Variable |Type |Units
|
||||
----------------------------|-------------|--------
|
||||
dyn.body.pos |double[3] |m
|
||||
dyn.body.vel |double[3] |m/s
|
||||
dyn.body.acc |double[3] |m/s^2
|
||||
dyn.FORCE_INIT |double[3] |N
|
||||
dyn.force |double[3] |N
|
||||
dyn.body.angle_force |double[3] |rad
|
||||
dyn.body.omegaDot |double[3] |rad/^s2
|
||||
dyn.body.omega |double[3] |rad*s^-1
|
||||
dyn.body.rotate |double[3] |
|
81
trick_sims/SIM_singlerigidbody/RUN_test/input.py
Normal file
@ -0,0 +1,81 @@
|
||||
################################################################################
|
||||
# _ ___ _ #
|
||||
# / |___| _ ) ___ __| |_ _ #
|
||||
# | |___| _ \/ _ \/ _` | || | #
|
||||
# |_| |___/\___/\__,_|\_, | #
|
||||
# __ ___ ___ __|__/ #
|
||||
# / / ___| \ / _ \| __| #
|
||||
# / _ \___| |) | (_) | _| #
|
||||
# \___/ |___/ \___/|_| #
|
||||
# #
|
||||
# This input creates a simple body with 6 DOF: #
|
||||
# -Creates 1 body #
|
||||
# -Initializes 6 DOF #
|
||||
################################################################################
|
||||
|
||||
# ============================================================================ -
|
||||
# This file is used to store several quality of life python functions.
|
||||
# ============================================================================ -
|
||||
exec(open("Modified_data/state_data.dr").read())
|
||||
exec(open("Modified_data/realtime.py").read())
|
||||
|
||||
################################################################################
|
||||
# dyn DATA #
|
||||
# (NOTE: dyn is our instance of BodySimObject) #
|
||||
# This builds our objects, and defines their physical properties. #
|
||||
################################################################################
|
||||
|
||||
# ============================================================================ -
|
||||
# Establish the physical properties of the body...CONSTANTS!
|
||||
# ============================================================================ -
|
||||
dyn.body.mass = 20.0
|
||||
dyn.body.radius = 2.0
|
||||
|
||||
# ============================================================================ -
|
||||
# Initialize system
|
||||
# ============================================================================ -
|
||||
M_PI = 3.141592653589793238460
|
||||
|
||||
#dyn.body.POS_INIT[0] = 0.0
|
||||
#dyn.body.POS_INIT[1] = 0.0
|
||||
#dyn.body.POS_INIT[2] = 0.0
|
||||
|
||||
#dyn.body.ANGLE_INIT[0] = 0.0
|
||||
#dyn.body.ANGLE_INIT[1] = 0.0
|
||||
#dyn.body.ANGLE_INIT[2] = 0.0
|
||||
|
||||
#dyn.body.OMEGA_INIT[0] = 0.0
|
||||
#dyn.body.OMEGA_INIT[1] = 0.0
|
||||
#dyn.body.OMEGA_INIT[2] = 0.0
|
||||
|
||||
#dyn.body.FORCE_INIT[0] = 0.0
|
||||
#dyn.body.FORCE_INIT[1] = 0.0
|
||||
#dyn.body.FORCE_INIT[2] = 10.0
|
||||
|
||||
#dyn.body.TORQUE_INIT[0] = 0.0
|
||||
#dyn.body.TORQUE_INIT[1] = 0.0
|
||||
#dyn.body.TORQUE_INIT[2] = 0.0
|
||||
|
||||
#dyn.body.VEL_INIT[0] = 0.0
|
||||
#dyn.body.VEL_INIT[1] = 0.0
|
||||
#dyn.body.VEL_INIT[2] = 0.0
|
||||
|
||||
#dyn.body.POS_FORCE[0] = 2.0
|
||||
#dyn.body.POS_FORCE[1] = 0.0
|
||||
#dyn.body.POS_FORCE[2] = 0.0
|
||||
|
||||
################################################################################
|
||||
# SIMULATION SET UP #
|
||||
# This is where we set up the remaining inputs to create a working sim. #
|
||||
################################################################################
|
||||
|
||||
# ============================================================================ -
|
||||
# getintegrator(integration method, number of variables to be integrated)
|
||||
# This sets up the integration scheme we use to analyze this system.
|
||||
# ============================================================================ -
|
||||
dyn_integloop.getIntegrator(trick.Runge_Kutta_4, 12)
|
||||
|
||||
# ============================================================================ -
|
||||
# This tells the sim to stop after a few seconds
|
||||
# ============================================================================ -
|
||||
trick.stop(10.0)
|
32
trick_sims/SIM_singlerigidbody/S_define
Normal file
@ -0,0 +1,32 @@
|
||||
/************************TRICK HEADER*************************
|
||||
PURPOSE:
|
||||
( Single body rigid dynamics simulation )
|
||||
LIBRARY DEPENDENCIES:
|
||||
((src/body.cpp)
|
||||
(src/body_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 "include/body.hh"
|
||||
class BodySimObject : public Trick::SimObject {
|
||||
public:
|
||||
BODY body;
|
||||
|
||||
BodySimObject() {
|
||||
("default_data") body.default_data() ;
|
||||
("initialization") body.init() ;
|
||||
("derivative") body.derivative() ;
|
||||
("integration") trick_ret = body.integ() ;
|
||||
("shutdown") body.body_shutdown();
|
||||
}
|
||||
};
|
||||
|
||||
BodySimObject dyn;
|
||||
IntegLoop dyn_integloop(0.01) dyn;
|
||||
|
14
trick_sims/SIM_singlerigidbody/S_overrides.mk
Normal file
@ -0,0 +1,14 @@
|
||||
TRICK_CFLAGS += -Imodels
|
||||
TRICK_CXXFLAGS += -Imodels
|
||||
|
||||
.PHONY: clean_graphics
|
||||
|
||||
all: models/singlerigidbodygraphics/build/SingleRigidBodyDisplay.jar
|
||||
|
||||
spotless: clean_graphics
|
||||
|
||||
models/singlerigidbodygraphics/build/SingleRigidBodyDisplay.jar:
|
||||
${MAKE} -C ./models/singlerigidbodygraphics
|
||||
|
||||
clean_graphics:
|
||||
${MAKE} -C ./models/singlerigidbodygraphics clean
|
78
trick_sims/SIM_singlerigidbody/models/include/body.hh
Normal file
@ -0,0 +1,78 @@
|
||||
/*********************************************************************
|
||||
PURPOSE: (Simulate a single rigid body with six degrees of freedom)
|
||||
LIBRARY DEPENDENCIES:
|
||||
((SingleRigidBody/src/body.o))
|
||||
*********************************************************************/
|
||||
#ifndef BODY_HH
|
||||
#define BODY_HH
|
||||
|
||||
class BODY {
|
||||
public:
|
||||
BODY();
|
||||
~BODY();
|
||||
//Variables
|
||||
|
||||
//Initializes state variables
|
||||
double POS_INIT[3];
|
||||
double VEL_INIT[3];
|
||||
double ANGLE_INIT[3];
|
||||
double OMEGA_INIT[3];
|
||||
|
||||
//State variables
|
||||
double pos[3];
|
||||
double vel[3];
|
||||
double angle[3];
|
||||
double omega[3];
|
||||
|
||||
double acc[3];
|
||||
double omegaDot[3];
|
||||
|
||||
double force[3];
|
||||
double FORCE_INIT[3];
|
||||
double force_remain[3];
|
||||
double POS_FORCE[3];
|
||||
|
||||
double torque[3];
|
||||
double TORQUE_INIT[3];
|
||||
double torque_remain[3];
|
||||
|
||||
double inertia;
|
||||
double inertia_matrix[3][3];
|
||||
|
||||
double radius;
|
||||
double mass;
|
||||
double mat_mass[6][6];
|
||||
double massmatrix[3][3];
|
||||
|
||||
double CM[3];
|
||||
double CM_skew[3][3];
|
||||
double m_CM_skew[3][3];
|
||||
double neg_m_CM_skew[3][3];
|
||||
|
||||
double vec_a[6];
|
||||
double vec_b[6];
|
||||
|
||||
double rotate[3][3];
|
||||
double angle_force[3];
|
||||
|
||||
double tmp_vec[6];
|
||||
double **mat_mass_dyn;
|
||||
double **mat_L;
|
||||
|
||||
// Methods
|
||||
void default_data();
|
||||
void init();
|
||||
void derivative();
|
||||
int integ();
|
||||
int body_shutdown();
|
||||
|
||||
void rotation_matrix();
|
||||
void calcforce();
|
||||
void calctorque();
|
||||
void calcforce_remain();
|
||||
void calctorque_remain();
|
||||
void eq_setup();
|
||||
void eq_solver();
|
||||
};
|
||||
|
||||
#endif
|
@ -0,0 +1,6 @@
|
||||
|
||||
all:
|
||||
mvn package
|
||||
|
||||
clean:
|
||||
rm -rf build
|
@ -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>SingleRigidBodyDisplay</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.SRBDisplay</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,152 @@
|
||||
// This file contains helper functions for the matrix operations necessary for the graphics to be generated.
|
||||
|
||||
package trick.matrixOps;
|
||||
|
||||
|
||||
|
||||
public class MatrixOps { // Defines the matrix operation class.
|
||||
|
||||
public static void printMatrix(double M[][]) { // Prints out the matrix.
|
||||
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[]) { // Prints out a vector passed as a double.
|
||||
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[]) { // Prints out a vector passed as an integer.
|
||||
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[][]) { // Multiplies two matrices together.
|
||||
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) { // Checks if the matrices can be multiplied.
|
||||
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)) { // Checks if the defined result matrix is the wrong size.
|
||||
System.out.println( "\n Result matrix is wrong size.");
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < A_rows; i++) { // Multiplies the two matrices together.
|
||||
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[]) { // Multiplies a matrix with a vector.
|
||||
int M_rows = M.length;
|
||||
int M_cols = M[0].length;
|
||||
int V_rows = V.length;
|
||||
|
||||
if (M_cols != V_rows) { // Checks if the matrix and the vector can be multiplied together.
|
||||
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) { // Checks if the defined result vector is the wrong size.
|
||||
System.out.println( "\n Result vector is wrong size.");
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i =0; i < M_rows ; i++) { // Multiplies the vector with the matrix.
|
||||
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[]) { // Adds two matrices together.
|
||||
if ((A.length != B.length) || (A.length != R.length)) {
|
||||
System.out.println( "\n MatrixOps::VplusV : Vectors are not the same size.");
|
||||
}
|
||||
for (int i=0; i<A.length ; i++) {
|
||||
R[i] = A[i] + B[i];
|
||||
}
|
||||
}
|
||||
|
||||
public static void VminusV(double R[], double A[], double B[]) { // Subtracts two matrices together.
|
||||
if ((A.length != B.length) || (A.length != R.length)) {
|
||||
System.out.println( "\n MatrixOps::VminusV : Vectors are not the same size.");
|
||||
return;
|
||||
}
|
||||
for (int i=0; i<A.length ; i++) {
|
||||
R[i] = A[i] - B[i];
|
||||
}
|
||||
}
|
||||
|
||||
public static void VcrossV(double R[], double A[], double B[]) { // Finds the cross product of two matrices.
|
||||
if ((R.length != 3) || (A.length != 3) || (B.length != 3)) {
|
||||
System.out.println( "\n MatrixOps::VcrossV : All vector args must be length 3.");
|
||||
return;
|
||||
}
|
||||
R[0] = A[1] * B[2] - A[2] * B[1];
|
||||
R[1] = A[2] * B[0] - A[0] * B[2];
|
||||
R[2] = A[0] * B[1] - A[1] * B[0];
|
||||
}
|
||||
|
||||
public static double VdotV(double A[], double B[]) { // Finds the dot product of two matrices.
|
||||
if (A.length != B.length) {
|
||||
System.out.println( "\n MatrixOps::VdotV : Vectors are not the same size.");
|
||||
return 0.0;
|
||||
}
|
||||
double R = 0.0;
|
||||
for (int i=0; i<A.length ; i++) {
|
||||
R += A[i] * B[i];
|
||||
}
|
||||
return R;
|
||||
}
|
||||
|
||||
public static void Vscale(double R[], double A[], double S) { // Scales a vector (Multiplies by a given number).
|
||||
if (A.length != R.length) {
|
||||
System.out.println( "\n MatrixOps::Vscale : Input and output vectors are not the same size.");
|
||||
return;
|
||||
}
|
||||
for (int i=0; i<A.length ; i++) {
|
||||
R[i] = A[i] * S;
|
||||
}
|
||||
}
|
||||
|
||||
public static double Vmagnitude (double V[]) { // Returns the magnitude of a vector (Length of a vector).
|
||||
double S = 0;
|
||||
for (int i =0; i < V.length ; i++) {
|
||||
S += V[i]*V[i];
|
||||
}
|
||||
return Math.sqrt(S);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -0,0 +1,628 @@
|
||||
// This file contains the architecture for the single rigid body simulation's 3D graphics client.
|
||||
|
||||
package trick;
|
||||
|
||||
// AWT is the abstract window toolkit.
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Color;
|
||||
import java.awt.event.MouseEvent;
|
||||
|
||||
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.*;
|
||||
|
||||
// Swing is a GUI widget toolkit.
|
||||
import javax.swing.JFrame; // Allows you to manage a top-level window.
|
||||
import javax.swing.JPanel; // The stuff within the window (controls, buttons, etc.).
|
||||
import javax.swing.event.MouseInputAdapter;
|
||||
|
||||
import trick.matrixOps.MatrixOps;
|
||||
|
||||
/**
|
||||
* @author Aditya Girish
|
||||
*/
|
||||
|
||||
class SingleRigidBodyView extends JPanel { // Main body class of how we view the SRB.
|
||||
|
||||
private int screen_half_width;
|
||||
private int screen_half_height;
|
||||
|
||||
private double illumination_vector[]; // World coordinates
|
||||
|
||||
private double vantageAzimuth; // Secifies the direction of the celestial light source.
|
||||
private double vantageElevation;
|
||||
|
||||
private double vantageDistance;
|
||||
private double beta;
|
||||
|
||||
private double worldToVantageRotation[][];
|
||||
|
||||
private Color bodyLineColor;
|
||||
private Color bodyFillColor;
|
||||
|
||||
private double[] bodyPos;
|
||||
|
||||
private double bodyToWorldRotation[][];
|
||||
|
||||
private double veh_vrtx_body[][];
|
||||
private double veh_vrtx_world[][];
|
||||
private int veh_vrtx_screen[][];
|
||||
|
||||
private int veh_edges[][];
|
||||
private int veh_triangles[][];
|
||||
|
||||
private double veh_unit_normals_body[][];
|
||||
private double veh_unit_normals_world[][];
|
||||
private double veh_unit_normals_vantage[][];
|
||||
|
||||
public SingleRigidBodyView() {
|
||||
|
||||
ViewListener viewListener = new ViewListener();
|
||||
addMouseListener(viewListener);
|
||||
addMouseMotionListener(viewListener);
|
||||
|
||||
// Direction of light.
|
||||
illumination_vector = new double[] {-0.707, 0.0, -0.707};
|
||||
|
||||
// Location of the observer, looking toward the world's origin.
|
||||
vantageAzimuth = Math.toRadians(45.0);
|
||||
vantageElevation = Math.toRadians(20.0);
|
||||
vantageDistance = 22.0;
|
||||
|
||||
// Half field of view angle
|
||||
beta = Math.toRadians(40.0);
|
||||
|
||||
worldToVantageRotation = new double[3][3];
|
||||
setAzElRotation(worldToVantageRotation, vantageAzimuth, vantageElevation);
|
||||
|
||||
bodyLineColor = Color.GRAY;
|
||||
bodyFillColor = new Color(255, 255, 250);
|
||||
|
||||
bodyPos = 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}};
|
||||
|
||||
|
||||
// The dodecahedron has 4 "layers" to it. I have labeled them as follows: top (T), upper-middle (UM), lower-middle (LM), and bottom (B)
|
||||
veh_vrtx_body = new double[][]
|
||||
{ {-1.37638,0.000000,0.262866}, // 0 - UM
|
||||
{1.37638,0.000000,-0.262866}, // 1 - LM
|
||||
{-0.425325,-1.30902,0.262866}, // 2 - UM
|
||||
{-0.425325,1.30902,0.262866}, // 3 - UM
|
||||
{1.11352,-0.809017,0.262866}, // 4 - UM
|
||||
{1.11352,0.809017,0.262866}, // 5 - UM
|
||||
{-0.262866,-0.809017,1.11352}, // 6 - T
|
||||
{-0.262866,0.809017,1.11352}, // 7 - T
|
||||
{-0.688191,-0.5,-1.11352}, // 8 - B
|
||||
{-0.688191,0.5,-1.11352}, // 9 - B
|
||||
{0.688191,-0.5,1.11352}, // 10 - T
|
||||
{0.688191,0.5,1.11352}, // 11 - T
|
||||
{0.850651,0.000000,-1.11352}, // 12 - B
|
||||
{-1.11352,-0.809017,-0.262866}, // 13 - LM
|
||||
{-1.11352,0.809017,-0.262866}, // 14 - LM
|
||||
{-0.850651,0.000000,1.11352}, // 15 - T
|
||||
{0.262866,-0.809017,-1.11352}, // 16 - B
|
||||
{0.262866,0.809017,-1.11352}, // 17 - B
|
||||
{0.425325,-1.30902,-0.262866}, // 18 - LM
|
||||
{0.425325,1.30902,-0.262866},}; // 19 - LM
|
||||
|
||||
veh_vrtx_world = new double[veh_vrtx_body.length][3];
|
||||
veh_vrtx_screen = new int[veh_vrtx_body.length][2];
|
||||
|
||||
// The edges of the dodecahedron are defined by taking a vertex at the UM or LM of the shape, and defining an edge to the top vertex (for UM) or bottom vertex (for LM), and defining edges to
|
||||
// each immediate adjacent vertex. The resulting pattern looks like 3 spokes coming out of the original UM or LM vertex.
|
||||
veh_edges = new int[][]
|
||||
{ {0, 13}, {0, 14}, {0, 15},
|
||||
{1, 4}, {1, 5}, {1, 12},
|
||||
{2, 6}, {2, 13}, {2, 18},
|
||||
{3, 7}, {3, 14}, {3, 19},
|
||||
{4, 10}, {4, 18}, {4, 1},
|
||||
{5, 11}, {5, 19}, {5, 1},
|
||||
{6, 2}, {6, 15}, {6, 10},
|
||||
{7, 11}, {7, 15}, {7, 3},
|
||||
{8, 9}, {8, 13}, {8, 16},
|
||||
{9, 14}, {9, 8}, {9, 17},
|
||||
{10, 4}, {10,6}, {10, 11},
|
||||
{11, 10}, {11, 7}, {11, 5},
|
||||
{12, 1}, {12, 16}, {12, 17},
|
||||
{13, 0}, {13, 2}, {13, 8},
|
||||
{14, 3}, {14, 0}, {14, 9},
|
||||
{15, 0}, {15, 7}, {15, 6},
|
||||
{16, 18}, {16, 8}, {16, 12},
|
||||
{17, 9}, {17, 12}, {17, 19},
|
||||
{18, 4}, {18, 2}, {18, 16},
|
||||
{19, 3}, {19, 5}, {19, 17}
|
||||
};
|
||||
|
||||
|
||||
// The order of the vertices in each of the triangles is significant. The points should follow
|
||||
// a path counter clock wise about the triangle's normal vector. The position normal side of
|
||||
// the triangle is the visable side.
|
||||
|
||||
veh_triangles = new int[][]
|
||||
{
|
||||
{0, 14, 9}, {0, 9, 8}, {0, 8, 13}, // First pentagon using vertices 0, 8, 9, 13, 14
|
||||
{13, 15, 0}, {13, 6, 15}, {13, 2, 6}, // Second pentagon using vertices 0, 2, 6, 13, 15
|
||||
{2, 13, 8}, {2, 8, 16}, {2, 16, 18}, // Third pentagon using vertices 2, 8, 13, 16, 18
|
||||
{18, 6, 2}, {18, 10 ,6}, {18, 4, 10}, // Fourth pentagon using vertices 2, 4, 6, 10, 18
|
||||
{4, 18, 16}, {4, 16, 12}, {4, 12, 1}, // Fifth pentagon using 1, 4, 12, 16, 18
|
||||
{1, 10, 4}, {1, 11, 10}, {1, 5, 11}, // Sixth pentagon using vertices 1, 4, 5, 10, 11
|
||||
{5, 1, 12}, {5, 12, 17}, {5, 17, 19}, // Seventh pentagon using vertices 1, 5, 12, 17, 19
|
||||
{19, 11, 5}, {19, 7, 11}, {19, 3, 7}, // Eight pentagon using vertices 3, 4, 7, 11, 19
|
||||
{3, 19, 17}, {3, 17, 9}, {3, 9, 14}, // Ninth pentagon using vertices 3, 9, 14, 17, 19
|
||||
{14, 7, 3}, {14, 15, 7}, {14, 0, 15}, // Tenth pentagon using vertices 0, 3, 7, 14, 15
|
||||
{15, 6, 10}, {15, 10, 11}, {15, 11, 7}, // Top pentagon (perpendicular above to xy plane)
|
||||
{12, 16, 8}, {12, 8, 9}, {12, 9, 17} // Bottom pentagon (perpendicular below to xy plane)
|
||||
};
|
||||
|
||||
// Create the normals for the triangles
|
||||
veh_unit_normals_body = new double[veh_triangles.length][3];
|
||||
double v1[] = {0.0, 0.0, 0.0};
|
||||
double v2[] = {0.0, 0.0, 0.0};
|
||||
for (int i=0; i < veh_unit_normals_body.length; i++ ) {
|
||||
MatrixOps.VminusV (v1, veh_vrtx_body[ veh_triangles[i][1] ], veh_vrtx_body[ veh_triangles[i][0] ]);
|
||||
MatrixOps.VminusV (v2, veh_vrtx_body[ veh_triangles[i][2] ], veh_vrtx_body[ veh_triangles[i][0] ]);
|
||||
MatrixOps.VcrossV (veh_unit_normals_body[i], v1, v2);
|
||||
double vmag = MatrixOps.Vmagnitude(veh_unit_normals_body[i]);
|
||||
MatrixOps.Vscale (veh_unit_normals_body[i], veh_unit_normals_body[i], 1.0/vmag);
|
||||
}
|
||||
|
||||
veh_unit_normals_world = new double[ veh_unit_normals_body.length ][3];
|
||||
veh_unit_normals_vantage = new double[ veh_unit_normals_body.length ][3];
|
||||
|
||||
}
|
||||
|
||||
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);
|
||||
setAzElRotation(worldToVantageRotation, vantageAzimuth, vantageElevation);
|
||||
repaint();
|
||||
}
|
||||
|
||||
public void setAzElRotation(double RotationMatrix[][], double azimuth, double elevation) { // Sets the azimuth and elevation rotation.
|
||||
double Rotation_about_Y[][] = {
|
||||
{ Math.cos(elevation), 0.0, Math.sin(elevation)},
|
||||
{ 0.0, 1.0, 0.0},
|
||||
{-Math.sin(elevation), 0.0, Math.cos(elevation)}
|
||||
};
|
||||
|
||||
double Rotation_about_Z[][] = {
|
||||
{Math.cos(azimuth), -Math.sin(azimuth), 0.0},
|
||||
{Math.sin(azimuth), Math.cos(azimuth), 0.0},
|
||||
{ 0.0, 0.0, 1.0}
|
||||
};
|
||||
MatrixOps.MtimesM( RotationMatrix, Rotation_about_Y, Rotation_about_Z);
|
||||
}
|
||||
|
||||
public void worldToScreenPoint( int result[], double V_world[]) {
|
||||
double V_vantage[] = new double[3];
|
||||
// Tranform vector in world coordinates to vantage coordinates.
|
||||
MatrixOps.MtimesV(V_vantage, worldToVantageRotation, V_world);
|
||||
// Perspective projection of point in 3D vantage coordinates to 2D screen coordinates.
|
||||
double perspective_scale = screen_half_width/(Math.tan(beta)*(vantageDistance-V_vantage[0]));
|
||||
result[0] = (int)(perspective_scale * V_vantage[1] + screen_half_width);
|
||||
result[1] = (int)(screen_half_height - perspective_scale * V_vantage[2]);
|
||||
}
|
||||
|
||||
public void setBodyPos( double x, double y, double z) {
|
||||
bodyPos[0] = x;
|
||||
bodyPos[1] = y;
|
||||
bodyPos[2] = z;
|
||||
}
|
||||
|
||||
public void drawLineSegmentInWorld(Graphics2D g, Color color, double start[], double end[]) {
|
||||
g.setPaint(color);
|
||||
int start_screen[] = {0, 0};
|
||||
int end_screen[] = {0, 0};
|
||||
worldToScreenPoint( start_screen, start);
|
||||
worldToScreenPoint( end_screen, end);
|
||||
g.drawLine( start_screen[0], start_screen[1], end_screen[0], end_screen[1]);
|
||||
}
|
||||
|
||||
public void drawLabelInWorld(Graphics2D g, Color color, double loc_world[], String s) {
|
||||
g.setPaint(color);
|
||||
int loc_screen[] = {0, 0};
|
||||
worldToScreenPoint( loc_screen, loc_world);
|
||||
g.drawString ( s, loc_screen[0], loc_screen[1]);
|
||||
}
|
||||
|
||||
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 the vehicle.
|
||||
|
||||
// Transform the vehicle vertices from body -> world, apply the vehicle position offset, and then to 2D screen points.
|
||||
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], bodyPos);
|
||||
|
||||
worldToScreenPoint (veh_vrtx_screen[i], veh_vrtx_world[i]);
|
||||
}
|
||||
|
||||
// Draw Solid Model
|
||||
|
||||
for (int i=0; i<veh_triangles.length ; i++) {
|
||||
double LOS_vantage[] = {1.0, 0.0, 0.0};
|
||||
|
||||
// Transform the vehicle triangle normals from Body -> World -> Vantage
|
||||
MatrixOps.MtimesV(veh_unit_normals_world[i], bodyToWorldRotation, veh_unit_normals_body[i]);
|
||||
MatrixOps.MtimesV(veh_unit_normals_vantage[i], worldToVantageRotation, veh_unit_normals_world[i]);
|
||||
|
||||
// Render the triangle only if it's facing us.
|
||||
double facing_angle = MatrixOps.VdotV(veh_unit_normals_vantage[i], LOS_vantage);
|
||||
if ( (facing_angle > 0.0) && (facing_angle < Math.toRadians(90))) {
|
||||
|
||||
// Calculate the diffuse reflection intensity.
|
||||
double neg_illumination_vector[] = {0.0, 0.0, 0.0};
|
||||
MatrixOps.Vscale(neg_illumination_vector, illumination_vector, -1.0);
|
||||
double diffuse_intensity = MatrixOps.VdotV(neg_illumination_vector, veh_unit_normals_world[i]);
|
||||
if (diffuse_intensity < 0.0) diffuse_intensity = 0.0;
|
||||
|
||||
// Proportion of the total light due to ambient light.
|
||||
// (1.0 - ambient) is the proportion of reflected light.
|
||||
double ambient = 0.8; // Must be between 0.0 and 1.0.
|
||||
|
||||
// The color intensity is a combination of ambient light intensity,
|
||||
// and diffuse reflection intensity.
|
||||
double color_intensity = (ambient + (1.0 - ambient) * diffuse_intensity);
|
||||
|
||||
g2d.setPaint( new Color( (int)(bodyFillColor.getRed() * color_intensity),
|
||||
(int)(bodyFillColor.getGreen() * color_intensity),
|
||||
(int)(bodyFillColor.getBlue() * color_intensity)));
|
||||
|
||||
// Draw the triangle.
|
||||
int triangle_poly_x[] = {0, 0, 0};
|
||||
int triangle_poly_y[] = {0, 0, 0};
|
||||
// For each point of the triangle.
|
||||
for (int j=0; j < 3; j++) {
|
||||
|
||||
triangle_poly_x[j] = veh_vrtx_screen[ veh_triangles[i][j] ][0];
|
||||
triangle_poly_y[j] = veh_vrtx_screen[ veh_triangles[i][j] ][1];
|
||||
|
||||
}
|
||||
g2d.fillPolygon(triangle_poly_x, triangle_poly_y, 3);
|
||||
}
|
||||
}
|
||||
|
||||
// Draw Wireframe Model
|
||||
|
||||
g2d.setPaint( bodyLineColor );
|
||||
|
||||
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 Center of Gravity Point
|
||||
int CG_screen[] = {0, 0};
|
||||
int CG_symbol_size = 15;
|
||||
worldToScreenPoint( CG_screen, bodyPos);
|
||||
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 World Coordinate Axes
|
||||
double origin_world[] = {0.0, 0.0, 0.0};
|
||||
double x_axis_world[] = {9.0, 0.0, 0.0};
|
||||
drawLineSegmentInWorld(g2d, Color.RED, origin_world, x_axis_world);
|
||||
drawLabelInWorld(g2d, Color.RED, x_axis_world, "X");
|
||||
double y_axis_world[] = {0.0, 9.0, 0.0};
|
||||
drawLineSegmentInWorld(g2d, Color.GREEN, origin_world, y_axis_world);
|
||||
drawLabelInWorld(g2d, Color.GREEN, y_axis_world, "Y");
|
||||
double z_axis_world[] = {0.0, 0.0, 9.0};
|
||||
drawLineSegmentInWorld(g2d, Color.BLUE, origin_world, z_axis_world);
|
||||
drawLabelInWorld(g2d, Color.BLUE, z_axis_world, "Z");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void paintComponent( Graphics g) {
|
||||
super.paintComponent(g);
|
||||
doDrawing(g);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class SRBDisplay extends JFrame {
|
||||
|
||||
private SingleRigidBodyView singleRigidBodyView;
|
||||
private BufferedReader in;
|
||||
private DataOutputStream out;
|
||||
|
||||
public SRBDisplay( SingleRigidBodyView srbv) { // Creates the display window.
|
||||
singleRigidBodyView = srbv;
|
||||
add(singleRigidBodyView);
|
||||
setTitle("SRB Display");
|
||||
setSize(1597, 987);
|
||||
setLocationRelativeTo(null);
|
||||
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
}
|
||||
|
||||
public void connectToServer( String host, int port ) throws IOException { // Connects to the server.
|
||||
Socket socket = new Socket(host, port);
|
||||
in = new BufferedReader( new InputStreamReader( socket.getInputStream()));
|
||||
out = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
|
||||
}
|
||||
|
||||
public void drawSRBView() {
|
||||
singleRigidBodyView.repaint();
|
||||
}
|
||||
|
||||
private static void printHelpText() {
|
||||
System.out.println(
|
||||
"----------------------------------------------------------------------\n"
|
||||
+ "usage: java jar SingleRigidBodyDisplay.jar <port-number>\n"
|
||||
+ "----------------------------------------------------------------------\n"
|
||||
);
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
|
||||
String host = "localHost";
|
||||
int port = 0;
|
||||
String bodyImageFile = 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);
|
||||
}
|
||||
|
||||
SingleRigidBodyView singleRigidBodyView = new SingleRigidBodyView();
|
||||
|
||||
SRBDisplay sd = new SRBDisplay(singleRigidBodyView);
|
||||
sd.setVisible(true);
|
||||
|
||||
double f_init_x = 0.0;
|
||||
double f_init_y = 0.0;
|
||||
double f_init_z = 0.0;
|
||||
|
||||
double accX = 0.0;
|
||||
double accY = 0.0;
|
||||
double accZ = 0.0;
|
||||
|
||||
double angleX = 0.0;
|
||||
double angleY = 0.0;
|
||||
double angleZ = 0.0;
|
||||
|
||||
double f_angleX = 0.0;
|
||||
double f_angleY = 0.0;
|
||||
double f_angleZ = 0.0;
|
||||
|
||||
double forceX = 0.0;
|
||||
double forceY = 0.0;
|
||||
double forceZ = 0.0;
|
||||
|
||||
double omegaX = 0.0;
|
||||
double omegaY = 0.0;
|
||||
double omegaZ = 0.0;
|
||||
|
||||
double omegaDotX = 0.0;
|
||||
double omegaDotY = 0.0;
|
||||
double omegaDotZ = 0.0;
|
||||
|
||||
double posX = 0.0;
|
||||
double posY = 0.0;
|
||||
double posZ = 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 velX = 0.0;
|
||||
double velY = 0.0;
|
||||
double velZ = 0.0;
|
||||
|
||||
System.out.println("Connecting to: " + host + ":" + port);
|
||||
sd.connectToServer(host, port);
|
||||
|
||||
sd.out.writeBytes("trick.var_set_client_tag(\"SRBDisplay\") \n" +
|
||||
"trick.var_pause() \n" +
|
||||
|
||||
"trick.var_add(\"dyn.body.FORCE_INIT[0]\") \n" + // 36
|
||||
"trick.var_add(\"dyn.body.FORCE_INIT[1]\") \n" +
|
||||
"trick.var_add(\"dyn.body.FORCE_INIT[2]\") \n" +
|
||||
|
||||
"trick.var_add(\"dyn.body.acc[0]\") \n" +
|
||||
"trick.var_add(\"dyn.body.acc[1]\") \n" +
|
||||
"trick.var_add(\"dyn.body.acc[2]\") \n" +
|
||||
|
||||
"trick.var_add(\"dyn.body.angle[0]\") \n" +
|
||||
"trick.var_add(\"dyn.body.angle[1]\") \n" +
|
||||
"trick.var_add(\"dyn.body.angle[2]\") \n" +
|
||||
|
||||
"trick.var_add(\"dyn.body.angle_force[0]\") \n" +
|
||||
"trick.var_add(\"dyn.body.angle_force[1]\") \n" +
|
||||
"trick.var_add(\"dyn.body.angle_force[2]\") \n" +
|
||||
|
||||
"trick.var_add(\"dyn.body.force[0]\") \n" +
|
||||
"trick.var_add(\"dyn.body.force[1]\") \n" +
|
||||
"trick.var_add(\"dyn.body.force[2]\") \n" +
|
||||
|
||||
"trick.var_add(\"dyn.body.omega[0]\") \n" +
|
||||
"trick.var_add(\"dyn.body.omega[1]\") \n" +
|
||||
"trick.var_add(\"dyn.body.omega[2]\") \n" +
|
||||
|
||||
"trick.var_add(\"dyn.body.omegaDot[0]\") \n" +
|
||||
"trick.var_add(\"dyn.body.omegaDot[1]\") \n" +
|
||||
"trick.var_add(\"dyn.body.omegaDot[2]\") \n" +
|
||||
|
||||
"trick.var_add(\"dyn.body.pos[0]\") \n" +
|
||||
"trick.var_add(\"dyn.body.pos[1]\") \n" +
|
||||
"trick.var_add(\"dyn.body.pos[2]\") \n" +
|
||||
|
||||
"trick.var_add(\"dyn.body.rotate[0][0]\") \n" +
|
||||
"trick.var_add(\"dyn.body.rotate[0][1]\") \n" +
|
||||
"trick.var_add(\"dyn.body.rotate[0][2]\") \n" +
|
||||
"trick.var_add(\"dyn.body.rotate[1][0]\") \n" +
|
||||
"trick.var_add(\"dyn.body.rotate[1][1]\") \n" +
|
||||
"trick.var_add(\"dyn.body.rotate[1][2]\") \n" +
|
||||
"trick.var_add(\"dyn.body.rotate[2][0]\") \n" +
|
||||
"trick.var_add(\"dyn.body.rotate[2][1]\") \n" +
|
||||
"trick.var_add(\"dyn.body.rotate[2][2]\") \n" +
|
||||
|
||||
"trick.var_add(\"dyn.body.vel[0]\") \n" +
|
||||
"trick.var_add(\"dyn.body.vel[1]\") \n" +
|
||||
"trick.var_add(\"dyn.body.vel[2]\") \n" +
|
||||
|
||||
"trick.var_ascii() \n" +
|
||||
"trick.var_cycle(0.1) \n" +
|
||||
"trick.var_unpause()\n" );
|
||||
|
||||
sd.out.flush();
|
||||
|
||||
sd.drawSRBView();
|
||||
|
||||
Boolean go = true;
|
||||
|
||||
while (go) {
|
||||
|
||||
String field[];
|
||||
|
||||
try {
|
||||
String line;
|
||||
line = sd.in.readLine();
|
||||
field = line.split("\t");
|
||||
|
||||
f_init_x = Double.parseDouble( field[1] );
|
||||
f_init_y = Double.parseDouble( field[2] );
|
||||
f_init_z = Double.parseDouble( field[3] );
|
||||
|
||||
accX = Double.parseDouble( field[4] );
|
||||
accY = Double.parseDouble( field[5] );
|
||||
accZ = Double.parseDouble( field[6] );
|
||||
|
||||
angleX = Double.parseDouble( field[7] );
|
||||
angleY = Double.parseDouble( field[8] );
|
||||
angleZ = Double.parseDouble( field[9] );
|
||||
|
||||
f_angleX = Double.parseDouble( field[10] );
|
||||
f_angleY = Double.parseDouble( field[11] );
|
||||
f_angleZ = Double.parseDouble( field[12] );
|
||||
|
||||
forceX = Double.parseDouble( field[13] );
|
||||
forceY = Double.parseDouble( field[14] );
|
||||
forceZ = Double.parseDouble( field[15] );
|
||||
|
||||
omegaX = Double.parseDouble( field[16] );
|
||||
omegaY = Double.parseDouble( field[17] );
|
||||
omegaZ = Double.parseDouble( field[18] );
|
||||
|
||||
omegaDotX = Double.parseDouble( field[19] );
|
||||
omegaDotY = Double.parseDouble( field[20] );
|
||||
omegaDotZ = Double.parseDouble( field[21] );
|
||||
|
||||
posX = Double.parseDouble( field[22] );
|
||||
posY = Double.parseDouble( field[23] );
|
||||
posZ = Double.parseDouble( field[24] );
|
||||
|
||||
Rxx = Double.parseDouble( field[25] );
|
||||
Rxy = Double.parseDouble( field[26] );
|
||||
Rxz = Double.parseDouble( field[27] );
|
||||
Ryx = Double.parseDouble( field[28] );
|
||||
Ryy = Double.parseDouble( field[29] );
|
||||
Ryz = Double.parseDouble( field[30] );
|
||||
Rzx = Double.parseDouble( field[31] );
|
||||
Rzy = Double.parseDouble( field[32] );
|
||||
Rzz = Double.parseDouble( field[33] );
|
||||
|
||||
velX = Double.parseDouble( field[34] );
|
||||
velY = Double.parseDouble( field[35] );
|
||||
velZ = Double.parseDouble( field[36] );
|
||||
|
||||
// Set the body position
|
||||
singleRigidBodyView.setBodyPos(posX, posY, posZ);
|
||||
|
||||
singleRigidBodyView.setBodyToWorldRotation( Rxx, Rxy, Rxz,
|
||||
Ryx, Ryy, Ryz,
|
||||
Rzx, Rzy, Rzz );
|
||||
|
||||
} catch (IOException | NullPointerException e ) {
|
||||
go = false;
|
||||
}
|
||||
sd.drawSRBView();
|
||||
}
|
||||
}
|
||||
}
|
314
trick_sims/SIM_singlerigidbody/models/src/body.cpp
Normal file
@ -0,0 +1,314 @@
|
||||
/**************************************************************************
|
||||
PURPOSE: (Test trick macros (matrix and vector) as well as trick functions
|
||||
including euler_matrix, deuler_123, and dLU_Choleski. Perform a
|
||||
single body motion with six degrees of freedom)
|
||||
LIBRARY DEPENDENCIES:
|
||||
((src/body.o))
|
||||
**************************************************************************/
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "trick/integrator_c_intf.h"
|
||||
#include "trick/trick_math_proto.h"
|
||||
#include "trick/trick_math_error.h"
|
||||
#include "trick/reference_frame.h"
|
||||
#include "trick/vector_macros.h"
|
||||
#include "trick/matrix_macros.h"
|
||||
|
||||
#include "../include/body.hh"
|
||||
|
||||
BODY::BODY(){};
|
||||
BODY::~BODY(){};
|
||||
|
||||
/*************************************************************************
|
||||
FUNCTION: SingleRigidBody::default_data()
|
||||
PURPOSE:` (Creates an object)
|
||||
*************************************************************************/
|
||||
|
||||
void BODY::default_data() {
|
||||
|
||||
//Initializing vectors and matricies to zero.
|
||||
|
||||
for(int i = 0; i<6; i++)
|
||||
vec_a[i] = 0.0;
|
||||
|
||||
|
||||
for(int i = 0; i<6; i++)
|
||||
vec_b[i] = 0.0;
|
||||
|
||||
|
||||
for(int i = 0; i<6; i++)
|
||||
for(int j = 0; j<6; j++)
|
||||
mat_mass[i][j] = 0.0;
|
||||
V_INIT(pos);
|
||||
V_INIT(vel);
|
||||
V_INIT(acc);
|
||||
V_INIT(force);
|
||||
V_INIT(force_remain);
|
||||
V_INIT(torque);
|
||||
V_INIT(torque_remain);
|
||||
V_INIT(angle);
|
||||
V_INIT(omega);
|
||||
V_INIT(omegaDot);
|
||||
V_INIT(angle_force);
|
||||
|
||||
M_INIT(CM_skew);
|
||||
M_INIT(m_CM_skew);
|
||||
M_INIT(massmatrix);
|
||||
M_INIT(rotate);
|
||||
|
||||
|
||||
// Inputs
|
||||
mass = 20.0;
|
||||
radius = 2.0;
|
||||
|
||||
POS_INIT[0] = 0.0;
|
||||
POS_INIT[1] = 0.0;
|
||||
POS_INIT[2] = 0.0;
|
||||
|
||||
ANGLE_INIT[0] = 0.0;
|
||||
ANGLE_INIT[1] = 0.0;
|
||||
ANGLE_INIT[2] = 0.0;
|
||||
|
||||
OMEGA_INIT[0] = 0.0;
|
||||
OMEGA_INIT[1] = 0.0;
|
||||
OMEGA_INIT[2] = 0.0;
|
||||
|
||||
FORCE_INIT[0] = 0.0;
|
||||
FORCE_INIT[1] = 0.0;
|
||||
FORCE_INIT[2] = 10.0;
|
||||
|
||||
VEL_INIT[0] = 0.0;
|
||||
VEL_INIT[1] = 0.0;
|
||||
VEL_INIT[2] = 0.0;
|
||||
|
||||
POS_FORCE[0] = 2.0;
|
||||
POS_FORCE[1] = 0.0;
|
||||
POS_FORCE[2] = 0.0;
|
||||
|
||||
};
|
||||
|
||||
/************************************************************************
|
||||
FUNCTION: SingleRigidBody::init()
|
||||
PURPOSE: (Initializing state variables, creating inertia and CoM skew
|
||||
matrices)
|
||||
************************************************************************/
|
||||
|
||||
void BODY::init() {
|
||||
|
||||
V_COPY(pos, POS_INIT);
|
||||
V_COPY(vel, VEL_INIT);
|
||||
V_COPY(angle, ANGLE_INIT);
|
||||
V_COPY(omega, OMEGA_INIT);
|
||||
|
||||
// Center of mass skew matrix
|
||||
V_INIT(CM);
|
||||
|
||||
V_SKEW(CM_skew, CM);
|
||||
|
||||
MxSCALAR(m_CM_skew, CM_skew, mass);
|
||||
MxSCALAR(neg_m_CM_skew, m_CM_skew, -1.0);
|
||||
|
||||
// Creates 3x3 matrix for inerta
|
||||
inertia = (2.0/5.0) * mass * radius * radius;
|
||||
inertia_matrix[0][0] = inertia_matrix[1][1] = inertia_matrix[2][2] = inertia;
|
||||
|
||||
// Creates 3x3 matrix for mass
|
||||
massmatrix[0][0] = massmatrix[1][1] = massmatrix[2][2] = mass;
|
||||
|
||||
// Combines inertia, center of mass, and mass matrix into a 6x6 matrix
|
||||
for(int i = 0; i<3; i++)
|
||||
for(int j = 0; j<3; j++)
|
||||
mat_mass[i][j] = massmatrix[i][j];
|
||||
|
||||
for(int i = 0; i<3; i++)
|
||||
for(int j = 3; j<6; j++)
|
||||
mat_mass[i][j] = neg_m_CM_skew[i][j-3];
|
||||
|
||||
for(int i = 3; i<6; i++)
|
||||
for(int j = 0; j<3; j++)
|
||||
mat_mass[i][j] = m_CM_skew[i-3][j];
|
||||
|
||||
for(int i = 3; i<6; i++)
|
||||
for(int j = 3; j<6; j++)
|
||||
mat_mass[i][j] = inertia_matrix[i-3][j-3];
|
||||
|
||||
// Temporary vector and dynamic memory for Choleski
|
||||
for(int i = 0; i<6; i++)
|
||||
tmp_vec[i] = 0.0;
|
||||
|
||||
mat_L = new double*[6];
|
||||
mat_mass_dyn = new double*[6];
|
||||
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
FUNCTION: BODY::rotation_matrix()
|
||||
PURPOSE: (Calculates transformation matrix from provided angles)
|
||||
*****************************************************************************/
|
||||
void BODY::rotation_matrix() {
|
||||
|
||||
// euler_matrix outputs the rotate matrix from angle
|
||||
euler_matrix(angle, rotate, 0, Roll_Pitch_Yaw);
|
||||
|
||||
};
|
||||
|
||||
/******************************************************************************
|
||||
FUNCTION: BODY::calcforce()
|
||||
PURPOSE: (Calculates force wrt inertial frame)
|
||||
******************************************************************************/
|
||||
void BODY::calcforce() {
|
||||
|
||||
MxV(force, rotate, FORCE_INIT);
|
||||
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
FUNCTION: BODY::calctorque()
|
||||
PURPOSE: (Calculates torque wrt inertial frame)
|
||||
*****************************************************************************/
|
||||
void BODY::calctorque() {
|
||||
|
||||
double torque_force[3];
|
||||
|
||||
V_CROSS(torque_force, POS_FORCE, FORCE_INIT);
|
||||
MxV(torque, rotate, torque_force);
|
||||
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
FUNCTION: BODY::calcforce_remain()
|
||||
PURPOSE: (Calculate remaining force wrt inertial frame)
|
||||
****************************************************************************/
|
||||
void BODY::calcforce_remain() {
|
||||
|
||||
double cross1[3];
|
||||
double cross2[3];
|
||||
|
||||
V_CROSS(cross1, omega, CM);
|
||||
V_CROSS(cross2, omega, cross1);
|
||||
V_SCALE(force_remain, cross2, mass);
|
||||
|
||||
};
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
FUNCTION: BODY::calctorque_remain()
|
||||
PURPOSE: (Calculate remaining torque wrt inertial frame)
|
||||
***************************************************************************/
|
||||
void BODY::calctorque_remain() {
|
||||
|
||||
double I_w[3];
|
||||
|
||||
MxV(I_w, inertia_matrix, omega);
|
||||
V_CROSS(torque_remain, omega, I_w);
|
||||
|
||||
|
||||
};
|
||||
|
||||
/***************************************************************************
|
||||
FUNCTION: BODY::eq_setup()
|
||||
PURPOSE: (Establishes b column vector for final eq M*a=b)
|
||||
***************************************************************************/
|
||||
void BODY::eq_setup() {
|
||||
|
||||
double remainder_force[3];
|
||||
double remainder_torque[3];
|
||||
|
||||
// Subtracts remaining from force & torque to get vec_b.
|
||||
V_SUB(remainder_force, force, force_remain);
|
||||
V_SUB(remainder_torque, torque, torque_remain);
|
||||
|
||||
for(int i = 0; i<3; i++){
|
||||
vec_b[i] = remainder_force[i];
|
||||
}
|
||||
|
||||
for(int i = 3; i<6; i++){
|
||||
vec_b[i] = remainder_torque[i-3];
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**************************************************************************
|
||||
FUNCTION: BODY::eq_solver()
|
||||
PURPOSE: (Performs choleski decomposition and computes linear and angular
|
||||
accelerations)
|
||||
**************************************************************************/
|
||||
|
||||
void BODY::eq_solver() {
|
||||
|
||||
// Solving a = b * M^-1
|
||||
|
||||
for(int i = 0; i<6; i++)
|
||||
{
|
||||
mat_mass_dyn[i] = mat_mass[i];
|
||||
mat_L[i] = new double[6];
|
||||
}
|
||||
|
||||
dLU_Choleski(mat_mass_dyn, mat_L, tmp_vec, 6, vec_b, vec_a, 0);
|
||||
|
||||
// Acceleration output
|
||||
for(int i = 0; i<3; i++)
|
||||
acc[i] = vec_a[i];
|
||||
|
||||
// Angular accleration output
|
||||
for(int i = 0; i<3; i++)
|
||||
omegaDot[i] = vec_a[i + 3];
|
||||
|
||||
};
|
||||
|
||||
/***************************************************************************
|
||||
FUNCTION: BODY::derivative()
|
||||
PURPOSE: (Calls all functions in desired order for calculations)
|
||||
***************************************************************************/
|
||||
void BODY::derivative() {
|
||||
|
||||
rotation_matrix();
|
||||
calcforce();
|
||||
calctorque();
|
||||
calcforce_remain();
|
||||
calctorque_remain();
|
||||
eq_setup();
|
||||
eq_solver();
|
||||
|
||||
};
|
||||
|
||||
/***************************************************************************
|
||||
FUNCTION: BODY::integrate()
|
||||
PURPOSE: (Sets up trick integration)
|
||||
***************************************************************************/
|
||||
|
||||
int BODY::integ() {
|
||||
|
||||
int integration_step;
|
||||
|
||||
load_state(
|
||||
&pos[0], &pos[1], &pos[2],
|
||||
&vel[0], &vel[1], &vel[2],
|
||||
&angle[0], &angle[1], &angle[2],
|
||||
&omega[0], &omega[1], &omega[2],
|
||||
|
||||
NULL);
|
||||
|
||||
|
||||
load_deriv(
|
||||
&vel[0], &vel[1], &vel[2],
|
||||
&acc[0], &acc[1], &acc[2],
|
||||
&omega[0], &omega[1], &omega[2],
|
||||
&omegaDot[0], &omegaDot[1], &omegaDot[2],
|
||||
|
||||
NULL);
|
||||
|
||||
integration_step = integrate();
|
||||
|
||||
unload_state(
|
||||
&pos[0], &pos[1], &pos[2],
|
||||
&vel[0], &vel[1], &vel[2],
|
||||
&angle[0], &angle[1], &angle[2],
|
||||
&omega[0], &omega[1], &omega[2],
|
||||
|
||||
NULL);
|
||||
|
||||
return(integration_step);
|
||||
|
||||
};
|
14
trick_sims/SIM_singlerigidbody/models/src/body_shutdown.cpp
Normal file
@ -0,0 +1,14 @@
|
||||
/************************************************************************
|
||||
PURPOSE: (Shutdown the simulation)
|
||||
*************************************************************************/
|
||||
#include "../include/body.hh"
|
||||
#include "trick/exec_proto.h"
|
||||
|
||||
int BODY::body_shutdown() {
|
||||
|
||||
delete[] mat_mass_dyn;
|
||||
delete[] mat_L;
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
@ -395,8 +395,11 @@ std::set<std::string> PrintAttributes::getEmptyFiles() {
|
||||
const clang::FileEntry * fe = (*fi).first ;
|
||||
#if (LIBCLANG_MAJOR < 4) // TODO delete when RHEL 7 no longer supported
|
||||
std::string header_file_name = fe->getName() ;
|
||||
#else
|
||||
#elif (LIBCLANG_MAJOR >= 4 && LIBCLANG_MAJOR < 18)
|
||||
std::string header_file_name = fe->getName().str() ;
|
||||
#else
|
||||
const clang::FileEntryRef fer = fi->first ;
|
||||
std::string header_file_name = fer.getName().str();
|
||||
#endif
|
||||
|
||||
if ( visited_files.find(header_file_name) != visited_files.end() ) {
|
||||
|
@ -66,68 +66,69 @@ std::string trim(const std::string& str, const std::string& whitespace ) {
|
||||
}
|
||||
|
||||
bool isInUserCode( clang::CompilerInstance & ci , clang::SourceLocation sl , HeaderSearchDirs & hsd ) {
|
||||
clang::FileID fid = ci.getSourceManager().getFileID(sl) ;
|
||||
bool ret = false ;
|
||||
if ( ! fid.isInvalid() ) {
|
||||
const clang::FileEntry * fe = ci.getSourceManager().getFileEntryForID(fid) ;
|
||||
if ( fe != NULL ) {
|
||||
#if (LIBCLANG_MAJOR < 4) // TODO delete when RHEL 7 no longer supported
|
||||
char * resolved_path = almostRealPath( fe->getName() ) ;
|
||||
#else
|
||||
char * resolved_path = almostRealPath( fe->getName().str() ) ;
|
||||
#endif
|
||||
if ( resolved_path != NULL ) {
|
||||
if ( hsd.isPathInUserDir(resolved_path)) {
|
||||
ret = true ;
|
||||
}
|
||||
free(resolved_path) ;
|
||||
}
|
||||
char* resolved_path = getResolvedPath(ci, sl);
|
||||
|
||||
if ( resolved_path != NULL ) {
|
||||
if ( hsd.isPathInUserDir(resolved_path)) {
|
||||
ret = true ;
|
||||
}
|
||||
free(resolved_path) ;
|
||||
}
|
||||
|
||||
return ret ;
|
||||
}
|
||||
|
||||
bool isInUserOrTrickCode( clang::CompilerInstance & ci , clang::SourceLocation sl , HeaderSearchDirs & hsd ) {
|
||||
clang::FileID fid = ci.getSourceManager().getFileID(sl) ;
|
||||
bool ret = false ;
|
||||
if ( ! fid.isInvalid() ) {
|
||||
const clang::FileEntry * fe = ci.getSourceManager().getFileEntryForID(fid) ;
|
||||
if ( fe != NULL ) {
|
||||
#if (LIBCLANG_MAJOR < 4) // TODO delete when RHEL 7 no longer supported
|
||||
char * resolved_path = almostRealPath( fe->getName() ) ;
|
||||
#else
|
||||
char * resolved_path = almostRealPath( fe->getName().str() ) ;
|
||||
#endif
|
||||
if ( resolved_path != NULL ) {
|
||||
if ( hsd.isPathInUserOrTrickDir(resolved_path)) {
|
||||
ret = true ;
|
||||
}
|
||||
free(resolved_path) ;
|
||||
}
|
||||
char* resolved_path = getResolvedPath(ci, sl);
|
||||
|
||||
if ( resolved_path != NULL ) {
|
||||
if ( hsd.isPathInUserOrTrickDir(resolved_path)) {
|
||||
ret = true ;
|
||||
}
|
||||
free(resolved_path) ;
|
||||
}
|
||||
|
||||
return ret ;
|
||||
}
|
||||
|
||||
std::string getFileName( clang::CompilerInstance & ci , clang::SourceLocation sl , HeaderSearchDirs & hsd ) {
|
||||
clang::FileID fid = ci.getSourceManager().getFileID(sl) ;
|
||||
std::string file_name;
|
||||
char* resolved_path;
|
||||
char* resolved_path = getResolvedPath(ci, sl);
|
||||
|
||||
if (resolved_path != NULL ) {
|
||||
if (hsd.isPathInUserDir(resolved_path)) {
|
||||
file_name.append(resolved_path);
|
||||
}
|
||||
free(resolved_path);
|
||||
}
|
||||
|
||||
return file_name;
|
||||
}
|
||||
|
||||
char * getResolvedPath(clang::CompilerInstance & ci , clang::SourceLocation sl) {
|
||||
clang::FileID fid = ci.getSourceManager().getFileID(sl) ;
|
||||
char* resolved_path = NULL;
|
||||
|
||||
if ( ! fid.isInvalid() ) {
|
||||
const clang::FileEntry * fe = ci.getSourceManager().getFileEntryForID(fid) ;
|
||||
if ( fe != NULL ) {
|
||||
#if (LIBCLANG_MAJOR < 4) // TODO delete when RHEL 7 no longer supported
|
||||
char * resolved_path = almostRealPath( fe->getName() ) ;
|
||||
resolved_path = almostRealPath( fe->getName() ) ;
|
||||
#elif (LIBCLANG_MAJOR >= 4 && LIBCLANG_MAJOR < 18)
|
||||
resolved_path = almostRealPath( fe->getName().str() ) ;
|
||||
#else
|
||||
char * resolved_path = almostRealPath( fe->getName().str() ) ;
|
||||
const clang::CustomizableOptional<clang::FileEntryRef> cfer = ci.getSourceManager().getFileEntryRefForID(fid) ;
|
||||
if (cfer.has_value()) {
|
||||
resolved_path = almostRealPath( cfer->getName().str() ) ;
|
||||
}
|
||||
|
||||
#endif
|
||||
if ( resolved_path != NULL and hsd.isPathInUserDir(resolved_path)) {
|
||||
file_name.append(resolved_path);
|
||||
}
|
||||
free(resolved_path);
|
||||
}
|
||||
}
|
||||
return file_name;
|
||||
|
||||
return resolved_path;
|
||||
}
|
||||
|
||||
#include <iostream>
|
||||
|
@ -21,7 +21,7 @@ bool isInUserOrTrickCode( clang::CompilerInstance & ci , clang::SourceLocation s
|
||||
std::string getFileName( clang::CompilerInstance & ci , clang::SourceLocation sl , HeaderSearchDirs & hsd ) ;
|
||||
char * almostRealPath( const std::string& in_path ) ;
|
||||
char * almostRealPath( const char * in_path ) ;
|
||||
|
||||
char * getResolvedPath(clang::CompilerInstance & ci , clang::SourceLocation sl);
|
||||
std::string color(const Color& color, const std::string& text);
|
||||
std::string bold(const std::string& text);
|
||||
std::string underline(const std::string& text);
|
||||
|
@ -312,7 +312,7 @@ int main(int argc, char * argv[]) {
|
||||
#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));
|
||||
const clang::FileEntryRef fileEntryRef = llvm::cantFail(ci.getFileManager().getFileRef(inputFilePath));
|
||||
#else
|
||||
const clang::FileEntry* fileEntry = ci.getFileManager().getFile(inputFilePath);
|
||||
#endif
|
||||
|
@ -115,7 +115,8 @@ public class SearchPanel extends JXPanel {
|
||||
listModel.clear();
|
||||
searcher.search(textField.getText().trim(),
|
||||
caseSensitiveCheckBox.isSelected(),
|
||||
regularExpressionCheckBox.isSelected());
|
||||
regularExpressionCheckBox.isSelected(),
|
||||
greedySearchCheckBox.isSelected());
|
||||
if (searcher.elementCount == 0) {
|
||||
progressBar.setIndeterminate(true);
|
||||
}
|
||||
@ -136,6 +137,12 @@ public class SearchPanel extends JXPanel {
|
||||
setToolTipText("Toggle regular expression searching.");
|
||||
}};
|
||||
|
||||
/** toggles case-insensitive searching */
|
||||
JCheckBox greedySearchCheckBox = new JCheckBox("Greedy Search") {{
|
||||
setName("greedySearchCheckBox");
|
||||
setToolTipText("Toggle multi-threaded search (Warning: may cause overruns).");
|
||||
}};
|
||||
|
||||
/** search results list model */
|
||||
EfficientListModel listModel = new EfficientListModel();
|
||||
|
||||
@ -227,6 +234,7 @@ public class SearchPanel extends JXPanel {
|
||||
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
|
||||
add(caseSensitiveCheckBox);
|
||||
add(regularExpressionCheckBox);
|
||||
add(greedySearchCheckBox);
|
||||
}});
|
||||
}}, constraints);
|
||||
|
||||
@ -306,6 +314,7 @@ public class SearchPanel extends JXPanel {
|
||||
textField.setEnabled(enabled);
|
||||
caseSensitiveCheckBox.setEnabled(enabled);
|
||||
regularExpressionCheckBox.setEnabled(enabled);
|
||||
greedySearchCheckBox.setEnabled(enabled);
|
||||
list.setEnabled(enabled);
|
||||
list.setComponentPopupMenu(enabled ? popupMenu : null);
|
||||
}
|
||||
|
@ -89,9 +89,10 @@ public class Searcher {
|
||||
* @param targetText the text for which to search
|
||||
* @param caseSensitive enables case sensitive searching
|
||||
* @param regularExpression enables regular expression searching
|
||||
* @param greedSearch enabled multi-threaded search
|
||||
*/
|
||||
public void search(final String targetText, final boolean caseSensitive,
|
||||
final boolean regularExpression) {
|
||||
final boolean regularExpression, final boolean greedySearch) {
|
||||
|
||||
final SearchFunction searchFunction = regularExpression ?
|
||||
|
||||
@ -124,7 +125,11 @@ public class Searcher {
|
||||
|
||||
cancelSearch();
|
||||
count = 0;
|
||||
threads = Runtime.getRuntime().availableProcessors();
|
||||
if (greedySearch) {
|
||||
threads = Runtime.getRuntime().availableProcessors();
|
||||
} else {
|
||||
threads = 1;
|
||||
}
|
||||
propertyChangeListener.propertyChange(new PropertyChangeEvent(this, "progress", 0, 0));
|
||||
final ConcurrentLinkedQueue<SieTemplate> roots = new ConcurrentLinkedQueue<SieTemplate>(rootTemplates);
|
||||
executorService = Executors.newFixedThreadPool(threads);
|
||||
|
@ -18,7 +18,7 @@ PROGRAMMERS:
|
||||
#include "trick/message_type.h"
|
||||
#include "trick/bitfield_proto.h"
|
||||
|
||||
Trick::DRAscii::DRAscii( std::string in_name ) : Trick::DataRecordGroup( in_name ) {
|
||||
Trick::DRAscii::DRAscii( std::string in_name, Trick::DR_Type dr_type ) : Trick::DataRecordGroup( in_name, dr_type ) {
|
||||
|
||||
ascii_float_format = "%20.8g" ;
|
||||
ascii_double_format = "%20.16g" ;
|
||||
|
@ -22,7 +22,7 @@ PROGRAMMERS:
|
||||
Other classes inherit from DRBinary. In these cases, we don't want to register the memory as DRBinary,
|
||||
so register_group will be set to false.
|
||||
*/
|
||||
Trick::DRBinary::DRBinary( std::string in_name , bool register_group ) : Trick::DataRecordGroup(in_name) {
|
||||
Trick::DRBinary::DRBinary( std::string in_name, bool register_group, Trick::DR_Type dr_type ) : Trick::DataRecordGroup(in_name, dr_type) {
|
||||
if ( register_group ) {
|
||||
register_group_with_mm(this, "Trick::DRBinary") ;
|
||||
}
|
||||
@ -190,4 +190,4 @@ int Trick::DRBinary::format_specific_shutdown() {
|
||||
close(fd) ;
|
||||
}
|
||||
return(0) ;
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ PROGRAMMERS:
|
||||
#include "trick/memorymanager_c_intf.h"
|
||||
#include "trick/message_proto.h"
|
||||
|
||||
Trick::DRHDF5::DRHDF5( std::string in_name ) : Trick::DataRecordGroup(in_name) {
|
||||
Trick::DRHDF5::DRHDF5( std::string in_name, Trick::DR_Type dr_type ) : Trick::DataRecordGroup(in_name, dr_type) {
|
||||
register_group_with_mm(this, "Trick::DRHDF5") ;
|
||||
}
|
||||
|
||||
|
@ -180,6 +180,10 @@ void Trick::DataRecordDispatcher::remove_all_groups() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@details
|
||||
-# Gets the data recording group by its name
|
||||
*/
|
||||
Trick::DataRecordGroup * Trick::DataRecordDispatcher::get_group(std::string in_name) {
|
||||
std::vector <Trick::DataRecordGroup *>::iterator it ;
|
||||
for ( it = groups.begin() ; it != groups.end() ; ++it ) {
|
||||
@ -189,6 +193,25 @@ Trick::DataRecordGroup * Trick::DataRecordDispatcher::get_group(std::string in_n
|
||||
return NULL ;
|
||||
}
|
||||
|
||||
/**
|
||||
@details
|
||||
-# Gets the data recording group by its id number
|
||||
*/
|
||||
Trick::DataRecordGroup * Trick::DataRecordDispatcher::get_group(int in_idx) {
|
||||
if (!groups.empty() && in_idx > -1 && in_idx < groups.size()) {
|
||||
return groups[in_idx];
|
||||
}
|
||||
return NULL ;
|
||||
}
|
||||
|
||||
/**
|
||||
@details
|
||||
-# Gets the size of all added data recroding groups
|
||||
*/
|
||||
int Trick::DataRecordDispatcher::get_groups_size() {
|
||||
return groups.size();
|
||||
}
|
||||
|
||||
/**
|
||||
@details
|
||||
-# If the writer thread condition variable is unlocked
|
||||
|
@ -54,7 +54,7 @@ Trick::DataRecordBuffer::~DataRecordBuffer() {
|
||||
free(ref) ;
|
||||
}
|
||||
|
||||
Trick::DataRecordGroup::DataRecordGroup( std::string in_name ) :
|
||||
Trick::DataRecordGroup::DataRecordGroup( std::string in_name, Trick::DR_Type dr_type ) :
|
||||
record(true) ,
|
||||
inited(false) ,
|
||||
group_name(in_name) ,
|
||||
@ -96,18 +96,7 @@ Trick::DataRecordGroup::DataRecordGroup( std::string in_name ) :
|
||||
// sim object name
|
||||
name = std::string("trick_data_record_group_") + in_name ;
|
||||
|
||||
// add_jobs_to_queue will fill in job_id later
|
||||
// make the init job run after all other initialization jobs but before the post init checkpoint
|
||||
// job so users can allocate memory in initialization jobs and checkpointing data rec groups will work
|
||||
add_job(0, 1, (char *)"initialization", NULL, cycle, (char *)"init", (char *)"TRK", 65534) ;
|
||||
add_job(0, 2, (char *)"end_of_frame", NULL, 1.0, (char *)"write_data", (char *)"TRK") ;
|
||||
add_job(0, 3, (char *)"checkpoint", NULL, 1.0, (char *)"checkpoint", (char *)"TRK") ;
|
||||
add_job(0, 4, (char *)"post_checkpoint", NULL, 1.0, (char *)"clear_checkpoint_vars", (char *)"TRK") ;
|
||||
// run the restart job in phase 60001
|
||||
add_job(0, 5, (char *)"restart", NULL, 1.0, (char *)"restart", (char *)"TRK", 60001) ;
|
||||
add_job(0, 6, (char *)"shutdown", NULL, 1.0, (char *)"shutdown", (char *)"TRK") ;
|
||||
|
||||
write_job = add_job(0, 99, (char *)job_class.c_str(), NULL, cycle, (char *)"data_record" , (char *)"TRK") ;
|
||||
configure_jobs(dr_type) ;
|
||||
|
||||
add_time_variable() ;
|
||||
}
|
||||
@ -429,6 +418,27 @@ int Trick::DataRecordGroup::init() {
|
||||
|
||||
}
|
||||
|
||||
void Trick::DataRecordGroup::configure_jobs(DR_Type type) {
|
||||
switch(type) {
|
||||
default:
|
||||
// run the restart job in phase 60001
|
||||
add_job(0, 5, (char *)"restart", NULL, 1.0, (char *)"restart", (char *)"TRK", 60001) ;
|
||||
|
||||
case DR_Type::DR_Type_FrameLogDataRecord:
|
||||
// add_jobs_to_queue will fill in job_id later
|
||||
// make the init job run after all other initialization jobs but before the post init checkpoint
|
||||
// job so users can allocate memory in initialization jobs and checkpointing data rec groups will work
|
||||
add_job(0, 1, (char *)"initialization", NULL, cycle, (char *)"init", (char *)"TRK", 65534) ;
|
||||
add_job(0, 2, (char *)"end_of_frame", NULL, 1.0, (char *)"write_data", (char *)"TRK") ;
|
||||
add_job(0, 3, (char *)"checkpoint", NULL, 1.0, (char *)"checkpoint", (char *)"TRK") ;
|
||||
add_job(0, 4, (char *)"post_checkpoint", NULL, 1.0, (char *)"clear_checkpoint_vars", (char *)"TRK") ;
|
||||
add_job(0, 6, (char *)"shutdown", NULL, 1.0, (char *)"shutdown", (char *)"TRK") ;
|
||||
|
||||
write_job = add_job(0, 99, (char *)job_class.c_str(), NULL, cycle, (char *)"data_record" , (char *)"TRK") ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
|
||||
int Trick::DataRecordGroup::checkpoint() {
|
||||
unsigned int jj ;
|
||||
|
||||
|
@ -79,6 +79,20 @@ extern "C" Trick::DataRecordGroup * get_data_record_group( std::string in_name )
|
||||
return NULL ;
|
||||
}
|
||||
|
||||
extern "C" Trick::DataRecordGroup * get_data_record_group_by_idx( int in_idx ) {
|
||||
if ( the_drd != NULL ) {
|
||||
return the_drd->get_group(in_idx) ;
|
||||
}
|
||||
return NULL ;
|
||||
}
|
||||
|
||||
extern "C" int get_num_data_record_groups() {
|
||||
if ( the_drd != NULL ) {
|
||||
return the_drd->get_groups_size() ;
|
||||
}
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
extern "C" int set_max_size_record_group (const char * in_name, uint64_t bytes ) {
|
||||
if ( the_drd != NULL ) {
|
||||
return the_drd->set_group_max_file_size(in_name, bytes ) ;
|
||||
|
@ -68,7 +68,7 @@ int Trick::DebugPause::debug_pause_on() {
|
||||
|
||||
debug_pause_flag = true ;
|
||||
|
||||
sem_name_stream << "itimersepmaphore_" << getpid() ;
|
||||
sem_name_stream << "debugstepmaphore_" << getpid() ;
|
||||
sem_name = sem_name_stream.str() ;
|
||||
|
||||
debug_sem = sem_open(sem_name.c_str(), O_CREAT, S_IRWXU , 0);
|
||||
|
@ -19,25 +19,13 @@ Trick::ExternalApplication::ExternalApplication() :
|
||||
host_source = port_source = AUTO;
|
||||
cycle_period_set = minimum_cycle_period_set = disconnect_behavior_set = height_set =
|
||||
width_set = x_set = y_set = auto_reconnect_set = false;
|
||||
|
||||
// c_intf uses char *, we manage the memory here in external application
|
||||
command_c_str = (char*)trick_MM->declare_var("char", (command.size() + 1) );
|
||||
strcpy(command_c_str, command.c_str());
|
||||
allocations.push_back(command_c_str);
|
||||
}
|
||||
|
||||
Trick::ExternalApplication::~ExternalApplication() {
|
||||
for(std::vector<char*>::iterator it = allocations.begin(); it != allocations.end(); ++it) {
|
||||
trick_MM->delete_var( (void*)*it );
|
||||
}
|
||||
allocations.clear();
|
||||
}
|
||||
|
||||
void Trick::ExternalApplication::set_startup_command(std::string in_command) {
|
||||
command = in_command;
|
||||
command_c_str = (char*)trick_MM->declare_var("char", (command.size() + 1) );
|
||||
strcpy(command_c_str, command.c_str());
|
||||
allocations.push_back((command_c_str));
|
||||
}
|
||||
|
||||
std::string Trick::ExternalApplication::get_startup_command() {
|
||||
@ -45,7 +33,7 @@ std::string Trick::ExternalApplication::get_startup_command() {
|
||||
}
|
||||
|
||||
const char * Trick::ExternalApplication::get_startup_command_c_str() {
|
||||
return command_c_str;
|
||||
return command.c_str();
|
||||
}
|
||||
|
||||
void Trick::ExternalApplication::add_arguments(std::string args) {
|
||||
|
@ -9,7 +9,7 @@
|
||||
-# All instances get the end_of_frame frame_log_clear job.
|
||||
*/
|
||||
Trick::FrameDataRecordGroup::FrameDataRecordGroup( int in_thread_id , std::string in_name )
|
||||
: Trick::DRBinary(in_name, false) , thread_id(in_thread_id ) {
|
||||
: Trick::DRBinary(in_name, false, Trick::DR_Type::DR_Type_FrameLogDataRecord ), thread_id(in_thread_id ) {
|
||||
if ( thread_id > 0 ) {
|
||||
add_job(thread_id, 1000, (char *)"top_of_frame", NULL, 1.0, (char *)"start_timer", (char *)"TRK", 1) ;
|
||||
// Frame logging uses phase 65533 in FrameLog.ccp. Stop the timer just before that.
|
||||
|
@ -127,6 +127,14 @@ int Trick::SlaveInfo::start() {
|
||||
startup_command << " 'cd " << sim_path << " ; " ;
|
||||
}
|
||||
|
||||
/** @li Set up remote shell environment if needed for the remote startup command */
|
||||
if ( !remote_shell_config_file.empty() ) {
|
||||
startup_command << " source " << remote_shell_config_file << " ; " ;
|
||||
// cd to sim_path directory again if in case the config file changed pwd
|
||||
// to a different directory other than the sim_path
|
||||
startup_command << " cd " << sim_path << " ; " ;
|
||||
}
|
||||
|
||||
if (strstr(passp->pw_shell, "csh")) {
|
||||
startup_command << " setenv TRICK_HOST_CPU `trick-gte TRICK_HOST_CPU` ; " ;
|
||||
} else {
|
||||
|
@ -37,19 +37,18 @@ int Trick::MemoryManager::delete_var(void* address ) {
|
||||
MemoryManager allocated it.
|
||||
*/
|
||||
if ( alloc_info->stcl == TRICK_LOCAL ) {
|
||||
if ( alloc_info->alloc_type == TRICK_ALLOC_MALLOC ) {
|
||||
// The destructor that we just called MAY have deleted addresses
|
||||
// that are already planned for deletion, say during reset_memory.
|
||||
// So, keep a record of what we've recently deleted so we don't
|
||||
// to warn that we can't find it, when reset_memory also tries to
|
||||
// delete that same address. Same for TRICK_ALLOC_NEW block
|
||||
deleted_addr_list.push_back(address);
|
||||
|
||||
if ( alloc_info->alloc_type == TRICK_ALLOC_MALLOC ) {
|
||||
// This will call a destructor ONLY if alloc_info->type is TRICK_STRUCTURED.
|
||||
// Otherwise it does nothing.
|
||||
io_src_destruct_class( alloc_info );
|
||||
|
||||
// The destructor that we just called MAY have deleted addresses
|
||||
// that are already planned for deletion, say during reset_memory.
|
||||
// So, keep a record of what we've recently deleted so we don't
|
||||
// to warn that we can't find it, when reset_memory also tries to
|
||||
// delete that same address.
|
||||
deleted_addr_list.push_back(address);
|
||||
|
||||
free( address);
|
||||
} else if ( alloc_info->alloc_type == TRICK_ALLOC_NEW ) {
|
||||
io_src_delete_class( alloc_info );
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include <math.h>
|
||||
#include <unistd.h>
|
||||
|
||||
@ -31,7 +32,7 @@ Trick::MessagePublisher::~MessagePublisher() {
|
||||
|
||||
void Trick::MessagePublisher::set_print_format() {
|
||||
num_digits = (int)round(log10((double)tics_per_sec)) ;
|
||||
snprintf(print_format, sizeof(print_format), "|L %%3d|%%s|%%s|%%s|T %%d|%%lld.%%0%dlld| ", num_digits) ;
|
||||
snprintf(print_format, sizeof(print_format), "|L %%3d|%%s.%%06Lu|%%s|%%s|T %%d|%%lld.%%0%dlld| ", num_digits) ;
|
||||
}
|
||||
|
||||
int Trick::MessagePublisher::init() {
|
||||
@ -49,14 +50,22 @@ int Trick::MessagePublisher::publish(int level , std::string message) {
|
||||
char header_buf[MAX_MSG_HEADER_SIZE];
|
||||
char hostname[64];
|
||||
time_t date ;
|
||||
// timeval contains both tv_sec and tv_usec
|
||||
// tv_sec represents seconds since the epoch and is used for time stamp without sub-second.
|
||||
// tv_usec are microseconds past the last second and is used for printing out sub-second.
|
||||
struct timeval time_val;
|
||||
std::string header ;
|
||||
long long tics = exec_get_time_tics() ;
|
||||
|
||||
/** @li Create message header with level, date, host, sim name, process id, sim time. */
|
||||
date = time(NULL) ;
|
||||
gettimeofday(&time_val, NULL);
|
||||
|
||||
// tv_sec represents seconds since the epoch
|
||||
date = time_val.tv_sec;
|
||||
|
||||
strftime(date_buf, (size_t) 20, "%Y/%m/%d,%H:%M:%S", localtime(&date));
|
||||
(void) gethostname(hostname, (size_t) 48);
|
||||
snprintf(header_buf, sizeof(header_buf), print_format , level, date_buf, hostname,
|
||||
snprintf(header_buf, sizeof(header_buf), print_format , level, date_buf, time_val.tv_usec, hostname,
|
||||
sim_name.c_str(), exec_get_process_id(), tics/tics_per_sec ,
|
||||
(long long)((double)(tics % tics_per_sec) * (double)(pow(10 , num_digits)/tics_per_sec)) ) ;
|
||||
header = header_buf ;
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
// message_publish when you don't have a message publisher class
|
||||
#define MAX_MSG_HEADER_SIZE 256
|
||||
@ -13,18 +14,27 @@ extern "C" int message_publish_standalone(int level, const char * format_msg, ..
|
||||
char date_buf[MAX_MSG_HEADER_SIZE];
|
||||
char hostname[64];
|
||||
time_t date ;
|
||||
// timeval contains both tv_sec and tv_usec
|
||||
// tv_sec represents seconds since the epoch and is used for time stamp without sub-second.
|
||||
// tv_usec are microseconds past the last second and is used for printing out sub-second.
|
||||
struct timeval time_val;
|
||||
|
||||
va_list args;
|
||||
|
||||
va_start(args, format_msg);
|
||||
(void) vsnprintf(msg_buf, MAX_MSG_SIZE, format_msg, args);
|
||||
va_end(args);
|
||||
|
||||
date = time(NULL) ;
|
||||
gettimeofday(&time_val, NULL);
|
||||
|
||||
// tv_sec represents seconds since the epoch
|
||||
date = time_val.tv_sec;
|
||||
|
||||
strftime(date_buf, (size_t) 20, "%Y/%m/%d,%H:%M:%S", localtime(&date));
|
||||
(void) gethostname(hostname, (size_t) 48);
|
||||
fprintf(stdout, "|L %d|%s| |%s|T %d|%.2f| %s" , level,
|
||||
fprintf(stdout, "|L %d|%s.%06Lu| |%s|T %d|%.2f| %s" , level,
|
||||
// so that we don't call any exec routines, use process id 0 and sim time 0.0
|
||||
date_buf, hostname , 0, 0.0, msg_buf) ;
|
||||
date_buf, time_val.tv_usec, hostname , 0, 0.0, msg_buf) ;
|
||||
fflush(stdout) ;
|
||||
|
||||
return (0);
|
||||
|
@ -91,6 +91,11 @@ int Trick::ScheduledJobQueue::push( JobData * new_job ) {
|
||||
|
||||
/* Increment the size of the queue */
|
||||
list_size++ ;
|
||||
|
||||
int new_job_index = ((unsigned long)insert_pt - (unsigned long)list) / sizeof(JobData**);
|
||||
if(new_job_index < curr_index) {
|
||||
curr_index++;
|
||||
}
|
||||
|
||||
return(0) ;
|
||||
|
||||
|
@ -70,6 +70,117 @@ TEST_F( ScheduledJobQueueTest , PushJobsbyJobOrder ) {
|
||||
EXPECT_TRUE( sjq.empty() ) ;
|
||||
}
|
||||
|
||||
TEST_F( ScheduledJobQueueTest , PushJobOntoSameIndex_CurrIndex0 ) {
|
||||
|
||||
Trick::JobData * job_ptr ;
|
||||
|
||||
EXPECT_EQ( sjq.size() , (unsigned int)0) ;
|
||||
EXPECT_TRUE( sjq.empty() ) ;
|
||||
|
||||
job_ptr = new Trick::JobData(0, 2 , "class_100", NULL, 1.0 , "job_4") ;
|
||||
job_ptr->sim_object_id = 4 ;
|
||||
job_ptr->job_class = 100 ;
|
||||
sjq.push(job_ptr) ;
|
||||
|
||||
EXPECT_EQ( sjq.size() , (unsigned int)1) ;
|
||||
EXPECT_EQ( sjq.get_curr_index() , (unsigned int)0) ;
|
||||
|
||||
job_ptr = new Trick::JobData(0, 2 , "class_100", NULL, 1.0 , "job_3") ;
|
||||
job_ptr->sim_object_id = 3 ;
|
||||
job_ptr->job_class = 100 ;
|
||||
sjq.push(job_ptr) ;
|
||||
|
||||
EXPECT_EQ( sjq.size() , (unsigned int)2) ;
|
||||
EXPECT_EQ( sjq.get_curr_index() , (unsigned int)0) ;
|
||||
|
||||
job_ptr = new Trick::JobData(0, 2 , "class_100", NULL, 1.0 , "job_2") ;
|
||||
job_ptr->sim_object_id = 2 ;
|
||||
job_ptr->job_class = 100 ;
|
||||
sjq.push(job_ptr) ;
|
||||
|
||||
EXPECT_EQ( sjq.size() , (unsigned int)3) ;
|
||||
EXPECT_EQ( sjq.get_curr_index() , (unsigned int)0) ;
|
||||
|
||||
job_ptr = new Trick::JobData(0, 2 , "class_100", NULL, 1.0 , "job_1") ;
|
||||
job_ptr->sim_object_id = 1 ;
|
||||
job_ptr->job_class = 100 ;
|
||||
sjq.push(job_ptr) ;
|
||||
|
||||
EXPECT_EQ( sjq.size() , (unsigned int)4) ;
|
||||
EXPECT_EQ( sjq.get_curr_index() , (unsigned int)0) ;
|
||||
|
||||
job_ptr = sjq.get_next_job() ;
|
||||
EXPECT_STREQ( job_ptr->name.c_str() , "job_1") ;
|
||||
|
||||
job_ptr = sjq.get_next_job() ;
|
||||
EXPECT_STREQ( job_ptr->name.c_str() , "job_2") ;
|
||||
|
||||
job_ptr = sjq.get_next_job() ;
|
||||
EXPECT_STREQ( job_ptr->name.c_str() , "job_3") ;
|
||||
|
||||
job_ptr = sjq.get_next_job() ;
|
||||
EXPECT_STREQ( job_ptr->name.c_str() , "job_4") ;
|
||||
|
||||
sjq.clear() ;
|
||||
EXPECT_EQ( sjq.size() , (unsigned int)0) ;
|
||||
EXPECT_TRUE( sjq.empty() ) ;
|
||||
}
|
||||
|
||||
TEST_F( ScheduledJobQueueTest , PushJobOntoSameIndex_CurrIndex1 ) {
|
||||
|
||||
Trick::JobData * job_ptr ;
|
||||
|
||||
EXPECT_EQ( sjq.size() , (unsigned int)0) ;
|
||||
EXPECT_TRUE( sjq.empty() ) ;
|
||||
|
||||
job_ptr = new Trick::JobData(0, 2 , "class_100", NULL, 1.0 , "job_1") ;
|
||||
job_ptr->sim_object_id = 1 ;
|
||||
job_ptr->job_class = 100 ;
|
||||
sjq.push(job_ptr) ;
|
||||
|
||||
sjq.get_next_job() ;
|
||||
|
||||
EXPECT_EQ( sjq.size() , (unsigned int)1) ;
|
||||
EXPECT_EQ( sjq.get_curr_index() , (unsigned int)1) ;
|
||||
|
||||
job_ptr = new Trick::JobData(0, 2 , "class_100", NULL, 1.0 , "job_4") ;
|
||||
job_ptr->sim_object_id = 4 ;
|
||||
job_ptr->job_class = 100 ;
|
||||
sjq.push(job_ptr) ;
|
||||
|
||||
EXPECT_EQ( sjq.size() , (unsigned int)2) ;
|
||||
EXPECT_EQ( sjq.get_curr_index() , (unsigned int)1) ;
|
||||
|
||||
job_ptr = new Trick::JobData(0, 2 , "class_100", NULL, 1.0 , "job_3") ;
|
||||
job_ptr->sim_object_id = 3 ;
|
||||
job_ptr->job_class = 100 ;
|
||||
sjq.push(job_ptr) ;
|
||||
|
||||
EXPECT_EQ( sjq.size() , (unsigned int)3) ;
|
||||
EXPECT_EQ( sjq.get_curr_index() , (unsigned int)1) ;
|
||||
|
||||
job_ptr = new Trick::JobData(0, 2 , "class_100", NULL, 1.0 , "job_2") ;
|
||||
job_ptr->sim_object_id = 2 ;
|
||||
job_ptr->job_class = 100 ;
|
||||
sjq.push(job_ptr) ;
|
||||
|
||||
EXPECT_EQ( sjq.size() , (unsigned int)4) ;
|
||||
EXPECT_EQ( sjq.get_curr_index() , (unsigned int)1) ;
|
||||
|
||||
job_ptr = sjq.get_next_job() ;
|
||||
EXPECT_STREQ( job_ptr->name.c_str() , "job_2") ;
|
||||
|
||||
job_ptr = sjq.get_next_job() ;
|
||||
EXPECT_STREQ( job_ptr->name.c_str() , "job_3") ;
|
||||
|
||||
job_ptr = sjq.get_next_job() ;
|
||||
EXPECT_STREQ( job_ptr->name.c_str() , "job_4") ;
|
||||
|
||||
sjq.clear() ;
|
||||
EXPECT_EQ( sjq.size() , (unsigned int)0) ;
|
||||
EXPECT_TRUE( sjq.empty() ) ;
|
||||
}
|
||||
|
||||
TEST_F( ScheduledJobQueueTest , PushJobsbySimObjectOrder ) {
|
||||
//req.add_requirement("512154259");
|
||||
|
||||
|
@ -112,21 +112,24 @@ int Trick::VariableServerListenThread::init_listen_device() {
|
||||
|
||||
// Called from init jobs
|
||||
int Trick::VariableServerListenThread::check_and_move_listen_device() {
|
||||
int ret ;
|
||||
int ret = 0;
|
||||
|
||||
if (_user_requested_address) {
|
||||
/* The user has requested a different source address or port in the input file */
|
||||
_listener->disconnect();
|
||||
ret = _listener->initialize(_requested_source_address, _requested_port);
|
||||
_requested_port = _listener->getPort();
|
||||
_requested_source_address = _listener->getHostname();
|
||||
|
||||
if (ret != 0) {
|
||||
message_publish(MSG_ERROR, "ERROR: Could not establish variable server source_address %s: port %d. Aborting.\n",
|
||||
_requested_source_address.c_str(), _requested_port);
|
||||
return -1 ;
|
||||
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
_requested_port = _listener->getPort();
|
||||
_requested_source_address = _listener->getHostname();
|
||||
}
|
||||
return 0 ;
|
||||
return ret ;
|
||||
}
|
||||
|
||||
void * Trick::VariableServerListenThread::thread_body() {
|
||||
@ -248,7 +251,10 @@ int Trick::VariableServerListenThread::restart() {
|
||||
message_publish(MSG_INFO, "restart variable server message port = %d\n", _listener->getPort());
|
||||
}
|
||||
|
||||
initializeMulticast();
|
||||
// Don't initialize the multicast group if it's already initialized
|
||||
if (!_multicast->isInitialized()) {
|
||||
initializeMulticast();
|
||||
}
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
|
401
trick_source/web/dashboard/package-lock.json
generated
@ -5475,6 +5475,98 @@
|
||||
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
|
||||
"integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg=="
|
||||
},
|
||||
"body-parser": {
|
||||
"version": "1.20.3",
|
||||
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz",
|
||||
"integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==",
|
||||
"requires": {
|
||||
"bytes": "3.1.2",
|
||||
"content-type": "~1.0.5",
|
||||
"debug": "2.6.9",
|
||||
"depd": "2.0.0",
|
||||
"destroy": "1.2.0",
|
||||
"http-errors": "2.0.0",
|
||||
"iconv-lite": "0.4.24",
|
||||
"on-finished": "2.4.1",
|
||||
"qs": "6.13.0",
|
||||
"raw-body": "2.5.2",
|
||||
"type-is": "~1.6.18",
|
||||
"unpipe": "1.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"bytes": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
|
||||
"integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg=="
|
||||
},
|
||||
"call-bind": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz",
|
||||
"integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==",
|
||||
"requires": {
|
||||
"es-define-property": "^1.0.0",
|
||||
"es-errors": "^1.3.0",
|
||||
"function-bind": "^1.1.2",
|
||||
"get-intrinsic": "^1.2.4",
|
||||
"set-function-length": "^1.2.1"
|
||||
}
|
||||
},
|
||||
"debug": {
|
||||
"version": "2.6.9",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
||||
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
||||
"requires": {
|
||||
"ms": "2.0.0"
|
||||
}
|
||||
},
|
||||
"function-bind": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
|
||||
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="
|
||||
},
|
||||
"get-intrinsic": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
|
||||
"integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==",
|
||||
"requires": {
|
||||
"es-errors": "^1.3.0",
|
||||
"function-bind": "^1.1.2",
|
||||
"has-proto": "^1.0.1",
|
||||
"has-symbols": "^1.0.3",
|
||||
"hasown": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"has-symbols": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
|
||||
"integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
|
||||
},
|
||||
"qs": {
|
||||
"version": "6.13.0",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz",
|
||||
"integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==",
|
||||
"requires": {
|
||||
"side-channel": "^1.0.6"
|
||||
}
|
||||
},
|
||||
"side-channel": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz",
|
||||
"integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==",
|
||||
"requires": {
|
||||
"call-bind": "^1.0.7",
|
||||
"es-errors": "^1.3.0",
|
||||
"get-intrinsic": "^1.2.4",
|
||||
"object-inspect": "^1.13.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"bonjour-service": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.1.1.tgz",
|
||||
@ -6810,9 +6902,9 @@
|
||||
"integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q=="
|
||||
},
|
||||
"encodeurl": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
|
||||
"integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w=="
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
|
||||
"integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg=="
|
||||
},
|
||||
"end-of-stream": {
|
||||
"version": "1.4.4",
|
||||
@ -6848,6 +6940,43 @@
|
||||
"resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz",
|
||||
"integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA=="
|
||||
},
|
||||
"es-define-property": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz",
|
||||
"integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==",
|
||||
"requires": {
|
||||
"get-intrinsic": "^1.2.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"function-bind": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
|
||||
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="
|
||||
},
|
||||
"get-intrinsic": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
|
||||
"integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==",
|
||||
"requires": {
|
||||
"es-errors": "^1.3.0",
|
||||
"function-bind": "^1.1.2",
|
||||
"has-proto": "^1.0.1",
|
||||
"has-symbols": "^1.0.3",
|
||||
"hasown": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"has-symbols": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
|
||||
"integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"es-errors": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
|
||||
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="
|
||||
},
|
||||
"es-iterator-helpers": {
|
||||
"version": "1.0.15",
|
||||
"resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.15.tgz",
|
||||
@ -7754,36 +7883,36 @@
|
||||
}
|
||||
},
|
||||
"express": {
|
||||
"version": "4.19.2",
|
||||
"resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz",
|
||||
"integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==",
|
||||
"version": "4.21.1",
|
||||
"resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz",
|
||||
"integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==",
|
||||
"requires": {
|
||||
"accepts": "~1.3.8",
|
||||
"array-flatten": "1.1.1",
|
||||
"body-parser": "1.20.2",
|
||||
"body-parser": "1.20.3",
|
||||
"content-disposition": "0.5.4",
|
||||
"content-type": "~1.0.4",
|
||||
"cookie": "0.6.0",
|
||||
"cookie": "0.7.1",
|
||||
"cookie-signature": "1.0.6",
|
||||
"debug": "2.6.9",
|
||||
"depd": "2.0.0",
|
||||
"encodeurl": "~1.0.2",
|
||||
"encodeurl": "~2.0.0",
|
||||
"escape-html": "~1.0.3",
|
||||
"etag": "~1.8.1",
|
||||
"finalhandler": "1.2.0",
|
||||
"finalhandler": "1.3.1",
|
||||
"fresh": "0.5.2",
|
||||
"http-errors": "2.0.0",
|
||||
"merge-descriptors": "1.0.1",
|
||||
"merge-descriptors": "1.0.3",
|
||||
"methods": "~1.1.2",
|
||||
"on-finished": "2.4.1",
|
||||
"parseurl": "~1.3.3",
|
||||
"path-to-regexp": "0.1.7",
|
||||
"path-to-regexp": "0.1.10",
|
||||
"proxy-addr": "~2.0.7",
|
||||
"qs": "6.11.0",
|
||||
"qs": "6.13.0",
|
||||
"range-parser": "~1.2.1",
|
||||
"safe-buffer": "5.2.1",
|
||||
"send": "0.18.0",
|
||||
"serve-static": "1.15.0",
|
||||
"send": "0.19.0",
|
||||
"serve-static": "1.16.2",
|
||||
"setprototypeof": "1.2.0",
|
||||
"statuses": "2.0.1",
|
||||
"type-is": "~1.6.18",
|
||||
@ -7796,34 +7925,10 @@
|
||||
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
|
||||
"integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg=="
|
||||
},
|
||||
"body-parser": {
|
||||
"version": "1.20.2",
|
||||
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz",
|
||||
"integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==",
|
||||
"requires": {
|
||||
"bytes": "3.1.2",
|
||||
"content-type": "~1.0.5",
|
||||
"debug": "2.6.9",
|
||||
"depd": "2.0.0",
|
||||
"destroy": "1.2.0",
|
||||
"http-errors": "2.0.0",
|
||||
"iconv-lite": "0.4.24",
|
||||
"on-finished": "2.4.1",
|
||||
"qs": "6.11.0",
|
||||
"raw-body": "2.5.2",
|
||||
"type-is": "~1.6.18",
|
||||
"unpipe": "1.0.0"
|
||||
}
|
||||
},
|
||||
"bytes": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
|
||||
"integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg=="
|
||||
},
|
||||
"cookie": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz",
|
||||
"integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw=="
|
||||
"version": "0.7.1",
|
||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz",
|
||||
"integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w=="
|
||||
},
|
||||
"debug": {
|
||||
"version": "2.6.9",
|
||||
@ -7838,17 +7943,6 @@
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
|
||||
},
|
||||
"raw-body": {
|
||||
"version": "2.5.2",
|
||||
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz",
|
||||
"integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==",
|
||||
"requires": {
|
||||
"bytes": "3.1.2",
|
||||
"http-errors": "2.0.0",
|
||||
"iconv-lite": "0.4.24",
|
||||
"unpipe": "1.0.0"
|
||||
}
|
||||
},
|
||||
"safe-buffer": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
||||
@ -8005,12 +8099,12 @@
|
||||
"integrity": "sha512-pjmC+bkIF8XI7fWaH8KxHcZL3DPybs1roSKP4rKDvy20tAWwIObE4+JIseG2byfGKhud5ZnM4YSGKBz7Sh0ndQ=="
|
||||
},
|
||||
"finalhandler": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz",
|
||||
"integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==",
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz",
|
||||
"integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==",
|
||||
"requires": {
|
||||
"debug": "2.6.9",
|
||||
"encodeurl": "~1.0.2",
|
||||
"encodeurl": "~2.0.0",
|
||||
"escape-html": "~1.0.3",
|
||||
"on-finished": "2.4.1",
|
||||
"parseurl": "~1.3.3",
|
||||
@ -8969,6 +9063,21 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"hasown": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
|
||||
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
|
||||
"requires": {
|
||||
"function-bind": "^1.1.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"function-bind": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
|
||||
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"he": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
|
||||
@ -9135,9 +9244,9 @@
|
||||
}
|
||||
},
|
||||
"http-proxy-middleware": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz",
|
||||
"integrity": "sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==",
|
||||
"version": "2.0.7",
|
||||
"resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.7.tgz",
|
||||
"integrity": "sha512-fgVY8AV7qU7z/MmXJ/rxwbrtQH4jBQ9m7kp3llF0liB7glmFeVZFBepQb32T3y8n8k2+AEYuMPCpinYW+/CuRA==",
|
||||
"requires": {
|
||||
"@types/http-proxy": "^1.17.8",
|
||||
"http-proxy": "^1.18.1",
|
||||
@ -11702,9 +11811,9 @@
|
||||
}
|
||||
},
|
||||
"merge-descriptors": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
|
||||
"integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w=="
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz",
|
||||
"integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ=="
|
||||
},
|
||||
"merge-stream": {
|
||||
"version": "2.0.0",
|
||||
@ -12046,6 +12155,11 @@
|
||||
"resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz",
|
||||
"integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw=="
|
||||
},
|
||||
"object-inspect": {
|
||||
"version": "1.13.2",
|
||||
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz",
|
||||
"integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g=="
|
||||
},
|
||||
"object-keys": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
|
||||
@ -12950,9 +13064,9 @@
|
||||
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
|
||||
},
|
||||
"path-to-regexp": {
|
||||
"version": "0.1.7",
|
||||
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
|
||||
"integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ=="
|
||||
"version": "0.1.10",
|
||||
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz",
|
||||
"integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w=="
|
||||
},
|
||||
"path-type": {
|
||||
"version": "4.0.0",
|
||||
@ -14031,11 +14145,58 @@
|
||||
"integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw=="
|
||||
},
|
||||
"qs": {
|
||||
"version": "6.11.0",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
|
||||
"integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==",
|
||||
"version": "6.13.0",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz",
|
||||
"integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==",
|
||||
"requires": {
|
||||
"side-channel": "^1.0.4"
|
||||
"side-channel": "^1.0.6"
|
||||
},
|
||||
"dependencies": {
|
||||
"call-bind": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz",
|
||||
"integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==",
|
||||
"requires": {
|
||||
"es-define-property": "^1.0.0",
|
||||
"es-errors": "^1.3.0",
|
||||
"function-bind": "^1.1.2",
|
||||
"get-intrinsic": "^1.2.4",
|
||||
"set-function-length": "^1.2.1"
|
||||
}
|
||||
},
|
||||
"function-bind": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
|
||||
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="
|
||||
},
|
||||
"get-intrinsic": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
|
||||
"integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==",
|
||||
"requires": {
|
||||
"es-errors": "^1.3.0",
|
||||
"function-bind": "^1.1.2",
|
||||
"has-proto": "^1.0.1",
|
||||
"has-symbols": "^1.0.3",
|
||||
"hasown": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"has-symbols": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
|
||||
"integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="
|
||||
},
|
||||
"side-channel": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz",
|
||||
"integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==",
|
||||
"requires": {
|
||||
"call-bind": "^1.0.7",
|
||||
"es-errors": "^1.3.0",
|
||||
"get-intrinsic": "^1.2.4",
|
||||
"object-inspect": "^1.13.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"querystringify": {
|
||||
@ -14074,6 +14235,24 @@
|
||||
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
|
||||
"integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="
|
||||
},
|
||||
"raw-body": {
|
||||
"version": "2.5.2",
|
||||
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz",
|
||||
"integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==",
|
||||
"requires": {
|
||||
"bytes": "3.1.2",
|
||||
"http-errors": "2.0.0",
|
||||
"iconv-lite": "0.4.24",
|
||||
"unpipe": "1.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"bytes": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
|
||||
"integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"react": {
|
||||
"version": "16.8.6",
|
||||
"resolved": "https://registry.npmjs.org/react/-/react-16.8.6.tgz",
|
||||
@ -14801,9 +14980,9 @@
|
||||
}
|
||||
},
|
||||
"rollup": {
|
||||
"version": "2.79.1",
|
||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz",
|
||||
"integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==",
|
||||
"version": "2.79.2",
|
||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.2.tgz",
|
||||
"integrity": "sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==",
|
||||
"requires": {
|
||||
"fsevents": "~2.3.2"
|
||||
}
|
||||
@ -15002,9 +15181,9 @@
|
||||
}
|
||||
},
|
||||
"send": {
|
||||
"version": "0.18.0",
|
||||
"resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz",
|
||||
"integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==",
|
||||
"version": "0.19.0",
|
||||
"resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz",
|
||||
"integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==",
|
||||
"requires": {
|
||||
"debug": "2.6.9",
|
||||
"depd": "2.0.0",
|
||||
@ -15036,6 +15215,11 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"encodeurl": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
|
||||
"integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w=="
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||
@ -15112,14 +15296,69 @@
|
||||
}
|
||||
},
|
||||
"serve-static": {
|
||||
"version": "1.15.0",
|
||||
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz",
|
||||
"integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==",
|
||||
"version": "1.16.2",
|
||||
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz",
|
||||
"integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==",
|
||||
"requires": {
|
||||
"encodeurl": "~1.0.2",
|
||||
"encodeurl": "~2.0.0",
|
||||
"escape-html": "~1.0.3",
|
||||
"parseurl": "~1.3.3",
|
||||
"send": "0.18.0"
|
||||
"send": "0.19.0"
|
||||
}
|
||||
},
|
||||
"set-function-length": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
|
||||
"integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
|
||||
"requires": {
|
||||
"define-data-property": "^1.1.4",
|
||||
"es-errors": "^1.3.0",
|
||||
"function-bind": "^1.1.2",
|
||||
"get-intrinsic": "^1.2.4",
|
||||
"gopd": "^1.0.1",
|
||||
"has-property-descriptors": "^1.0.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"define-data-property": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
|
||||
"integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
|
||||
"requires": {
|
||||
"es-define-property": "^1.0.0",
|
||||
"es-errors": "^1.3.0",
|
||||
"gopd": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"function-bind": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
|
||||
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="
|
||||
},
|
||||
"get-intrinsic": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
|
||||
"integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==",
|
||||
"requires": {
|
||||
"es-errors": "^1.3.0",
|
||||
"function-bind": "^1.1.2",
|
||||
"has-proto": "^1.0.1",
|
||||
"has-symbols": "^1.0.3",
|
||||
"hasown": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"has-property-descriptors": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
|
||||
"integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
|
||||
"requires": {
|
||||
"es-define-property": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"has-symbols": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
|
||||
"integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"set-function-name": {
|
||||
|