├── Kernel Selection
├── README.md
└── docs
│ ├── allkernels.jpg
│ └── ours.jpg
├── LICENSE
├── README.md
├── VIO Analysis
├── README.md
└── docs
│ ├── scenario1.PNG
│ ├── scenario2.PNG
│ ├── scenario3.PNG
│ ├── scenario4.PNG
│ ├── scenario5.PNG
│ └── scene1.PNG
├── core_navigation
├── CMakeLists.txt
├── config
│ ├── custom_rosconsole.conf
│ ├── init_params.yaml
│ └── parameters.yaml
├── include
│ └── core_navigation
│ │ ├── CoreNav.h
│ │ ├── InsConst.h
│ │ └── InsUtils.h
├── launch
│ └── corenav.launch
├── msg
│ ├── GP_Input.msg
│ └── GP_Output.msg
├── package.xml
├── script
│ ├── gp_slip_node.py
│ ├── run_cn_frombag.sh
│ ├── slipVal.csv
│ └── utils
│ │ ├── __init__.py
│ │ ├── __init__.pyc
│ │ ├── __pycache__
│ │ ├── __init__.cpython-35.pyc
│ │ ├── __init__.cpython-37.pyc
│ │ ├── data.cpython-35.pyc
│ │ └── data.cpython-37.pyc
│ │ ├── data.py
│ │ ├── data.pyc
│ │ ├── plot.py
│ │ └── utils.py
├── src
│ ├── CoreNav.cpp
│ ├── InsUtils.cpp
│ └── core_nav.cpp
└── srv
│ └── SetStopping.srv
├── docs
├── corenav7.gif
├── framework.png
└── readme.md
├── geometry_utils
├── CMakeLists.txt
├── LICENSE
├── cmake
│ └── FindEigen3.cmake
├── include
│ └── geometry_utils
│ │ ├── GeometryUtils.h
│ │ ├── GeometryUtilsMath.h
│ │ ├── GeometryUtilsROS.h
│ │ ├── GeometryUtilsSerialization.h
│ │ ├── Matrix2x2.h
│ │ ├── Matrix3x3.h
│ │ ├── Matrix4x4.h
│ │ ├── MatrixNxMBase.h
│ │ ├── MatrixNxNBase.h
│ │ ├── Quaternion.h
│ │ ├── Rotation2.h
│ │ ├── Rotation3.h
│ │ ├── RotationNBase.h
│ │ ├── Transform2.h
│ │ ├── Transform3.h
│ │ ├── Vector2.h
│ │ ├── Vector3.h
│ │ ├── Vector4.h
│ │ ├── VectorNBase.h
│ │ └── YAMLLoader.h
├── package.xml
└── tests
│ ├── test_base.cc
│ ├── test_equals.cc
│ ├── test_math.cc
│ └── test_so3error.cc
├── gp_predictor
├── CMakeLists.txt
├── include
│ └── gp_predictor
│ │ └── gp_predictor.h
├── launch
│ └── gp_predictor.launch
├── package.xml
└── src
│ └── gp_predictor.cpp
├── gps_core_navigation
├── CMakeLists.txt
├── config
│ ├── init_params.yaml
│ └── parameters.yaml
├── include
│ └── gps_core_navigation
│ │ ├── InsConst.h
│ │ ├── InsUtils.h
│ │ └── gps_CoreNav.h
├── launch
│ └── gps_corenav.launch
├── msg
│ ├── GP_Input.msg
│ └── GP_Output.msg
├── package.xml
└── src
│ ├── InsUtils.cpp
│ ├── gps_CoreNav.cpp
│ └── gps_core_nav.cpp
├── gps_data_log
├── CMakeLists.txt
├── package.xml
└── scripts
│ └── gps_log_node.py
├── hw_interface
├── CMakeLists.txt
├── include
│ └── hw_interface
│ │ ├── base_UDP_interface.hpp
│ │ ├── base_interface.hpp
│ │ ├── base_serial_interface.hpp
│ │ ├── bit_utils.h
│ │ ├── hw_interface.hpp
│ │ ├── shared_const_buffer.hpp
│ │ └── telemetry.hpp
├── launch
│ ├── hw_interface.launch
│ ├── hw_interface_debug.launch
│ └── hw_interface_plugins.launch
├── package.xml
└── src
│ ├── base_UDP_interface.cpp
│ ├── base_interface.cpp
│ ├── base_serial_interface.cpp
│ ├── hw_interface.cpp
│ └── hw_interface_node.cpp
├── hw_interface_plugins
├── hw_interface_plugin_adis_imu
│ ├── CMakeLists.txt
│ ├── adis_imu_plugin.xml
│ ├── include
│ │ └── hw_interface_plugin_adis_imu
│ │ │ └── hw_interface_plugin_adis_imu_serial.hpp
│ ├── launch
│ │ ├── Adis_Imu_Serial_Interface.launch
│ │ └── launch_params
│ │ │ └── Adis_Imu_Serial_launch_params.yaml
│ ├── package.xml
│ ├── readme.md
│ └── src
│ │ └── hw_interface_plugin_adis_imu_serial.cpp
└── hw_interface_plugin_roboteq
│ ├── CMakeLists.txt
│ ├── include
│ └── hw_interface_plugin_roboteq
│ │ ├── hw_interface_plugin_roboteq.hpp
│ │ ├── hw_interface_plugin_roboteq_brushed.hpp
│ │ └── hw_interface_plugin_roboteq_brushless.hpp
│ ├── launch
│ ├── Left_Roboteq_Interface.launch
│ ├── Right_Roboteq_Interface.launch
│ └── launch_params
│ │ ├── Left_Roboteq_launch_params.yaml
│ │ └── Right_Roboteq_launch_params.yaml
│ ├── msg
│ ├── ActuatorOut.msg
│ └── RoboteqData.msg
│ ├── package.xml
│ ├── roboteq_plugins.xml
│ └── src
│ ├── hw_interface_plugin_roboteq.cpp
│ ├── hw_interface_plugin_roboteq_brushed.cpp
│ └── hw_interface_plugin_roboteq_brushless.cpp
├── imu_filter
├── CMakeLists.txt
├── README.md
├── launch
│ └── imu_filter.launch
├── package.xml
└── src
│ └── imu_filter.cpp
├── init_core_navigation
├── CMakeLists.txt
├── config
│ └── parameters.yaml
├── include
│ └── init_core_navigation
│ │ └── InitCoreNav.h
├── launch
│ └── init_corenav.launch
├── package.xml
└── src
│ ├── InitCoreNav.cpp
│ ├── initDev.txt
│ └── init_core_nav.cpp
├── novatel_launch
├── CMakeLists.txt
├── launch
│ └── novatel.launch
└── package.xml
├── parameter_utils
├── CMakeLists.txt
├── LICENSE
├── include
│ └── parameter_utils
│ │ └── ParameterUtils.h
└── package.xml
└── pathfinder_control
├── CMakeLists.txt
├── config
├── pathfinder_simple_sim_control.yaml
├── teleop.yaml
└── twist_mux.yaml
├── launch
├── control.launch
├── control_sim.launch
├── drive_stop.launch
└── teleop.launch
├── package.xml
└── src
├── drive_straight_with_stop.cpp
├── pathfinder_control_node.cpp
├── pathfinder_sim_control_node.cpp
└── pathfinder_sim_localization_node.cpp
/Kernel Selection/README.md:
--------------------------------------------------------------------------------
1 | ## Overview
2 |
3 | **Author: Cagri Kilic
4 | Affiliation: [WVU NAVLAB](https://navigationlab.wvu.edu/)
5 | Maintainer: Cagri Kilic, cakilic@mix.wvu.edu**
6 |
7 | Supplementary Kernel Function Selection analyses for the Slip-Based Autonomous ZUPT through Gaussian Process to Improve Planetary Rover Proprioceptive Localization paper.
8 |
9 | The Kernel Functions are used from GPy Gaussian Process (GP) framework https://sheffieldml.github.io/GPy/ and scikit-learn https://scikit-learn.org/ libraries
10 |
11 | The first figure shows the kernel function(s) representation against the same slip data. The aim is heuristically find the best representation of the slip prediction over time. We assumed that slip could happen in two ways. 1) Randomly due to traversing over a rock, entering a pothole, or small local terrain imperfections, 2) continuously due to the mechanical properties of deformable terrains. These two slip behaviors can be represented as spikes for random slips and slowly increasing slip due to continuous slippage.
12 |
13 | ## Kernel Functions
14 |
15 |
16 |
17 |
18 | After careful consideration through mathematical expressions of the kernels, field tests, and simulation analyses, we have selected two kernel functions: Brownian Kernel to model random, high impulsive slippage, and Radial Basis Function Kernel to model continuous similar slip values. Then we have built the composite kernel model to capture both slippage behaviors during traversal as shown in second figure.
19 |
20 | ## Selected Composite Kernel (RBF * Brownian)
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/Kernel Selection/docs/allkernels.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wvu-navLab/corenav-GP/db4c04fb1d0c9a7222cec29800dd3a838ab9903e/Kernel Selection/docs/allkernels.jpg
--------------------------------------------------------------------------------
/Kernel Selection/docs/ours.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wvu-navLab/corenav-GP/db4c04fb1d0c9a7222cec29800dd3a838ab9903e/Kernel Selection/docs/ours.jpg
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Cagri Kilic
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ## Overview
7 |
8 | **Author: Cagri Kilic
9 | Affiliation: [WVU NAVLAB](https://navigationlab.wvu.edu/)
10 | Maintainer: Cagri Kilic, cakilic@mix.wvu.edu**
11 |
12 | Slip-Based Autonomous ZUPT through Gaussian Process to Improve Planetary Rover Localization
13 |
14 | ## Architecture
15 |
16 |
17 |
18 |
19 | **Keywords:** Mars Sample Return, planetary rovers, time series prediction, slip, zero velocity update, rover localization
20 |
21 |
22 | ## Citation
23 |
24 | If you find this library useful, please cite the following publication:
25 |
26 | **[1]** Cagri Kilic, Nicholas Ohi, Yu Gu, Jason N. Gross: **Slip-Based Autonomous ZUPT through Gaussian Process to Improve Planetary Rover Localization**. IEEE Robotics and Automation Letters (RA-L), 2021. https://doi.org/10.1109/LRA.2021.3068893
27 |
28 | @article{Kilic2021,
29 | author={Kilic, Cagri and Ohi, Nicholas and and Gu, Yu and Gross, Jason N},
30 | journal={IEEE Robotics and Automation Letters},
31 | title={Slip-Based Autonomous ZUPT through Gaussian Process to Improve Planetary Rover Localization},
32 | year={2021},
33 | volume={6},
34 | number={3},
35 | pages={4782-4789},
36 | doi={10.1109/LRA.2021.3068893}
37 | }
38 |
39 |
40 | **[2]** Cagri Kilic and Jason Gross: **Pathfinder GPS, IMU, and Wheel Odometry Data on Various Terrains**, IEEE Dataport, November 23, 2020, doi: https://dx.doi.org/10.21227/vz7z-jc84.
41 |
42 | @data{Kilic2020Pathfinder,
43 | doi = {10.21227/vz7z-jc84},
44 | url = {https://dx.doi.org/10.21227/vz7z-jc84},
45 | author = {Cagri Kilic; Jason Gross },
46 | publisher = {IEEE Dataport},
47 | title = {Pathfinder GPS, IMU, and Wheel Odometry Data on Various Terrains},
48 | year = {2020} }
49 |
50 | }
51 |
52 | **[3]** Cagri Kilic, Jason N. Gross, Nicholas Ohi, Ryan Watson, Jared Strader, Thomas Swiger, Scott Harper, and Yu Gu: **Improved Planetary Rover Inertial Navigation and Wheel Odometry Performance through Periodic Use of Zero-Type Constraints**. IEEE/RSJ International Conference on Intelligent Robots and Systems (IROS), 2019. https://doi.org/10.1109/IROS40897.2019.8967634
53 |
54 | @inproceedings{Kilic2019,
55 | author = {Kilic, Cagri and Gross, Jason N. and Ohi, Nicholas and Watson, Ryan and Strader, Jared and Swiger, Thomas and Harper, Scott and Gu, Yu},
56 | booktitle = {2019 IEEE/RSJ International Conference on Intelligent Robots and Systems (IROS)},
57 | title = {{Improved Planetary Rover Inertial Navigation and Wheel Odometry Performance through Periodic Use of Zero-Type Constraints}},
58 | year = {2019},
59 | pages={552-559},
60 | doi={10.1109/IROS40897.2019.8967634},
61 | ISSN={2153-0858},
62 | publisher = {IEEE},
63 |
64 | }
65 |
--------------------------------------------------------------------------------
/VIO Analysis/README.md:
--------------------------------------------------------------------------------
1 | ## Overview
2 |
3 | **Author: Cagri Kilic
4 | Affiliation: [WVU NAVLAB](https://navigationlab.wvu.edu/)
5 | Maintainer: Cagri Kilic, cakilic@mix.wvu.edu**
6 |
7 | Supplementary Visual-Inertial Odometry (VIO) Analyses in low-feature environment for the Slip-Based Autonomous ZUPT through Gaussian Process to Improve Planetary Rover Proprioceptive Localization paper.
8 |
9 | The VIO solution is generated using ROS Wrapper for Intel® RealSense™ Devices https://github.com/IntelRealSense/realsense-ros
10 |
11 | Each figure provides a DGPS solution, filter estimation (corenav-GP solution), 2D Dead Reckoning (only WO and IMU heading). The Google Map representation of the ground truth (DGPS) solution is provided to visualize the low-feature environment (Point Marion, PA, Ashpiles Mars Analog Environment). Solution accuracy values are given for the corenav-GP implementation.
12 |
13 | ### Scenario 1, Execution 1
14 |
15 |
16 |
17 |
18 | *VIO failed after traversing 124m
19 |
20 | ### Scenario 1, Execution 2
21 |
22 |
23 |
24 |
25 |
26 | ### Scenario 1, Execution 3
27 |
28 |
29 |
30 |
31 | ### Scenario 1 Analysis
32 |
33 |
34 |
35 |
36 |
37 | The median values (out of 3 execution) of RMSE for CoreNav-GP are E=1.03m, N=0.49m, U=0.65m
38 |
39 | The median values (out of 3 execution) of RMSE for VIO are E=2.70m, N=12.22*, U=2.12m
40 |
41 | In Execution 1, there is only 124m out of 150m traversed solution for VIO. After 124m, VIO failed and outputs NaN values. For this reason, the star (*) values show the accuracy until 124 m.
42 |
43 |
44 | ### Additional Scenario 1
45 |
46 |
47 |
48 |
49 | The values of RMSE for CoreNav-GP are E=0.66m, N=0.40m, U=2.89m
50 |
51 | The values of RMSE for VIO are E=13.27m, N=56.62m, U=2.12m
52 |
53 | ### Additional Scenario 2
54 |
55 |
56 |
57 |
58 | The values of RMSE for CoreNav-GP are E=1.23m, N=2.51m, U=1.97m
59 |
60 | The values of RMSE for VIO are E=44.04m, N=27.24m, U=0.42m
61 |
62 |
63 |
--------------------------------------------------------------------------------
/VIO Analysis/docs/scenario1.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wvu-navLab/corenav-GP/db4c04fb1d0c9a7222cec29800dd3a838ab9903e/VIO Analysis/docs/scenario1.PNG
--------------------------------------------------------------------------------
/VIO Analysis/docs/scenario2.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wvu-navLab/corenav-GP/db4c04fb1d0c9a7222cec29800dd3a838ab9903e/VIO Analysis/docs/scenario2.PNG
--------------------------------------------------------------------------------
/VIO Analysis/docs/scenario3.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wvu-navLab/corenav-GP/db4c04fb1d0c9a7222cec29800dd3a838ab9903e/VIO Analysis/docs/scenario3.PNG
--------------------------------------------------------------------------------
/VIO Analysis/docs/scenario4.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wvu-navLab/corenav-GP/db4c04fb1d0c9a7222cec29800dd3a838ab9903e/VIO Analysis/docs/scenario4.PNG
--------------------------------------------------------------------------------
/VIO Analysis/docs/scenario5.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wvu-navLab/corenav-GP/db4c04fb1d0c9a7222cec29800dd3a838ab9903e/VIO Analysis/docs/scenario5.PNG
--------------------------------------------------------------------------------
/VIO Analysis/docs/scene1.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wvu-navLab/corenav-GP/db4c04fb1d0c9a7222cec29800dd3a838ab9903e/VIO Analysis/docs/scene1.PNG
--------------------------------------------------------------------------------
/core_navigation/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 2.8.3)
2 | project(core_nav)
3 |
4 | set (CMAKE_CXX_STANDARD 11)
5 |
6 |
7 | find_package(catkin REQUIRED COMPONENTS
8 | hw_interface_plugin_roboteq
9 | roscpp
10 | geometry_utils
11 | parameter_utils
12 | geometry_msgs
13 | sensor_msgs
14 | tf2_ros
15 | tf
16 | std_msgs
17 | message_generation
18 | )
19 |
20 | add_message_files(
21 | FILES
22 | GP_Input.msg
23 | GP_Output.msg
24 | )
25 |
26 | add_service_files(
27 | FILES
28 | SetStopping.srv
29 | )
30 |
31 |
32 | generate_messages(
33 | DEPENDENCIES
34 | std_msgs
35 | geometry_msgs
36 | )
37 |
38 | catkin_package(
39 | INCLUDE_DIRS include
40 | LIBRARIES ${PROJECT_NAME}
41 | CATKIN_DEPENDS
42 | roscpp
43 | geometry_utils
44 | parameter_utils
45 | geometry_msgs
46 | sensor_msgs
47 | tf2_ros
48 | tf
49 | )
50 |
51 | include_directories(
52 | include
53 | ${catkin_INCLUDE_DIRS}
54 | )
55 |
56 | link_directories(
57 | ${catkin_LIBRARY_DIRS}
58 | )
59 |
60 | add_library(${PROJECT_NAME} src/CoreNav.cpp)
61 | target_link_libraries(${PROJECT_NAME}
62 | ${catkin_LIBRARIES}
63 | )
64 |
65 | add_executable(${PROJECT_NAME}_node src/${PROJECT_NAME}.cpp)
66 | target_link_libraries(${PROJECT_NAME}_node
67 | ${PROJECT_NAME}
68 | ${catkin_LIBRARIES}
69 | )
70 |
--------------------------------------------------------------------------------
/core_navigation/config/custom_rosconsole.conf:
--------------------------------------------------------------------------------
1 | # config/custom_rosconsole.conf
2 | # You can define your own by e.g. copying this file and setting
3 | # ROSCONSOLE_CONFIG_FILE (in your environment) to point to the new file
4 | #
5 | log4j.logger.ros=INFO
6 | log4j.logger.ros.core_nav=DEBUG
7 | log4j.logger.ros.roscpp.superdebug=WARN
8 |
--------------------------------------------------------------------------------
/core_navigation/config/init_params.yaml:
--------------------------------------------------------------------------------
1 | mean_bias_a:
2 | x: 0.269614133542350
3 | y: -0.262166124574161
4 | z: -9.804005623794065
5 | mean_bias_g:
6 | x: 0.000268715437386711
7 | y: -0.000161452230267971
8 | z: 0.000678693501054130
9 | init_ecef:
10 | x: 859153.015300000
11 | y: -4836303.72660000
12 | z: 4055378.50100000
13 | init_llh:
14 | x: 0.693457963620326
15 | y: -1.39498384275845
16 | z: 334.993517334743
17 | init_att:
18 | x: 0.0
19 | y: 0.0
20 | z: -0.733038286
21 |
--------------------------------------------------------------------------------
/core_navigation/config/parameters.yaml:
--------------------------------------------------------------------------------
1 | init:
2 | orientation:
3 | # x: 0.0
4 | # y: 0.0
5 | # z: 0.0
6 | covx: 1.218469679146834e-06
7 | covy: 1.218469679146834e-06
8 | covz: 1.218469679146834e-06
9 | velocity:
10 | x: 0.0
11 | y: 0.0
12 | z: 0.0
13 | covx: 4.000000000000001e-07
14 | covy: 4.000000000000001e-07
15 | covz: 4.000000000000001e-07
16 | position:
17 | # x: 0.691949695095547
18 | # y: -1.395750757746275
19 | # z: 312.2643980319930
20 | covx: 0.0
21 | covy: 0.0
22 | covz: 0.0
23 | std_bias_a:
24 | x: 0.017333461987301
25 | y: 0.012647240119246
26 | z: 0.020974348023053
27 | std_bias_g:
28 | x: 0.000802891989877233
29 | y: 0.000904288959007464
30 | z: 0.000852026432825422
31 | # bias:
32 | # accel:
33 | # x: 7.549135895545244e-04
34 | # y: 0.001805886718248
35 | # z: 0.002395586011438
36 | # gyro:
37 | # x: 8.674066138832567e-05
38 | # y: 1.005391303275586e-04
39 | # z: 8.919962404601004e-05
40 | # ecef:
41 | # x: 8.565078494000000e+05
42 | # y: -4.842978088500000e+06
43 | # z: 4.047980191900000e+06
44 |
45 | imu:
46 | publish_hz: 50
47 | sensor_pub_rate: 50
48 | topic: /imu_filtered
49 | # topic: /imu/data
50 | noise:
51 | sig_gyro_inRun : 7.757018897752577e-06
52 | sig_ARW : 2.908882086657216e-05
53 | sig_accel_inRun : 3.139200000000000e-05
54 | sig_VRW : 1.333333333333333e-04
55 |
56 | odo:
57 | topic: /dead_reckoning/odometry
58 | updates:
59 | do_zupt: false
60 | do_zaru: false
61 |
62 | encoderLeft:
63 | topic: /roboteq/drivemotorin/left
64 |
65 | encoderRight:
66 | topic: /roboteq/drivemotorin/right
67 | cmd:
68 | topic: /cmd_vel_out
69 | joint:
70 | topic: /dead_reckoning/joint_states
71 | gp:
72 | topic: /core_nav/core_nav/gp_result
73 | stop:
74 | topic: /core_nav/core_nav/stop_cmd
75 |
76 | frames:
77 | frame_id_out: map
78 | frame_id_fixed: odom
79 | frame_id_imu: imu_link
80 | frame_id_odo: odom_link
81 |
82 | wheel:
83 | # T_r_: 0.125
84 | T_r_: 0.685
85 | s_or_: -0.07
86 | # s_or_: 0.0
87 | s_delta_or_: -0.6
88 | # s_delta_or_: 0.0
89 |
--------------------------------------------------------------------------------
/core_navigation/include/core_navigation/InsConst.h:
--------------------------------------------------------------------------------
1 | /**
2 | * @file InsConst.h
3 | * @brief House values that are repeatedly used
4 | * @author Cagri
5 | */
6 |
7 | #pragma once
8 |
9 | namespace INS {
10 |
11 | const double omega_ie = 7.292115e-5; // rotation of Earth in rad/sec
12 | const double Ro = 6378137.0; //WGS84 Equatorial Radius
13 | const double Rp = 6356752.31425; //WGS84 Polar Radius
14 | const double flat= 1.0/298.257223563; // WGS84 Earth flattening
15 | const double ecc = 0.0818191909425; // WGS84 Eccentricity 0.0818191908426
16 | const double t_const = pow((1.0 - flat),2.0); // constant
17 | const double wheel_radius=0.11; //meters
18 | const double wheelbase=0.555; //meters
19 | const double gravity= 9.80665;
20 | const double PI = 3.14159265358979;
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/core_navigation/include/core_navigation/InsUtils.h:
--------------------------------------------------------------------------------
1 | /**
2 | * @file InsUtils.h
3 | * @brief Tools required to process inertial data
4 | * @author Cagri, Ryan
5 | */
6 |
7 | #pragma once
8 |
9 | #include
10 | #include
11 | #include
12 |
13 | #include
14 | #include
15 | #include
16 | #include
17 | #include
18 | #include
19 |
20 | #include
21 |
22 | #include
23 |
24 | namespace INS {
25 |
26 | typedef Eigen::VectorXd Vector;
27 | typedef Eigen::MatrixXd Matrix;
28 |
29 | typedef Eigen::Matrix Vector3;
30 | typedef Eigen::Matrix Vector6;
31 | typedef Eigen::Matrix Matrix3;
32 |
33 | Vector3 calc_gravity(const double latitude, const double height);
34 |
35 | Matrix3 skew_symm(const Vector3 vec);
36 |
37 | Matrix3 eul_to_dcm(double phi, double theta, double psi);
38 |
39 | Matrix insErrorStateModel_LNF(double R_EPlus, double R_N, Vector3 insLLHPlus, Vector3 insVelPlus, double dt, Matrix3 CbnPlus, double omega_ie,Vector3 omega_n_in,Vector3 f_ib_b,double gravity);
40 |
41 | Matrix calc_Q(double R_N, double R_E, Vector3 insLLHPlus, double dt, Matrix3 CbnPlus,Vector3 f_ib_b);
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/core_navigation/launch/corenav.launch:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
10 |
11 |
12 |
13 | position: {x: 0.691949695095547, y: -1.395750757746275, z: 312.2643980319930}
14 | velocity: {vx: 0.0, vy: 0.0, vz: 0.0}
15 | orientation: {qx: 0.0, qy: 0.0, qz: 0.0, qw: 1.0}
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/core_navigation/msg/GP_Input.msg:
--------------------------------------------------------------------------------
1 | Header header
2 | float64[] time_array
3 | float64[] slip_array
4 |
--------------------------------------------------------------------------------
/core_navigation/msg/GP_Output.msg:
--------------------------------------------------------------------------------
1 | Header header
2 | float64[] mean
3 | float64[] sigma
4 |
--------------------------------------------------------------------------------
/core_navigation/package.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | core_nav
4 | 0.1.0
5 | Core Navigation
6 |
7 | Cagri Kilic
8 | Cagri Kilic
9 |
10 | GPLv2
11 |
12 | catkin
13 |
14 | roscpp
15 | geometry_utils
16 | parameter_utils
17 | geometry_msgs
18 | sensor_msgs
19 | nav_msgs
20 | tf2_ros
21 | tf
22 | hw_interface_plugin_roboteq
23 | std_msgs
24 | message_generation
25 | roscpp
26 | geometry_utils
27 | parameter_utils
28 | geometry_msgs
29 | sensor_msgs
30 | nav_msgs
31 | tf2_ros
32 | tf
33 | hw_interface_plugin_roboteq
34 | std_msgs
35 | message_runtime
36 |
37 |
--------------------------------------------------------------------------------
/core_navigation/script/gp_slip_node.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | import sys
3 | import GPy
4 | import rospy
5 | import numpy as np
6 | #from matplotlib import pyplot as plt
7 | #from utils.data import *
8 | from core_nav.msg import GP_Input
9 | from core_nav.msg import GP_Output
10 | #from IPython.display import display
11 |
12 | pub = rospy.Publisher('/core_nav/core_nav/gp_result', GP_Output, queue_size=1)
13 |
14 |
15 |
16 | def callback(data):
17 | # Do GP stuff here *********
18 | rospy.loginfo("GP Input Arrived")
19 | X = data.time_array
20 | #X = [1,2,3,4,5]
21 | X = np.array(X).reshape(len(X), 1)
22 |
23 | Y = data.slip_array
24 | #Y = [0.1,0.05,-0.009,0.1,-0.002]
25 | Y = np.array(Y).reshape(len(Y), 1)
26 |
27 | per = 0.9
28 |
29 | x_train, y_train = X[:int(per * len(X))], Y[:int(per * len(Y))]
30 | x_test, y_test = X[int(per * len(X)):], Y[int(per * len(Y)):]
31 | kernel = (GPy.kern.RBF(1)) * GPy.kern.Brownian(1)
32 | # # GPy.kern.Matern32(1), GPy.kern.Matern52(1), GPy.kern.Brownian(1),
33 | # # GPy.kern.Bias(1), GPy.kern.Linear(1), GPy.kern.PeriodicExponential(1),
34 | # # GPy.kern.White(1)]
35 | m = GPy.models.GPRegression(x_train, y_train, kernel)
36 | m.optimize(messages=False)
37 |
38 |
39 | # display(m)
40 | means = [] # predictions
41 | variances = [] # uncertainty
42 | #means2= [] #predictions
43 | #variances2 = [] #uncertainty
44 | # X_=np.arange(X.min(),X.max()+50, 0.1)
45 | X_ = np.arange(X.min(), X.max() + 600, 1)
46 |
47 | for x in X_:
48 | mean, covar = m.predict(np.array([[x]]))
49 | variances.append(covar[0])
50 | means.append(mean[0])
51 | #means2.append(mean[0])
52 | #variances2.append(covar[0])
53 |
54 | # **************************
55 |
56 | # Write output arrays into msg_out.mean and msg_out.sigma
57 | msg_out = GP_Output()
58 | # TODO: need to populate the header (i.e. msg_out.header)
59 | msg_out.mean = np.array(means[int(len(X)):]) # [0,1,3,4] # for example
60 | # [6,7,8,9] # for example
61 | msg_out.sigma = 2 * np.sqrt(np.array(variances[int(len(X)):]))
62 | rospy.loginfo("Publishing GP Results")
63 | pub.publish(msg_out)
64 |
65 | #ses = 2 * np.sqrt(np.array(variances2))
66 | #means = np.array(means2)
67 | #var1 = np.array(means + ses).reshape(1, len(means + ses))
68 | #var2 = np.array(means - ses).reshape(1, len(means - ses))
69 | # m.plot()
70 | # plt.xlim(X.min(), X_.max())
71 | # plt.plot(X, Y, c='r', linewidth=0.2)
72 | # # confidence intervals #C0C0C0
73 | # plt.fill_between(X_, var2[0, :], var1[0, :], alpha=0.3, color='k')
74 | # plt.plot(x_test, y_test, 'xk')
75 | # plt.ylim(-1.5, 1.5)
76 | # plt.show()
77 |
78 |
79 | def gaussian_process():
80 | rospy.init_node('gp_slip_node')
81 | rospy.Subscriber('/core_nav/core_nav/gp_input', GP_Input, callback)
82 | #rospy.loginfo_once("GP Mode Has Started")
83 | rospy.spin()
84 |
85 |
86 | if __name__ == '__main__':
87 | gaussian_process()
88 |
--------------------------------------------------------------------------------
/core_navigation/script/run_cn_frombag.sh:
--------------------------------------------------------------------------------
1 | !/bin/bash
2 | SESSION=core_nav
3 | ## Start up
4 | tmux -2 new-session -d -s $SESSION
5 |
6 | tmux split-window -v -p 50
7 | tmux split-window -h -p 50
8 | tmux select-pane -t 0
9 | tmux split-window -h -p 50
10 |
11 |
12 | tmux send-keys -t 0 "sleep 3; roslaunch init_core_nav init_corenav.launch " C-m
13 | tmux send-keys -t 1 "sleep 5; roslaunch core_nav corenav.launch" C-m
14 | tmux send-keys -t 2 "sleep 4; cd ~/Desktop; rosbag play 2019-06-28-17-16-48.bag " C-m
15 | tmux send-keys -t 3 "cd ../../..; source devel/setup.bash" C-m
16 | tmux send-keys -t 4 "rqt_multiplot" C-m
17 |
18 | # Attach to session
19 | tmux -2 attach-session -t $SESSION
20 |
--------------------------------------------------------------------------------
/core_navigation/script/utils/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wvu-navLab/corenav-GP/db4c04fb1d0c9a7222cec29800dd3a838ab9903e/core_navigation/script/utils/__init__.py
--------------------------------------------------------------------------------
/core_navigation/script/utils/__init__.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wvu-navLab/corenav-GP/db4c04fb1d0c9a7222cec29800dd3a838ab9903e/core_navigation/script/utils/__init__.pyc
--------------------------------------------------------------------------------
/core_navigation/script/utils/__pycache__/__init__.cpython-35.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wvu-navLab/corenav-GP/db4c04fb1d0c9a7222cec29800dd3a838ab9903e/core_navigation/script/utils/__pycache__/__init__.cpython-35.pyc
--------------------------------------------------------------------------------
/core_navigation/script/utils/__pycache__/__init__.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wvu-navLab/corenav-GP/db4c04fb1d0c9a7222cec29800dd3a838ab9903e/core_navigation/script/utils/__pycache__/__init__.cpython-37.pyc
--------------------------------------------------------------------------------
/core_navigation/script/utils/__pycache__/data.cpython-35.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wvu-navLab/corenav-GP/db4c04fb1d0c9a7222cec29800dd3a838ab9903e/core_navigation/script/utils/__pycache__/data.cpython-35.pyc
--------------------------------------------------------------------------------
/core_navigation/script/utils/__pycache__/data.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wvu-navLab/corenav-GP/db4c04fb1d0c9a7222cec29800dd3a838ab9903e/core_navigation/script/utils/__pycache__/data.cpython-37.pyc
--------------------------------------------------------------------------------
/core_navigation/script/utils/data.py:
--------------------------------------------------------------------------------
1 | import pandas as pd
2 |
3 |
4 | def load_co2(file_path):
5 | co2 = pd.read_csv(file_path, header=None, index_col=None)
6 |
7 | co2_x = co2[1].values
8 | co2_y = co2[0].values
9 |
10 | return co2_x, co2_y
11 |
12 |
13 | def load_erie(file_path):
14 | erie = pd.read_csv(file_path, header=0, names=["date", "level"], index_col=None)
15 |
16 | erie = erie["level"].values
17 | erie = erie[:len(erie)-1]
18 | return erie
19 |
20 | def load_slip(file_path):
21 | slip = pd.read_csv(file_path, header=0, names=["date", "level"], index_col=None)
22 |
23 | slip = slip["level"].values
24 | slip = slip[:len(slip)-1]
25 | return slip
26 |
27 | def load_airline(file_path):
28 | airline = pd.read_csv(file_path, header=None)
29 | airline = airline[1].values
30 |
31 | return airline
32 |
33 |
34 | def load_solar(file_path):
35 | solar = pd.read_csv(file_path, sep=' ', header=None, skiprows=7)
36 | solar = solar[1].values
37 |
38 | return solar
39 |
--------------------------------------------------------------------------------
/core_navigation/script/utils/data.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wvu-navLab/corenav-GP/db4c04fb1d0c9a7222cec29800dd3a838ab9903e/core_navigation/script/utils/data.pyc
--------------------------------------------------------------------------------
/core_navigation/script/utils/plot.py:
--------------------------------------------------------------------------------
1 | import matplotlib.pyplot as plt
2 | import numpy as np
3 |
4 |
5 | def plot_co2(y_true, mean, lb, ub, trainlen, n, r):
6 | plt.plot(range(len(y_true)),y_true,'b',label="Actual")
7 | plt.plot(range(len(y_true)),mean,'r', label="ESN Prediction")
8 | plt.fill_between(range(len(y_true)), lb, ub, facecolor='grey', alpha=0.3)
9 | lo,hi = plt.ylim()
10 | plt.plot([trainlen,trainlen],[lo+np.spacing(1),hi-np.spacing(1)],'k:')
11 | plt.xlabel('Months since Aug 1960')
12 | plt.ylabel('CO2 Concentration (ppmv)')
13 | plt.legend(loc=2)
14 | plt.show()
15 |
16 |
17 | def plot_erie(y_true, mean, lb, ub, trainlen, n, r):
18 | plt.plot(range(len(y_true)),y_true,'b',label="Actual")
19 | plt.plot(range(len(y_true)),mean,'r', label="ESN Prediction")
20 | plt.fill_between(range(len(y_true)), lb, ub, facecolor='grey', alpha=0.3)
21 | lo,hi = plt.ylim()
22 | plt.plot([trainlen,trainlen],[lo+np.spacing(1),hi-np.spacing(1)],'k:')
23 | plt.xlabel('Months since Aug 1922')
24 | plt.ylabel('Water Level')
25 | plt.legend(loc=2)
26 | plt.show()
27 |
28 | def plot_airline(y_true, mean, lb, ub, trainlen, n, r):
29 | plt.plot(range(len(y_true)),y_true,'b',label="Target")
30 | plt.plot(range(len(y_true)),mean,'r', label="ESN n="+str(n)+", r="+str(r))
31 | plt.fill_between(range(len(y_true)), lb, ub, facecolor='grey', alpha=0.3)
32 | lo,hi = plt.ylim()
33 | plt.plot([trainlen,trainlen],[lo+np.spacing(1),hi-np.spacing(1)],'k:')
34 | plt.xlabel('Time (months)')
35 | plt.ylabel('Number of Passengers')
36 | plt.legend(loc=2, fontsize='x-small')
37 | plt.show()
38 |
39 |
40 | def plot_solar(y_true, mean, lb, ub, trainlen, n, r):
41 | plt.plot(range(len(y_true)),y_true,'b',label="Target")
42 | plt.plot(range(len(y_true)),mean,'r', label="ESN n="+str(n)+", r="+str(r))
43 | plt.fill_between(range(len(y_true)), lb, ub, facecolor='grey', alpha=0.3)
44 | lo,hi = plt.ylim()
45 | plt.plot([trainlen,trainlen],[lo+np.spacing(1),hi-np.spacing(1)],'k:')
46 | plt.xlabel('Years since 1629')
47 | plt.ylabel('TSI (w/m^2)')
48 | plt.legend(loc=2, fontsize='x-small')
49 | plt.show()
50 |
--------------------------------------------------------------------------------
/core_navigation/script/utils/utils.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | from sklearn.linear_model import LinearRegression
3 | from sklearn.preprocessing import MinMaxScaler
4 |
5 |
6 | def scale(x_train, y_train, x_test, y_test):
7 | scaler = MinMaxScaler(feature_range=(-1, 1))
8 |
9 | scale_values = np.concatenate((x_train.reshape(-1), y_train.reshape(-1)))
10 | scale_values = np.unique(scale_values)
11 | scaler.fit(scale_values.reshape(-1, 1))
12 |
13 | x_train = scaler.transform(x_train.reshape(-1, 1)).reshape(x_train.shape[0], x_train.shape[1], x_train.shape[2])
14 | y_train = scaler.transform(y_train.reshape(-1, 1)).reshape(y_train.shape[0], y_train.shape[1])
15 |
16 | x_test = scaler.transform(x_test.reshape(-1, 1)).reshape(x_test.shape[0], x_test.shape[1], x_test.shape[2])
17 | y_test = scaler.transform(y_test.reshape(-1, 1)).reshape(y_test.shape[0], y_test.shape[1])
18 |
19 | return scaler, x_train, y_train, x_test, y_test
20 |
21 |
22 | def detrend(data, train_percent, window_length):
23 | idx = int(len(data) * train_percent) - (window_length - 1)
24 |
25 | model = LinearRegression()
26 | model.fit(np.arange(idx).reshape(-1, 1), data[:idx])
27 |
28 | trend = model.predict(np.arange(len(data)).reshape(-1, 1))
29 |
30 | data = data - trend
31 |
32 | return data, trend
33 |
34 |
35 | def create_window_data(data, window_size):
36 | temp = []
37 |
38 | for i in range(len(data) - window_size):
39 | temp.append(data[i: i + window_size])
40 |
41 | temp = np.array(temp)
42 |
43 | x = temp[:, :-1]
44 | y = temp[:, -1]
45 |
46 | x = np.expand_dims(x, axis=2)
47 | y = np.expand_dims(y, axis=1)
48 |
49 | return x, y
50 |
51 |
52 | def create_direct_data(data, window_length, train_percent):
53 | data, trend = detrend(data, train_percent, window_length)
54 |
55 | x, y = create_window_data(data, window_length + 1)
56 | split = int(train_percent * len(x))
57 |
58 | x_train, y_train = x[:split], y[:split]
59 | x_test, y_test = x[split:], y[split:]
60 |
61 | scaler, x_train, y_train, x_test, y_test = scale(x_train, y_train, x_test, y_test)
62 |
63 | return x_train, y_train, x_test, y_test, scaler, trend
64 |
65 |
66 | def predict_sliding(model, x_train, test_len, seq_len, window_length, full=True):
67 | train_pred = model.predict(x_train)
68 | cur_window = train_pred[-seq_len:]
69 | cur_window = cur_window.reshape(window_length)
70 | pred = []
71 |
72 | for i in range(test_len):
73 | pred.append(model.predict(np.expand_dims(cur_window, axis=0))[0][0])
74 | cur_window = cur_window[1:]
75 | cur_window = np.concatenate((cur_window, np.array([pred[i]])))
76 |
77 | pred = np.array(pred)
78 |
79 | if full:
80 | result = np.concatenate((train_pred.reshape(-1), pred))
81 | else:
82 | result = pred
83 |
84 | return result
85 |
86 |
87 | def predict_sliding_rnn(model, x_train, test_len, seq_len, window_length, full=True):
88 | train_pred = model.predict(x_train)
89 | cur_window = train_pred[-seq_len:]
90 | cur_window = cur_window.reshape(window_length)
91 | pred = []
92 |
93 | for i in range(test_len):
94 | pred.append(model.predict(np.expand_dims(cur_window, axis=0))[0][0])
95 | cur_window = cur_window[1:]
96 | cur_window = np.concatenate((cur_window, np.array([pred[i]])))
97 |
98 | pred = np.array(pred)
99 |
100 | if full:
101 | result = np.concatenate((train_pred.reshape(-1), pred))
102 | else:
103 | result = pred
104 |
105 | return result
106 |
107 |
108 | def invert_scale(scaler, values):
109 | if values.ndim == 1:
110 | values = np.reshape(values, (-1, 1))
111 |
112 | inverted = scaler.inverse_transform(values)
113 | inverted = np.reshape(inverted, -1)
114 |
115 | return inverted
116 |
--------------------------------------------------------------------------------
/core_navigation/src/core_nav.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | int main(int argc, char** argv){
5 | ros::init(argc, argv, "inertial propagation");
6 | ros::NodeHandle n("~");
7 |
8 | CoreNav coreNav;
9 | if(!coreNav.Initialize(n)) {
10 | ROS_ERROR("%s: Failed to initialize the nav. filter.",
11 | ros::this_node::getName().c_str());
12 | return EXIT_FAILURE;
13 | }
14 |
15 |
16 | // while(ros::ok())
17 | // {
18 | // if(coreNav.propagate_flag)
19 | // {
20 | // // ROS_INFO("Propagate flag: Before Propagate\n");
21 | // coreNav.Propagate();
22 | // // ROS_INFO("Propagate flag: After Propagate\n");
23 | // coreNav.propagate_flag =false;
24 | // }
25 | //
26 | // if(coreNav.update_flag)
27 | // {
28 | // // ROS_INFO("Update Flag: before update\n");
29 | // coreNav.Update();
30 | // // ROS_INFO("Update Flag: after update\n");
31 | // coreNav.update_flag =false;
32 | // }
33 | // ros::spinOnce();
34 | // }
35 |
36 | ros::spin();
37 |
38 | return EXIT_SUCCESS;
39 | }
40 |
41 |
42 | // #include
43 | // #include
44 | //
45 | // int main(int argc, char** argv){
46 | // ros::init(argc, argv, "inertial propagation");
47 | // ros::NodeHandle n("~");
48 | //
49 | // CoreNav coreNav;
50 | // if(!coreNav.Initialize(n)) {
51 | // ROS_ERROR("%s: Failed to initialize the nav. filter.",
52 | // ros::this_node::getName().c_str());
53 | // return EXIT_FAILURE;
54 | // }
55 | // // ros::MultiThreadedSpinner spinner(0);
56 | // // spinner.spin();
57 | // // ros::AsyncSpinner spinner(0);
58 | // // spinner.start();
59 | // while(ros::ok())
60 | // {
61 | // if(coreNav.propagate_flag)
62 | // {
63 | // // ROS_INFO("Propagate flag: Before Propagate\n");
64 | // // coreNav.Propagate(coreNav.imu,coreNav.odo,coreNav.cmd,coreNav.encoderLeft,coreNav.encoderRight,coreNav.joint);
65 | // coreNav.Propagate();
66 | //
67 | // // ROS_INFO("Propagate flag: After Propagate\n");
68 | // coreNav.propagate_flag =false;
69 | // }
70 | //
71 | // if(coreNav.update_flag)
72 | // {
73 | // // ROS_INFO("Update Flag: before update\n");
74 | // // coreNav.Update(coreNav.odo,coreNav.joint);
75 | // coreNav.Update();
76 | //
77 | // // ROS_INFO("Update Flag: after update\n");
78 | // coreNav.update_flag =false;
79 | // }
80 | // ros::spinOnce();
81 | // }
82 | // // ros::spin();
83 | //
84 | // // ros::waitForShutdown();
85 | // return EXIT_SUCCESS;
86 | // }
87 |
--------------------------------------------------------------------------------
/core_navigation/srv/SetStopping.srv:
--------------------------------------------------------------------------------
1 | bool stopping
2 | ---
3 | float64[225] PvecData
4 | float64[225] QvecData
5 | float64[225] STMvecData
6 | float64[60] HvecData
7 | geometry_msgs/Point PosData
8 |
--------------------------------------------------------------------------------
/docs/corenav7.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wvu-navLab/corenav-GP/db4c04fb1d0c9a7222cec29800dd3a838ab9903e/docs/corenav7.gif
--------------------------------------------------------------------------------
/docs/framework.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wvu-navLab/corenav-GP/db4c04fb1d0c9a7222cec29800dd3a838ab9903e/docs/framework.png
--------------------------------------------------------------------------------
/docs/readme.md:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/geometry_utils/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 2.8.3)
2 | project(geometry_utils)
3 |
4 | set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_LIST_DIR}/cmake")
5 |
6 | find_package(catkin REQUIRED COMPONENTS roscpp)
7 | find_package(Eigen3 REQUIRED)
8 |
9 | catkin_package(
10 | INCLUDE_DIRS
11 | include
12 | ${EIGEN3_INCLUDE_DIR}
13 | LIBRARIES
14 | DEPENDS
15 | Eigen3
16 | )
17 |
18 | include_directories(include ${EIGEN3_INCLUDE_DIR} ${catkin_INCLUDE_DIRS})
19 |
20 | install(DIRECTORY include/${PROJECT_NAME}/
21 | DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
22 | FILES_MATCHING PATTERN "*.h"
23 | )
24 |
25 | install(DIRECTORY cmake/
26 | DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}
27 | FILES_MATCHING PATTERN "*.cmake"
28 | )
29 |
30 | add_executable(test_math tests/test_math.cc)
31 | target_link_libraries(test_math
32 | ${catkin_LIBRARIES}
33 | boost_unit_test_framework
34 | )
35 |
36 | add_executable(test_base tests/test_base.cc)
37 | target_link_libraries(test_base
38 | ${catkin_LIBRARIES}
39 | boost_unit_test_framework
40 | )
41 |
42 | add_executable(test_equals tests/test_equals.cc)
43 | target_link_libraries(test_equals
44 | ${catkin_LIBRARIES}
45 | boost_unit_test_framework
46 | )
47 |
48 | add_executable(test_so3error tests/test_so3error.cc)
49 | target_link_libraries(test_so3error
50 | ${catkin_LIBRARIES}
51 | boost_unit_test_framework
52 | )
53 |
--------------------------------------------------------------------------------
/geometry_utils/cmake/FindEigen3.cmake:
--------------------------------------------------------------------------------
1 | # - Try to find Eigen3 lib
2 | #
3 | # This module supports requiring a minimum version, e.g. you can do
4 | # find_package(Eigen3 3.1.2)
5 | # to require version 3.1.2 or newer of Eigen3.
6 | #
7 | # Once done this will define
8 | #
9 | # EIGEN3_FOUND - system has eigen lib with correct version
10 | # EIGEN3_INCLUDE_DIR - the eigen include directory
11 | # EIGEN3_VERSION - eigen version
12 |
13 | # Copyright (c) 2006, 2007 Montel Laurent,
14 | # Copyright (c) 2008, 2009 Gael Guennebaud,
15 | # Copyright (c) 2009 Benoit Jacob
16 | # Redistribution and use is allowed according to the terms of the 2-clause BSD license.
17 |
18 | if(NOT Eigen3_FIND_VERSION)
19 | if(NOT Eigen3_FIND_VERSION_MAJOR)
20 | set(Eigen3_FIND_VERSION_MAJOR 2)
21 | endif(NOT Eigen3_FIND_VERSION_MAJOR)
22 | if(NOT Eigen3_FIND_VERSION_MINOR)
23 | set(Eigen3_FIND_VERSION_MINOR 91)
24 | endif(NOT Eigen3_FIND_VERSION_MINOR)
25 | if(NOT Eigen3_FIND_VERSION_PATCH)
26 | set(Eigen3_FIND_VERSION_PATCH 0)
27 | endif(NOT Eigen3_FIND_VERSION_PATCH)
28 |
29 | set(Eigen3_FIND_VERSION "${Eigen3_FIND_VERSION_MAJOR}.${Eigen3_FIND_VERSION_MINOR}.${Eigen3_FIND_VERSION_PATCH}")
30 | endif(NOT Eigen3_FIND_VERSION)
31 |
32 | macro(_eigen3_check_version)
33 | file(READ "${EIGEN3_INCLUDE_DIR}/Eigen/src/Core/util/Macros.h" _eigen3_version_header)
34 |
35 | string(REGEX MATCH "define[ \t]+EIGEN_WORLD_VERSION[ \t]+([0-9]+)" _eigen3_world_version_match "${_eigen3_version_header}")
36 | set(EIGEN3_WORLD_VERSION "${CMAKE_MATCH_1}")
37 | string(REGEX MATCH "define[ \t]+EIGEN_MAJOR_VERSION[ \t]+([0-9]+)" _eigen3_major_version_match "${_eigen3_version_header}")
38 | set(EIGEN3_MAJOR_VERSION "${CMAKE_MATCH_1}")
39 | string(REGEX MATCH "define[ \t]+EIGEN_MINOR_VERSION[ \t]+([0-9]+)" _eigen3_minor_version_match "${_eigen3_version_header}")
40 | set(EIGEN3_MINOR_VERSION "${CMAKE_MATCH_1}")
41 |
42 | set(EIGEN3_VERSION ${EIGEN3_WORLD_VERSION}.${EIGEN3_MAJOR_VERSION}.${EIGEN3_MINOR_VERSION})
43 | if(${EIGEN3_VERSION} VERSION_LESS ${Eigen3_FIND_VERSION})
44 | set(EIGEN3_VERSION_OK FALSE)
45 | else(${EIGEN3_VERSION} VERSION_LESS ${Eigen3_FIND_VERSION})
46 | set(EIGEN3_VERSION_OK TRUE)
47 | endif(${EIGEN3_VERSION} VERSION_LESS ${Eigen3_FIND_VERSION})
48 |
49 | if(NOT EIGEN3_VERSION_OK)
50 |
51 | message(STATUS "Eigen3 version ${EIGEN3_VERSION} found in ${EIGEN3_INCLUDE_DIR}, "
52 | "but at least version ${Eigen3_FIND_VERSION} is required")
53 | endif(NOT EIGEN3_VERSION_OK)
54 | endmacro(_eigen3_check_version)
55 |
56 | if (EIGEN3_INCLUDE_DIR)
57 |
58 | # in cache already
59 | _eigen3_check_version()
60 | set(EIGEN3_FOUND ${EIGEN3_VERSION_OK})
61 |
62 | else (EIGEN3_INCLUDE_DIR)
63 |
64 | find_path(EIGEN3_INCLUDE_DIR NAMES signature_of_eigen3_matrix_library
65 | PATHS
66 | ${CMAKE_INSTALL_PREFIX}/include
67 | ${KDE4_INCLUDE_DIR}
68 | PATH_SUFFIXES eigen3 eigen
69 | )
70 |
71 | if(EIGEN3_INCLUDE_DIR)
72 | _eigen3_check_version()
73 | endif(EIGEN3_INCLUDE_DIR)
74 |
75 | include(FindPackageHandleStandardArgs)
76 | find_package_handle_standard_args(Eigen3 DEFAULT_MSG EIGEN3_INCLUDE_DIR EIGEN3_VERSION_OK)
77 |
78 | mark_as_advanced(EIGEN3_INCLUDE_DIR)
79 |
80 | endif(EIGEN3_INCLUDE_DIR)
81 |
82 |
--------------------------------------------------------------------------------
/geometry_utils/include/geometry_utils/GeometryUtils.h:
--------------------------------------------------------------------------------
1 | /*
2 | geometry_utils: Utility library to provide common geometry types and transformations
3 | Copyright (C) 2014 Nathan Michael
4 | 2016 Erik Nelson
5 |
6 | This program is free software; you can redistribute it and/or
7 | modify it under the terms of the GNU General Public License
8 | as published by the Free Software Foundation; either version 2
9 | of the License, or (at your option) any later version.
10 |
11 | This program is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with this program; if not, write to the Free Software
18 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 | */
20 |
21 | #ifndef GEOMETRY_UTILS_H
22 | #define GEOMETRY_UTILS_H
23 |
24 | #include "Vector2.h"
25 | #include "Vector3.h"
26 | #include "Vector4.h"
27 | #include "Quaternion.h"
28 | #include "Matrix2x2.h"
29 | #include "Matrix3x3.h"
30 | #include "Matrix4x4.h"
31 | #include "Rotation2.h"
32 | #include "Rotation3.h"
33 | #include "Transform2.h"
34 | #include "Transform3.h"
35 |
36 | namespace geometry_utils {
37 | inline double Unroll(double x) {
38 | x = fmod(x, 2.0 * M_PI);
39 | if (x < 0)
40 | x += 2.0 * M_PI;
41 | return x;
42 | }
43 |
44 | inline double Normalize(double x) {
45 | x = fmod(x + M_PI, 2.0 * M_PI);
46 | if (x < 0)
47 | x += 2.0 * M_PI;
48 | return x - M_PI;
49 | }
50 |
51 | inline double S1Distance(double from, double to) {
52 | double result = Unroll(Unroll(to) - Unroll(from));
53 | if (result > M_PI)
54 | result = -(2.0 * M_PI - result);
55 | return Normalize(result);
56 | }
57 |
58 | inline double Rad2Deg(double angle) {
59 | return angle * 180.0 * M_1_PI;
60 | }
61 |
62 | inline double Deg2Rad(double angle) {
63 | return angle * M_PI / 180.0;
64 | }
65 |
66 | inline Vec3 Rad2Deg(const Vec3& angles) {
67 | return Vec3(Rad2Deg(angles(0)), Rad2Deg(angles(1)), Rad2Deg(angles(2)));
68 | }
69 |
70 | inline Vec3 Deg2Rad(const Vec3& angles) {
71 | return Vec3(Deg2Rad(angles(0)), Deg2Rad(angles(1)), Deg2Rad(angles(2)));
72 | }
73 |
74 | inline Vec3 RToZYX(const Rot3& rot) {
75 | return rot.GetEulerZYX();
76 | }
77 |
78 | inline Rot3 ZYXToR(const Vec3& angles) {
79 | return Rot3(angles);
80 | }
81 |
82 | inline Rot3 QuatToR(const Quat& quat) {
83 | return Rot3(quat);
84 | }
85 |
86 | inline Quat RToQuat(const Rot3& rot) {
87 | return Quat(Eigen::Quaterniond(rot.Eigen()));
88 | }
89 |
90 | inline double GetRoll(const Rot3& r) {
91 | return r.Roll();
92 | }
93 |
94 | inline double GetRoll(const Quat& q) {
95 | return Rot3(q).Roll();
96 | }
97 |
98 | inline double GetPitch(const Rot3& r) {
99 | return r.Pitch();
100 | }
101 |
102 | inline double GetPitch(const Quat& q) {
103 | return Rot3(q).Pitch();
104 | }
105 |
106 | inline double GetYaw(const Rot3& r) {
107 | return r.Yaw();
108 | }
109 |
110 | inline double GetYaw(const Quat& q) {
111 | return Rot3(q).Yaw();
112 | }
113 |
114 | inline double SO3Error(const Quat& q1, const Quat& q2) {
115 | return Rot3(q1).Error(Rot3(q2));
116 | }
117 |
118 | inline double SO3Error(const Rot3& r1, const Rot3& r2) {
119 | return r1.Error(r2);
120 | }
121 |
122 | inline Vec3 CartesianToSpherical(const Vec3& v) {
123 | double rho = v.Norm();
124 | return Vec3(rho, acos(v.Z() / rho), atan2(v.Y(), v.X()));
125 | }
126 |
127 | inline Vec3 SphericalToCartesian(const Vec3& v) {
128 | return Vec3(v(0) * sin(v(1)) * cos(v(2)), v(0) * sin(v(1)) * sin(v(2)),
129 | v(0) * cos(v(1)));
130 | }
131 |
132 | inline Vec3 NEDCartesian(const Vec3& v) {
133 | return Vec3(v(0), -v(1), -v(2));
134 | }
135 |
136 | }
137 |
138 | #endif
139 |
--------------------------------------------------------------------------------
/geometry_utils/include/geometry_utils/GeometryUtilsMath.h:
--------------------------------------------------------------------------------
1 | /*
2 | geometry_utils: Utility library to provide common geometry types and transformations
3 | Copyright (C) 2014 Nathan Michael
4 | 2016 Erik Nelson
5 |
6 | This program is free software; you can redistribute it and/or
7 | modify it under the terms of the GNU General Public License
8 | as published by the Free Software Foundation; either version 2
9 | of the License, or (at your option) any later version.
10 |
11 | This program is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with this program; if not, write to the Free Software
18 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 | */
20 |
21 | #ifndef GEOMETRY_UTILS_MATH_H
22 | #define GEOMETRY_UTILS_MATH_H
23 |
24 | #include
25 |
26 | namespace geometry_utils {
27 | namespace math {
28 |
29 | template inline T cos(T in);
30 | template<> inline float cos(float in) { return ::cosf(in); }
31 | template<> inline double cos(double in) { return ::cos(in); }
32 |
33 | template inline T acos(T in);
34 | template<> inline float acos(float in) { return ::acosf(in); }
35 | template<> inline double acos(double in) { return ::acos(in); }
36 |
37 | template inline T sin(T in);
38 | template<> inline float sin(float in) { return ::sinf(in); }
39 | template<> inline double sin(double in) { return ::sin(in); }
40 |
41 | template inline T asin(T in);
42 | template<> inline float asin(float in) { return ::asinf(in); }
43 | template<> inline double asin(double in) { return ::asin(in); }
44 |
45 | template inline T tan(T in);
46 | template<> inline float tan(float in) { return ::tanf(in); }
47 | template<> inline double tan(double in) { return ::tan(in); }
48 |
49 | template inline T atan(T in);
50 | template<> inline float atan(float in) { return ::atanf(in); }
51 | template<> inline double atan(double in) { return ::atan(in); }
52 |
53 | template inline T fabs(T in);
54 | template<> inline float fabs(float in) { return ::fabsf(in); }
55 | template<> inline double fabs(double in) { return ::fabs(in); }
56 |
57 | template inline T fmin(T v1, T v2);
58 | template<> inline float fmin(float v1, float v2) { return ::fminf(v1, v2); }
59 | template<> inline double fmin(double v1, double v2) { return ::fmin(v1, v2); }
60 |
61 | template inline T fmax(T v1, T v2);
62 | template<> inline float fmax(float v1, float v2) { return ::fmaxf(v1, v2); }
63 | template<> inline double fmax(double v1, double v2) { return ::fmax(v1, v2); }
64 |
65 | template inline T sqrt(T in);
66 | template<> inline float sqrt(float in) { return ::sqrtf(in); }
67 | template<> inline double sqrt(double in) { return ::sqrt(in); }
68 |
69 | template inline T pow(T in, T exp);
70 | template<> inline float pow(float in, float exp) { return ::powf(in, exp); }
71 | template<> inline double pow(double in, double exp) { return ::pow(in, exp); }
72 |
73 | template inline T atan2(T y, T x);
74 | template<> inline float atan2(float y, float x) { return ::atan2f(y, x); }
75 | template<> inline double atan2(double y, double x) { return ::atan2(y, x); }
76 |
77 | template inline T hypot(T x, T y);
78 | template<> inline float hypot(float x, float y) { return ::hypotf(x, y); }
79 | template<> inline double hypot(double x, double y) { return ::hypot(x, y); }
80 |
81 | }
82 | }
83 | #endif
84 |
--------------------------------------------------------------------------------
/geometry_utils/include/geometry_utils/GeometryUtilsROS.h:
--------------------------------------------------------------------------------
1 | /*
2 | geometry_utils: Utility library to provide common geometry types and transformations
3 | Copyright (C) 2013 Nathan Michael
4 | 2015 Erik Nelson
5 |
6 | This program is free software; you can redistribute it and/or
7 | modify it under the terms of the GNU General Public License
8 | as published by the Free Software Foundation; either version 2
9 | of the License, or (at your option) any later version.
10 |
11 | This program is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with this program; if not, write to the Free Software
18 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 | */
20 |
21 | #ifndef GEOMETRY_UTILS_ROS_H
22 | #define GEOMETRY_UTILS_ROS_H
23 |
24 | #include "GeometryUtils.h"
25 |
26 | #include
27 | #include
28 | #include
29 | #include
30 | #include
31 | #include
32 |
33 | namespace geometry_utils {
34 | namespace ros {
35 |
36 | inline Vec3 FromROS(const geometry_msgs::Point& p) {
37 | return Vec3(p.x, p.y, p.z);
38 | }
39 |
40 | inline Vec3 FromROS(const geometry_msgs::Point32& p) {
41 | return Vec3(p.x, p.y, p.z);
42 | }
43 |
44 | inline Vec3 FromROS(const geometry_msgs::Vector3& p) {
45 | return Vec3(p.x, p.y, p.z);
46 | }
47 |
48 | inline Quat FromROS(const geometry_msgs::Quaternion& msg) {
49 | return Quat(msg.w, msg.x, msg.y, msg.z);
50 | }
51 |
52 | inline Transform3 FromROS(const geometry_msgs::Pose& msg) {
53 | return Transform3(FromROS(msg.position), QuatToR(FromROS(msg.orientation)));
54 | }
55 |
56 | inline Transform3 FromROS(const geometry_msgs::Transform& msg) {
57 | return Transform3(FromROS(msg.translation), QuatToR(FromROS(msg.rotation)));
58 | }
59 |
60 | inline geometry_msgs::Point ToRosPoint(const Vec2& v) {
61 | geometry_msgs::Point msg;
62 | msg.x = v(0);
63 | msg.y = v(1);
64 | msg.z = 0.0;
65 |
66 | return msg;
67 | }
68 |
69 | inline geometry_msgs::Point ToRosPoint(const Vec3& v) {
70 | geometry_msgs::Point msg;
71 | msg.x = v(0);
72 | msg.y = v(1);
73 | msg.z = v(2);
74 |
75 | return msg;
76 | }
77 |
78 | inline geometry_msgs::Point32 ToRosPoint32(const Vec2& v) {
79 | geometry_msgs::Point32 msg;
80 | msg.x = v(0);
81 | msg.y = v(1);
82 | msg.z = 0.0f;
83 |
84 | return msg;
85 | }
86 |
87 | inline geometry_msgs::Point32 ToRosPoint32(const Vec3& v) {
88 | geometry_msgs::Point32 msg;
89 | msg.x = v(0);
90 | msg.y = v(1);
91 | msg.z = v(2);
92 |
93 | return msg;
94 | }
95 |
96 | inline geometry_msgs::Vector3 ToRosVec(const Vec2& v) {
97 | geometry_msgs::Vector3 msg;
98 | msg.x = v(0);
99 | msg.y = v(1);
100 | msg.z = 0.0;
101 |
102 | return msg;
103 | }
104 |
105 | inline geometry_msgs::Vector3 ToRosVec(const Vec3& v) {
106 | geometry_msgs::Vector3 msg;
107 | msg.x = v(0);
108 | msg.y = v(1);
109 | msg.z = v(2);
110 |
111 | return msg;
112 | }
113 |
114 | inline geometry_msgs::Quaternion ToRosQuat(const Quat& quat) {
115 | geometry_msgs::Quaternion msg;
116 | msg.w = quat.W();
117 | msg.x = quat.X();
118 | msg.y = quat.Y();
119 | msg.z = quat.Z();
120 |
121 | return msg;
122 | }
123 |
124 | inline geometry_msgs::Pose ToRosPose(const Transform2& trans) {
125 | geometry_msgs::Pose msg;
126 | msg.position = ToRosPoint(trans.translation);
127 | msg.orientation = ToRosQuat(RToQuat(Rot3(trans.rotation)));
128 |
129 | return msg;
130 | }
131 |
132 | inline geometry_msgs::Pose ToRosPose(const Transform3& trans) {
133 | geometry_msgs::Pose msg;
134 | msg.position = ToRosPoint(trans.translation);
135 | msg.orientation = ToRosQuat(RToQuat(trans.rotation));
136 |
137 | return msg;
138 | }
139 |
140 | inline geometry_msgs::Transform ToRosTransform(const Transform2& trans) {
141 | geometry_msgs::Transform msg;
142 | msg.translation = ToRosVec(trans.translation);
143 | msg.rotation = ToRosQuat(RToQuat(Rot3(trans.rotation)));
144 |
145 | return msg;
146 | }
147 |
148 | inline geometry_msgs::Transform ToRosTransform(const Transform3& trans) {
149 | geometry_msgs::Transform msg;
150 | msg.translation = ToRosVec(trans.translation);
151 | msg.rotation = ToRosQuat(RToQuat(trans.rotation));
152 |
153 | return msg;
154 | }
155 |
156 | inline geometry_msgs::Quaternion ToRosQuat(const Vec3& angles) {
157 | return ToRosQuat(RToQuat(ZYXToR(angles)));
158 | }
159 |
160 | inline Vec3 RosQuatToZYX(const geometry_msgs::Quaternion& msg) {
161 | return RToZYX(QuatToR(FromROS(msg)));
162 | }
163 |
164 | inline double GetRoll(const geometry_msgs::Quaternion& q) {
165 | return Rot3(FromROS(q)).Roll();
166 | }
167 |
168 | inline double GetPitch(const geometry_msgs::Quaternion& q) {
169 | return Rot3(FromROS(q)).Pitch();
170 | }
171 |
172 | inline double GetYaw(const geometry_msgs::Quaternion& q) {
173 | return Rot3(FromROS(q)).Yaw();
174 | }
175 |
176 | }
177 | }
178 | #endif
179 |
--------------------------------------------------------------------------------
/geometry_utils/include/geometry_utils/GeometryUtilsSerialization.h:
--------------------------------------------------------------------------------
1 | /*
2 | geometry_utils: Utility library to provide common geometry types and transformations
3 | Copyright (C) 2013 Nathan Michael
4 | 2016 Erik Nelson
5 |
6 | This program is free software; you can redistribute it and/or
7 | modify it under the terms of the GNU General Public License
8 | as published by the Free Software Foundation; either version 2
9 | of the License, or (at your option) any later version.
10 |
11 | This program is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with this program; if not, write to the Free Software
18 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 | */
20 |
21 | #ifndef GEOMETRY_UTILS_SERIALIZATION_H
22 | #define GEOMETRY_UTILS_SERIALIZATION_H
23 |
24 | #include "GeometryUtils.h"
25 |
26 | #include
27 | #include
28 |
29 | namespace boost {
30 | namespace serialization {
31 |
32 | template
33 | void Serialize(Archive & ar, geometry_utils::Vector2& v,
34 | const unsigned int version) {
35 | ar & v(0);
36 | ar & v(1);
37 | }
38 |
39 | template
40 | void Serialize(Archive & ar, geometry_utils::Vector3& v,
41 | const unsigned int version) {
42 | ar & v(0);
43 | ar & v(1);
44 | ar & v(2);
45 | }
46 |
47 | template
48 | void Serialize(Archive & ar, geometry_utils::Vector4& v,
49 | const unsigned int version) {
50 | ar & v(0);
51 | ar & v(1);
52 | ar & v(2);
53 | ar & v(3);
54 | }
55 |
56 | template
57 | void Serialize(Archive & ar, geometry_utils::Matrix3x3& m,
58 | const unsigned int version) {
59 | for (unsigned int i = 0; i < 3; i++)
60 | for (unsigned int j = 0; j < 3; j++)
61 | ar & m(i, j);
62 | }
63 |
64 | template
65 | void Serialize(Archive & ar, geometry_utils::Transform& t,
66 | const unsigned int version) {
67 | ar & t.translation;
68 | ar & t.rotation;
69 | }
70 |
71 | }
72 | }
73 | #endif
74 |
--------------------------------------------------------------------------------
/geometry_utils/include/geometry_utils/Matrix2x2.h:
--------------------------------------------------------------------------------
1 | #ifndef GEOMETRY_UTILS_MATRIX2X2_H
2 | #define GEOMETRY_UTILS_MATRIX2X2_H
3 |
4 | #include "MatrixNxNBase.h"
5 | #include "Vector2.h"
6 |
7 | namespace geometry_utils {
8 |
9 | template
10 | struct Matrix2x2Base : MatrixNxNBase {
11 | Matrix2x2Base() : MatrixNxNBase() {}
12 | Matrix2x2Base(T val) : MatrixNxNBase(val) {}
13 | Matrix2x2Base(const Matrix2x2Base& in) : MatrixNxNBase(in.data) {}
14 | Matrix2x2Base(const boost::array& in) : MatrixNxNBase(in) {}
15 | Matrix2x2Base(T (&in)[2 * 2]) : MatrixNxNBase(in) {}
16 | Matrix2x2Base(const Eigen::Matrix& in) : MatrixNxNBase(in) {}
17 | Matrix2x2Base(const MatrixNxNBase& in) : MatrixNxNBase(in) {}
18 | Matrix2x2Base(const MatrixNxMBase& in) : MatrixNxNBase(in) {}
19 |
20 | Matrix2x2Base(T R11, T R12, T R21, T R22) {
21 | this->data[0] = R11;
22 | this->data[1] = R12;
23 | this->data[2] = R21;
24 | this->data[3] = R22;
25 | }
26 |
27 | virtual inline T Det() const {
28 | T a = this->data[0];
29 | T b = this->data[1];
30 | T c = this->data[2];
31 | T d = this->data[3];
32 | return (-(b * c) + a * d);
33 | }
34 |
35 | virtual inline MatrixNxNBase Inv() const {
36 | Vector2Base e(SingularValues());
37 |
38 | T emax = e(0);
39 | T emin = e(1);
40 |
41 | if (emin < std::numeric_limits::denorm_min())
42 | throw std::runtime_error("Matrix2x2Base: appears singular");
43 |
44 | if (emax / emin > std::numeric_limits::epsilon()) {
45 | T a = this->data[0];
46 | T b = this->data[1];
47 | T c = this->data[2];
48 | T d = this->data[3];
49 |
50 | T tmp[4] = {d / (-b * c + a * d), b / (b * c - a * d),
51 | c / (b * c - a * d), a / (-b * c + a * d)};
52 | return MatrixNxNBase(tmp);
53 | } else
54 | throw std::runtime_error("Matrix2x2Base: appears singular");
55 | }
56 |
57 | virtual inline Vector2Base SingularValues() const {
58 | T a = this->data[0];
59 | T b = this->data[1];
60 | T c = this->data[2];
61 | T d = this->data[3];
62 |
63 | T tmp1 = a * a + b * b + c * c + d * d;
64 | T tmp2 = math::sqrt((math::pow(b + c, static_cast(2)) +
65 | math::pow(a - d, static_cast(2))) *
66 | (math::pow(b - c, static_cast(2)) +
67 | math::pow(a + d, static_cast(2))));
68 |
69 | T e1 = math::sqrt(tmp1 - tmp2) * M_SQRT1_2;
70 | T e2 = math::sqrt(tmp1 + tmp2) * M_SQRT1_2;
71 |
72 | return Vector2Base(e1 > e2 ? e1 : e2, e1 < e2 ? e1 : e2);
73 | }
74 | };
75 |
76 | inline Matrix2x2Base operator*(const float& lhs,
77 | const Matrix2x2Base& rhs) {
78 | return Matrix2x2Base(rhs * lhs);
79 | }
80 |
81 | inline Matrix2x2Base operator*(const double& lhs,
82 | const Matrix2x2Base& rhs) {
83 | return Matrix2x2Base(rhs * lhs);
84 | }
85 |
86 | typedef Matrix2x2Base Matrix2x2f;
87 | typedef Matrix2x2Base Mat22f;
88 |
89 | typedef Matrix2x2Base Matrix2x2d;
90 | typedef Matrix2x2Base Mat22d;
91 |
92 | typedef Matrix2x2Base Matrix2x2;
93 | typedef Matrix2x2Base Mat22;
94 |
95 | }
96 |
97 | #endif
98 |
--------------------------------------------------------------------------------
/geometry_utils/include/geometry_utils/Matrix3x3.h:
--------------------------------------------------------------------------------
1 | #ifndef GEOMETRY_UTILS_MATRIX3X3_H
2 | #define GEOMETRY_UTILS_MATRIX3X3_H
3 |
4 | #include "MatrixNxNBase.h"
5 |
6 | namespace geometry_utils {
7 |
8 | template
9 | struct Matrix3x3Base : MatrixNxNBase {
10 | Matrix3x3Base() : MatrixNxNBase() {}
11 | Matrix3x3Base(T val) : MatrixNxNBase(val) {}
12 | Matrix3x3Base(const Matrix3x3Base& in) : MatrixNxNBase(in.data) {}
13 | Matrix3x3Base(const boost::array& in) : MatrixNxNBase(in) {}
14 | Matrix3x3Base(T (&in)[9]) : MatrixNxNBase(in) {}
15 | Matrix3x3Base(const Eigen::Matrix& in) : MatrixNxNBase(in) {}
16 | Matrix3x3Base(const MatrixNxNBase& in) : MatrixNxNBase(in) {}
17 | Matrix3x3Base(const MatrixNxMBase& in) : MatrixNxNBase(in) {}
18 |
19 | Matrix3x3Base(T R11, T R12, T R13, T R21, T R22, T R23, T R31, T R32, T R33) {
20 | this->data[0] = R11;
21 | this->data[1] = R12;
22 | this->data[2] = R13;
23 | this->data[3] = R21;
24 | this->data[4] = R22;
25 | this->data[5] = R23;
26 | this->data[6] = R31;
27 | this->data[7] = R32;
28 | this->data[8] = R33;
29 | }
30 |
31 | inline T Det() const {
32 | T a = this->data[0];
33 | T b = this->data[1];
34 | T c = this->data[2];
35 | T d = this->data[3];
36 | T e = this->data[4];
37 | T f = this->data[5];
38 | T g = this->data[6];
39 | T h = this->data[7];
40 | T i = this->data[8];
41 | return (-(c * e * g) + b * f * g + c * d * h - a * f * h - b * d * i +
42 | a * e * i);
43 | }
44 |
45 | virtual inline MatrixNxNBase Inv() const {
46 | if (math::fabs(Det()) < std::numeric_limits::denorm_min())
47 | throw std::runtime_error("Matrix3x3Base: appears singular");
48 |
49 | T a = this->data[0];
50 | T b = this->data[1];
51 | T c = this->data[2];
52 | T d = this->data[3];
53 | T e = this->data[4];
54 | T f = this->data[5];
55 | T g = this->data[6];
56 | T h = this->data[7];
57 | T i = this->data[8];
58 | T tmp[9] = {(f * h - e * i) / (c * e * g - b * f * g - c * d * h +
59 | a * f * h + b * d * i - a * e * i),
60 | (c * h - b * i) / (-(c * e * g) + b * f * g + c * d * h -
61 | a * f * h - b * d * i + a * e * i),
62 | (c * e - b * f) / (c * e * g - b * f * g - c * d * h +
63 | a * f * h + b * d * i - a * e * i),
64 | (f * g - d * i) / (-(c * e * g) + b * f * g + c * d * h -
65 | a * f * h - b * d * i + a * e * i),
66 | (c * g - a * i) / (c * e * g - b * f * g - c * d * h +
67 | a * f * h + b * d * i - a * e * i),
68 | (c * d - a * f) / (-(c * e * g) + b * f * g + c * d * h -
69 | a * f * h - b * d * i + a * e * i),
70 | (e * g - d * h) / (c * e * g - b * f * g - c * d * h +
71 | a * f * h + b * d * i - a * e * i),
72 | (b * g - a * h) / (-(c * e * g) + b * f * g + c * d * h -
73 | a * f * h - b * d * i + a * e * i),
74 | (b * d - a * e) / (c * e * g - b * f * g - c * d * h +
75 | a * f * h + b * d * i - a * e * i)};
76 | return MatrixNxNBase(tmp);
77 | }
78 | };
79 |
80 | inline Matrix3x3Base operator*(const float& lhs,
81 | const Matrix3x3Base& rhs) {
82 | return Matrix3x3Base(rhs.Scale(lhs));
83 | }
84 |
85 | inline Matrix3x3Base operator*(const double& lhs,
86 | const Matrix3x3Base& rhs) {
87 | return Matrix3x3Base(rhs.Scale(lhs));
88 | }
89 |
90 | typedef Matrix3x3Base Matrix3x3f;
91 | typedef Matrix3x3Base Mat33f;
92 |
93 | typedef Matrix3x3Base Matrix3x3d;
94 | typedef Matrix3x3Base Mat33d;
95 |
96 | typedef Matrix3x3Base Matrix3x3;
97 | typedef Matrix3x3Base Mat33;
98 |
99 | }
100 |
101 | #endif
102 |
--------------------------------------------------------------------------------
/geometry_utils/include/geometry_utils/MatrixNxNBase.h:
--------------------------------------------------------------------------------
1 | #ifndef GEOMETRY_UTILS_MATRIXNXN_H
2 | #define GEOMETRY_UTILS_MATRIXNXN_H
3 |
4 | #include
5 | #include "VectorNBase.h"
6 | #include "GeometryUtilsMath.h"
7 | #include "MatrixNxMBase.h"
8 |
9 | namespace geometry_utils {
10 |
11 | template
12 | struct MatrixNxNBase : MatrixNxMBase {
13 | MatrixNxNBase() : MatrixNxMBase() {}
14 | MatrixNxNBase(T val) : MatrixNxMBase(val) {}
15 | MatrixNxNBase(const MatrixNxNBase& in) : MatrixNxMBase(in.data) {}
16 | MatrixNxNBase(const boost::array& in) : MatrixNxMBase(in) {}
17 | MatrixNxNBase(T (&in)[N * N]) : MatrixNxMBase(in) {}
18 | MatrixNxNBase(const Eigen::Matrix& in)
19 | : MatrixNxMBase(in) {}
20 | MatrixNxNBase(const MatrixNxMBase& in)
21 | : MatrixNxMBase(in) {}
22 |
23 | inline void Eye() {
24 | this->data.fill(0);
25 | for (size_t i = 0; i < this->nrows; i++)
26 | this->data[this->nrows * i + i] = 1;
27 | }
28 |
29 | virtual inline T Det() const {
30 | std::cerr << "MatrixNxMBase::det not implemented" << std::endl;
31 | return T();
32 | }
33 |
34 | virtual inline MatrixNxNBase Inv() const {
35 | std::cerr << "MatrixNxMBase::inv not implemented" << std::endl;
36 | return MatrixNxNBase();
37 | }
38 |
39 | static inline MatrixNxNBase Diag(const VectorNBase& in) {
40 | T d[N * N] = {0};
41 | for (size_t i = 0; i < N; i++)
42 | d[N * i + i] = in(i);
43 | return MatrixNxNBase(d);
44 | }
45 | };
46 |
47 | template
48 | inline MatrixNxNBase operator*(const float& lhs,
49 | const MatrixNxNBase& rhs) {
50 | return MatrixNxNBase(rhs * lhs);
51 | }
52 |
53 | template
54 | inline MatrixNxNBase operator*(const double& lhs,
55 | const MatrixNxNBase& rhs) {
56 | return MatrixNxNBase(rhs * lhs);
57 | }
58 |
59 | template
60 | inline MatrixNxNBase Inv(const MatrixNxNBase& m) {
61 | return m.Inv();
62 | }
63 |
64 | }
65 |
66 | #endif
67 |
--------------------------------------------------------------------------------
/geometry_utils/include/geometry_utils/Quaternion.h:
--------------------------------------------------------------------------------
1 | #ifndef GEOMETRY_UTILS_QUATERNION_H
2 | #define GEOMETRY_UTILS_QUATERNION_H
3 |
4 | #include
5 | #include
6 | #include
7 | #include "GeometryUtilsMath.h"
8 |
9 | namespace geometry_utils {
10 |
11 | template
12 | struct QuaternionBase : VectorNBase {
13 | QuaternionBase() : VectorNBase() {
14 | this->data.assign(0);
15 | this->data[0] = 1;
16 | }
17 |
18 | QuaternionBase(T val) : VectorNBase(val) {}
19 | QuaternionBase(const QuaternionBase& in) : VectorNBase(in.data) {}
20 | QuaternionBase(const boost::array& in) : VectorNBase(in) {}
21 | QuaternionBase(T (&in)[4]) : VectorNBase(in) {}
22 | QuaternionBase(const Eigen::Quaternion& in) {
23 | this->data[0] = in.w();
24 | this->data[1] = in.x();
25 | this->data[2] = in.y();
26 | this->data[3] = in.z();
27 | }
28 | QuaternionBase(const VectorNBase& in) : VectorNBase(in) {}
29 |
30 | QuaternionBase(T w, T x, T y, T z) {
31 | this->data[0] = w;
32 | this->data[1] = x;
33 | this->data[2] = y;
34 | this->data[3] = z;
35 | }
36 |
37 | inline QuaternionBase operator*(const QuaternionBase& rhs) const {
38 | T a1 = this->data[0];
39 | T b1 = this->data[1];
40 | T c1 = this->data[2];
41 | T d1 = this->data[3];
42 | T a2 = rhs.data[0];
43 | T b2 = rhs.data[1];
44 | T c2 = rhs.data[2];
45 | T d2 = rhs.data[3];
46 | return QuaternionBase(a1 * a2 - b1 * b2 - c1 * c2 - d1 * d2,
47 | a2 * b1 + a1 * b2 - c2 * d1 + c1 * d2,
48 | a2 * c1 + a1 * c2 + b2 * d1 - b1 * d2,
49 | -(b2 * c1) + b1 * c2 + a2 * d1 + a1 * d2);
50 | }
51 |
52 | inline T& W() { return this->data[0]; }
53 | inline const T& W() const { return this->data[0]; }
54 |
55 | inline T& X() { return this->data[1]; }
56 | inline const T& X() const { return this->data[1]; }
57 |
58 | inline T& Y() { return this->data[2]; }
59 | inline const T& Y() const { return this->data[2]; }
60 |
61 | inline T& Z() { return this->data[3]; }
62 | inline const T& Z() const { return this->data[3]; }
63 |
64 | inline QuaternionBase Conj() const {
65 | return QuaternionBase(this->data[0], -this->data[1], -this->data[2],
66 | -this->data[3]);
67 | }
68 |
69 | inline QuaternionBase Error(const QuaternionBase& q) const {
70 | return q * (*this).Conj();
71 | }
72 |
73 | inline QuaternionBase AxisAngle() const {
74 | QuaternionBase q((*this));
75 | if (q.W() > 1)
76 | q = q.Normalize();
77 | T den = math::sqrt(1 - q.W() * q.W());
78 | if (den < 1e-6)
79 | den = 1;
80 | return QuaternionBase(2 * math::acos(q.W()), q.X() / den, q.Y() / den,
81 | q.Z() / den);
82 | }
83 | };
84 |
85 | typedef QuaternionBase Quaternionf;
86 | typedef QuaternionBase Quatf;
87 |
88 | typedef QuaternionBase Quaterniond;
89 | typedef QuaternionBase Quatd;
90 |
91 | typedef QuaternionBase Quaternion;
92 | typedef QuaternionBase Quat;
93 |
94 | }
95 |
96 | #endif
97 |
--------------------------------------------------------------------------------
/geometry_utils/include/geometry_utils/Rotation2.h:
--------------------------------------------------------------------------------
1 | #ifndef GEOMETRY_UTILS_ROTATION2_H
2 | #define GEOMETRY_UTILS_ROTATION2_H
3 |
4 | #include
5 | #include "GeometryUtilsMath.h"
6 | #include "RotationNBase.h"
7 | #include "Matrix2x2.h"
8 |
9 | namespace geometry_utils {
10 |
11 | template
12 | struct Rotation2Base : RotationNBase {
13 | Rotation2Base() : RotationNBase() {}
14 | Rotation2Base(const Rotation2Base& in) : RotationNBase(in.data) {}
15 | Rotation2Base(const boost::array& in) : RotationNBase(in) {}
16 | Rotation2Base(T (&in)[2 * 2]) : RotationNBase(in) {}
17 | Rotation2Base(const Eigen::Matrix& in) : RotationNBase(in) {}
18 | Rotation2Base(const Eigen::Rotation2D& in)
19 | : RotationNBase(in.toRotationMatrix()) {}
20 | Rotation2Base(const RotationNBase& in) : RotationNBase(in) {}
21 | Rotation2Base(const Matrix2x2Base& in) : RotationNBase(in) {}
22 | Rotation2Base(const MatrixNxMBase& in) : RotationNBase(in) {}
23 |
24 | Rotation2Base(T val) { FromAngle(val); }
25 |
26 | Rotation2Base(T R11, T R12, T R21, T R22) {
27 | this->data[0] = R11;
28 | this->data[1] = R12;
29 | this->data[2] = R21;
30 | this->data[3] = R22;
31 | }
32 |
33 | virtual inline bool Equals(const Rotation2Base& that,
34 | const T ptol = 1e-8) const {
35 | return Error(that) < ptol;
36 | }
37 |
38 | inline T Error(const Rotation2Base& r) const {
39 | return math::sin(Angle() - r.Angle());
40 | }
41 |
42 | inline T Angle() const {
43 | return math::atan2(this->data[2], this->data[0]);
44 | }
45 |
46 | inline void FromAngle(T val) {
47 | this->data[0] = math::cos(val);
48 | this->data[1] = -math::sin(val);
49 | this->data[2] = math::sin(val);
50 | this->data[3] = math::cos(val);
51 | }
52 |
53 | inline Eigen::Rotation2D Eigen() {
54 | return Eigen::Rotation2D(Angle());
55 | }
56 | };
57 |
58 | inline Rotation2Base operator*(const float& lhs,
59 | const Rotation2Base& rhs) {
60 | return Rotation2Base(rhs.Scale(lhs));
61 | }
62 |
63 | inline Rotation2Base operator*(const double& lhs,
64 | const Rotation2Base& rhs) {
65 | return Rotation2Base(rhs.Scale(lhs));
66 | }
67 |
68 | template
69 | inline Eigen::Rotation2D Eigen(const Rotation2Base& in) {
70 | return in.Eigen();
71 | }
72 |
73 | typedef Rotation2Base Rotation2f;
74 | typedef Rotation2Base Rot2f;
75 |
76 | typedef Rotation2Base Rotation2d;
77 | typedef Rotation2Base Rot2d;
78 |
79 | typedef Rotation2Base Rotation2;
80 | typedef Rotation2Base Rot2;
81 |
82 | }
83 |
84 | #endif
85 |
--------------------------------------------------------------------------------
/geometry_utils/include/geometry_utils/RotationNBase.h:
--------------------------------------------------------------------------------
1 | #ifndef GEOMETRY_UTILS_ROTATIONN_H
2 | #define GEOMETRY_UTILS_ROTATIONN_H
3 |
4 | #include
5 | #include
6 | #include "VectorNBase.h"
7 | #include "MatrixNxNBase.h"
8 |
9 | namespace geometry_utils {
10 |
11 | template
12 | struct RotationNBase : MatrixNxNBase {
13 | RotationNBase() : MatrixNxNBase() { this->Eye(); }
14 |
15 | RotationNBase(const RotationNBase& in) : MatrixNxNBase(in.data) {}
16 | RotationNBase(const boost::array& in) : MatrixNxNBase(in) {}
17 | RotationNBase(T (&in)[N * N]) : MatrixNxNBase(in) {}
18 | RotationNBase(const Eigen::Matrix& in) : MatrixNxNBase(in) {}
19 | RotationNBase(const MatrixNxNBase& in) : MatrixNxNBase(in) {}
20 |
21 | virtual inline MatrixNxNBase Inv() const {
22 | return this->Trans();
23 | }
24 | };
25 |
26 | template
27 | inline RotationNBase operator*(const float& lhs,
28 | const RotationNBase& rhs) {
29 | return RotationNBase(rhs * lhs);
30 | }
31 |
32 | template
33 | inline RotationNBase operator*(const double& lhs,
34 | const RotationNBase& rhs) {
35 | return RotationNBase(rhs * lhs);
36 | }
37 |
38 | template
39 | inline RotationNBase Inv(const RotationNBase& m) {
40 | return m.Inv();
41 | }
42 |
43 | }
44 |
45 | #endif
46 |
--------------------------------------------------------------------------------
/geometry_utils/include/geometry_utils/Transform2.h:
--------------------------------------------------------------------------------
1 | #ifndef GEOMETRY_UTILS_TRANSFORM2_H
2 | #define GEOMETRY_UTILS_TRANSFORM2_H
3 |
4 | #include "Vector2.h"
5 | #include "Rotation2.h"
6 |
7 | namespace geometry_utils {
8 |
9 | template
10 | struct Transform2Base {
11 | typedef boost::shared_ptr Ptr;
12 | typedef boost::shared_ptr ConstPtr;
13 |
14 | Vector2Base translation;
15 | Rotation2Base rotation;
16 |
17 | Transform2Base() {
18 | translation.Zeros();
19 | rotation.Eye();
20 | }
21 |
22 | Transform2Base(const Vector2Base& translation_,
23 | const Rotation2Base& rotation_)
24 | : translation(translation_), rotation(rotation_) {}
25 |
26 | Transform2Base(const Transform2Base& in)
27 | : translation(in.translation), rotation(in.rotation) {}
28 |
29 | Transform2Base(T x, T y, T th) : translation(x, y), rotation(th) {}
30 |
31 | Transform2Base& operator=(const Transform2Base& rhs) {
32 | if (this == &rhs)
33 | return *this;
34 | translation = rhs.translation;
35 | rotation = rhs.rotation;
36 | return *this;
37 | }
38 |
39 | Vector2Base operator*(const Vector2Base& p) const {
40 | return rotation * p + translation;
41 | }
42 |
43 | Transform2Base operator+(const Transform2Base& t) const {
44 | return Transform2Base(translation + rotation * t.translation,
45 | rotation * t.rotation);
46 | }
47 |
48 | bool operator==(const Transform2Base& that) const {
49 | return this->Equals(that);
50 | }
51 |
52 | bool operator!=(const Transform2Base& that) const {
53 | return !this->Equals(that);
54 | }
55 |
56 | bool Equals(const Transform2Base& that, const T ptol = 1e-5,
57 | const T rtol = 1e-5) const {
58 | return (translation.Equals(that.translation, ptol) &&
59 | rotation.Equals(that.rotation, rtol));
60 | }
61 |
62 | void Print(const std::string& prefix = std::string()) const {
63 | if (!prefix.empty())
64 | std::cout << prefix << std::endl;
65 | std::cout << (*this) << std::endl;
66 | }
67 |
68 | static Transform2Base Identity() {
69 | return Transform2Base();
70 | }
71 | };
72 |
73 | template
74 | std::ostream& operator<<(std::ostream& out, const Transform2Base& m) {
75 | out << "Translation:" << std::endl << m.translation << std::endl;
76 | out << "Rotation:" << std::endl << m.rotation;
77 | return out;
78 | }
79 |
80 | template
81 | Transform2Base PoseUpdate(const Transform2Base& t1,
82 | const Transform2Base& t2) {
83 | return Transform2Base(t1.translation + t1.rotation * t2.translation,
84 | t1.rotation * t2.rotation);
85 | }
86 |
87 | template
88 | Transform2Base PoseInverse(const Transform2Base& t) {
89 | return Transform2Base(-1.0 * t.rotation.Trans() * t.translation,
90 | t.rotation.Trans());
91 | }
92 |
93 | template
94 | Transform2Base PoseDelta(const Transform2Base& t1,
95 | const Transform2Base& t2) {
96 | return Transform2Base(
97 | t1.rotation.Trans() * (t2.translation - t1.translation),
98 | t1.rotation.Trans() * t2.rotation);
99 | }
100 |
101 | typedef Transform2Base Transform2f;
102 | typedef Transform2Base