New upstream version 6.8.0+ds
Jose Luis Rivero
2 years ago
0 | # More info: | |
1 | # https://help.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners | |
2 | ||
3 | * @scpeters | |
4 | tutorials/* @maryaB-osr |
0 | #!/bin/sh -l | |
1 | ||
2 | set -x | |
3 | ||
4 | BUILD_DIR=`pwd` | |
5 | ||
6 | # Install | |
7 | make install | |
8 | ||
9 | # Compile examples | |
10 | cd ../examples | |
11 | mkdir build | |
12 | cd build | |
13 | cmake .. | |
14 | make | |
15 | ./graph_example | |
16 | ||
17 | cd $BUILD_DIR |
0 | name: Ubuntu CI | |
1 | ||
2 | on: [push, pull_request] | |
3 | ||
4 | jobs: | |
5 | bionic-ci: | |
6 | runs-on: ubuntu-latest | |
7 | name: Ubuntu Bionic CI | |
8 | steps: | |
9 | - name: Checkout | |
10 | uses: actions/checkout@v2 | |
11 | - name: Compile and test | |
12 | id: ci | |
13 | uses: ignition-tooling/action-ignition-ci@master | |
14 | with: | |
15 | codecov-token: ${{ secrets.CODECOV_TOKEN }} | |
16 | focal-ci: | |
17 | runs-on: ubuntu-latest | |
18 | name: Ubuntu Focal CI | |
19 | steps: | |
20 | - name: Checkout | |
21 | uses: actions/checkout@v2 | |
22 | - name: Compile and test | |
23 | id: ci | |
24 | uses: ignition-tooling/action-ignition-ci@focal |
0 | name: PR Collection Labeler | |
1 | ||
2 | on: pull_request_target | |
3 | ||
4 | jobs: | |
5 | pr_collection_labeler: | |
6 | runs-on: ubuntu-latest | |
7 | steps: | |
8 | - name: Add collection labels | |
9 | if: github.event.action == 'opened' | |
10 | uses: ignition-tooling/pr-collection-labeler@v1 | |
11 | with: | |
12 | github-token: ${{ secrets.GITHUB_TOKEN }} |
0 | on: | |
1 | issues: | |
2 | types: [opened] | |
3 | pull_request_target: | |
4 | types: [opened] | |
5 | name: Ticket opened | |
6 | jobs: | |
7 | assign: | |
8 | name: Add ticket to inbox | |
9 | runs-on: ubuntu-latest | |
10 | steps: | |
11 | - name: Add ticket to inbox | |
12 | uses: technote-space/create-project-card-action@v1 | |
13 | with: | |
14 | PROJECT: Core development | |
15 | COLUMN: Inbox | |
16 | GITHUB_TOKEN: ${{ secrets.TRIAGE_TOKEN }} | |
17 | CHECK_ORG_PROJECT: true | |
18 |
0 | load( | |
1 | "//ign_bazel:build_defs.bzl", | |
2 | "IGNITION_FEATURES", | |
3 | "IGNITION_VISIBILITY", | |
4 | "cmake_configure_file", | |
5 | "generate_include_header", | |
6 | "ign_config_header", | |
7 | "ign_export_header", | |
8 | ) | |
9 | ||
10 | package( | |
11 | default_visibility = IGNITION_VISIBILITY, | |
12 | features = IGNITION_FEATURES, | |
13 | ) | |
14 | ||
15 | licenses(["notice"]) | |
16 | ||
17 | exports_files(["LICENSE"]) | |
18 | ||
19 | PROJECT_NAME = "ignition-math" | |
20 | ||
21 | PROJECT_MAJOR = 6 | |
22 | ||
23 | PROJECT_MINOR = 8 | |
24 | ||
25 | PROJECT_PATCH = 0 | |
26 | ||
27 | # Generates config.hh based on the version numbers in CMake code. | |
28 | ign_config_header( | |
29 | name = "config", | |
30 | src = "include/ignition/math/config.hh.in", | |
31 | cmakelists = ["CMakeLists.txt"], | |
32 | project_name = "ignition-math", | |
33 | project_version = (PROJECT_MAJOR, PROJECT_MINOR, PROJECT_PATCH), | |
34 | ) | |
35 | ||
36 | ign_export_header( | |
37 | name = "include/ignition/math/Export.hh", | |
38 | export_base = "IGNITION_MATH", | |
39 | lib_name = "ignition-math", | |
40 | visibility = ["//visibility:private"], | |
41 | ) | |
42 | ||
43 | public_headers_no_gen = glob([ | |
44 | "include/ignition/math/*.hh", | |
45 | "include/ignition/math/detail/*.hh", | |
46 | "include/ignition/math/graph/*.hh", | |
47 | ]) | |
48 | ||
49 | private_headers = glob(["src/*.hh"]) | |
50 | ||
51 | sources = glob( | |
52 | ["src/*.cc"], | |
53 | exclude = ["src/*_TEST.cc"], | |
54 | ) | |
55 | ||
56 | generate_include_header( | |
57 | name = "mathhh_genrule", | |
58 | out = "include/ignition/math.hh", | |
59 | hdrs = public_headers_no_gen + [ | |
60 | "include/ignition/math/config.hh", | |
61 | "include/ignition/math/Export.hh", | |
62 | ], | |
63 | ) | |
64 | ||
65 | public_headers = public_headers_no_gen + [ | |
66 | "include/ignition/math/config.hh", | |
67 | "include/ignition/math/Export.hh", | |
68 | "include/ignition/math.hh", | |
69 | ] | |
70 | ||
71 | cc_library( | |
72 | name = "ign_math", | |
73 | srcs = sources + private_headers, | |
74 | hdrs = public_headers, | |
75 | includes = ["include"], | |
76 | ) | |
77 | ||
78 | # use shared library only when absolutely needd | |
79 | cc_binary( | |
80 | name = "libignition-math6.so", | |
81 | includes = ["include"], | |
82 | linkopts = ["-Wl,-soname,libignition-math6.so"], | |
83 | linkshared = True, | |
84 | deps = [ | |
85 | ":ign_math", | |
86 | ], | |
87 | ) | |
88 | ||
89 | [cc_test( | |
90 | name = src.replace("/", "_").replace(".cc", "").replace("src_", ""), | |
91 | srcs = [src], | |
92 | deps = [ | |
93 | ":ign_math", | |
94 | "@gtest", | |
95 | "@gtest//:gtest_main", | |
96 | ], | |
97 | ) for src in glob( | |
98 | [ | |
99 | "src/*_TEST.cc", | |
100 | "src/graph/*_TEST.cc", | |
101 | ], | |
102 | )] |
2 | 2 | #============================================================================ |
3 | 3 | # Initialize the project |
4 | 4 | #============================================================================ |
5 | project(ignition-math6 VERSION 6.7.0) | |
5 | project(ignition-math6 VERSION 6.8.0) | |
6 | 6 | |
7 | 7 | #============================================================================ |
8 | 8 | # Find ignition-cmake |
14 | 14 | # Configure the project |
15 | 15 | #============================================================================ |
16 | 16 | set (c++standard 17) |
17 | ign_configure_project() | |
17 | ign_configure_project(VERSION_SUFFIX) | |
18 | 18 | |
19 | 19 | #============================================================================ |
20 | 20 | # Set project-specific options |
1 | 1 | |
2 | 2 | ## Ignition Math 6.x.x |
3 | 3 | |
4 | ## Ignition Math 6.7.0 (2020-1X-XX) | |
4 | ## Ignition Math 6.8.0 (2021-03-30) | |
5 | ||
6 | 1. Add speed limiter class | |
7 | * [Pull request #194](https://github.com/ignitionrobotics/ign-math/pull/194) | |
8 | ||
9 | 1. Bazel Updates for math6 | |
10 | * [Pull request #171](https://github.com/ignitionrobotics/ign-math/pull/171) | |
11 | ||
12 | 1. Add Equal tolerance method to Quaternion | |
13 | * [Pull request #196](https://github.com/ignitionrobotics/ign-math/pull/196) | |
14 | ||
15 | 1. Fix broken link in MassMatrix3.hh | |
16 | * [Pull request #197](https://github.com/ignitionrobotics/ign-math/pull/197) | |
17 | ||
18 | 1. Add instructions to build and run examples | |
19 | * [Pull request #192](https://github.com/ignitionrobotics/ign-math/pull/192) | |
20 | ||
21 | 1. Infrastructure and documentation | |
22 | * [Pull request #189](https://github.com/ignitionrobotics/ign-math/pull/189) | |
23 | * [Pull request #193](https://github.com/ignitionrobotics/ign-math/pull/193) | |
24 | * [Pull request #195](https://github.com/ignitionrobotics/ign-math/pull/195) | |
25 | * [Pull request #201](https://github.com/ignitionrobotics/ign-math/pull/201) | |
26 | ||
27 | 1. Remove unnecessary copy constructor declaration from Box | |
28 | * [Pull request 187](https://github.com/ignitionrobotics/ign-math/pull/187) | |
29 | ||
30 | 1. Windows installation via conda-forge | |
31 | * [Pull request 185](https://github.com/ignitionrobotics/ign-math/pull/185) | |
32 | ||
33 | 1. Add rule-of-five members for Angle | |
34 | * [Pull request 186](https://github.com/ignitionrobotics/ign-math/pull/186) | |
35 | ||
36 | 1. Ellipsoid: new shape class with inertia calculation method | |
37 | * [Pull request 182](https://github.com/ignitionrobotics/ign-math/pull/182) | |
38 | ||
39 | 1. Avoid moving a return value, it might prevent (N)RVO | |
40 | * [Pull request 183](https://github.com/ignitionrobotics/ign-math/pull/183) | |
41 | ||
42 | 1. Properly handle stream errors when reading math objects | |
43 | * [Pull request 180](https://github.com/ignitionrobotics/ign-math/pull/180) | |
44 | * [Pull request 181](https://github.com/ignitionrobotics/ign-math/pull/181) | |
45 | ||
46 | ## Ignition Math 6.7.0 (2020-11-23) | |
5 | 47 | |
6 | 48 | 1. Capsule: new shape class with inertia calculation method |
7 | 49 | * [Pull request 163](https://github.com/ignitionrobotics/ign-math/pull/163) |
8 | 8 | |
9 | 9 | Build | Status |
10 | 10 | -- | -- |
11 | Test coverage | [![codecov](https://codecov.io/gh/ignitionrobotics/ign-math/branch/master/graph/badge.svg)](https://codecov.io/gh/ignitionrobotics/ign-math) | |
12 | Ubuntu Bionic | [![Build Status](https://build.osrfoundation.org/buildStatus/icon?job=ignition_math-ci-master-bionic-amd64)](https://build.osrfoundation.org/job/ignition_math-ci-master-bionic-amd64) | |
13 | Homebrew | [![Build Status](https://build.osrfoundation.org/buildStatus/icon?job=ignition_math-ci-master-homebrew-amd64)](https://build.osrfoundation.org/job/ignition_math-ci-master-homebrew-amd64) | |
14 | Windows | [![Build Status](https://build.osrfoundation.org/buildStatus/icon?job=ignition_math-ci-master-windows7-amd64)](https://build.osrfoundation.org/job/ignition_math-ci-master-windows7-amd64) | |
11 | Test coverage | [![codecov](https://codecov.io/gh/ignitionrobotics/ign-math/branch/ign-math6/graph/badge.svg)](https://codecov.io/gh/ignitionrobotics/ign-math) | |
12 | Ubuntu Bionic | [![Build Status](https://build.osrfoundation.org/buildStatus/icon?job=ignition_math-ci-ign-math6-bionic-amd64)](https://build.osrfoundation.org/job/ignition_math-ci-ign-math6-bionic-amd64) | |
13 | Homebrew | [![Build Status](https://build.osrfoundation.org/buildStatus/icon?job=ignition_math-ci-ign-math6-homebrew-amd64)](https://build.osrfoundation.org/job/ignition_math-ci-ign-math6-homebrew-amd64) | |
14 | Windows | [![Build Status](https://build.osrfoundation.org/buildStatus/icon?job=ignition_math-ci-ign-math6-windows7-amd64)](https://build.osrfoundation.org/job/ignition_math-ci-ign-math6-windows7-amd64) | |
15 | 15 | |
16 | 16 | Ignition Math, a component of [Ignition |
17 | 17 | Robotics](https://ignitionrobotics.org), provides general purpose math |
24 | 24 | [Install](#install) |
25 | 25 | |
26 | 26 | [Usage](#usage) |
27 | ||
28 | [Documentation](#documentation) | |
29 | ||
30 | [Testing](#testing) | |
31 | 27 | |
32 | 28 | [Folder Structure](#folder-structure) |
33 | 29 | |
51 | 47 | |
52 | 48 | # Install |
53 | 49 | |
54 | See the [installation tutorial](https://ignitionrobotics.org/api/math/6.6/install.html). | |
50 | See the [installation tutorial](https://ignitionrobotics.org/api/math/6.8/install.html). | |
55 | 51 | |
56 | 52 | # Usage |
57 | 53 | |
58 | Please refer to the [examples directory](https://github.com/ignitionrobotics/ign-math/raw/master/examples/). | |
59 | ||
60 | # Documentation | |
61 | ||
62 | API and tutorials can be found at [https://ignitionrobotics.org/libs/math](https://ignitionrobotics.org/libs/math). | |
63 | ||
64 | You can also generate the documentation from a clone of this repository by following these steps. | |
65 | ||
66 | 1. You will need Doxygen. On Ubuntu Doxygen can be installed using | |
67 | ||
68 | ``` | |
69 | sudo apt-get install doxygen | |
70 | ``` | |
71 | ||
72 | 2. Clone the repository | |
73 | ||
74 | ``` | |
75 | git clone https://github.com/ignitionrobotics/ign-math | |
76 | ``` | |
77 | ||
78 | 3. Configure and build the documentation. | |
79 | ||
80 | ``` | |
81 | cd ign-math; mkdir build; cd build; cmake ../; make doc | |
82 | ``` | |
83 | ||
84 | 4. View the documentation by running the following command from the build directory. | |
85 | ||
86 | ``` | |
87 | firefox doxygen/html/index.html | |
88 | ``` | |
89 | ||
90 | # Testing | |
91 | ||
92 | Follow these steps to run tests and static code analysis in your clone of this repository. | |
93 | ||
94 | 1. Follow the [source install instruction](https://ignitionrobotics.org/libs/math#source-install). | |
95 | ||
96 | 2. Run tests. | |
97 | ||
98 | ``` | |
99 | make test | |
100 | ``` | |
101 | ||
102 | 3. Static code checker. | |
103 | ||
104 | ``` | |
105 | make codecheck | |
106 | ``` | |
107 | ||
108 | ## Ruby Tests | |
109 | ||
110 | ### Usage | |
111 | ||
112 | The C++ classes are available in Ruby code by interface files (`.i`) used by swig to build a C++ extension module. | |
113 | ||
114 | The interfaces and Ruby test codes are in the `src` folder. To use a C++ class in Ruby you need to: | |
115 | ||
116 | 1. Create an interface file describing the class as in Swig and Ruby reference at [The Ruby-to-C/C++ Mapping](http://www.swig.org/Doc1.3/Ruby.html#Ruby_nn11) | |
117 | ||
118 | 2. Include the interface file in `/src/ing_math.i` | |
119 | ||
120 | 3. Create the Ruby file and import the class as in Swig and Ruby reference at [C++ Classes](http://www.swig.org/Doc1.3/Ruby.html#Ruby_nn18) | |
121 | ||
122 | ### Tests | |
123 | ||
124 | `make test` already runs all tests, including the ones made in Ruby, but you can run a Ruby test individually using | |
125 | ||
126 | ``` | |
127 | ctest -R Ruby_TEST.rb | |
128 | ``` | |
54 | Please refer to the [examples directory](https://github.com/ignitionrobotics/ign-math/raw/ign-math6/examples/). | |
129 | 55 | |
130 | 56 | # Folder Structure |
131 | 57 | |
149 | 75 | # Contributing |
150 | 76 | |
151 | 77 | Please see |
152 | [CONTRIBUTING.md](https://github.com/ignitionrobotics/ign-gazebo/blob/master/CONTRIBUTING.md). | |
78 | [CONTRIBUTING.md](https://github.com/ignitionrobotics/ign-gazebo/blob/main/CONTRIBUTING.md). | |
153 | 79 | |
154 | 80 | # Code of Conduct |
155 | 81 | |
156 | 82 | Please see |
157 | [CODE_OF_CONDUCT.md](https://github.com/ignitionrobotics/ign-gazebo/blob/master/CODE_OF_CONDUCT.md). | |
83 | [CODE_OF_CONDUCT.md](https://github.com/ignitionrobotics/ign-gazebo/blob/main/CODE_OF_CONDUCT.md). | |
158 | 84 | |
159 | 85 | # Versioning |
160 | 86 | |
162 | 88 | |
163 | 89 | # License |
164 | 90 | |
165 | This library is licensed under [Apache 2.0](https://www.apache.org/licenses/LICENSE-2.0). See also the [LICENSE](https://github.com/ignitionrobotics/ign-math/blob/master/LICENSE) file. | |
91 | This library is licensed under [Apache 2.0](https://www.apache.org/licenses/LICENSE-2.0). See also the [LICENSE](https://github.com/ignitionrobotics/ign-math/blob/main/LICENSE) file. |
0 | os: | |
1 | - Visual Studio 2017 | |
2 | ||
3 | configuration: | |
4 | - Debug | |
5 | - Release | |
6 | ||
7 | environment: | |
8 | CTEST_OUTPUT_ON_FAILURE: 1 | |
9 | ||
10 | install: | |
11 | - git clone https://github.com/ignitionrobotics/ign-cmake | |
12 | - cd ign-cmake | |
13 | - git checkout ign-cmake2 | |
14 | - md build | |
15 | - cd build | |
16 | - cmake .. -DBUILD_TESTING:BOOL=False | |
17 | - cmake --build . --target INSTALL | |
18 | - cd ../.. | |
19 | build_script: | |
20 | - md build | |
21 | - cd build | |
22 | - cmake .. -DCMAKE_CXX_FLAGS="-WX" | |
23 | - cmake --build . --config %CONFIGURATION% | |
24 | ||
25 | after_build: | |
26 | - cmake --build . --config %CONFIGURATION% --target INSTALL | |
27 | ||
28 | test_script: | |
29 | - cmake --build . --config %CONFIGURATION% --target RUN_TESTS | |
30 | # Build the examples to make sure that find_package(ignition-math* REQUIRED) works | |
31 | - cd ../examples | |
32 | - md build | |
33 | - cd build | |
34 | - cmake .. | |
35 | - cmake --build . --config %CONFIGURATION% | |
36 | - cd .. | |
37 |
0 | image: ubuntu:bionic | |
1 | ||
2 | pipelines: | |
3 | default: | |
4 | - step: | |
5 | script: | |
6 | - apt-get update | |
7 | - apt-get -y install cmake build-essential curl git cppcheck ruby-dev swig g++-8 libeigen3-dev doxygen | |
8 | - update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-8 800 --slave /usr/bin/g++ g++ /usr/bin/g++-8 --slave /usr/bin/gcov gcov /usr/bin/gcov-8 | |
9 | - gcc -v | |
10 | - g++ -v | |
11 | - gcov -v | |
12 | # lcov | |
13 | - git clone https://github.com/linux-test-project/lcov.git | |
14 | - cd lcov | |
15 | # see https://github.com/linux-test-project/lcov/issues/55 | |
16 | - git checkout 1e0df571 | |
17 | - make install | |
18 | - cd .. | |
19 | # Ignition cmake | |
20 | - echo "deb http://packages.osrfoundation.org/gazebo/ubuntu-stable bionic main" > /etc/apt/sources.list.d/gazebo-stable.list | |
21 | # - echo "deb http://packages.osrfoundation.org/gazebo/ubuntu-prerelease bionic main" > /etc/apt/sources.list.d/gazebo-prerelease.list | |
22 | - apt-key adv --keyserver keyserver.ubuntu.com --recv-keys D2486D2DD83DB69272AFE98867170598AF249743 | |
23 | - apt-get update | |
24 | - apt-get -y install | |
25 | libignition-cmake2-dev | |
26 | # Ignition math | |
27 | - mkdir build | |
28 | - cd build | |
29 | - cmake .. -DCMAKE_BUILD_TYPE=coverage | |
30 | - make | |
31 | # Make sure documentation generation generated no warnings. | |
32 | - make doc | |
33 | - bash <(curl -s https://github.com/ignitionrobotics/ign-cmake/raw/master/tools/doc_check.sh) | |
34 | - make test | |
35 | - make coverage | |
36 | # Use a special version of codecov for handling gcc8 output. | |
37 | - bash <(curl -s https://raw.githubusercontent.com/codecov/codecov-bash/4678d212cce2078bbaaf5027af0c0dafaad6a095/codecov) -X gcovout -X gcov | |
38 | - make codecheck | |
39 | - make install | |
40 | # Examples | |
41 | - cd .. | |
42 | - cd examples | |
43 | - mkdir build | |
44 | - cd build | |
45 | - cmake .. | |
46 | - make | |
47 | - ./graph_example |
0 | ||
1 | :: NOTE: This script is only meant to be used as part of the ignition developers' CI system | |
2 | :: Users and developers should build and install this library using cmake and Visual Studio | |
3 | ||
4 | :: Install dependencies | |
5 | call %win_lib% :download_unzip_install eigen3-3.3.4.zip | |
6 | call %win_lib% :install_ign_project ign-cmake ign-cmake2 | |
7 | ||
8 | :: Set configuration variables | |
9 | @set build_type=Release | |
10 | @if not "%1"=="" set build_type=%1 | |
11 | @echo Configuring for build type %build_type% | |
12 | ||
13 | :: Use legacy install location if unset | |
14 | @if "%WORKSPACE_INSTALL_DIR%"=="" set WORKSPACE_INSTALL_DIR="install\%build_type%" | |
15 | ||
16 | :: Go to the directory that this configure.bat file exists in | |
17 | cd /d %~dp0 | |
18 | ||
19 | :: Create a build directory and configure | |
20 | md build | |
21 | cd build | |
22 | cmake .. -G "NMake Makefiles" -DCMAKE_INSTALL_PREFIX="%WORKSPACE_INSTALL_DIR%" -DCMAKE_BUILD_TYPE="%build_type%" -DBUILD_TESTING:BOOL=False | |
23 | :: Note: We disable testing by default. If the intention is for the CI to build and test | |
24 | :: this project, then the CI script will turn it back on. | |
25 | ||
26 | :: If the caller wants to build and/or install, they should do so after calling this script |
0 | load( | |
1 | "//ign_bazel:build_defs.bzl", | |
2 | "IGNITION_ROOT", | |
3 | "IGNITION_VISIBILITY", | |
4 | ) | |
5 | ||
6 | package( | |
7 | default_visibility = IGNITION_VISIBILITY, | |
8 | ) | |
9 | ||
10 | licenses(["notice"]) | |
11 | ||
12 | public_headers = [ | |
13 | "include/ignition/math/eigen3/Conversions.hh", | |
14 | ] | |
15 | ||
16 | cc_library( | |
17 | name = "eigen3", | |
18 | srcs = public_headers, | |
19 | hdrs = public_headers, | |
20 | includes = ["include"], | |
21 | deps = [ | |
22 | "@eigen3", | |
23 | IGNITION_ROOT + "ign_math", | |
24 | ], | |
25 | ) | |
26 | ||
27 | [cc_test( | |
28 | name = src.replace("/", "_").replace(".cc", "").replace("src_", ""), | |
29 | srcs = [src], | |
30 | deps = [ | |
31 | ":eigen3", | |
32 | "@gtest", | |
33 | "@gtest//:gtest_main", | |
34 | ], | |
35 | ) for src in glob( | |
36 | [ | |
37 | "src/*_TEST.cc", | |
38 | ], | |
39 | )] |
0 | ## Examples | |
1 | ||
2 | Example programs using Ignition Math. | |
3 | ||
4 | ## Build | |
5 | ||
6 | Create directory: | |
7 | ||
8 | ``` | |
9 | cd examples | |
10 | mkdir build | |
11 | cd build | |
12 | ``` | |
13 | ||
14 | Configure: | |
15 | ||
16 | ``` | |
17 | cmake .. | |
18 | ``` | |
19 | ||
20 | Build on Unix: | |
21 | ||
22 | ||
23 | ``` | |
24 | make | |
25 | ``` | |
26 | ||
27 | To build on Windows, make sure the configuration matches `ign-math`'s | |
28 | configuration: | |
29 | ||
30 | ``` | |
31 | cmake -build . --config Release | |
32 | ``` | |
33 | ||
34 | ## Run | |
35 | ||
36 | Several executables were created in the build folder. | |
37 | ||
38 | For example, run the angle exaample on Unix: | |
39 | ||
40 | ``` | |
41 | cd examples/build | |
42 | ./angle_example | |
43 | ``` | |
44 | ||
45 | Run on Windows: | |
46 | ||
47 | ``` | |
48 | cd examples\build\Release | |
49 | angle_example.exe | |
50 | ``` |
96 | 96 | /// \param[in] _angle Angle to copy |
97 | 97 | public: Angle(const Angle &_angle); |
98 | 98 | |
99 | /// \brief Move constructor | |
100 | /// \param[in] _angle Angle to move | |
101 | public: Angle(Angle &&_angle) noexcept; | |
102 | ||
99 | 103 | /// \brief Destructor |
100 | 104 | public: virtual ~Angle(); |
105 | ||
106 | /// \brief Copy assignment operator | |
107 | /// \param[in] _angle Angle to copy | |
108 | public: Angle& operator=(const Angle &_angle); | |
109 | ||
110 | /// \brief Move assignment operator | |
111 | /// \param[in] _angle Angle to move | |
112 | public: Angle& operator=(Angle &&_angle) noexcept; | |
101 | 113 | |
102 | 114 | /// \brief Set the value from an angle in radians. |
103 | 115 | /// \param[in] _radian Radian value. |
80 | 80 | /// \param[in] _mat Material property for the box. |
81 | 81 | public: Box(const Vector3<Precision> &_size, |
82 | 82 | const ignition::math::Material &_mat); |
83 | ||
84 | /// \brief Copy Constructor. | |
85 | /// \param[in] _b Box to copy. | |
86 | public: Box(const Box<Precision> &_b); | |
87 | 83 | |
88 | 84 | /// \brief Destructor. |
89 | 85 | public: virtual ~Box() = default; |
256 | 256 | _in.setf(std::ios_base::skipws); |
257 | 257 | _in >> _pt.r >> _pt.g >> _pt.b; |
258 | 258 | // Since alpha is optional, check if it's there before parsing |
259 | while (!_in.eof() && std::isspace(_in.peek())) | |
259 | while (_in.good() && std::isspace(_in.peek())) | |
260 | 260 | { |
261 | 261 | _in.get(); |
262 | 262 | } |
263 | if (!_in.eof()) | |
263 | if (_in.good()) | |
264 | 264 | { |
265 | 265 | _in >> _pt.a; |
266 | 266 | } |
267 | else | |
267 | else if (!_in.fail()) | |
268 | 268 | { |
269 | 269 | _pt.a = 1.0; |
270 | 270 | } |
0 | /* | |
1 | * Copyright (C) 2020 Open Source Robotics Foundation | |
2 | * | |
3 | * Licensed under the Apache License, Version 2.0 (the "License"); | |
4 | * you may not use this file except in compliance with the License. | |
5 | * You may obtain a copy of the License at | |
6 | * | |
7 | * http://www.apache.org/licenses/LICENSE-2.0 | |
8 | * | |
9 | * Unless required by applicable law or agreed to in writing, software | |
10 | * distributed under the License is distributed on an "AS IS" BASIS, | |
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
12 | * See the License for the specific language governing permissions and | |
13 | * limitations under the License. | |
14 | * | |
15 | */ | |
16 | #ifndef IGNITION_MATH_ELLIPSOID_HH_ | |
17 | #define IGNITION_MATH_ELLIPSOID_HH_ | |
18 | ||
19 | #include <optional> | |
20 | #include "ignition/math/MassMatrix3.hh" | |
21 | #include "ignition/math/Material.hh" | |
22 | ||
23 | namespace ignition | |
24 | { | |
25 | namespace math | |
26 | { | |
27 | // Inline bracket to help doxygen filtering. | |
28 | inline namespace IGNITION_MATH_VERSION_NAMESPACE { | |
29 | // | |
30 | /// \class Ellipsoid Ellipsoid.hh ignition/math/Ellipsoid.hh | |
31 | /// \brief A representation of a general ellipsoid. | |
32 | /// | |
33 | /// The ellipsoid class supports defining a ellipsoid with three radii and | |
34 | /// material properties. Radii are in meters. See Material for more on | |
35 | /// material properties. | |
36 | /// \tparam Precision Scalar numeric type. | |
37 | template<typename Precision> | |
38 | class Ellipsoid | |
39 | { | |
40 | /// \brief Default constructor. The default radius and length are both | |
41 | /// zero. | |
42 | public: Ellipsoid() = default; | |
43 | ||
44 | /// \brief Construct a ellipsoid with a Vector3 of three radii. | |
45 | /// \param[in] _radii The three radii (x, y, z) defining this ellipsoid | |
46 | public: explicit Ellipsoid(const Vector3<Precision> &_radii); | |
47 | ||
48 | /// \brief Construct a ellipsoid with three radii and a material. | |
49 | /// \param[in] _radii The three radii (x, y, z) defining this ellipsoid | |
50 | /// \param[in] _mat Material property for the ellipsoid. | |
51 | public: Ellipsoid(const Vector3<Precision> &_radii, | |
52 | const Material &_mat); | |
53 | ||
54 | /// \brief Get the radius in meters. | |
55 | /// \return The radius of the ellipsoid in meters. | |
56 | public: Vector3<Precision> Radii() const; | |
57 | ||
58 | /// \brief Set the radius in meters. | |
59 | /// \param[in] _radius The radius of the ellipsoid in meters. | |
60 | public: void SetRadii(const Vector3<Precision> &_radii); | |
61 | ||
62 | /// \brief Get the material associated with this ellipsoid. | |
63 | /// \return The material assigned to this ellipsoid | |
64 | public: const Material &Mat() const; | |
65 | ||
66 | /// \brief Set the material associated with this ellipsoid. | |
67 | /// \param[in] _mat The material assigned to this ellipsoid | |
68 | public: void SetMat(const Material &_mat); | |
69 | ||
70 | /// \brief Get the mass matrix for this ellipsoid. This function | |
71 | /// is only meaningful if the ellipsoid's radii and material | |
72 | /// have been set. | |
73 | /// \return The computed mass matrix if parameters are valid | |
74 | /// (radius > 0), (length > 0), and (density > 0). Otherwise | |
75 | /// std::nullopt is returned. | |
76 | public: std::optional< MassMatrix3<Precision> > MassMatrix() const; | |
77 | ||
78 | /// \brief Check if this ellipsoid is equal to the provided ellipsoid. | |
79 | /// Radius, length, and material properties will be checked. | |
80 | public: bool operator==(const Ellipsoid &_ellipsoid) const; | |
81 | ||
82 | /// \brief Get the volume of the ellipsoid in m^3. | |
83 | /// \return Volume of the ellipsoid in m^3. | |
84 | public: Precision Volume() const; | |
85 | ||
86 | /// \brief Compute the ellipsoid's density given a mass value. The | |
87 | /// ellipsoid is assumed to be solid with uniform density. This | |
88 | /// function requires the ellipsoid's radius and length to be set to | |
89 | /// values greater than zero. The Material of the ellipsoid is ignored. | |
90 | /// \param[in] _mass Mass of the ellipsoid, in kg. This value should be | |
91 | /// greater than zero. | |
92 | /// \return Density of the ellipsoid in kg/m^3. A NaN is returned | |
93 | /// if radius, length or _mass is <= 0. | |
94 | public: Precision DensityFromMass(const Precision _mass) const; | |
95 | ||
96 | /// \brief Set the density of this ellipsoid based on a mass value. | |
97 | /// Density is computed using | |
98 | /// Precision DensityFromMass(const Precision _mass) const. The | |
99 | /// ellipsoid is assumed to be solid with uniform density. This | |
100 | /// function requires the ellipsoid's radius and length to be set to | |
101 | /// values greater than zero. The existing Material density value is | |
102 | /// overwritten only if the return value from this true. | |
103 | /// \param[in] _mass Mass of the ellipsoid, in kg. This value should be | |
104 | /// greater than zero. | |
105 | /// \return True if the density was set. False is returned if the | |
106 | /// ellipsoid's radius, length, or the _mass value are <= 0. | |
107 | /// \sa Precision DensityFromMass(const Precision _mass) const | |
108 | public: bool SetDensityFromMass(const Precision _mass); | |
109 | ||
110 | /// \brief Radius of the ellipsoid. | |
111 | private: Vector3<Precision> radii = Vector3<Precision>::Zero; | |
112 | ||
113 | /// \brief the ellipsoid's material. | |
114 | private: Material material; | |
115 | }; | |
116 | ||
117 | /// \typedef Ellipsoid<int> Ellipsoidi | |
118 | /// \brief Ellipsoid with integer precision. | |
119 | typedef Ellipsoid<int> Ellipsoidi; | |
120 | ||
121 | /// \typedef Ellipsoid<double> Ellipsoidd | |
122 | /// \brief Ellipsoid with double precision. | |
123 | typedef Ellipsoid<double> Ellipsoidd; | |
124 | ||
125 | /// \typedef Ellipsoid<float> Ellipsoidf | |
126 | /// \brief Ellipsoid with float precision. | |
127 | typedef Ellipsoid<float> Ellipsoidf; | |
128 | } | |
129 | } | |
130 | } | |
131 | #include "ignition/math/detail/Ellipsoid.hh" | |
132 | ||
133 | #endif |
557 | 557 | IGN_MASSMATRIX3_DEFAULT_TOLERANCE<T>) |
558 | 558 | { |
559 | 559 | // The following was borrowed heavily from: |
560 | // https://github.com/RobotLocomotion/drake/blob/master/multibody/multibody_tree/rotational_inertia.h | |
560 | // https://github.com/RobotLocomotion/drake/blob/v0.27.0/multibody/tree/rotational_inertia.h | |
561 | 561 | |
562 | 562 | // Compute the maximum possible moment of inertia, which will be |
563 | 563 | // used to compute whether the moments are valid. |
518 | 518 | >> d[3] >> d[4] >> d[5] |
519 | 519 | >> d[6] >> d[7] >> d[8]; |
520 | 520 | |
521 | _m.Set(d[0], d[1], d[2], | |
522 | d[3], d[4], d[5], | |
523 | d[6], d[7], d[8]); | |
521 | if (!_in.fail()) | |
522 | { | |
523 | _m.Set(d[0], d[1], d[2], | |
524 | d[3], d[4], d[5], | |
525 | d[6], d[7], d[8]); | |
526 | } | |
524 | 527 | return _in; |
525 | 528 | } |
526 | 529 |
840 | 840 | >> d[8] >> d[9] >> d[10] >> d[11] |
841 | 841 | >> d[12] >> d[13] >> d[14] >> d[15]; |
842 | 842 | |
843 | _m.Set(d[0], d[1], d[2], d[3], | |
844 | d[4], d[5], d[6], d[7], | |
845 | d[8], d[9], d[10], d[11], | |
846 | d[12], d[13], d[14], d[15]); | |
843 | if (!_in.fail()) | |
844 | { | |
845 | _m.Set(d[0], d[1], d[2], d[3], | |
846 | d[4], d[5], d[6], d[7], | |
847 | d[8], d[9], d[10], d[11], | |
848 | d[12], d[13], d[14], d[15]); | |
849 | } | |
847 | 850 | return _in; |
848 | 851 | } |
849 | 852 |
688 | 688 | return _v + uv + uuv; |
689 | 689 | } |
690 | 690 | |
691 | /// \brief Equality test with tolerance. | |
692 | /// \param[in] _qt Quaternion<T> for comparison | |
693 | /// \param[in] _tol equality tolerance | |
694 | /// \return true if the elements of the quaternions are equal | |
695 | /// within the tolerance specified by _tol, false otherwise | |
696 | public: bool Equal(const Quaternion<T> &_qt, const T &_tol) const | |
697 | { | |
698 | return equal(this->qx, _qt.qx, _tol) && | |
699 | equal(this->qy, _qt.qy, _tol) && | |
700 | equal(this->qz, _qt.qz, _tol) && | |
701 | equal(this->qw, _qt.qw, _tol); | |
702 | } | |
703 | ||
691 | 704 | /// \brief Equal to operator |
692 | 705 | /// \param[in] _qt Quaternion<T> for comparison |
693 | 706 | /// \return True if equal |
694 | 707 | public: bool operator==(const Quaternion<T> &_qt) const |
695 | 708 | { |
696 | return equal(this->qx, _qt.qx, static_cast<T>(0.001)) && | |
697 | equal(this->qy, _qt.qy, static_cast<T>(0.001)) && | |
698 | equal(this->qz, _qt.qz, static_cast<T>(0.001)) && | |
699 | equal(this->qw, _qt.qw, static_cast<T>(0.001)); | |
709 | return this->Equal(_qt, static_cast<T>(0.001)); | |
700 | 710 | } |
701 | 711 | |
702 | 712 | /// \brief Not equal to operator |
704 | 714 | /// \return True if not equal |
705 | 715 | public: bool operator!=(const Quaternion<T> &_qt) const |
706 | 716 | { |
707 | return !equal(this->qx, _qt.qx, static_cast<T>(0.001)) || | |
708 | !equal(this->qy, _qt.qy, static_cast<T>(0.001)) || | |
709 | !equal(this->qz, _qt.qz, static_cast<T>(0.001)) || | |
710 | !equal(this->qw, _qt.qw, static_cast<T>(0.001)); | |
717 | return !(*this == _qt); | |
711 | 718 | } |
712 | 719 | |
713 | 720 | /// \brief Unary minus operator |
1063 | 1070 | _in.setf(std::ios_base::skipws); |
1064 | 1071 | _in >> roll >> pitch >> yaw; |
1065 | 1072 | |
1066 | _q.Euler(Vector3<T>(*roll, *pitch, *yaw)); | |
1073 | if (!_in.fail()) | |
1074 | { | |
1075 | _q.Euler(Vector3<T>(*roll, *pitch, *yaw)); | |
1076 | } | |
1067 | 1077 | |
1068 | 1078 | return _in; |
1069 | 1079 | } |
0 | /* | |
1 | * Copyright (C) 2021 Open Source Robotics Foundation | |
2 | * | |
3 | * Licensed under the Apache License, Version 2.0 (the "License"); | |
4 | * you may not use this file except in compliance with the License. | |
5 | * You may obtain a copy of the License at | |
6 | * | |
7 | * http://www.apache.org/licenses/LICENSE-2.0 | |
8 | * | |
9 | * Unless required by applicable law or agreed to in writing, software | |
10 | * distributed under the License is distributed on an "AS IS" BASIS, | |
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
12 | * See the License for the specific language governing permissions and | |
13 | * limitations under the License. | |
14 | * | |
15 | */ | |
16 | ||
17 | #ifndef IGNITION_MATH_SYSTEMS_SPEEDLIMITER_HH_ | |
18 | #define IGNITION_MATH_SYSTEMS_SPEEDLIMITER_HH_ | |
19 | ||
20 | #include <chrono> | |
21 | #include <memory> | |
22 | #include <ignition/math/config.hh> | |
23 | #include "ignition/math/Helpers.hh" | |
24 | ||
25 | namespace ignition | |
26 | { | |
27 | namespace math | |
28 | { | |
29 | // Inline bracket to help doxygen filtering. | |
30 | inline namespace IGNITION_MATH_VERSION_NAMESPACE { | |
31 | // Forward declaration. | |
32 | class SpeedLimiterPrivate; | |
33 | ||
34 | /// \brief Class to limit velocity, acceleration and jerk. | |
35 | class IGNITION_MATH_VISIBLE SpeedLimiter | |
36 | { | |
37 | /// \brief Constructor. | |
38 | /// There are no limits by default. | |
39 | public: SpeedLimiter(); | |
40 | ||
41 | /// \brief Destructor. | |
42 | public: ~SpeedLimiter(); | |
43 | ||
44 | /// \brief Set minimum velocity limit in m/s, usually <= 0. | |
45 | /// \param[in] _lim Minimum velocity. | |
46 | public: void SetMinVelocity(double _lim); | |
47 | ||
48 | /// \brief Get minimum velocity limit, defaults to negative infinity. | |
49 | /// \return Minimum velocity. | |
50 | public: double MinVelocity() const; | |
51 | ||
52 | /// \brief Set maximum velocity limit in m/s, usually >= 0. | |
53 | /// \param[in] _lim Maximum velocity. | |
54 | public: void SetMaxVelocity(double _lim); | |
55 | ||
56 | /// \brief Get maximum velocity limit, defaults to positive infinity. | |
57 | /// \return Maximum velocity. | |
58 | public: double MaxVelocity() const; | |
59 | ||
60 | /// \brief Set minimum acceleration limit in m/s^2, usually <= 0. | |
61 | /// \param[in] _lim Minimum acceleration. | |
62 | public: void SetMinAcceleration(double _lim); | |
63 | ||
64 | /// \brief Get minimum acceleration limit, defaults to negative infinity. | |
65 | /// \return Minimum acceleration. | |
66 | public: double MinAcceleration() const; | |
67 | ||
68 | /// \brief Set maximum acceleration limit in m/s^2, usually >= 0. | |
69 | /// \param[in] _lim Maximum acceleration. | |
70 | public: void SetMaxAcceleration(double _lim); | |
71 | ||
72 | /// \brief Get maximum acceleration limit, defaults to positive infinity. | |
73 | /// \return Maximum acceleration. | |
74 | public: double MaxAcceleration() const; | |
75 | ||
76 | /// \brief Set minimum jerk limit in m/s^3, usually <= 0. | |
77 | /// \param[in] _lim Minimum jerk. | |
78 | public: void SetMinJerk(double _lim); | |
79 | ||
80 | /// \brief Get minimum jerk limit, defaults to negative infinity. | |
81 | /// \return Minimum jerk. | |
82 | public: double MinJerk() const; | |
83 | ||
84 | /// \brief Set maximum jerk limit in m/s^3, usually >= 0. | |
85 | /// \param[in] _lim Maximum jerk. | |
86 | public: void SetMaxJerk(double _lim); | |
87 | ||
88 | /// \brief Get maximum jerk limit, defaults to positive infinity. | |
89 | /// \return Maximum jerk. | |
90 | public: double MaxJerk() const; | |
91 | ||
92 | /// \brief Limit velocity, acceleration and jerk. | |
93 | /// \param [in, out] _vel Velocity to limit [m/s]. | |
94 | /// \param [in] _prevVel Previous velocity to _vel [m/s]. | |
95 | /// \param [in] _prevPrevVel Previous velocity to _prevVel [m/s]. | |
96 | /// \param [in] _dt Time step. | |
97 | /// \return Limiting difference, which is (out _vel - in _vel). | |
98 | public: double Limit(double &_vel, | |
99 | double _prevVel, | |
100 | double _prevPrevVel, | |
101 | std::chrono::steady_clock::duration _dt) const; | |
102 | ||
103 | /// \brief Limit the velocity. | |
104 | /// \param [in, out] _vel Velocity to limit [m/s]. | |
105 | /// \return Limiting difference, which is (out _vel - in _vel). | |
106 | public: double LimitVelocity(double &_vel) const; | |
107 | ||
108 | /// \brief Limit the acceleration using a first-order backward difference | |
109 | /// method. | |
110 | /// \param [in, out] _vel Velocity [m/s]. | |
111 | /// \param [in] _prevVel Previous velocity [m/s]. | |
112 | /// \param [in] _dt Time step. | |
113 | /// \return Limiting difference, which is (out _vel - in _vel). | |
114 | public: double LimitAcceleration( | |
115 | double &_vel, | |
116 | double _prevVel, | |
117 | std::chrono::steady_clock::duration _dt) const; | |
118 | ||
119 | /// \brief Limit the jerk using a second-order backward difference method. | |
120 | /// \param [in, out] _vel Velocity to limit [m/s]. | |
121 | /// \param [in] _prevVel Previous velocity to v [m/s]. | |
122 | /// \param [in] _prevPrevVel Previous velocity to prevVel [m/s]. | |
123 | /// \param [in] _dt Time step. | |
124 | /// \return Limiting difference, which is (out _vel - in _vel). | |
125 | /// \see http://en.wikipedia.org/wiki/Jerk_%28physics%29#Motion_control. | |
126 | public: double LimitJerk( | |
127 | double &_vel, | |
128 | double _prevVel, | |
129 | double _prevPrevVel, | |
130 | std::chrono::steady_clock::duration _dt) const; | |
131 | ||
132 | #ifdef _WIN32 | |
133 | // Disable warning C4251 which is triggered by | |
134 | // std::unique_ptr | |
135 | #pragma warning(push) | |
136 | #pragma warning(disable: 4251) | |
137 | #endif | |
138 | /// \brief Private data pointer. | |
139 | private: std::unique_ptr<SpeedLimiterPrivate> dataPtr; | |
140 | #ifdef _WIN32 | |
141 | #pragma warning(pop) | |
142 | #endif | |
143 | }; | |
144 | } | |
145 | } | |
146 | } | |
147 | ||
148 | #endif |
357 | 357 | double kelvin; |
358 | 358 | _in >> kelvin; |
359 | 359 | |
360 | _temp.SetKelvin(kelvin); | |
360 | if (!_in.fail()) | |
361 | { | |
362 | _temp.SetKelvin(kelvin); | |
363 | } | |
361 | 364 | return _in; |
362 | 365 | } |
363 | 366 |
560 | 560 | // Skip white spaces |
561 | 561 | _in.setf(std::ios_base::skipws); |
562 | 562 | _in >> x >> y; |
563 | _pt.Set(x, y); | |
563 | if (!_in.fail()) | |
564 | { | |
565 | _pt.Set(x, y); | |
566 | } | |
564 | 567 | return _in; |
565 | 568 | } |
566 | 569 |
738 | 738 | _in.setf(std::ios_base::skipws); |
739 | 739 | T x, y, z; |
740 | 740 | _in >> x >> y >> z; |
741 | _pt.Set(x, y, z); | |
741 | if (!_in.fail()) | |
742 | { | |
743 | _pt.Set(x, y, z); | |
744 | } | |
742 | 745 | return _in; |
743 | 746 | } |
744 | 747 |
715 | 715 | // Skip white spaces |
716 | 716 | _in.setf(std::ios_base::skipws); |
717 | 717 | _in >> x >> y >> z >> w; |
718 | _pt.Set(x, y, z, w); | |
718 | if (!_in.fail()) | |
719 | { | |
720 | _pt.Set(x, y, z, w); | |
721 | } | |
719 | 722 | return _in; |
720 | 723 | } |
721 | 724 |
0 | /* | |
1 | * Copyright (C) 2020 Open Source Robotics Foundation | |
2 | * | |
3 | * Licensed under the Apache License, Version 2.0 (the "License"); | |
4 | * you may not use this file except in compliance with the License. | |
5 | * You may obtain a copy of the License at | |
6 | * | |
7 | * http://www.apache.org/licenses/LICENSE-2.0 | |
8 | * | |
9 | * Unless required by applicable law or agreed to in writing, software | |
10 | * distributed under the License is distributed on an "AS IS" BASIS, | |
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
12 | * See the License for the specific language governing permissions and | |
13 | * limitations under the License. | |
14 | * | |
15 | */ | |
16 | #ifndef IGNITION_MATH_DETAIL_ELLIPSOID_HH_ | |
17 | #define IGNITION_MATH_DETAIL_ELLIPSOID_HH_ | |
18 | ||
19 | #include <limits> | |
20 | #include <optional> | |
21 | #include <ignition/math/Helpers.hh> | |
22 | #include <ignition/math/Inertial.hh> | |
23 | ||
24 | namespace ignition | |
25 | { | |
26 | namespace math | |
27 | { | |
28 | ||
29 | ////////////////////////////////////////////////// | |
30 | template<typename T> | |
31 | Ellipsoid<T>::Ellipsoid(const Vector3<T> &_radii) : radii(_radii) {} | |
32 | ||
33 | ////////////////////////////////////////////////// | |
34 | template<typename T> | |
35 | Ellipsoid<T>::Ellipsoid(const Vector3<T> &_radii, const Material &_mat) | |
36 | : radii(_radii), material(_mat) {} | |
37 | ||
38 | ////////////////////////////////////////////////// | |
39 | template<typename T> | |
40 | Vector3<T> Ellipsoid<T>::Radii() const | |
41 | { | |
42 | return this->radii; | |
43 | } | |
44 | ||
45 | ////////////////////////////////////////////////// | |
46 | template<typename T> | |
47 | void Ellipsoid<T>::SetRadii(const Vector3<T> &_radii) | |
48 | { | |
49 | this->radii = _radii; | |
50 | } | |
51 | ||
52 | ////////////////////////////////////////////////// | |
53 | template<typename T> | |
54 | const Material &Ellipsoid<T>::Mat() const | |
55 | { | |
56 | return this->material; | |
57 | } | |
58 | ||
59 | ////////////////////////////////////////////////// | |
60 | template<typename T> | |
61 | void Ellipsoid<T>::SetMat(const Material &_mat) | |
62 | { | |
63 | this->material = _mat; | |
64 | } | |
65 | ||
66 | ////////////////////////////////////////////////// | |
67 | template<typename T> | |
68 | bool Ellipsoid<T>::operator==(const Ellipsoid &_ellipsoid) const | |
69 | { | |
70 | return this->radii == _ellipsoid.radii && | |
71 | this->material == _ellipsoid.material; | |
72 | } | |
73 | ||
74 | ////////////////////////////////////////////////// | |
75 | template<typename T> | |
76 | std::optional< MassMatrix3<T> > Ellipsoid<T>::MassMatrix() const | |
77 | { | |
78 | if (this->radii.X() <= 0 || this->radii.Y() <= 0 || this->radii.Z() <= 0) | |
79 | return std::nullopt; | |
80 | ||
81 | // mass and inertia of ellipsoid taken from | |
82 | // https://en.wikipedia.org/wiki/Ellipsoid | |
83 | const T mass = this->material.Density() * this->Volume(); | |
84 | const T x2 = std::pow(this->radii.X(), 2); | |
85 | const T y2 = std::pow(this->radii.Y(), 2); | |
86 | const T z2 = std::pow(this->radii.Z(), 2); | |
87 | const T ixx = (mass / 5.) * (y2 + z2); | |
88 | const T iyy = (mass / 5.) * (x2 + z2); | |
89 | const T izz = (mass / 5.) * (x2 + y2); | |
90 | return std::make_optional<MassMatrix3<T>>( | |
91 | mass, Vector3(ixx, iyy, izz), Vector3<T>::Zero); | |
92 | } | |
93 | ||
94 | ////////////////////////////////////////////////// | |
95 | template<typename T> | |
96 | T Ellipsoid<T>::Volume() const | |
97 | { | |
98 | constexpr T kFourThirdsPi = 4. * IGN_PI / 3.; | |
99 | return kFourThirdsPi * this->radii.X() * this->radii.Y() * this->radii.Z(); | |
100 | } | |
101 | ||
102 | ////////////////////////////////////////////////// | |
103 | template<typename T> | |
104 | bool Ellipsoid<T>::SetDensityFromMass(const T _mass) | |
105 | { | |
106 | T newDensity = this->DensityFromMass(_mass); | |
107 | if (isnan(newDensity)) | |
108 | return false; | |
109 | ||
110 | this->material.SetDensity(newDensity); | |
111 | return true; | |
112 | } | |
113 | ||
114 | ////////////////////////////////////////////////// | |
115 | template<typename T> | |
116 | T Ellipsoid<T>::DensityFromMass(const T _mass) const | |
117 | { | |
118 | if (this->radii.X() <= 0 || this->radii.Y() <= 0 || this->radii.Z() <=0 | |
119 | || _mass <= 0) | |
120 | return std::numeric_limits<T>::quiet_NaN(); | |
121 | ||
122 | return _mass / this->Volume(); | |
123 | } | |
124 | ||
125 | } | |
126 | } | |
127 | #endif |
183 | 183 | for (auto const &v : this->vertices) |
184 | 184 | res.emplace(std::make_pair(v.first, std::cref(v.second))); |
185 | 185 | |
186 | return std::move(res); | |
186 | return res; | |
187 | 187 | } |
188 | 188 | |
189 | 189 | /// \brief The collection of all vertices in the graph with name == _name. |
198 | 198 | res.emplace(std::make_pair(vertex.first, std::cref(vertex.second))); |
199 | 199 | } |
200 | 200 | |
201 | return std::move(res); | |
201 | return res; | |
202 | 202 | } |
203 | 203 | |
204 | 204 | /// \brief Add a new edge to the graph. |
270 | 270 | res.emplace(std::make_pair(edge.first, std::cref(edge.second))); |
271 | 271 | } |
272 | 272 | |
273 | return std::move(res); | |
273 | return res; | |
274 | 274 | } |
275 | 275 | |
276 | 276 | /// \brief Get all vertices that are directly connected with one edge |
439 | 439 | res.emplace(std::make_pair(edge.Id(), std::cref(edge))); |
440 | 440 | } |
441 | 441 | |
442 | return std::move(res); | |
442 | return res; | |
443 | 443 | } |
444 | 444 | |
445 | 445 | /// \brief Get the set of outgoing edges from a given vertex. |
475 | 475 | res.emplace(std::make_pair(edge.Id(), std::cref(edge))); |
476 | 476 | } |
477 | 477 | |
478 | return std::move(res); | |
478 | return res; | |
479 | 479 | } |
480 | 480 | |
481 | 481 | /// \brief Get the set of incoming edges to a given vertex. |
36 | 36 | } |
37 | 37 | |
38 | 38 | ////////////////////////////////////////////////// |
39 | Angle::Angle(const Angle &_angle) | |
40 | { | |
41 | this->value = _angle.value; | |
42 | } | |
39 | Angle::Angle(const Angle &_angle) = default; | |
43 | 40 | |
44 | 41 | ////////////////////////////////////////////////// |
45 | Angle::~Angle() | |
46 | { | |
47 | } | |
42 | Angle::Angle(Angle &&_angle) noexcept = default; | |
43 | ||
44 | ////////////////////////////////////////////////// | |
45 | Angle::~Angle() = default; | |
46 | ||
47 | ////////////////////////////////////////////////// | |
48 | Angle &Angle::operator=(const Angle &_angle) = default; | |
49 | ||
50 | ////////////////////////////////////////////////// | |
51 | Angle &Angle::operator=(Angle &&_angle) noexcept = default; | |
48 | 52 | |
49 | 53 | ////////////////////////////////////////////////// |
50 | 54 | void Angle::Radian(double _radian) |
0 | /* | |
1 | * Copyright (C) 2020 Open Source Robotics Foundation | |
2 | * | |
3 | * Licensed under the Apache License, Version 2.0 (the "License"); | |
4 | * you may not use this file except in compliance with the License. | |
5 | * You may obtain a copy of the License at | |
6 | * | |
7 | * http://www.apache.org/licenses/LICENSE-2.0 | |
8 | * | |
9 | * Unless required by applicable law or agreed to in writing, software | |
10 | * distributed under the License is distributed on an "AS IS" BASIS, | |
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
12 | * See the License for the specific language governing permissions and | |
13 | * limitations under the License. | |
14 | * | |
15 | */ | |
16 | #include <gtest/gtest.h> | |
17 | #include <cmath> | |
18 | #include <iostream> | |
19 | ||
20 | #include "ignition/math/Ellipsoid.hh" | |
21 | #include "ignition/math/Helpers.hh" | |
22 | #include "ignition/math/Vector3.hh" | |
23 | ||
24 | using namespace ignition; | |
25 | ||
26 | ///////////////////////////////////////////////// | |
27 | TEST(EllipsoidTest, Constructor) | |
28 | { | |
29 | // Default constructor | |
30 | { | |
31 | math::Ellipsoidd ellipsoid; | |
32 | EXPECT_EQ(math::Vector3d::Zero, ellipsoid.Radii()); | |
33 | EXPECT_EQ(math::Material(), ellipsoid.Mat()); | |
34 | ||
35 | math::Ellipsoidd ellipsoid2; | |
36 | EXPECT_EQ(ellipsoid, ellipsoid2); | |
37 | } | |
38 | ||
39 | // Vector3 of radii constructor | |
40 | { | |
41 | const math::Vector3d expectedRadii(1.0, 2.0, 3.0); | |
42 | math::Ellipsoidd ellipsoid(expectedRadii); | |
43 | EXPECT_EQ(expectedRadii, ellipsoid.Radii()); | |
44 | EXPECT_EQ(math::Material(), ellipsoid.Mat()); | |
45 | ||
46 | math::Ellipsoidd ellipsoid2(expectedRadii); | |
47 | EXPECT_EQ(ellipsoid, ellipsoid2); | |
48 | } | |
49 | ||
50 | // Vector3 of radii and material | |
51 | { | |
52 | const math::Vector3d expectedRadii(1.0, 2.0, 3.0); | |
53 | const math::Material expectedMaterial(math::MaterialType::WOOD); | |
54 | math::Ellipsoidd ellipsoid(expectedRadii, expectedMaterial); | |
55 | EXPECT_EQ(expectedRadii, ellipsoid.Radii()); | |
56 | EXPECT_EQ(expectedMaterial, ellipsoid.Mat()); | |
57 | ||
58 | math::Ellipsoidd ellipsoid2(expectedRadii, expectedMaterial); | |
59 | EXPECT_EQ(ellipsoid, ellipsoid2); | |
60 | } | |
61 | } | |
62 | ||
63 | ////////////////////////////////////////////////// | |
64 | TEST(EllipsoidTest, Mutators) | |
65 | { | |
66 | math::Ellipsoidd ellipsoid; | |
67 | EXPECT_EQ(math::Vector3d::Zero, ellipsoid.Radii()); | |
68 | EXPECT_EQ(math::Material(), ellipsoid.Mat()); | |
69 | ||
70 | const math::Vector3d expectedRadii(1.0, 2.0, 3.0); | |
71 | ellipsoid.SetRadii(expectedRadii); | |
72 | ||
73 | const math::Material expectedMaterial(math::MaterialType::PINE); | |
74 | ellipsoid.SetMat(expectedMaterial); | |
75 | ||
76 | EXPECT_EQ(expectedRadii, ellipsoid.Radii()); | |
77 | EXPECT_EQ(expectedMaterial, ellipsoid.Mat()); | |
78 | } | |
79 | ||
80 | ////////////////////////////////////////////////// | |
81 | TEST(EllipsoidTest, VolumeAndDensity) | |
82 | { | |
83 | double mass = 1.0; | |
84 | // Basic sphere | |
85 | math::Ellipsoidd ellipsoid(2. * math::Vector3d::One); | |
86 | ||
87 | double expectedVolume = (4. / 3.) * IGN_PI * std::pow(2.0, 3); | |
88 | EXPECT_DOUBLE_EQ(expectedVolume, ellipsoid.Volume()); | |
89 | ||
90 | double expectedDensity = mass / expectedVolume; | |
91 | EXPECT_DOUBLE_EQ(expectedDensity, ellipsoid.DensityFromMass(mass)); | |
92 | ||
93 | math::Ellipsoidd ellipsoid2(math::Vector3d(1, 10, 100)); | |
94 | expectedVolume = (4. / 3.) * IGN_PI * 1. * 10. * 100.; | |
95 | EXPECT_DOUBLE_EQ(expectedVolume, ellipsoid2.Volume()); | |
96 | ||
97 | expectedDensity = mass / expectedVolume; | |
98 | EXPECT_DOUBLE_EQ(expectedDensity, ellipsoid2.DensityFromMass(mass)); | |
99 | ||
100 | // Check bad cases | |
101 | math::Ellipsoidd ellipsoid3(math::Vector3d::Zero); | |
102 | EXPECT_FALSE(ellipsoid3.SetDensityFromMass(mass)); | |
103 | ||
104 | math::Ellipsoidd ellipsoid4(-math::Vector3d::One); | |
105 | EXPECT_FALSE(ellipsoid4.SetDensityFromMass(mass)); | |
106 | ||
107 | math::Ellipsoidd ellipsoid5(math::Vector3d(-1, 1, 1)); | |
108 | EXPECT_FALSE(ellipsoid5.SetDensityFromMass(mass)); | |
109 | ||
110 | math::Ellipsoidd ellipsoid6(math::Vector3d(-1, -1, 1)); | |
111 | EXPECT_FALSE(ellipsoid6.SetDensityFromMass(mass)); | |
112 | } | |
113 | ||
114 | ////////////////////////////////////////////////// | |
115 | TEST(EllipsoidTest, Mass) | |
116 | { | |
117 | const double mass = 2.0; | |
118 | math::Ellipsoidd ellipsoid(math::Vector3d(1, 10, 100)); | |
119 | ellipsoid.SetDensityFromMass(mass); | |
120 | ||
121 | const double ixx = (mass / 5.0) * (10. * 10. + 100. * 100.); | |
122 | const double iyy = (mass / 5.0) * (1. * 1. + 100. * 100.); | |
123 | const double izz = (mass / 5.0) * (1. * 1. + 10. * 10.); | |
124 | math::MassMatrix3d expectedMassMat( | |
125 | mass, math::Vector3d(ixx, iyy, izz), math::Vector3d::Zero); | |
126 | ||
127 | const auto massMat = ellipsoid.MassMatrix(); | |
128 | ASSERT_NE(std::nullopt, massMat); | |
129 | EXPECT_EQ(expectedMassMat, *massMat); | |
130 | EXPECT_EQ(expectedMassMat.DiagonalMoments(), massMat->DiagonalMoments()); | |
131 | EXPECT_DOUBLE_EQ(expectedMassMat.Mass(), massMat->Mass()); | |
132 | ||
133 | // Zero case | |
134 | const math::Ellipsoidd ellipsoid2; | |
135 | EXPECT_EQ(std::nullopt, ellipsoid2.MassMatrix()); | |
136 | ||
137 | // Check bad cases | |
138 | const math::Ellipsoidd ellipsoid3(-math::Vector3d::One); | |
139 | EXPECT_EQ(std::nullopt, ellipsoid3.MassMatrix()); | |
140 | ||
141 | const math::Ellipsoidd ellipsoid4(math::Vector3d(-1, 1, 1)); | |
142 | EXPECT_EQ(std::nullopt, ellipsoid4.MassMatrix()); | |
143 | ||
144 | const math::Ellipsoidd ellipsoid5(math::Vector3d(-1, -1, 1)); | |
145 | EXPECT_EQ(std::nullopt, ellipsoid5.MassMatrix()); | |
146 | } |
128 | 128 | |
129 | 129 | math::Quaterniond q(q1); |
130 | 130 | EXPECT_TRUE(q == q1); |
131 | } | |
132 | ||
133 | ///////////////////////////////////////////////// | |
134 | TEST(QuaternionTest, Equal) | |
135 | { | |
136 | // doubles | |
137 | math::Quaterniond q(1, 2, 3, 4); | |
138 | math::Quaterniond q2(1.01, 2.015, 3.002, 4.007); | |
139 | EXPECT_TRUE(q.Equal(q2, 0.02)); | |
140 | EXPECT_FALSE(q.Equal(q2, 0.01)); | |
141 | ||
142 | // floats | |
143 | math::Quaternionf q3(1, 2, 3, 4); | |
144 | math::Quaternionf q4(1.05f, 2.1f, 3.03f, 4.04f); | |
145 | EXPECT_TRUE(q3.Equal(q4, 0.2f)); | |
146 | EXPECT_FALSE(q3.Equal(q4, 0.04f)); | |
147 | ||
148 | // ints | |
149 | math::Quaternioni q5(3, 5, -1, 9); | |
150 | math::Quaternioni q6(3, 6, 1, 12); | |
151 | EXPECT_TRUE(q5.Equal(q6, 3)); | |
152 | EXPECT_FALSE(q5.Equal(q6, 2)); | |
131 | 153 | } |
132 | 154 | |
133 | 155 | ///////////////////////////////////////////////// |
0 | /* | |
1 | * Copyright (C) 2021 Open Source Robotics Foundation | |
2 | * | |
3 | * Licensed under the Apache License, Version 2.0 (the "License"); | |
4 | * you may not use this file except in compliance with the License. | |
5 | * You may obtain a copy of the License at | |
6 | * | |
7 | * http://www.apache.org/licenses/LICENSE-2.0 | |
8 | * | |
9 | * Unless required by applicable law or agreed to in writing, software | |
10 | * distributed under the License is distributed on an "AS IS" BASIS, | |
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
12 | * See the License for the specific language governing permissions and | |
13 | * limitations under the License. | |
14 | * | |
15 | */ | |
16 | ||
17 | #include "ignition/math/Helpers.hh" | |
18 | #include "ignition/math/SpeedLimiter.hh" | |
19 | ||
20 | using namespace ignition; | |
21 | using namespace math; | |
22 | ||
23 | /// \brief Private SpeedLimiter data class. | |
24 | class ignition::math::SpeedLimiterPrivate | |
25 | { | |
26 | /// \brief Minimum velocity limit. | |
27 | public: double minVelocity{-std::numeric_limits<double>::infinity()}; | |
28 | ||
29 | /// \brief Maximum velocity limit. | |
30 | public: double maxVelocity{std::numeric_limits<double>::infinity()}; | |
31 | ||
32 | /// \brief Minimum acceleration limit. | |
33 | public: double minAcceleration{-std::numeric_limits<double>::infinity()}; | |
34 | ||
35 | /// \brief Maximum acceleration limit. | |
36 | public: double maxAcceleration{std::numeric_limits<double>::infinity()}; | |
37 | ||
38 | /// \brief Minimum jerk limit. | |
39 | public: double minJerk{-std::numeric_limits<double>::infinity()}; | |
40 | ||
41 | /// \brief Maximum jerk limit. | |
42 | public: double maxJerk{std::numeric_limits<double>::infinity()}; | |
43 | }; | |
44 | ||
45 | ////////////////////////////////////////////////// | |
46 | SpeedLimiter::SpeedLimiter() | |
47 | : dataPtr(std::make_unique<SpeedLimiterPrivate>()) | |
48 | { | |
49 | } | |
50 | ||
51 | ////////////////////////////////////////////////// | |
52 | SpeedLimiter::~SpeedLimiter() = default; | |
53 | ||
54 | ////////////////////////////////////////////////// | |
55 | void SpeedLimiter::SetMinVelocity(double _lim) | |
56 | { | |
57 | this->dataPtr->minVelocity = _lim; | |
58 | } | |
59 | ||
60 | ////////////////////////////////////////////////// | |
61 | double SpeedLimiter::MinVelocity() const | |
62 | { | |
63 | return this->dataPtr->minVelocity; | |
64 | } | |
65 | ||
66 | ////////////////////////////////////////////////// | |
67 | void SpeedLimiter::SetMaxVelocity(double _lim) | |
68 | { | |
69 | this->dataPtr->maxVelocity = _lim; | |
70 | } | |
71 | ||
72 | ////////////////////////////////////////////////// | |
73 | double SpeedLimiter::MaxVelocity() const | |
74 | { | |
75 | return this->dataPtr->maxVelocity; | |
76 | } | |
77 | ||
78 | ////////////////////////////////////////////////// | |
79 | void SpeedLimiter::SetMinAcceleration(double _lim) | |
80 | { | |
81 | this->dataPtr->minAcceleration = _lim; | |
82 | } | |
83 | ||
84 | ////////////////////////////////////////////////// | |
85 | double SpeedLimiter::MinAcceleration() const | |
86 | { | |
87 | return this->dataPtr->minAcceleration; | |
88 | } | |
89 | ||
90 | ////////////////////////////////////////////////// | |
91 | void SpeedLimiter::SetMaxAcceleration(double _lim) | |
92 | { | |
93 | this->dataPtr->maxAcceleration = _lim; | |
94 | } | |
95 | ||
96 | ////////////////////////////////////////////////// | |
97 | double SpeedLimiter::MaxAcceleration() const | |
98 | { | |
99 | return this->dataPtr->maxAcceleration; | |
100 | } | |
101 | ||
102 | ////////////////////////////////////////////////// | |
103 | void SpeedLimiter::SetMinJerk(double _lim) | |
104 | { | |
105 | this->dataPtr->minJerk = _lim; | |
106 | } | |
107 | ||
108 | ////////////////////////////////////////////////// | |
109 | double SpeedLimiter::MinJerk() const | |
110 | { | |
111 | return this->dataPtr->minJerk; | |
112 | } | |
113 | ||
114 | ////////////////////////////////////////////////// | |
115 | void SpeedLimiter::SetMaxJerk(double _lim) | |
116 | { | |
117 | this->dataPtr->maxJerk = _lim; | |
118 | } | |
119 | ||
120 | ////////////////////////////////////////////////// | |
121 | double SpeedLimiter::MaxJerk() const | |
122 | { | |
123 | return this->dataPtr->maxJerk; | |
124 | } | |
125 | ||
126 | ////////////////////////////////////////////////// | |
127 | double SpeedLimiter::Limit(double &_vel, double _prevVel, double _prevPrevVel, | |
128 | std::chrono::steady_clock::duration _dt) const | |
129 | { | |
130 | const double vUnclamped = _vel; | |
131 | ||
132 | this->LimitJerk(_vel, _prevVel, _prevPrevVel, _dt); | |
133 | this->LimitAcceleration(_vel, _prevVel, _dt); | |
134 | this->LimitVelocity(_vel); | |
135 | ||
136 | return _vel - vUnclamped; | |
137 | } | |
138 | ||
139 | ////////////////////////////////////////////////// | |
140 | double SpeedLimiter::LimitVelocity(double &_vel) const | |
141 | { | |
142 | const double vUnclamped = _vel; | |
143 | ||
144 | _vel = ignition::math::clamp( | |
145 | _vel, this->dataPtr->minVelocity, this->dataPtr->maxVelocity); | |
146 | ||
147 | return _vel - vUnclamped; | |
148 | } | |
149 | ||
150 | ////////////////////////////////////////////////// | |
151 | double SpeedLimiter::LimitAcceleration(double &_vel, double _prevVel, | |
152 | std::chrono::steady_clock::duration _dt) const | |
153 | { | |
154 | const double vUnclamped = _vel; | |
155 | ||
156 | const double dtSec = std::chrono::duration<double>(_dt).count(); | |
157 | ||
158 | if (equal(dtSec, 0.0)) | |
159 | return 0.0; | |
160 | ||
161 | const double accUnclamped = (_vel - _prevVel) / dtSec; | |
162 | ||
163 | const double accClamped = ignition::math::clamp(accUnclamped, | |
164 | this->dataPtr->minAcceleration, this->dataPtr->maxAcceleration); | |
165 | ||
166 | _vel = _prevVel + accClamped * dtSec; | |
167 | ||
168 | return _vel - vUnclamped; | |
169 | } | |
170 | ||
171 | ////////////////////////////////////////////////// | |
172 | double SpeedLimiter::LimitJerk(double &_vel, double _prevVel, | |
173 | double _prevPrevVel, std::chrono::steady_clock::duration _dt) const | |
174 | { | |
175 | const double vUnclamped = _vel; | |
176 | ||
177 | const double dtSec = std::chrono::duration<double>(_dt).count(); | |
178 | ||
179 | if (equal(dtSec, 0.0)) | |
180 | return 0.0; | |
181 | ||
182 | const double accUnclamped = (_vel - _prevVel) / dtSec; | |
183 | const double accPrev = (_prevVel - _prevPrevVel) / dtSec; | |
184 | const double jerkUnclamped = (accUnclamped - accPrev) / dtSec; | |
185 | ||
186 | const double jerkClamped = ignition::math::clamp(jerkUnclamped, | |
187 | this->dataPtr->minJerk, this->dataPtr->maxJerk); | |
188 | ||
189 | const double accClamped = accPrev + jerkClamped * dtSec; | |
190 | ||
191 | _vel = _prevVel + accClamped * dtSec; | |
192 | ||
193 | return _vel - vUnclamped; | |
194 | } |
0 | /* | |
1 | * Copyright (C) 2021 Open Source Robotics Foundation | |
2 | * | |
3 | * Licensed under the Apache License, Version 2.0 (the "License"); | |
4 | * you may not use this file except in compliance with the License. | |
5 | * You may obtain a copy of the License at | |
6 | * | |
7 | * http://www.apache.org/licenses/LICENSE-2.0 | |
8 | * | |
9 | * Unless required by applicable law or agreed to in writing, software | |
10 | * distributed under the License is distributed on an "AS IS" BASIS, | |
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
12 | * See the License for the specific language governing permissions and | |
13 | * limitations under the License. | |
14 | * | |
15 | */ | |
16 | ||
17 | #include <gtest/gtest.h> | |
18 | ||
19 | #include "ignition/math/Helpers.hh" | |
20 | #include "ignition/math/SpeedLimiter.hh" | |
21 | ||
22 | using namespace ignition; | |
23 | using namespace math; | |
24 | using namespace std::literals::chrono_literals; | |
25 | ||
26 | ///////////////////////////////////////////////// | |
27 | TEST(SpeedLimiterTest, Default) | |
28 | { | |
29 | // Unlimited by default, the velocity shouldn't change. | |
30 | SpeedLimiter limiter; | |
31 | ||
32 | EXPECT_DOUBLE_EQ(-std::numeric_limits<double>::infinity(), | |
33 | limiter.MinVelocity()); | |
34 | EXPECT_DOUBLE_EQ(std::numeric_limits<double>::infinity(), | |
35 | limiter.MaxVelocity()); | |
36 | EXPECT_DOUBLE_EQ(-std::numeric_limits<double>::infinity(), | |
37 | limiter.MinAcceleration()); | |
38 | EXPECT_DOUBLE_EQ(std::numeric_limits<double>::infinity(), | |
39 | limiter.MaxAcceleration()); | |
40 | EXPECT_DOUBLE_EQ(-std::numeric_limits<double>::infinity(), | |
41 | limiter.MinJerk()); | |
42 | EXPECT_DOUBLE_EQ(std::numeric_limits<double>::infinity(), | |
43 | limiter.MaxJerk()); | |
44 | ||
45 | double vel{5.0}; | |
46 | EXPECT_DOUBLE_EQ(0.0, limiter.Limit(vel, 4.0, 3.0, 1ms)); | |
47 | EXPECT_DOUBLE_EQ(5.0, vel); | |
48 | ||
49 | EXPECT_DOUBLE_EQ(0.0, limiter.LimitVelocity(vel)); | |
50 | EXPECT_DOUBLE_EQ(5.0, vel); | |
51 | ||
52 | EXPECT_DOUBLE_EQ(0.0, limiter.LimitAcceleration(vel, 4.0, 1ms)); | |
53 | EXPECT_DOUBLE_EQ(5.0, vel); | |
54 | ||
55 | EXPECT_DOUBLE_EQ(0.0, limiter.LimitJerk(vel, 4.0, 3.0, 1ms)); | |
56 | EXPECT_DOUBLE_EQ(5.0, vel); | |
57 | ||
58 | vel = 0.0; | |
59 | EXPECT_DOUBLE_EQ(0.0, limiter.Limit(vel, 4.0, 3.0, 1ms)); | |
60 | EXPECT_DOUBLE_EQ(0.0, vel); | |
61 | } | |
62 | ||
63 | ///////////////////////////////////////////////// | |
64 | TEST(SpeedLimiterTest, LimitVelocity) | |
65 | { | |
66 | double minVel = -1.0; | |
67 | double maxVel = 4.0; | |
68 | ||
69 | SpeedLimiter limiter; | |
70 | limiter.SetMinVelocity(minVel); | |
71 | limiter.SetMaxVelocity(maxVel); | |
72 | ||
73 | EXPECT_DOUBLE_EQ(minVel, limiter.MinVelocity()); | |
74 | EXPECT_DOUBLE_EQ(maxVel, limiter.MaxVelocity()); | |
75 | ||
76 | // Within bounds | |
77 | double vel{1.0}; | |
78 | EXPECT_DOUBLE_EQ(0.0, limiter.LimitVelocity(vel)); | |
79 | EXPECT_DOUBLE_EQ(1.0, vel); | |
80 | ||
81 | // Above upper bound | |
82 | vel = 5.0; | |
83 | EXPECT_DOUBLE_EQ(-1.0, limiter.LimitVelocity(vel)); | |
84 | EXPECT_DOUBLE_EQ(maxVel, vel); | |
85 | ||
86 | // Under lower bound | |
87 | vel = -2.0; | |
88 | EXPECT_DOUBLE_EQ(1.0, limiter.LimitVelocity(vel)); | |
89 | EXPECT_DOUBLE_EQ(minVel, vel); | |
90 | } | |
91 | ||
92 | ///////////////////////////////////////////////// | |
93 | TEST(SpeedLimiterTest, LimitAcceleration) | |
94 | { | |
95 | double minAcc = -2.0; | |
96 | double maxAcc = 4.0; | |
97 | ||
98 | SpeedLimiter limiter; | |
99 | limiter.SetMinAcceleration(minAcc); | |
100 | limiter.SetMaxAcceleration(maxAcc); | |
101 | ||
102 | EXPECT_DOUBLE_EQ(minAcc, limiter.MinAcceleration()); | |
103 | EXPECT_DOUBLE_EQ(maxAcc, limiter.MaxAcceleration()); | |
104 | ||
105 | auto dt = 1s; | |
106 | const double dtSec = std::chrono::duration<double>(dt).count(); | |
107 | ||
108 | // Within bounds | |
109 | double vel{2.0}; | |
110 | double velPrev = 1.0; | |
111 | EXPECT_GT(vel - velPrev, minAcc * dtSec); | |
112 | EXPECT_LT(vel - velPrev, maxAcc * dtSec); | |
113 | ||
114 | EXPECT_DOUBLE_EQ(0.0, limiter.LimitAcceleration(vel, velPrev, dt)); | |
115 | EXPECT_DOUBLE_EQ(2.0, vel); | |
116 | ||
117 | // Above upper bound | |
118 | vel = 10.0; | |
119 | velPrev = 1.0; | |
120 | EXPECT_GT(vel - velPrev, minAcc * dtSec); | |
121 | EXPECT_GT(vel - velPrev, maxAcc * dtSec); | |
122 | ||
123 | EXPECT_DOUBLE_EQ(-5.0, limiter.LimitAcceleration(vel, velPrev, dt)); | |
124 | EXPECT_DOUBLE_EQ(5.0, vel); | |
125 | EXPECT_DOUBLE_EQ(vel - velPrev, maxAcc * dtSec); | |
126 | ||
127 | // Under lower bound | |
128 | vel = -8.0; | |
129 | velPrev = -2.0; | |
130 | EXPECT_LT(vel - velPrev, minAcc * dtSec); | |
131 | EXPECT_LT(vel - velPrev, maxAcc * dtSec); | |
132 | ||
133 | EXPECT_DOUBLE_EQ(4.0, limiter.LimitAcceleration(vel, velPrev, dt)); | |
134 | EXPECT_DOUBLE_EQ(-4.0, vel); | |
135 | EXPECT_DOUBLE_EQ(vel - velPrev, minAcc * dtSec); | |
136 | } | |
137 | ||
138 | ///////////////////////////////////////////////// | |
139 | TEST(SpeedLimiterTest, LimitJerk) | |
140 | { | |
141 | double minJerk = -1.0; | |
142 | double maxJerk = 1.0; | |
143 | ||
144 | SpeedLimiter limiter; | |
145 | limiter.SetMinJerk(minJerk); | |
146 | limiter.SetMaxJerk(maxJerk); | |
147 | ||
148 | EXPECT_DOUBLE_EQ(minJerk, limiter.MinJerk()); | |
149 | EXPECT_DOUBLE_EQ(maxJerk, limiter.MaxJerk()); | |
150 | ||
151 | auto dt = 1s; | |
152 | const double dtSec = std::chrono::duration<double>(dt).count(); | |
153 | ||
154 | // Within bounds | |
155 | double vel{2.0}; | |
156 | double velPrev = 1.0; | |
157 | double velPrevPrev = 0.5; | |
158 | double acc = (vel - velPrev) / dtSec; | |
159 | double accPrev = (velPrev - velPrevPrev) / dtSec; | |
160 | EXPECT_GT(acc - accPrev, minJerk * dtSec); | |
161 | EXPECT_LT(acc - accPrev, maxJerk * dtSec); | |
162 | ||
163 | EXPECT_DOUBLE_EQ(0.0, limiter.LimitJerk(vel, velPrev, velPrevPrev, dt)); | |
164 | EXPECT_DOUBLE_EQ(2.0, vel); | |
165 | ||
166 | // Above upper bound (desired: accel 4.0, jerk 3.0) | |
167 | vel = 6.0; | |
168 | velPrev = 2.0; | |
169 | velPrevPrev = 1.0; | |
170 | acc = (vel - velPrev) / dtSec; | |
171 | accPrev = (velPrev - velPrevPrev) / dtSec; | |
172 | EXPECT_GT(acc - accPrev, minJerk * dtSec); | |
173 | EXPECT_GT(acc - accPrev, maxJerk * dtSec); | |
174 | ||
175 | EXPECT_DOUBLE_EQ(-2.0, limiter.LimitJerk(vel, velPrev, velPrevPrev, dt)); | |
176 | EXPECT_DOUBLE_EQ(4.0, vel); | |
177 | acc = (vel - velPrev) / dtSec; | |
178 | EXPECT_DOUBLE_EQ(acc - accPrev, maxJerk * dtSec); | |
179 | ||
180 | // Under lower bound | |
181 | vel = -6.0; | |
182 | velPrev = -2.0; | |
183 | velPrevPrev = -1.0; | |
184 | acc = (vel - velPrev) / dtSec; | |
185 | accPrev = (velPrev - velPrevPrev) / dtSec; | |
186 | EXPECT_LT(acc - accPrev, minJerk * dtSec); | |
187 | EXPECT_LT(acc - accPrev, maxJerk * dtSec); | |
188 | ||
189 | EXPECT_DOUBLE_EQ(2.0, limiter.LimitJerk(vel, velPrev, velPrevPrev, dt)); | |
190 | EXPECT_DOUBLE_EQ(-4.0, vel); | |
191 | ||
192 | acc = vel - velPrev; | |
193 | EXPECT_DOUBLE_EQ(acc - accPrev, minJerk * dtSec); | |
194 | } | |
195 | ||
196 | ///////////////////////////////////////////////// | |
197 | TEST(SpeedLimiterTest, LimitAll) | |
198 | { | |
199 | double minVel = -4.0; | |
200 | double maxVel = 4.0; | |
201 | double minAcc = -2.0; | |
202 | double maxAcc = 2.0; | |
203 | double minJerk = -1.0; | |
204 | double maxJerk = 1.0; | |
205 | ||
206 | SpeedLimiter limiter; | |
207 | limiter.SetMinVelocity(minVel); | |
208 | limiter.SetMaxVelocity(maxVel); | |
209 | limiter.SetMinAcceleration(minAcc); | |
210 | limiter.SetMaxAcceleration(maxAcc); | |
211 | limiter.SetMinJerk(minJerk); | |
212 | limiter.SetMaxJerk(maxJerk); | |
213 | ||
214 | EXPECT_DOUBLE_EQ(minVel, limiter.MinVelocity()); | |
215 | EXPECT_DOUBLE_EQ(maxVel, limiter.MaxVelocity()); | |
216 | EXPECT_DOUBLE_EQ(minAcc, limiter.MinAcceleration()); | |
217 | EXPECT_DOUBLE_EQ(maxAcc, limiter.MaxAcceleration()); | |
218 | EXPECT_DOUBLE_EQ(minJerk, limiter.MinJerk()); | |
219 | EXPECT_DOUBLE_EQ(maxJerk, limiter.MaxJerk()); | |
220 | ||
221 | auto dt = 1s; | |
222 | ||
223 | // Within bounds | |
224 | double vel{2.0}; | |
225 | double velPrev = 1.0; | |
226 | double velPrevPrev = 0.5; | |
227 | EXPECT_DOUBLE_EQ(0.0, limiter.Limit(vel, velPrev, velPrevPrev, dt)); | |
228 | EXPECT_DOUBLE_EQ(2.0, vel); | |
229 | ||
230 | // Above upper velocity bound | |
231 | vel = 5.0; | |
232 | velPrev = 2.0; | |
233 | velPrevPrev = 1.0; | |
234 | EXPECT_DOUBLE_EQ(-1.0, limiter.Limit(vel, velPrev, velPrevPrev, dt)); | |
235 | EXPECT_DOUBLE_EQ(4.0, vel); | |
236 | ||
237 | // Above upper acceleration bound (desired accel: 3.0) | |
238 | vel = 4.0; | |
239 | velPrev = 1.0; | |
240 | velPrevPrev = 0.0; | |
241 | EXPECT_DOUBLE_EQ(-1.0, limiter.Limit(vel, velPrev, velPrevPrev, dt)); | |
242 | EXPECT_DOUBLE_EQ(3.0, vel); | |
243 | ||
244 | // Above upper jerk bound (desired jerk: 1.5, accel: 1.8) | |
245 | vel = 2.1; | |
246 | velPrev = 0.3; | |
247 | velPrevPrev = 0.0; | |
248 | EXPECT_DOUBLE_EQ(-0.5, limiter.Limit(vel, velPrev, velPrevPrev, dt)); | |
249 | EXPECT_DOUBLE_EQ(1.6, vel); | |
250 | ||
251 | // No change in zero time | |
252 | dt = 0s; | |
253 | vel = 2.1; | |
254 | ||
255 | EXPECT_DOUBLE_EQ(0.0, limiter.Limit(vel, velPrev, velPrevPrev, dt)); | |
256 | EXPECT_DOUBLE_EQ(2.1, vel); | |
257 | } |
33 | 33 | |
34 | 34 | |
35 | 35 | // Helper functions copied from |
36 | // https://github.com/ignitionrobotics/ign-common/raw/master/src/Filesystem_TEST.cc | |
36 | // https://github.com/ignitionrobotics/ign-common/raw/ign-common3/src/Filesystem_TEST.cc | |
37 | 37 | |
38 | 38 | #ifndef _WIN32 |
39 | 39 | #include <dirent.h> // NOLINT(build/include_order) |
1 | 1 | |
2 | 2 | Next Tutorial: \ref cppgetstarted |
3 | 3 | |
4 | # Overview | |
5 | ||
6 | This tutorial describes how to install Ignition Math on Linux, Mac OS X and | |
7 | Windows via either a binary distribution or from source. | |
8 | ||
9 | [Install](#install) | |
10 | ||
11 | * [Binary Install](#binary-install) | |
12 | ||
13 | * [Source Install](#source-install) | |
14 | ||
15 | * [Prerequisites](#prerequisites) | |
16 | ||
17 | * [Building from Source](#building-from-source) | |
18 | ||
19 | # Install | |
20 | ||
21 | We recommend following the [Binary Install](#binary-install) instructions to get up and running as quickly and painlessly as possible. | |
22 | ||
23 | The [Source Install](#source-install) instructions should be used if you need the very latest software improvements, you need to modify the code, or you plan to make a contribution. | |
24 | ||
25 | ## Binary Install | |
26 | ||
27 | ### Ubuntu Linux | |
4 | These instructions are for installing only Ignition Math. | |
5 | If you're interested in using all the Ignition libraries, check out this [Ignition installation](https://ignitionrobotics.org/docs/latest/install). | |
6 | ||
7 | We recommend following the Binary Installation instructions to get up and running as quickly and painlessly as possible. | |
8 | ||
9 | The Source Installation instructions should be used if you need the very latest software improvements, you need to modify the code, or you plan to make a contribution. | |
10 | ||
11 | # Binary Installation | |
12 | ||
13 | ## Ubuntu Linux | |
28 | 14 | |
29 | 15 | Setup your computer to accept software from |
30 | 16 | *packages.osrfoundation.org*: |
31 | ||
32 | ```{.sh} | |
17 | ``` | |
33 | 18 | sudo sh -c 'echo "deb http://packages.osrfoundation.org/gazebo/ubuntu-stable `lsb_release -cs` main" > /etc/apt/sources.list.d/gazebo-stable.list' |
34 | 19 | ``` |
35 | 20 | |
36 | 21 | Setup keys: |
37 | ||
38 | ```{.sh} | |
22 | ``` | |
39 | 23 | wget http://packages.osrfoundation.org/gazebo.key -O - | sudo apt-key add - |
40 | 24 | ``` |
41 | 25 | |
42 | 26 | Install Ignition Math: |
43 | ||
44 | 27 | ``` |
45 | 28 | sudo apt install libignition-math<#>-dev |
46 | 29 | ``` |
48 | 31 | Be sure to replace `<#>` with a number value, such as 1 or 2, depending on |
49 | 32 | which version you need. |
50 | 33 | |
51 | ## Source Install | |
52 | ||
53 | Source installation can be performed in UNIX systems by first installing the | |
54 | necessary prerequisites followed by building from source. | |
55 | ||
56 | ### Prerequisites | |
34 | ## Windows | |
35 | ||
36 | Install [Conda package management system](https://docs.conda.io/projects/conda/en/latest/user-guide/install/download.html). | |
37 | Miniconda suffices. | |
38 | ||
39 | Create if necessary, and activate a Conda environment: | |
40 | ``` | |
41 | conda create -n ign-ws | |
42 | conda activate ign-ws | |
43 | ``` | |
44 | ||
45 | Install: | |
46 | ``` | |
47 | conda install libignition-math<#> --channel conda-forge | |
48 | ``` | |
49 | ||
50 | Be sure to replace `<#>` with a number value, such as 1 or 2, depending on | |
51 | which version you need. | |
52 | ||
53 | # Source Installation | |
54 | ||
55 | Source installation can be performed by first installing the necessary | |
56 | prerequisites followed by building from source. | |
57 | ||
58 | ## Prerequisites | |
59 | ||
60 | Ignition Math requires: | |
61 | ||
62 | * [Ignition CMake](https://ignitionrobotics.org/libs/cmake) | |
63 | ||
64 | ### Ubuntu Linux | |
57 | 65 | |
58 | 66 | The optional Eigen component of Ignition Math requires: |
59 | 67 | |
60 | * [Eigen](http://eigen.tuxfamily.org/index.php?title=Main_Page). Refer to the [Eigen Documentation](http://eigen.tuxfamily.org/index.php?title=Main_Page#Documentation) for installation instructions. On Ubuntu systems, `apt-get` can be used to install Eigen: | |
61 | ||
62 | ``` | |
63 | sudo apt-get install libeigen3-dev | |
64 | ``` | |
68 | * [Eigen](http://eigen.tuxfamily.org/index.php?title=Main_Page). Refer to the [Eigen Documentation](http://eigen.tuxfamily.org/index.php?title=Main_Page#Documentation) for installation instructions. On Ubuntu systems, `apt-get` can be used to install Eigen: | |
69 | ``` | |
70 | sudo apt-get install libeigen3-dev | |
71 | ``` | |
65 | 72 | |
66 | 73 | The optional Ruby tests of Ignition Math require: |
67 | 74 | |
68 | * [Ruby](https://www.ruby-lang.org/). Refer to the [Ruby Documentation](https://www.ruby-lang.org/downloads/) for installation instructions. On Ubuntu systems `apt-get` can be used to install Ubuntu Package `ruby-dev`: | |
69 | ||
70 | ``` | |
71 | sudo apt-get install ruby-dev | |
72 | ``` | |
73 | ||
74 | * [Swig](http://www.swig.org/). Refer to the [Swig Documentation](http://www.swig.org/download.html) for installation instructions. On Ubuntu systems `apt-get` can be used to install Swig: | |
75 | ||
76 | ``` | |
77 | sudo apt-get install swig | |
78 | ``` | |
79 | ||
80 | ### Building from source | |
75 | * [Ruby](https://www.ruby-lang.org/). Refer to the [Ruby Documentation](https://www.ruby-lang.org/downloads/) for installation instructions. On Ubuntu systems `apt-get` can be used to install Ubuntu Package `ruby-dev`: | |
76 | ``` | |
77 | sudo apt-get install ruby-dev | |
78 | ``` | |
79 | ||
80 | * [Swig](http://www.swig.org/). Refer to the [Swig Documentation](http://www.swig.org/download.html) for installation instructions. On Ubuntu systems `apt-get` can be used to install Swig: | |
81 | ``` | |
82 | sudo apt-get install swig | |
83 | ``` | |
84 | ||
85 | ### Windows 10 | |
86 | ||
87 | First, follow the [ign-cmake](https://github.com/ignitionrobotics/ign-cmake) tutorial for installing Conda, Visual Studio, CMake, and other prerequisites, and also for creating a Conda environment. | |
88 | ||
89 | The optional Eigen component of Ignition Math requires: | |
90 | ||
91 | * [Eigen](http://eigen.tuxfamily.org/index.php?title=Main_Page). Refer to the [Eigen Documentation](http://eigen.tuxfamily.org/index.php?title=Main_Page#Documentation) for installation instructions. On Windows, we will use `conda` to install Eigen: | |
92 | ``` | |
93 | conda install eigen --channel conda-forge | |
94 | ``` | |
95 | ||
96 | ## Building from Source | |
97 | ||
98 | ### Ubuntu | |
81 | 99 | |
82 | 100 | 1. Clone the repository |
83 | ||
84 | ``` | |
85 | git clone https://github.com/ignitionrobotics/ign-math -b ign-math<#> | |
86 | ``` | |
87 | Be sure to replace `<#>` with a number value, such as 1 or 2, depending on | |
88 | which version you need. | |
101 | ``` | |
102 | git clone https://github.com/ignitionrobotics/ign-math -b ign-math<#> | |
103 | ``` | |
104 | Be sure to replace `<#>` with a number value, such as 1 or 2, depending on | |
105 | which version you need. | |
89 | 106 | |
90 | 107 | 2. Install dependencies |
91 | ||
92 | ``` | |
93 | export SYSTEM_VERSION=bionic | |
94 | sudo apt -y install \ | |
95 | $(sort -u $(find . -iname 'packages-'$SYSTEM_VERSION'.apt' -o -iname 'packages.apt') | tr '\n' ' ') | |
96 | ``` | |
108 | ``` | |
109 | export SYSTEM_VERSION=bionic | |
110 | sudo apt -y install \ | |
111 | $(sort -u $(find . -iname 'packages-'$SYSTEM_VERSION'.apt' -o -iname 'packages.apt') | tr '\n' ' ') | |
112 | ``` | |
97 | 113 | |
98 | 114 | 3. Configure and build |
99 | ||
100 | ``` | |
101 | cd ign-math; mkdir build; cd build; cmake ..; make | |
102 | ``` | |
103 | ||
104 | 4. Optionally, install Ignition Math | |
105 | ||
106 | ``` | |
107 | sudo make install | |
108 | ``` | |
115 | ``` | |
116 | cd ign-math | |
117 | mkdir build | |
118 | cd build | |
119 | cmake .. | |
120 | make | |
121 | ``` | |
122 | ||
123 | 4. Optionally, install | |
124 | ``` | |
125 | sudo make install | |
126 | ``` | |
127 | ||
128 | ### Windows | |
129 | ||
130 | 1. Navigate to `condabin` if necessary to use the `conda` command (i.e., if Conda is not in your `PATH` environment variable. You can find the location of `condabin` in Anaconda Prompt, `where conda`). | |
131 | Activate the Conda environment created in the prerequisites: | |
132 | ``` | |
133 | conda activate ign-ws | |
134 | ``` | |
135 | ||
136 | 2. Install dependencies | |
137 | ||
138 | You can view available versions and their dependencies: | |
139 | ``` | |
140 | conda search libignition-math* --channel conda-forge --info | |
141 | ``` | |
142 | See the [Conda release repository](https://github.com/conda-forge/libignition-math4-feedstock) for more information. | |
143 | ||
144 | Install dependencies, replacing `<#>` with the desired version: | |
145 | ``` | |
146 | conda install libignition-cmake<#> --channel conda-forge | |
147 | ``` | |
148 | ||
149 | 3. Navigate to where you would like to build the library, and clone the repository. | |
150 | ``` | |
151 | # Optionally, append `-b ign-math#` (replace # with a number) to check out a specific version | |
152 | git clone https://github.com/ignitionrobotics/ign-math.git | |
153 | ``` | |
154 | ||
155 | 4. Configure and build | |
156 | ``` | |
157 | cd ign-math | |
158 | mkdir build | |
159 | cd build | |
160 | cmake .. -DBUILD_TESTING=OFF # Optionally, -DCMAKE_INSTALL_PREFIX=path\to\install | |
161 | cmake --build . --config Release | |
162 | ``` | |
163 | ||
164 | 5. Optionally, install | |
165 | ``` | |
166 | cmake --install . --config Release | |
167 | ``` | |
168 | ||
169 | # Documentation | |
170 | ||
171 | API and tutorials can be found at [https://ignitionrobotics.org/libs/math](https://ignitionrobotics.org/libs/math). | |
172 | ||
173 | You can also generate the documentation from a clone of this repository by following these steps. | |
174 | ||
175 | 1. You will need Doxygen. On Ubuntu Doxygen can be installed using | |
176 | ``` | |
177 | sudo apt-get install doxygen | |
178 | ``` | |
179 | ||
180 | 2. Clone the repository | |
181 | ``` | |
182 | git clone https://github.com/ignitionrobotics/ign-math | |
183 | ``` | |
184 | ||
185 | 3. Configure and build the documentation. | |
186 | ``` | |
187 | cd ign-math; mkdir build; cd build; cmake ../; make doc | |
188 | ``` | |
189 | ||
190 | 4. View the documentation by running the following command from the build directory. | |
191 | ``` | |
192 | firefox doxygen/html/index.html | |
193 | ``` | |
194 | ||
195 | # Testing | |
196 | ||
197 | Follow these steps to run tests and static code analysis in your clone of this repository. | |
198 | ||
199 | 1. Follow the [source install instruction](https://ignitionrobotics.org/libs/math#source-install). | |
200 | ||
201 | 2. Run tests. | |
202 | ``` | |
203 | make test | |
204 | ``` | |
205 | ||
206 | 3. Static code checker. | |
207 | ``` | |
208 | make codecheck | |
209 | ``` | |
210 | ||
211 | ## Ruby Tests | |
212 | ||
213 | ### Usage | |
214 | ||
215 | The C++ classes are available in Ruby code by interface files (`.i`) used by swig to build a C++ extension module. | |
216 | ||
217 | The interfaces and Ruby test codes are in the `src` folder. To use a C++ class in Ruby you need to: | |
218 | ||
219 | 1. Create an interface file describing the class as in Swig and Ruby reference at [The Ruby-to-C/C++ Mapping](http://www.swig.org/D oc1.3/Ruby.html#Ruby_nn11) | |
220 | ||
221 | 2. Include the interface file in `/src/ing_math.i` | |
222 | ||
223 | 3. Create the Ruby file and import the class as in Swig and Ruby reference at [C++ Classes](http://www.swig.org/Doc1.3/Ruby.html#Ruby_nn18) | |
224 | ||
225 | ### Tests | |
226 | ||
227 | `make test` already runs all tests, including the ones made in Ruby, but you can run a Ruby test individually using | |
228 | ``` | |
229 | ctest -R Ruby_TEST.rb | |
230 | ``` | |
231 |