From a6b34af4eede621c063413257099a19866ac9e11 Mon Sep 17 00:00:00 2001
From: Christoph Gruber
Date: Thu, 10 Jun 2021 14:27:34 +0200
Subject: [PATCH 01/15] migration to ROS2
---
CMakeLists.txt | 162 +++---
LICENSE | 1 +
README.md | 81 ++-
config/params.yaml | 254 ++++-----
.../config => config}/robot.urdf.xacro | 15 +-
config/rviz2.rviz | 263 +++++++++
include/lio_sam/utility.hpp | 442 +++++++++++++++
include/utility.h | 342 ------------
launch/include/config/rviz.rviz | 527 ------------------
launch/include/module_loam.launch | 10 -
launch/include/module_navsat.launch | 20 -
.../module_robot_state_publisher.launch | 11 -
launch/include/module_rviz.launch | 8 -
.../include/rosconsole/rosconsole_error.conf | 2 -
.../include/rosconsole/rosconsole_info.conf | 2 -
.../include/rosconsole/rosconsole_warn.conf | 2 -
launch/run.launch | 20 -
launch/run.launch.py | 73 +++
msg/CloudInfo.msg | 29 +
msg/cloud_info.msg | 29 -
package.xml | 72 +--
src/featureExtraction.cpp | 107 ++--
src/imageProjection.cpp | 181 +++---
src/imuPreintegration.cpp | 225 ++++----
src/mapOptmization.cpp | 407 +++++++-------
srv/save_map.srv | 4 -
26 files changed, 1528 insertions(+), 1761 deletions(-)
rename {launch/include/config => config}/robot.urdf.xacro (70%)
create mode 100644 config/rviz2.rviz
create mode 100644 include/lio_sam/utility.hpp
delete mode 100644 include/utility.h
delete mode 100644 launch/include/config/rviz.rviz
delete mode 100644 launch/include/module_loam.launch
delete mode 100644 launch/include/module_navsat.launch
delete mode 100644 launch/include/module_robot_state_publisher.launch
delete mode 100644 launch/include/module_rviz.launch
delete mode 100644 launch/include/rosconsole/rosconsole_error.conf
delete mode 100644 launch/include/rosconsole/rosconsole_info.conf
delete mode 100644 launch/include/rosconsole/rosconsole_warn.conf
delete mode 100644 launch/run.launch
create mode 100644 launch/run.launch.py
create mode 100644 msg/CloudInfo.msg
delete mode 100644 msg/cloud_info.msg
delete mode 100644 srv/save_map.srv
diff --git a/CMakeLists.txt b/CMakeLists.txt
index a260eab6..04be5d63 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,102 +1,102 @@
-cmake_minimum_required(VERSION 2.8.3)
+cmake_minimum_required(VERSION 3.5)
project(lio_sam)
-set(CMAKE_BUILD_TYPE "Release")
-set(CMAKE_CXX_FLAGS "-std=c++11")
-set(CMAKE_CXX_FLAGS_RELEASE "-O3 -Wall -g -pthread")
-
-find_package(catkin REQUIRED COMPONENTS
- tf
- roscpp
- rospy
- cv_bridge
- # pcl library
- pcl_conversions
- # msgs
- std_msgs
- sensor_msgs
- geometry_msgs
- nav_msgs
- message_generation
- visualization_msgs
+if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
+ set(CMAKE_BUILD_TYPE Release)
+endif()
+
+# find dependencies
+find_package(ament_cmake REQUIRED)
+find_package(rosidl_default_generators REQUIRED)
+find_package(rclcpp REQUIRED)
+find_package(rclpy REQUIRED)
+find_package(cv_bridge REQUIRED)
+find_package(std_msgs REQUIRED)
+find_package(sensor_msgs REQUIRED)
+find_package(geometry_msgs REQUIRED)
+find_package(nav_msgs REQUIRED)
+find_package(visualization_msgs REQUIRED)
+find_package(tf2 REQUIRED)
+find_package(tf2_geometry_msgs REQUIRED)
+find_package(tf2_sensor_msgs REQUIRED)
+find_package(tf2_eigen REQUIRED)
+find_package(tf2_ros REQUIRED)
+find_package(OpenCV REQUIRED)
+find_package(PCL REQUIRED)
+find_package(GTSAM REQUIRED)
+find_package(Eigen REQUIRED)
+
+include_directories(
+ include/lio_sam
)
-find_package(OpenMP REQUIRED)
-find_package(PCL REQUIRED QUIET)
-find_package(OpenCV REQUIRED QUIET)
-find_package(GTSAM REQUIRED QUIET)
+rosidl_generate_interfaces(${PROJECT_NAME} "msg/CloudInfo.msg" DEPENDENCIES std_msgs sensor_msgs)
+
+add_executable(${PROJECT_NAME}_featureExtraction src/featureExtraction.cpp)
+ament_target_dependencies(${PROJECT_NAME}_featureExtraction rclcpp rclpy std_msgs sensor_msgs geometry_msgs nav_msgs tf2 tf2_ros tf2_eigen tf2_sensor_msgs tf2_geometry_msgs OpenCV PCL)
+rosidl_target_interfaces(${PROJECT_NAME}_featureExtraction ${PROJECT_NAME} "rosidl_typesupport_cpp")
+
+add_executable(${PROJECT_NAME}_imageProjection src/imageProjection.cpp)
+ament_target_dependencies(${PROJECT_NAME}_imageProjection rclcpp rclpy std_msgs sensor_msgs geometry_msgs nav_msgs tf2 tf2_ros tf2_eigen tf2_sensor_msgs tf2_geometry_msgs OpenCV PCL)
+rosidl_target_interfaces(${PROJECT_NAME}_imageProjection ${PROJECT_NAME} "rosidl_typesupport_cpp")
-add_message_files(
- DIRECTORY msg
- FILES
- cloud_info.msg
+add_executable(${PROJECT_NAME}_imuPreintegration src/imuPreintegration.cpp)
+ament_target_dependencies(${PROJECT_NAME}_imuPreintegration rclcpp rclpy std_msgs sensor_msgs geometry_msgs nav_msgs tf2 tf2_ros tf2_eigen tf2_sensor_msgs tf2_geometry_msgs OpenCV PCL GTSAM Eigen)
+target_link_libraries(${PROJECT_NAME}_imuPreintegration gtsam)
+rosidl_target_interfaces(${PROJECT_NAME}_imuPreintegration ${PROJECT_NAME} "rosidl_typesupport_cpp")
+
+add_executable(${PROJECT_NAME}_mapOptimization src/mapOptmization.cpp)
+ament_target_dependencies(${PROJECT_NAME}_mapOptimization rclcpp rclpy std_msgs sensor_msgs geometry_msgs nav_msgs visualization_msgs tf2 tf2_ros tf2_eigen tf2_sensor_msgs tf2_geometry_msgs OpenCV PCL GTSAM)
+target_link_libraries(${PROJECT_NAME}_mapOptimization gtsam)
+rosidl_target_interfaces(${PROJECT_NAME}_mapOptimization ${PROJECT_NAME} "rosidl_typesupport_cpp")
+
+install(
+ DIRECTORY launch
+ DESTINATION share/${PROJECT_NAME}/
)
-add_service_files(
- DIRECTORY srv
- FILES
- save_map.srv
+install(
+ DIRECTORY config
+ DESTINATION share/${PROJECT_NAME}/
)
-generate_messages(
- DEPENDENCIES
- geometry_msgs
- std_msgs
- nav_msgs
- sensor_msgs
+install(
+ TARGETS ${PROJECT_NAME}_imageProjection
+ DESTINATION lib/${PROJECT_NAME}
)
-catkin_package(
- INCLUDE_DIRS include
- DEPENDS PCL GTSAM
-
- CATKIN_DEPENDS
- std_msgs
- nav_msgs
- geometry_msgs
- sensor_msgs
- message_runtime
- message_generation
- visualization_msgs
+install(
+ TARGETS ${PROJECT_NAME}_imuPreintegration
+ DESTINATION lib/${PROJECT_NAME}
)
-# include directories
-include_directories(
- include
- ${catkin_INCLUDE_DIRS}
- ${PCL_INCLUDE_DIRS}
- ${OpenCV_INCLUDE_DIRS}
- ${GTSAM_INCLUDE_DIR}
+install(
+ TARGETS ${PROJECT_NAME}_featureExtraction
+ DESTINATION lib/${PROJECT_NAME}
)
-# link directories
-link_directories(
- include
- ${PCL_LIBRARY_DIRS}
- ${OpenCV_LIBRARY_DIRS}
- ${GTSAM_LIBRARY_DIRS}
+install(
+ TARGETS ${PROJECT_NAME}_mapOptimization
+ DESTINATION lib/${PROJECT_NAME}
)
-###########
-## Build ##
-###########
+install(
+ DIRECTORY "include/"
+ DESTINATION include
+)
-# Range Image Projection
-add_executable(${PROJECT_NAME}_imageProjection src/imageProjection.cpp)
-add_dependencies(${PROJECT_NAME}_imageProjection ${catkin_EXPORTED_TARGETS} ${PROJECT_NAME}_generate_messages_cpp)
-target_link_libraries(${PROJECT_NAME}_imageProjection ${catkin_LIBRARIES} ${PCL_LIBRARIES} ${OpenCV_LIBRARIES})
+ament_export_include_directories(include)
-# Feature Association
-add_executable(${PROJECT_NAME}_featureExtraction src/featureExtraction.cpp)
-add_dependencies(${PROJECT_NAME}_featureExtraction ${catkin_EXPORTED_TARGETS} ${PROJECT_NAME}_generate_messages_cpp)
-target_link_libraries(${PROJECT_NAME}_featureExtraction ${catkin_LIBRARIES} ${PCL_LIBRARIES} ${OpenCV_LIBRARIES})
+if(BUILD_TESTING)
+ find_package(ament_lint_auto REQUIRED)
+ # the following line skips the linter which checks for copyrights
+ # uncomment the line when a copyright and license is not present in all source files
+ #set(ament_cmake_copyright_FOUND TRUE)
+ # the following line skips cpplint (only works in a git repo)
+ # uncomment the line when this package is not in a git repo
+ #set(ament_cmake_cpplint_FOUND TRUE)
+ ament_lint_auto_find_test_dependencies()
+endif()
-# Mapping Optimization
-add_executable(${PROJECT_NAME}_mapOptmization src/mapOptmization.cpp)
-add_dependencies(${PROJECT_NAME}_mapOptmization ${catkin_EXPORTED_TARGETS} ${PROJECT_NAME}_generate_messages_cpp)
-target_compile_options(${PROJECT_NAME}_mapOptmization PRIVATE ${OpenMP_CXX_FLAGS})
-target_link_libraries(${PROJECT_NAME}_mapOptmization ${catkin_LIBRARIES} ${PCL_LIBRARIES} ${OpenCV_LIBRARIES} ${OpenMP_CXX_FLAGS} gtsam)
+ament_package()
-# IMU Preintegration
-add_executable(${PROJECT_NAME}_imuPreintegration src/imuPreintegration.cpp)
-target_link_libraries(${PROJECT_NAME}_imuPreintegration ${catkin_LIBRARIES} ${PCL_LIBRARIES} ${OpenCV_LIBRARIES} gtsam)
diff --git a/LICENSE b/LICENSE
index 5df67dcf..d4c5d8db 100755
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,7 @@
BSD 3-Clause License
Copyright (c) 2020, Tixiao Shan
+Copyright (c) 2021, Christoph Gruber
All rights reserved.
Redistribution and use in source and binary forms, with or without
diff --git a/README.md b/README.md
index 1df3ea4b..2bc31da6 100644
--- a/README.md
+++ b/README.md
@@ -17,6 +17,8 @@
- [**System architecture**](#system-architecture)
+ - [**Notes on ROS2 branch**](#notes-on-ros2-branch)
+
- [**Package dependency**](#dependency)
- [**Package install**](#install)
@@ -51,34 +53,47 @@ We design a system that maintains two graphs and runs up to 10x faster than real
- The factor graph in "mapOptimization.cpp" optimizes lidar odometry factor and GPS factor. This factor graph is maintained consistently throughout the whole test.
- The factor graph in "imuPreintegration.cpp" optimizes IMU and lidar odometry factor and estimates IMU bias. This factor graph is reset periodically and guarantees real-time odometry estimation at IMU frequency.
+## Notes on ROS2 branch
+
+There are some features of the original ROS1 version that are currently missing in this ROS2 version, namely:
+- The service for saving maps
+- Testing with Velodyne lidars and Microstrain IMUs
+- A launch file for the navsat module/GPS factor
+- The rviz2 configuration misses many elements
+
+This branch was tested with an Ouster lidar and a Xsens IMU using the following ROS2 drivers:
+- [ros2_ouster_drivers](https://github.com/ros-drivers/ros2_ouster_drivers)
+- [bluespace_ai_xsens_ros_mti_driver](https://github.com/bluespace-ai/bluespace_ai_xsens_ros_mti_driver)
+
+In these tests, the IMU was mounted on the bottom of the lidar such that their x-axes pointed in the same direction. The parameters `extrinsicRot` and `extrinsicRPY` in `params.yaml` correspond to this constellation.
+
## Dependency
-- [ROS](http://wiki.ros.org/ROS/Installation) (tested with Kinetic and Melodic)
+- [ROS2](https://docs.ros.org/en/foxy/Installation.html) (tested with Foxy on Ubuntu 20.04)
```
- sudo apt-get install -y ros-kinetic-navigation
- sudo apt-get install -y ros-kinetic-robot-localization
- sudo apt-get install -y ros-kinetic-robot-state-publisher
+ sudo apt install ros-foxy-perception-pcl \
+ ros-foxy-pcl-msgs \
+ ros-foxy-vision-opencv \
+ ros-foxy-xacro
```
- [gtsam](https://github.com/borglab/gtsam/releases) (Georgia Tech Smoothing and Mapping library)
```
- wget -O ~/Downloads/gtsam.zip https://github.com/borglab/gtsam/archive/4.0.2.zip
- cd ~/Downloads/ && unzip gtsam.zip -d ~/Downloads/
- cd ~/Downloads/gtsam-4.0.2/
- mkdir build && cd build
- cmake -DGTSAM_BUILD_WITH_MARCH_NATIVE=OFF ..
- sudo make install -j8
+ # Add GTSAM-PPA
+ sudo add-apt-repository ppa:borglab/gtsam-release-4.0
+ sudo apt install libgtsam-dev libgtsam-unstable-dev
```
## Install
Use the following commands to download and compile the package.
-```
-cd ~/catkin_ws/src
-git clone https://github.com/TixiaoShan/LIO-SAM.git
-cd ..
-catkin_make
-```
+ ```
+ cd ~/ros2_ws/src
+ git clone https://github.com/TixiaoShan/LIO-SAM.git
+ git checkout ros2
+ cd ..
+ colcon build
+ ```
## Prepare lidar data
@@ -106,34 +121,20 @@ The user needs to prepare the point cloud data in the correct format for cloud d
## Sample datasets
- * Download some sample datasets to test the functionality of the package. The datasets below is configured to run using the default settings:
- - **Walking dataset:** [[Google Drive](https://drive.google.com/drive/folders/1gJHwfdHCRdjP7vuT556pv8atqrCJPbUq?usp=sharing)]
- - **Park dataset:** [[Google Drive](https://drive.google.com/drive/folders/1gJHwfdHCRdjP7vuT556pv8atqrCJPbUq?usp=sharing)]
- - **Garden dataset:** [[Google Drive](https://drive.google.com/drive/folders/1gJHwfdHCRdjP7vuT556pv8atqrCJPbUq?usp=sharing)]
+For data protection reasons, no data set can currently be made available for ROS2.
- * The datasets below need the parameters to be configured. In these datasets, the point cloud topic is "points_raw." The IMU topic is "imu_correct," which gives the IMU data in ROS REP105 standard. Because no IMU transformation is needed for this dataset, the following configurations need to be changed to run this dataset successfully:
- - The "imuTopic" parameter in "config/params.yaml" needs to be set to "imu_correct".
- - The "extrinsicRot" and "extrinsicRPY" in "config/params.yaml" needs to be set as identity matrices.
- - **Rotation dataset:** [[Google Drive](https://drive.google.com/drive/folders/1gJHwfdHCRdjP7vuT556pv8atqrCJPbUq?usp=sharing)]
- - **Campus dataset (large):** [[Google Drive](https://drive.google.com/drive/folders/1gJHwfdHCRdjP7vuT556pv8atqrCJPbUq?usp=sharing)]
- - **Campus dataset (small):** [[Google Drive](https://drive.google.com/drive/folders/1gJHwfdHCRdjP7vuT556pv8atqrCJPbUq?usp=sharing)]
-
- * Ouster (OS1-128) dataset. No extrinsics need to be changed for this dataset if you are using the default settings. Please follow the Ouster notes below to configure the package to run with Ouster data. A video of the dataset can be found on [YouTube](https://youtu.be/O7fKgZQzkEo):
- - **Rooftop dataset:** [[Google Drive](https://drive.google.com/drive/folders/1gJHwfdHCRdjP7vuT556pv8atqrCJPbUq?usp=sharing)]
-
- * KITTI dataset. The extrinsics can be found in the Notes KITTI section below. To generate more bags using other KITTI raw data, you can use the python script provided in "config/doc/kitti2bag".
- - **2011_09_30_drive_0028:** [[Google Drive](https://drive.google.com/drive/folders/1gJHwfdHCRdjP7vuT556pv8atqrCJPbUq?usp=sharing)]
+README.md of the master branch contains some links to ROS1 rosbags. Using [ros1_bridge](https://github.com/ros2/ros1_bridge) with these rosbags and this ROS2 branch of LIO-SAM did however not succeeed for timing reasons.
## Run the package
1. Run the launch file:
```
-roslaunch lio_sam run.launch
+ros2 launch lio_sam run.launch.py
```
2. Play existing bag files:
```
-rosbag play your-bag.bag -r 3
+ros2 bag play your-bag.bag
```
## Other notes
@@ -179,17 +180,6 @@ rosbag play your-bag.bag -r 3
-## Service
- - /lio_sam/save_map
- - save map as a PCD file.
- ``` bash
- rosservice call [service] [resolution] [destination]
- ```
- - Example:
- ``` bash
- $ rosservice call /lio_sam/save_map 0.2 "/Downloads/LOAM/"
- ```
-
## Issues
- **Zigzag or jerking behavior**: if your lidar and IMU data formats are consistent with the requirement of LIO-SAM, this problem is likely caused by un-synced timestamp of lidar and IMU data.
@@ -233,7 +223,6 @@ Part of the code is adapted from [LeGO-LOAM](https://github.com/RobustFieldAuton
## Related Package
- [Lidar-IMU calibration](https://github.com/chennuo0125-HIT/lidar_imu_calib)
- - [LIO-SAM with ROS2](https://github.com/CAKGOD/lio_sam_ros2)
- [LIO-SAM with Scan Context](https://github.com/gisbi-kim/SC-LIO-SAM)
## Acknowledgement
diff --git a/config/params.yaml b/config/params.yaml
index 23f87558..567c6215 100644
--- a/config/params.yaml
+++ b/config/params.yaml
@@ -1,161 +1,93 @@
-lio_sam:
-
- # Topics
- pointCloudTopic: "points_raw" # Point cloud data
- imuTopic: "imu_raw" # IMU data
- odomTopic: "odometry/imu" # IMU pre-preintegration odometry, same frequency as IMU
- gpsTopic: "odometry/gpsz" # GPS odometry topic from navsat, see module_navsat.launch file
-
- # Frames
- lidarFrame: "base_link"
- baselinkFrame: "base_link"
- odometryFrame: "odom"
- mapFrame: "map"
-
- # GPS Settings
- useImuHeadingInitialization: true # if using GPS data, set to "true"
- useGpsElevation: false # if GPS elevation is bad, set to "false"
- gpsCovThreshold: 2.0 # m^2, threshold for using GPS data
- poseCovThreshold: 25.0 # m^2, threshold for using GPS data
-
- # Export settings
- savePCD: false # https://github.com/TixiaoShan/LIO-SAM/issues/3
- savePCDDirectory: "/Downloads/LOAM/" # in your home folder, starts and ends with "/". Warning: the code deletes "LOAM" folder then recreates it. See "mapOptimization" for implementation
-
- # Sensor Settings
- sensor: velodyne # lidar sensor type, either 'velodyne' or 'ouster'
- N_SCAN: 16 # number of lidar channel (i.e., 16, 32, 64, 128)
- Horizon_SCAN: 1800 # lidar horizontal resolution (Velodyne:1800, Ouster:512,1024,2048)
- downsampleRate: 1 # default: 1. Downsample your data if too many points. i.e., 16 = 64 / 4, 16 = 16 / 1
- lidarMinRange: 1.0 # default: 1.0, minimum lidar range to be used
- lidarMaxRange: 1000.0 # default: 1000.0, maximum lidar range to be used
-
- # IMU Settings
- imuAccNoise: 3.9939570888238808e-03
- imuGyrNoise: 1.5636343949698187e-03
- imuAccBiasN: 6.4356659353532566e-05
- imuGyrBiasN: 3.5640318696367613e-05
- imuGravity: 9.80511
- imuRPYWeight: 0.01
-
- # Extrinsics (lidar -> IMU)
- extrinsicTrans: [0.0, 0.0, 0.0]
- extrinsicRot: [-1, 0, 0,
- 0, 1, 0,
- 0, 0, -1]
- extrinsicRPY: [0, 1, 0,
- -1, 0, 0,
- 0, 0, 1]
- # extrinsicRot: [1, 0, 0,
- # 0, 1, 0,
- # 0, 0, 1]
- # extrinsicRPY: [1, 0, 0,
- # 0, 1, 0,
- # 0, 0, 1]
-
- # LOAM feature threshold
- edgeThreshold: 1.0
- surfThreshold: 0.1
- edgeFeatureMinValidNum: 10
- surfFeatureMinValidNum: 100
-
- # voxel filter paprams
- odometrySurfLeafSize: 0.4 # default: 0.4 - outdoor, 0.2 - indoor
- mappingCornerLeafSize: 0.2 # default: 0.2 - outdoor, 0.1 - indoor
- mappingSurfLeafSize: 0.4 # default: 0.4 - outdoor, 0.2 - indoor
-
- # robot motion constraint (in case you are using a 2D robot)
- z_tollerance: 1000 # meters
- rotation_tollerance: 1000 # radians
-
- # CPU Params
- numberOfCores: 4 # number of cores for mapping optimization
- mappingProcessInterval: 0.15 # seconds, regulate mapping frequency
-
- # Surrounding map
- surroundingkeyframeAddingDistThreshold: 1.0 # meters, regulate keyframe adding threshold
- surroundingkeyframeAddingAngleThreshold: 0.2 # radians, regulate keyframe adding threshold
- surroundingKeyframeDensity: 2.0 # meters, downsample surrounding keyframe poses
- surroundingKeyframeSearchRadius: 50.0 # meters, within n meters scan-to-map optimization (when loop closure disabled)
-
- # Loop closure
- loopClosureEnableFlag: true
- loopClosureFrequency: 1.0 # Hz, regulate loop closure constraint add frequency
- surroundingKeyframeSize: 50 # submap size (when loop closure enabled)
- historyKeyframeSearchRadius: 15.0 # meters, key frame that is within n meters from current pose will be considerd for loop closure
- historyKeyframeSearchTimeDiff: 30.0 # seconds, key frame that is n seconds older will be considered for loop closure
- historyKeyframeSearchNum: 25 # number of hostory key frames will be fused into a submap for loop closure
- historyKeyframeFitnessScore: 0.3 # icp threshold, the smaller the better alignment
-
- # Visualization
- globalMapVisualizationSearchRadius: 1000.0 # meters, global map visualization radius
- globalMapVisualizationPoseDensity: 10.0 # meters, global map visualization keyframe density
- globalMapVisualizationLeafSize: 1.0 # meters, global map visualization cloud density
-
-
-
-
-# Navsat (convert GPS coordinates to Cartesian)
-navsat:
- frequency: 50
- wait_for_datum: false
- delay: 0.0
- magnetic_declination_radians: 0
- yaw_offset: 0
- zero_altitude: true
- broadcast_utm_transform: false
- broadcast_utm_transform_as_parent_frame: false
- publish_filtered_gps: false
-
-# EKF for Navsat
-ekf_gps:
- publish_tf: false
- map_frame: map
- odom_frame: odom
- base_link_frame: base_link
- world_frame: odom
-
- frequency: 50
- two_d_mode: false
- sensor_timeout: 0.01
- # -------------------------------------
- # External IMU:
- # -------------------------------------
- imu0: imu_correct
- # make sure the input is aligned with ROS REP105. "imu_correct" is manually transformed by myself. EKF can also transform the data using tf between your imu and base_link
- imu0_config: [false, false, false,
- true, true, true,
- false, false, false,
- false, false, true,
- true, true, true]
- imu0_differential: false
- imu0_queue_size: 50
- imu0_remove_gravitational_acceleration: true
- # -------------------------------------
- # Odometry (From Navsat):
- # -------------------------------------
- odom0: odometry/gps
- odom0_config: [true, true, true,
- false, false, false,
- false, false, false,
- false, false, false,
- false, false, false]
- odom0_differential: false
- odom0_queue_size: 10
-
- # x y z r p y x_dot y_dot z_dot r_dot p_dot y_dot x_ddot y_ddot z_ddot
- process_noise_covariance: [ 1.0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 1.0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 10.0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0.03, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0.03, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0.1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0.25, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0.25, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0.04, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.01, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.01, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.5, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.01, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.01, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.015]
+/lio_sam*:
+ ros__parameters:
+
+ # Topics
+ pointCloudTopic: "/points" # Point cloud data
+ imuTopic: "/imu/data" # IMU data
+ odomTopic: "odometry/imu" # IMU pre-preintegration odometry, same frequency as IMU
+ gpsTopic: "odometry/gpsz" # GPS odometry topic from navsat, see module_navsat.launch file
+
+ # Frames
+ lidarFrame: "lidar_link"
+ baselinkFrame: "base_link"
+ odometryFrame: "odom"
+ mapFrame: "map"
+
+ # GPS Settings
+ useImuHeadingInitialization: false # if using GPS data, set to "true"
+ useGpsElevation: false # if GPS elevation is bad, set to "false"
+ gpsCovThreshold: 2.0 # m^2, threshold for using GPS data
+ poseCovThreshold: 25.0 # m^2, threshold for using GPS data
+
+ # Export settings
+ savePCD: false # https://github.com/TixiaoShan/LIO-SAM/issues/3
+ savePCDDirectory: "/Downloads/LOAM/" # in your home folder, starts and ends with "/". Warning: the code deletes "LOAM" folder then recreates it. See "mapOptimization" for implementation
+
+ # Sensor Settings
+ sensor: ouster # lidar sensor type, either 'velodyne' or 'ouster'
+ N_SCAN: 64 # number of lidar channel (i.e., 16, 32, 64, 128)
+ Horizon_SCAN: 512 # lidar horizontal resolution (Velodyne:1800, Ouster:512,1024,2048)
+ downsampleRate: 1 # default: 1. Downsample your data if too many
+ # points. i.e., 16 = 64 / 4, 16 = 16 / 1
+ lidarMinRange: 1.0 # default: 1.0, minimum lidar range to be used
+ lidarMaxRange: 1000.0 # default: 1000.0, maximum lidar range to be used
+
+ # IMU Settings
+ imuAccNoise: 3.9939570888238808e-03
+ imuGyrNoise: 1.5636343949698187e-03
+ imuAccBiasN: 6.4356659353532566e-05
+ imuGyrBiasN: 3.5640318696367613e-05
+
+ imuGravity: 9.80511
+ imuRPYWeight: 0.01
+
+ extrinsicTrans: [ 0.0, 0.0, 0.0 ]
+ extrinsicRot: [ 1.0, 0.0, 0.0,
+ 0.0, -1.0, 0.0,
+ 0.0, 0.0, -1.0 ]
+ extrinsicRPY: [ 1.0, 0.0, 0.0,
+ 0.0, -1.0, 0.0,
+ 0.0, 0.0, -1.0 ]
+
+ # LOAM feature threshold
+ edgeThreshold: 1.0
+ surfThreshold: 0.1
+ edgeFeatureMinValidNum: 10
+ surfFeatureMinValidNum: 100
+
+ # voxel filter paprams
+ odometrySurfLeafSize: 0.4 # default: 0.4 - outdoor, 0.2 - indoor
+ mappingCornerLeafSize: 0.2 # default: 0.2 - outdoor, 0.1 - indoor
+ mappingSurfLeafSize: 0.4 # default: 0.4 - outdoor, 0.2 - indoor
+
+ # robot motion constraint (in case you are using a 2D robot)
+ z_tollerance: 1000.0 # meters
+ rotation_tollerance: 1000.0 # radians
+
+ # CPU Params
+ numberOfCores: 4 # number of cores for mapping optimization
+ mappingProcessInterval: 0.15 # seconds, regulate mapping frequency
+
+ # Surrounding map
+ surroundingkeyframeAddingDistThreshold: 1.0 # meters, regulate keyframe adding threshold
+ surroundingkeyframeAddingAngleThreshold: 0.2 # radians, regulate keyframe adding threshold
+ surroundingKeyframeDensity: 2.0 # meters, downsample surrounding keyframe poses
+ surroundingKeyframeSearchRadius: 50.0 # meters, within n meters scan-to-map optimization
+ # (when loop closure disabled)
+
+ # Loop closure
+ loopClosureEnableFlag: true
+ loopClosureFrequency: 1.0 # Hz, regulate loop closure constraint add frequency
+ surroundingKeyframeSize: 50 # submap size (when loop closure enabled)
+ historyKeyframeSearchRadius: 15.0 # meters, key frame that is within n meters from
+ # current pose will be considerd for loop closure
+ historyKeyframeSearchTimeDiff: 30.0 # seconds, key frame that is n seconds older will be
+ # considered for loop closure
+ historyKeyframeSearchNum: 25 # number of hostory key frames will be fused into a
+ # submap for loop closure
+ historyKeyframeFitnessScore: 0.3 # icp threshold, the smaller the better alignment
+
+ # Visualization
+ globalMapVisualizationSearchRadius: 1000.0 # meters, global map visualization radius
+ globalMapVisualizationPoseDensity: 10.0 # meters, global map visualization keyframe density
+ globalMapVisualizationLeafSize: 1.0 # meters, global map visualization cloud density
diff --git a/launch/include/config/robot.urdf.xacro b/config/robot.urdf.xacro
similarity index 70%
rename from launch/include/config/robot.urdf.xacro
rename to config/robot.urdf.xacro
index 1e3f31a7..604363e3 100644
--- a/launch/include/config/robot.urdf.xacro
+++ b/config/robot.urdf.xacro
@@ -11,6 +11,13 @@
+
+
+
+
+
+
+
@@ -18,10 +25,10 @@
-
-
-
-
+
+
+
+
diff --git a/config/rviz2.rviz b/config/rviz2.rviz
new file mode 100644
index 00000000..efbc2d4c
--- /dev/null
+++ b/config/rviz2.rviz
@@ -0,0 +1,263 @@
+Panels:
+ - Class: rviz_common/Displays
+ Help Height: 78
+ Name: Displays
+ Property Tree Widget:
+ Expanded:
+ - /Global Options1
+ - /Status1
+ - /PointCloud21
+ - /TF1
+ - /MarkerArray1
+ - /PointCloud22
+ - /PointCloud22/Topic1
+ Splitter Ratio: 0.35384616255760193
+ Tree Height: 787
+ - Class: rviz_common/Selection
+ Name: Selection
+ - Class: rviz_common/Tool Properties
+ Expanded:
+ - /2D Goal Pose1
+ - /Publish Point1
+ Name: Tool Properties
+ Splitter Ratio: 0.5886790156364441
+ - Class: rviz_common/Views
+ Expanded:
+ - /Current View1
+ Name: Views
+ Splitter Ratio: 0.5
+Visualization Manager:
+ Class: ""
+ Displays:
+ - Alpha: 0.5
+ Cell Size: 1
+ Class: rviz_default_plugins/Grid
+ Color: 160; 160; 164
+ Enabled: true
+ Line Style:
+ Line Width: 0.029999999329447746
+ Value: Lines
+ Name: Grid
+ Normal Cell Count: 0
+ Offset:
+ X: 0
+ Y: 0
+ Z: 0
+ Plane: XY
+ Plane Cell Count: 10
+ Reference Frame:
+ Value: true
+ - Alpha: 1
+ Autocompute Intensity Bounds: true
+ Autocompute Value Bounds:
+ Max Value: -0.8519169092178345
+ Min Value: -4.6142706871032715
+ Value: true
+ Axis: Z
+ Channel Name: intensity
+ Class: rviz_default_plugins/PointCloud2
+ Color: 255; 255; 255
+ Color Transformer: AxisColor
+ Decay Time: 1000
+ Enabled: true
+ Invert Rainbow: false
+ Max Color: 255; 255; 255
+ Max Intensity: 92.95751190185547
+ Min Color: 0; 0; 0
+ Min Intensity: 5.530245304107666
+ Name: PointCloud2
+ Position Transformer: XYZ
+ Selectable: true
+ Size (Pixels): 1
+ Size (m): 0.009999999776482582
+ Style: Points
+ Topic:
+ Depth: 5
+ Durability Policy: Volatile
+ History Policy: Keep Last
+ Reliability Policy: Reliable
+ Value: /lio_sam/mapping/cloud_registered
+ Use Fixed Frame: true
+ Use rainbow: true
+ Value: true
+ - Class: rviz_default_plugins/TF
+ Enabled: true
+ Frame Timeout: 15
+ Frames:
+ All Enabled: true
+ base_link:
+ Value: true
+ chassis_link:
+ Value: true
+ imu_link:
+ Value: true
+ map:
+ Value: true
+ navsat_link:
+ Value: true
+ odom:
+ Value: true
+ os0_32/os_sensor:
+ Value: true
+ Marker Scale: 1
+ Name: TF
+ Show Arrows: true
+ Show Axes: true
+ Show Names: false
+ Tree:
+ map:
+ odom:
+ {}
+ Update Interval: 0
+ Value: true
+ - Alpha: 1
+ Buffer Length: 1
+ Class: rviz_default_plugins/Path
+ Color: 85; 255; 255
+ Enabled: true
+ Head Diameter: 0.30000001192092896
+ Head Length: 0.20000000298023224
+ Length: 0.30000001192092896
+ Line Style: Billboards
+ Line Width: 0.029999999329447746
+ Name: Path
+ Offset:
+ X: 0
+ Y: 0
+ Z: 0
+ Pose Color: 255; 85; 255
+ Pose Style: None
+ Radius: 0.029999999329447746
+ Shaft Diameter: 0.10000000149011612
+ Shaft Length: 0.10000000149011612
+ Topic:
+ Depth: 5
+ Durability Policy: Volatile
+ History Policy: Keep Last
+ Reliability Policy: Reliable
+ Value: /lio_sam/mapping/path
+ Value: true
+ - Class: rviz_default_plugins/MarkerArray
+ Enabled: true
+ Name: MarkerArray
+ Namespaces:
+ {}
+ Topic:
+ Depth: 5
+ Durability Policy: Volatile
+ History Policy: Keep Last
+ Reliability Policy: Reliable
+ Value: /lio_sam/mapping/loop_closure_constraints
+ Value: true
+ - Alpha: 1
+ Autocompute Intensity Bounds: true
+ Autocompute Value Bounds:
+ Max Value: 10
+ Min Value: -10
+ Value: true
+ Axis: Z
+ Channel Name: intensity
+ Class: rviz_default_plugins/PointCloud2
+ Color: 255; 255; 255
+ Color Transformer: ""
+ Decay Time: 0
+ Enabled: true
+ Invert Rainbow: false
+ Max Color: 255; 255; 255
+ Max Intensity: 4096
+ Min Color: 0; 0; 0
+ Min Intensity: 0
+ Name: PointCloud2
+ Position Transformer: ""
+ Selectable: true
+ Size (Pixels): 3
+ Size (m): 0.009999999776482582
+ Style: Flat Squares
+ Topic:
+ Depth: 5
+ Durability Policy: Volatile
+ History Policy: Keep Last
+ Reliability Policy: System Default
+ Value: /points
+ Use Fixed Frame: true
+ Use rainbow: true
+ Value: true
+ Enabled: true
+ Global Options:
+ Background Color: 48; 48; 48
+ Fixed Frame: map
+ Frame Rate: 30
+ Name: root
+ Tools:
+ - Class: rviz_default_plugins/Interact
+ Hide Inactive Objects: true
+ - Class: rviz_default_plugins/MoveCamera
+ - Class: rviz_default_plugins/Select
+ - Class: rviz_default_plugins/FocusCamera
+ - Class: rviz_default_plugins/Measure
+ Line color: 128; 128; 0
+ - Class: rviz_default_plugins/SetInitialPose
+ Topic:
+ Depth: 5
+ Durability Policy: Volatile
+ History Policy: Keep Last
+ Reliability Policy: Reliable
+ Value: /initialpose
+ - Class: rviz_default_plugins/SetGoal
+ Topic:
+ Depth: 5
+ Durability Policy: Volatile
+ History Policy: Keep Last
+ Reliability Policy: Reliable
+ Value: /goal_pose
+ - Class: rviz_default_plugins/PublishPoint
+ Single click: true
+ Topic:
+ Depth: 5
+ Durability Policy: Volatile
+ History Policy: Keep Last
+ Reliability Policy: Reliable
+ Value: /clicked_point
+ Transformation:
+ Current:
+ Class: rviz_default_plugins/TF
+ Value: true
+ Views:
+ Current:
+ Class: rviz_default_plugins/Orbit
+ Distance: 142.68260192871094
+ Enable Stereo Rendering:
+ Stereo Eye Separation: 0.05999999865889549
+ Stereo Focal Distance: 1
+ Swap Stereo Eyes: false
+ Value: false
+ Focal Point:
+ X: 0
+ Y: 0
+ Z: 0
+ Focal Shape Fixed Size: true
+ Focal Shape Size: 0.05000000074505806
+ Invert Z Axis: false
+ Name: Current View
+ Near Clip Distance: 0.009999999776482582
+ Pitch: 0.47039806842803955
+ Target Frame:
+ Value: Orbit (rviz)
+ Yaw: 0.5903979539871216
+ Saved: ~
+Window Geometry:
+ Displays:
+ collapsed: false
+ Height: 1016
+ Hide Left Dock: false
+ Hide Right Dock: false
+ QMainWindow State: 000000ff00000000fd00000004000000000000020a0000039efc0200000008fb0000001200530065006c0065006300740069006f006e00000001e10000009b0000005c00fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed000001df00000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073010000003d0000039e000000c900fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261000000010000010f0000039efc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a00560069006500770073010000003d0000039e000000a400fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e10000019700000003000004420000003efc0100000002fb0000000800540069006d00650100000000000004420000000000000000fb0000000800540069006d00650100000000000004500000000000000000000004130000039e00000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000
+ Selection:
+ collapsed: false
+ Tool Properties:
+ collapsed: false
+ Views:
+ collapsed: false
+ Width: 1848
+ X: 72
+ Y: 27
diff --git a/include/lio_sam/utility.hpp b/include/lio_sam/utility.hpp
new file mode 100644
index 00000000..6c9e15d6
--- /dev/null
+++ b/include/lio_sam/utility.hpp
@@ -0,0 +1,442 @@
+#pragma once
+#ifndef _UTILITY_LIDAR_ODOMETRY_H_
+#define _UTILITY_LIDAR_ODOMETRY_H_
+
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+using namespace std;
+
+typedef pcl::PointXYZI PointType;
+
+enum class SensorType { VELODYNE, OUSTER };
+
+class ParamServer : public rclcpp::Node
+{
+public:
+ std::string robot_id;
+
+ //Topics
+ string pointCloudTopic;
+ string imuTopic;
+ string odomTopic;
+ string gpsTopic;
+
+ //Frames
+ string lidarFrame;
+ string baselinkFrame;
+ string odometryFrame;
+ string mapFrame;
+
+ // GPS Settings
+ bool useImuHeadingInitialization;
+ bool useGpsElevation;
+ float gpsCovThreshold;
+ float poseCovThreshold;
+
+ // Save pcd
+ bool savePCD;
+ string savePCDDirectory;
+
+ // Lidar Sensor Configuration
+ SensorType sensor = SensorType::OUSTER;
+ int N_SCAN;
+ int Horizon_SCAN;
+ int downsampleRate;
+ float lidarMinRange;
+ float lidarMaxRange;
+
+ // IMU
+ float imuAccNoise;
+ float imuGyrNoise;
+ float imuAccBiasN;
+ float imuGyrBiasN;
+ float imuGravity;
+ float imuRPYWeight;
+ vector extRotV;
+ vector extRPYV;
+ vector extTransV;
+ Eigen::Matrix3d extRot;
+ Eigen::Matrix3d extRPY;
+ Eigen::Vector3d extTrans;
+ Eigen::Quaterniond extQRPY;
+
+ // LOAM
+ float edgeThreshold;
+ float surfThreshold;
+ int edgeFeatureMinValidNum;
+ int surfFeatureMinValidNum;
+
+ // voxel filter paprams
+ float odometrySurfLeafSize;
+ float mappingCornerLeafSize;
+ float mappingSurfLeafSize ;
+
+ float z_tollerance;
+ float rotation_tollerance;
+
+ // CPU Params
+ int numberOfCores;
+ double mappingProcessInterval;
+
+ // Surrounding map
+ float surroundingkeyframeAddingDistThreshold;
+ float surroundingkeyframeAddingAngleThreshold;
+ float surroundingKeyframeDensity;
+ float surroundingKeyframeSearchRadius;
+
+ // Loop closure
+ bool loopClosureEnableFlag;
+ float loopClosureFrequency;
+ int surroundingKeyframeSize;
+ float historyKeyframeSearchRadius;
+ float historyKeyframeSearchTimeDiff;
+ int historyKeyframeSearchNum;
+ float historyKeyframeFitnessScore;
+
+ // global map visualization radius
+ float globalMapVisualizationSearchRadius;
+ float globalMapVisualizationPoseDensity;
+ float globalMapVisualizationLeafSize;
+
+ ParamServer(std::string node_name, const rclcpp::NodeOptions & options) : Node(node_name, options)
+ {
+ declare_parameter("pointCloudTopic", "points");
+ get_parameter("pointCloudTopic", pointCloudTopic);
+ declare_parameter("imuTopic", "imu/data");
+ get_parameter("imuTopic", imuTopic);
+ declare_parameter("odomTopic", "lio_sam/odometry/imu");
+ get_parameter("odomTopic", odomTopic);
+ declare_parameter("gpsTopic", "lio_sam/odometry/gps");
+ get_parameter("gpsTopic", gpsTopic);
+
+ declare_parameter("lidarFrame", "laser_data_frame");
+ get_parameter("lidarFrame", lidarFrame);
+ declare_parameter("baselinkFrame", "base_link");
+ get_parameter("baselinkFrame", baselinkFrame);
+ declare_parameter("odometryFrame", "odom");
+ get_parameter("odometryFrame", odometryFrame);
+ declare_parameter("mapFrame", "map");
+ get_parameter("mapFrame", mapFrame);
+
+ declare_parameter("useImuHeadingInitialization", false);
+ get_parameter("useImuHeadingInitialization", useImuHeadingInitialization);
+ declare_parameter("useGpsElevation", false);
+ get_parameter("useGpsElevation", useGpsElevation);
+ declare_parameter("gpsCovThreshold", 2.0);
+ get_parameter("gpsCovThreshold", gpsCovThreshold);
+ declare_parameter("poseCovThreshold", 25.0);
+ get_parameter("poseCovThreshold", poseCovThreshold);
+
+ declare_parameter("savePCD", false);
+ get_parameter("savePCD", savePCD);
+
+ declare_parameter("savePCDDirectory", "/Downloads/LOAM/");
+ get_parameter("savePCDDirectory", savePCDDirectory);
+
+ declare_parameter("N_SCAN", 64);
+ get_parameter("N_SCAN", N_SCAN);
+ declare_parameter("Horizon_SCAN", 512);
+ get_parameter("Horizon_SCAN", Horizon_SCAN);
+ declare_parameter("downsampleRate", 1);
+ get_parameter("downsampleRate", downsampleRate);
+ declare_parameter("lidarMinRange", 5.5);
+ get_parameter("lidarMinRange", lidarMinRange);
+ declare_parameter("lidarMaxRange", 1000.0);
+ get_parameter("lidarMaxRange", lidarMaxRange);
+
+ declare_parameter("imuAccNoise", 9e-4);
+ get_parameter("imuAccNoise", imuAccNoise);
+ declare_parameter("imuGyrNoise", 1.6e-4);
+ get_parameter("imuGyrNoise", imuGyrNoise);
+ declare_parameter("imuAccBiasN", 5e-4);
+ get_parameter("imuAccBiasN", imuAccBiasN);
+ declare_parameter("imuGyrBiasN", 7e-5);
+ get_parameter("imuGyrBiasN", imuGyrBiasN);
+ declare_parameter("imuGravity", 9.80511);
+ get_parameter("imuGravity", imuGravity);
+ declare_parameter("imuRPYWeight", 0.01);
+ get_parameter("imuRPYWeight", imuRPYWeight);
+
+ double ida[] = { 1.0, 0.0, 0.0,
+ 0.0, 1.0, 0.0,
+ 0.0, 0.0, 1.0};
+ std::vector < double > id(ida, std::end(ida));
+ declare_parameter("extrinsicRot", id);
+ get_parameter("extrinsicRot", extRotV);
+ declare_parameter("extrinsicRPY", id);
+ get_parameter("extrinsicRPY", extRPYV);
+ double zea[] = {0.0, 0.0, 0.0};
+ std::vector < double > ze(zea, std::end(zea));
+ declare_parameter("extrinsicTrans", ze);
+ get_parameter("extrinsicTrans", extTransV);
+
+ extRot = Eigen::Map>(extRotV.data(), 3, 3);
+ extRPY = Eigen::Map>(extRPYV.data(), 3, 3);
+ extTrans = Eigen::Map>(extTransV.data(), 3, 1);
+ extQRPY = Eigen::Quaterniond(extRPY);
+
+ declare_parameter("edgeThreshold", 1.0);
+ get_parameter("edgeThreshold", edgeThreshold);
+ declare_parameter("surfThreshold", 0.1);
+ get_parameter("surfThreshold", surfThreshold);
+ declare_parameter("edgeFeatureMinValidNum", 10);
+ get_parameter("edgeFeatureMinValidNum", edgeFeatureMinValidNum);
+ declare_parameter("surfFeatureMinValidNum", 100);
+ get_parameter("surfFeatureMinValidNum", surfFeatureMinValidNum);
+
+ declare_parameter("odometrySurfLeafSize", 0.4);
+ get_parameter("odometrySurfLeafSize", odometrySurfLeafSize);
+ declare_parameter("mappingCornerLeafSize", 0.2);
+ get_parameter("mappingCornerLeafSize", mappingCornerLeafSize);
+ declare_parameter("mappingSurfLeafSize", 0.4);
+ get_parameter("mappingSurfLeafSize", mappingSurfLeafSize);
+
+ declare_parameter("z_tollerance", 1000.0);
+ get_parameter("z_tollerance", z_tollerance);
+ declare_parameter("rotation_tollerance", 1000.0);
+ get_parameter("rotation_tollerance", rotation_tollerance);
+
+ declare_parameter("numberOfCores", 4);
+ get_parameter("numberOfCores", numberOfCores);
+ declare_parameter("mappingProcessInterval", 0.15);
+ get_parameter("mappingProcessInterval", mappingProcessInterval);
+
+ declare_parameter("surroundingkeyframeAddingDistThreshold", 1.0);
+ get_parameter("surroundingkeyframeAddingDistThreshold", surroundingkeyframeAddingDistThreshold);
+ declare_parameter("surroundingkeyframeAddingAngleThreshold", 0.2);
+ get_parameter("surroundingkeyframeAddingAngleThreshold", surroundingkeyframeAddingAngleThreshold);
+ declare_parameter("surroundingKeyframeDensity", 2.0);
+ get_parameter("surroundingKeyframeDensity", surroundingKeyframeDensity);
+ declare_parameter("surroundingKeyframeSearchRadius", 50.0);
+ get_parameter("surroundingKeyframeSearchRadius", surroundingKeyframeSearchRadius);
+
+ declare_parameter("loopClosureEnableFlag", true);
+ get_parameter("loopClosureEnableFlag", loopClosureEnableFlag);
+ declare_parameter("loopClosureFrequency", 1.0);
+ get_parameter("loopClosureFrequency", loopClosureFrequency);
+ declare_parameter("surroundingKeyframeSize", 50);
+ get_parameter("surroundingKeyframeSize", surroundingKeyframeSize);
+ declare_parameter("historyKeyframeSearchRadius", 15.0);
+ get_parameter("historyKeyframeSearchRadius", historyKeyframeSearchRadius);
+ declare_parameter("historyKeyframeSearchTimeDiff", 30.0);
+ get_parameter("historyKeyframeSearchTimeDiff", historyKeyframeSearchTimeDiff);
+ declare_parameter("historyKeyframeSearchNum", 25);
+ get_parameter("historyKeyframeSearchNum", historyKeyframeSearchNum);
+ declare_parameter("historyKeyframeFitnessScore", 0.3);
+ get_parameter("historyKeyframeFitnessScore", historyKeyframeFitnessScore);
+
+ declare_parameter("globalMapVisualizationSearchRadius", 1000.0);
+ get_parameter("globalMapVisualizationSearchRadius", globalMapVisualizationSearchRadius);
+ declare_parameter("globalMapVisualizationPoseDensity", 10.0);
+ get_parameter("globalMapVisualizationPoseDensity", globalMapVisualizationPoseDensity);
+ declare_parameter("globalMapVisualizationLeafSize", 1.0);
+ get_parameter("globalMapVisualizationLeafSize", globalMapVisualizationLeafSize);
+
+ usleep(100);
+ }
+
+ sensor_msgs::msg::Imu imuConverter(const sensor_msgs::msg::Imu& imu_in)
+ {
+ sensor_msgs::msg::Imu imu_out = imu_in;
+ // rotate acceleration
+ Eigen::Vector3d acc(imu_in.linear_acceleration.x, imu_in.linear_acceleration.y, imu_in.linear_acceleration.z);
+ acc = extRot * acc;
+ imu_out.linear_acceleration.x = acc.x();
+ imu_out.linear_acceleration.y = acc.y();
+ imu_out.linear_acceleration.z = acc.z();
+ // rotate gyroscope
+ Eigen::Vector3d gyr(imu_in.angular_velocity.x, imu_in.angular_velocity.y, imu_in.angular_velocity.z);
+ gyr = extRot * gyr;
+ imu_out.angular_velocity.x = gyr.x();
+ imu_out.angular_velocity.y = gyr.y();
+ imu_out.angular_velocity.z = gyr.z();
+ // rotate roll pitch yaw
+ Eigen::Quaterniond q_from(imu_in.orientation.w, imu_in.orientation.x, imu_in.orientation.y, imu_in.orientation.z);
+ Eigen::Quaterniond q_final = q_from * extQRPY;
+ imu_out.orientation.x = q_final.x();
+ imu_out.orientation.y = q_final.y();
+ imu_out.orientation.z = q_final.z();
+ imu_out.orientation.w = q_final.w();
+
+ if (sqrt(q_final.x()*q_final.x() + q_final.y()*q_final.y() + q_final.z()*q_final.z() + q_final.w()*q_final.w()) < 0.1)
+ {
+ RCLCPP_ERROR(get_logger(), "Invalid quaternion, please use a 9-axis IMU!");
+ rclcpp::shutdown();
+ }
+
+ return imu_out;
+ }
+};
+
+
+sensor_msgs::msg::PointCloud2 publishCloud(rclcpp::Publisher::SharedPtr thisPub, pcl::PointCloud::Ptr thisCloud, rclcpp::Time thisStamp, std::string thisFrame)
+{
+ sensor_msgs::msg::PointCloud2 tempCloud;
+ pcl::toROSMsg(*thisCloud, tempCloud);
+ tempCloud.header.stamp = thisStamp;
+ tempCloud.header.frame_id = thisFrame;
+ if (thisPub->get_subscription_count() != 0)
+ thisPub->publish(tempCloud);
+ return tempCloud;
+}
+
+template
+double stamp2Sec(const T& stamp)
+{
+ return rclcpp::Time(stamp).seconds();
+}
+
+
+template
+void imuAngular2rosAngular(sensor_msgs::msg::Imu *thisImuMsg, T *angular_x, T *angular_y, T *angular_z)
+{
+ *angular_x = thisImuMsg->angular_velocity.x;
+ *angular_y = thisImuMsg->angular_velocity.y;
+ *angular_z = thisImuMsg->angular_velocity.z;
+}
+
+
+template
+void imuAccel2rosAccel(sensor_msgs::msg::Imu *thisImuMsg, T *acc_x, T *acc_y, T *acc_z)
+{
+ *acc_x = thisImuMsg->linear_acceleration.x;
+ *acc_y = thisImuMsg->linear_acceleration.y;
+ *acc_z = thisImuMsg->linear_acceleration.z;
+}
+
+
+template
+void imuRPY2rosRPY(sensor_msgs::msg::Imu *thisImuMsg, T *rosRoll, T *rosPitch, T *rosYaw)
+{
+ double imuRoll, imuPitch, imuYaw;
+ tf2::Quaternion orientation;
+ tf2::fromMsg(thisImuMsg->orientation, orientation);
+ tf2::Matrix3x3(orientation).getRPY(imuRoll, imuPitch, imuYaw);
+
+ *rosRoll = imuRoll;
+ *rosPitch = imuPitch;
+ *rosYaw = imuYaw;
+}
+
+
+float pointDistance(PointType p)
+{
+ return sqrt(p.x*p.x + p.y*p.y + p.z*p.z);
+}
+
+
+float pointDistance(PointType p1, PointType p2)
+{
+ return sqrt((p1.x-p2.x)*(p1.x-p2.x) + (p1.y-p2.y)*(p1.y-p2.y) + (p1.z-p2.z)*(p1.z-p2.z));
+}
+
+rmw_qos_profile_t qos_profile{
+ RMW_QOS_POLICY_HISTORY_KEEP_LAST,
+ 1,
+ RMW_QOS_POLICY_RELIABILITY_BEST_EFFORT,
+ RMW_QOS_POLICY_DURABILITY_VOLATILE,
+ RMW_QOS_DEADLINE_DEFAULT,
+ RMW_QOS_LIFESPAN_DEFAULT,
+ RMW_QOS_POLICY_LIVELINESS_SYSTEM_DEFAULT,
+ RMW_QOS_LIVELINESS_LEASE_DURATION_DEFAULT,
+ false
+};
+
+auto qos = rclcpp::QoS(
+ rclcpp::QoSInitialization(
+ qos_profile.history,
+ qos_profile.depth
+ ),
+ qos_profile);
+
+rmw_qos_profile_t qos_profile_imu{
+ RMW_QOS_POLICY_HISTORY_KEEP_LAST,
+ 2000,
+ RMW_QOS_POLICY_RELIABILITY_BEST_EFFORT,
+ RMW_QOS_POLICY_DURABILITY_VOLATILE,
+ RMW_QOS_DEADLINE_DEFAULT,
+ RMW_QOS_LIFESPAN_DEFAULT,
+ RMW_QOS_POLICY_LIVELINESS_SYSTEM_DEFAULT,
+ RMW_QOS_LIVELINESS_LEASE_DURATION_DEFAULT,
+ false
+};
+
+auto qos_imu = rclcpp::QoS(
+ rclcpp::QoSInitialization(
+ qos_profile_imu.history,
+ qos_profile_imu.depth
+ ),
+ qos_profile_imu);
+
+rmw_qos_profile_t qos_profile_lidar{
+ RMW_QOS_POLICY_HISTORY_KEEP_LAST,
+ 5,
+ RMW_QOS_POLICY_RELIABILITY_BEST_EFFORT,
+ RMW_QOS_POLICY_DURABILITY_VOLATILE,
+ RMW_QOS_DEADLINE_DEFAULT,
+ RMW_QOS_LIFESPAN_DEFAULT,
+ RMW_QOS_POLICY_LIVELINESS_SYSTEM_DEFAULT,
+ RMW_QOS_LIVELINESS_LEASE_DURATION_DEFAULT,
+ false
+};
+
+auto qos_lidar = rclcpp::QoS(
+ rclcpp::QoSInitialization(
+ qos_profile_lidar.history,
+ qos_profile_lidar.depth
+ ),
+ qos_profile_lidar);
+
+#endif
diff --git a/include/utility.h b/include/utility.h
deleted file mode 100644
index c1f5feff..00000000
--- a/include/utility.h
+++ /dev/null
@@ -1,342 +0,0 @@
-#pragma once
-#ifndef _UTILITY_LIDAR_ODOMETRY_H_
-#define _UTILITY_LIDAR_ODOMETRY_H_
-
-#include
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-#include
-#include
-#include
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-using namespace std;
-
-typedef pcl::PointXYZI PointType;
-
-enum class SensorType { VELODYNE, OUSTER };
-
-class ParamServer
-{
-public:
-
- ros::NodeHandle nh;
-
- std::string robot_id;
-
- //Topics
- string pointCloudTopic;
- string imuTopic;
- string odomTopic;
- string gpsTopic;
-
- //Frames
- string lidarFrame;
- string baselinkFrame;
- string odometryFrame;
- string mapFrame;
-
- // GPS Settings
- bool useImuHeadingInitialization;
- bool useGpsElevation;
- float gpsCovThreshold;
- float poseCovThreshold;
-
- // Save pcd
- bool savePCD;
- string savePCDDirectory;
-
- // Lidar Sensor Configuration
- SensorType sensor;
- int N_SCAN;
- int Horizon_SCAN;
- int downsampleRate;
- float lidarMinRange;
- float lidarMaxRange;
-
- // IMU
- float imuAccNoise;
- float imuGyrNoise;
- float imuAccBiasN;
- float imuGyrBiasN;
- float imuGravity;
- float imuRPYWeight;
- vector extRotV;
- vector extRPYV;
- vector extTransV;
- Eigen::Matrix3d extRot;
- Eigen::Matrix3d extRPY;
- Eigen::Vector3d extTrans;
- Eigen::Quaterniond extQRPY;
-
- // LOAM
- float edgeThreshold;
- float surfThreshold;
- int edgeFeatureMinValidNum;
- int surfFeatureMinValidNum;
-
- // voxel filter paprams
- float odometrySurfLeafSize;
- float mappingCornerLeafSize;
- float mappingSurfLeafSize ;
-
- float z_tollerance;
- float rotation_tollerance;
-
- // CPU Params
- int numberOfCores;
- double mappingProcessInterval;
-
- // Surrounding map
- float surroundingkeyframeAddingDistThreshold;
- float surroundingkeyframeAddingAngleThreshold;
- float surroundingKeyframeDensity;
- float surroundingKeyframeSearchRadius;
-
- // Loop closure
- bool loopClosureEnableFlag;
- float loopClosureFrequency;
- int surroundingKeyframeSize;
- float historyKeyframeSearchRadius;
- float historyKeyframeSearchTimeDiff;
- int historyKeyframeSearchNum;
- float historyKeyframeFitnessScore;
-
- // global map visualization radius
- float globalMapVisualizationSearchRadius;
- float globalMapVisualizationPoseDensity;
- float globalMapVisualizationLeafSize;
-
- ParamServer()
- {
- nh.param("/robot_id", robot_id, "roboat");
-
- nh.param("lio_sam/pointCloudTopic", pointCloudTopic, "points_raw");
- nh.param("lio_sam/imuTopic", imuTopic, "imu_correct");
- nh.param("lio_sam/odomTopic", odomTopic, "odometry/imu");
- nh.param("lio_sam/gpsTopic", gpsTopic, "odometry/gps");
-
- nh.param("lio_sam/lidarFrame", lidarFrame, "base_link");
- nh.param("lio_sam/baselinkFrame", baselinkFrame, "base_link");
- nh.param("lio_sam/odometryFrame", odometryFrame, "odom");
- nh.param("lio_sam/mapFrame", mapFrame, "map");
-
- nh.param("lio_sam/useImuHeadingInitialization", useImuHeadingInitialization, false);
- nh.param("lio_sam/useGpsElevation", useGpsElevation, false);
- nh.param("lio_sam/gpsCovThreshold", gpsCovThreshold, 2.0);
- nh.param("lio_sam/poseCovThreshold", poseCovThreshold, 25.0);
-
- nh.param("lio_sam/savePCD", savePCD, false);
- nh.param("lio_sam/savePCDDirectory", savePCDDirectory, "/Downloads/LOAM/");
-
- std::string sensorStr;
- nh.param("lio_sam/sensor", sensorStr, "");
- if (sensorStr == "velodyne")
- {
- sensor = SensorType::VELODYNE;
- }
- else if (sensorStr == "ouster")
- {
- sensor = SensorType::OUSTER;
- }
- else
- {
- ROS_ERROR_STREAM(
- "Invalid sensor type (must be either 'velodyne' or 'ouster'): " << sensorStr);
- ros::shutdown();
- }
-
- nh.param("lio_sam/N_SCAN", N_SCAN, 16);
- nh.param("lio_sam/Horizon_SCAN", Horizon_SCAN, 1800);
- nh.param("lio_sam/downsampleRate", downsampleRate, 1);
- nh.param("lio_sam/lidarMinRange", lidarMinRange, 1.0);
- nh.param("lio_sam/lidarMaxRange", lidarMaxRange, 1000.0);
-
- nh.param("lio_sam/imuAccNoise", imuAccNoise, 0.01);
- nh.param("lio_sam/imuGyrNoise", imuGyrNoise, 0.001);
- nh.param("lio_sam/imuAccBiasN", imuAccBiasN, 0.0002);
- nh.param("lio_sam/imuGyrBiasN", imuGyrBiasN, 0.00003);
- nh.param("lio_sam/imuGravity", imuGravity, 9.80511);
- nh.param("lio_sam/imuRPYWeight", imuRPYWeight, 0.01);
- nh.param>("lio_sam/extrinsicRot", extRotV, vector());
- nh.param>("lio_sam/extrinsicRPY", extRPYV, vector());
- nh.param>("lio_sam/extrinsicTrans", extTransV, vector());
- extRot = Eigen::Map>(extRotV.data(), 3, 3);
- extRPY = Eigen::Map>(extRPYV.data(), 3, 3);
- extTrans = Eigen::Map>(extTransV.data(), 3, 1);
- extQRPY = Eigen::Quaterniond(extRPY);
-
- nh.param("lio_sam/edgeThreshold", edgeThreshold, 0.1);
- nh.param("lio_sam/surfThreshold", surfThreshold, 0.1);
- nh.param("lio_sam/edgeFeatureMinValidNum", edgeFeatureMinValidNum, 10);
- nh.param("lio_sam/surfFeatureMinValidNum", surfFeatureMinValidNum, 100);
-
- nh.param("lio_sam/odometrySurfLeafSize", odometrySurfLeafSize, 0.2);
- nh.param("lio_sam/mappingCornerLeafSize", mappingCornerLeafSize, 0.2);
- nh.param("lio_sam/mappingSurfLeafSize", mappingSurfLeafSize, 0.2);
-
- nh.param("lio_sam/z_tollerance", z_tollerance, FLT_MAX);
- nh.param("lio_sam/rotation_tollerance", rotation_tollerance, FLT_MAX);
-
- nh.param("lio_sam/numberOfCores", numberOfCores, 2);
- nh.param("lio_sam/mappingProcessInterval", mappingProcessInterval, 0.15);
-
- nh.param("lio_sam/surroundingkeyframeAddingDistThreshold", surroundingkeyframeAddingDistThreshold, 1.0);
- nh.param("lio_sam/surroundingkeyframeAddingAngleThreshold", surroundingkeyframeAddingAngleThreshold, 0.2);
- nh.param("lio_sam/surroundingKeyframeDensity", surroundingKeyframeDensity, 1.0);
- nh.param("lio_sam/surroundingKeyframeSearchRadius", surroundingKeyframeSearchRadius, 50.0);
-
- nh.param("lio_sam/loopClosureEnableFlag", loopClosureEnableFlag, false);
- nh.param("lio_sam/loopClosureFrequency", loopClosureFrequency, 1.0);
- nh.param("lio_sam/surroundingKeyframeSize", surroundingKeyframeSize, 50);
- nh.param("lio_sam/historyKeyframeSearchRadius", historyKeyframeSearchRadius, 10.0);
- nh.param("lio_sam/historyKeyframeSearchTimeDiff", historyKeyframeSearchTimeDiff, 30.0);
- nh.param("lio_sam/historyKeyframeSearchNum", historyKeyframeSearchNum, 25);
- nh.param("lio_sam/historyKeyframeFitnessScore", historyKeyframeFitnessScore, 0.3);
-
- nh.param("lio_sam/globalMapVisualizationSearchRadius", globalMapVisualizationSearchRadius, 1e3);
- nh.param("lio_sam/globalMapVisualizationPoseDensity", globalMapVisualizationPoseDensity, 10.0);
- nh.param("lio_sam/globalMapVisualizationLeafSize", globalMapVisualizationLeafSize, 1.0);
-
- usleep(100);
- }
-
- sensor_msgs::Imu imuConverter(const sensor_msgs::Imu& imu_in)
- {
- sensor_msgs::Imu imu_out = imu_in;
- // rotate acceleration
- Eigen::Vector3d acc(imu_in.linear_acceleration.x, imu_in.linear_acceleration.y, imu_in.linear_acceleration.z);
- acc = extRot * acc;
- imu_out.linear_acceleration.x = acc.x();
- imu_out.linear_acceleration.y = acc.y();
- imu_out.linear_acceleration.z = acc.z();
- // rotate gyroscope
- Eigen::Vector3d gyr(imu_in.angular_velocity.x, imu_in.angular_velocity.y, imu_in.angular_velocity.z);
- gyr = extRot * gyr;
- imu_out.angular_velocity.x = gyr.x();
- imu_out.angular_velocity.y = gyr.y();
- imu_out.angular_velocity.z = gyr.z();
- // rotate roll pitch yaw
- Eigen::Quaterniond q_from(imu_in.orientation.w, imu_in.orientation.x, imu_in.orientation.y, imu_in.orientation.z);
- Eigen::Quaterniond q_final = q_from * extQRPY;
- imu_out.orientation.x = q_final.x();
- imu_out.orientation.y = q_final.y();
- imu_out.orientation.z = q_final.z();
- imu_out.orientation.w = q_final.w();
-
- if (sqrt(q_final.x()*q_final.x() + q_final.y()*q_final.y() + q_final.z()*q_final.z() + q_final.w()*q_final.w()) < 0.1)
- {
- ROS_ERROR("Invalid quaternion, please use a 9-axis IMU!");
- ros::shutdown();
- }
-
- return imu_out;
- }
-};
-
-
-sensor_msgs::PointCloud2 publishCloud(ros::Publisher *thisPub, pcl::PointCloud::Ptr thisCloud, ros::Time thisStamp, std::string thisFrame)
-{
- sensor_msgs::PointCloud2 tempCloud;
- pcl::toROSMsg(*thisCloud, tempCloud);
- tempCloud.header.stamp = thisStamp;
- tempCloud.header.frame_id = thisFrame;
- if (thisPub->getNumSubscribers() != 0)
- thisPub->publish(tempCloud);
- return tempCloud;
-}
-
-template
-double ROS_TIME(T msg)
-{
- return msg->header.stamp.toSec();
-}
-
-
-template
-void imuAngular2rosAngular(sensor_msgs::Imu *thisImuMsg, T *angular_x, T *angular_y, T *angular_z)
-{
- *angular_x = thisImuMsg->angular_velocity.x;
- *angular_y = thisImuMsg->angular_velocity.y;
- *angular_z = thisImuMsg->angular_velocity.z;
-}
-
-
-template
-void imuAccel2rosAccel(sensor_msgs::Imu *thisImuMsg, T *acc_x, T *acc_y, T *acc_z)
-{
- *acc_x = thisImuMsg->linear_acceleration.x;
- *acc_y = thisImuMsg->linear_acceleration.y;
- *acc_z = thisImuMsg->linear_acceleration.z;
-}
-
-
-template
-void imuRPY2rosRPY(sensor_msgs::Imu *thisImuMsg, T *rosRoll, T *rosPitch, T *rosYaw)
-{
- double imuRoll, imuPitch, imuYaw;
- tf::Quaternion orientation;
- tf::quaternionMsgToTF(thisImuMsg->orientation, orientation);
- tf::Matrix3x3(orientation).getRPY(imuRoll, imuPitch, imuYaw);
-
- *rosRoll = imuRoll;
- *rosPitch = imuPitch;
- *rosYaw = imuYaw;
-}
-
-
-float pointDistance(PointType p)
-{
- return sqrt(p.x*p.x + p.y*p.y + p.z*p.z);
-}
-
-
-float pointDistance(PointType p1, PointType p2)
-{
- return sqrt((p1.x-p2.x)*(p1.x-p2.x) + (p1.y-p2.y)*(p1.y-p2.y) + (p1.z-p2.z)*(p1.z-p2.z));
-}
-
-#endif
diff --git a/launch/include/config/rviz.rviz b/launch/include/config/rviz.rviz
deleted file mode 100644
index 85dd826a..00000000
--- a/launch/include/config/rviz.rviz
+++ /dev/null
@@ -1,527 +0,0 @@
-Panels:
- - Class: rviz/Displays
- Help Height: 191
- Name: Displays
- Property Tree Widget:
- Expanded:
- - /links1
- - /Odometry1
- - /Point Cloud1
- - /Feature Cloud1
- - /Mapping1
- Splitter Ratio: 0.5600000023841858
- Tree Height: 824
- - Class: rviz/Selection
- Name: Selection
- - Class: rviz/Views
- Expanded:
- - /Current View1
- Name: Views
- Splitter Ratio: 0.5
- - Class: rviz/Tool Properties
- Expanded: ~
- Name: Tool Properties
- Splitter Ratio: 0.5
-Preferences:
- PromptSaveOnExit: true
-Toolbars:
- toolButtonStyle: 2
-Visualization Manager:
- Class: ""
- Displays:
- - Class: rviz/Group
- Displays:
- - Class: rviz/TF
- Enabled: false
- Frame Timeout: 999
- Frames:
- All Enabled: false
- Marker Scale: 3
- Name: TF
- Show Arrows: true
- Show Axes: true
- Show Names: true
- Tree:
- {}
- Update Interval: 0
- Value: false
- - Class: rviz/Axes
- Enabled: true
- Length: 2
- Name: map
- Radius: 0.5
- Reference Frame: map
- Value: true
- - Class: rviz/Axes
- Enabled: true
- Length: 1
- Name: base_link
- Radius: 0.30000001192092896
- Reference Frame: base_link
- Value: true
- Enabled: true
- Name: links
- - Class: rviz/Group
- Displays:
- - Angle Tolerance: 0.10000000149011612
- Class: rviz/Odometry
- Covariance:
- Orientation:
- Alpha: 0.5
- Color: 255; 255; 127
- Color Style: Unique
- Frame: Local
- Offset: 1
- Scale: 1
- Value: true
- Position:
- Alpha: 0.30000001192092896
- Color: 204; 51; 204
- Scale: 1
- Value: true
- Value: false
- Enabled: true
- Keep: 300
- Name: Odom IMU
- Position Tolerance: 0.10000000149011612
- Shape:
- Alpha: 1
- Axes Length: 0.5
- Axes Radius: 0.10000000149011612
- Color: 255; 25; 0
- Head Length: 0.30000001192092896
- Head Radius: 0.10000000149011612
- Shaft Length: 1
- Shaft Radius: 0.05000000074505806
- Value: Axes
- Topic: /odometry/imu
- Unreliable: false
- Value: true
- - Angle Tolerance: 0.10000000149011612
- Class: rviz/Odometry
- Covariance:
- Orientation:
- Alpha: 0.5
- Color: 255; 255; 127
- Color Style: Unique
- Frame: Local
- Offset: 1
- Scale: 1
- Value: true
- Position:
- Alpha: 0.30000001192092896
- Color: 204; 51; 204
- Scale: 1
- Value: true
- Value: false
- Enabled: true
- Keep: 300
- Name: Odom GPS
- Position Tolerance: 0.10000000149011612
- Shape:
- Alpha: 1
- Axes Length: 1
- Axes Radius: 0.30000001192092896
- Color: 255; 25; 0
- Head Length: 0.30000001192092896
- Head Radius: 0.10000000149011612
- Shaft Length: 1
- Shaft Radius: 0.05000000074505806
- Value: Axes
- Topic: /odometry/gps
- Unreliable: false
- Value: true
- - Angle Tolerance: 0.10000000149011612
- Class: rviz/Odometry
- Covariance:
- Orientation:
- Alpha: 0.5
- Color: 255; 255; 127
- Color Style: Unique
- Frame: Local
- Offset: 1
- Scale: 1
- Value: true
- Position:
- Alpha: 0.30000001192092896
- Color: 204; 51; 204
- Scale: 1
- Value: true
- Value: false
- Enabled: false
- Keep: 300
- Name: Odom lidar
- Position Tolerance: 0.10000000149011612
- Shape:
- Alpha: 1
- Axes Length: 0.25
- Axes Radius: 0.10000000149011612
- Color: 255; 25; 0
- Head Length: 0.30000001192092896
- Head Radius: 0.10000000149011612
- Shaft Length: 1
- Shaft Radius: 0.05000000074505806
- Value: Axes
- Topic: /lio_sam/mapping/odometry
- Unreliable: false
- Value: false
- Enabled: false
- Name: Odometry
- - Class: rviz/Group
- Displays:
- - Alpha: 1
- Autocompute Intensity Bounds: false
- Autocompute Value Bounds:
- Max Value: 10
- Min Value: -10
- Value: true
- Axis: Z
- Channel Name: intensity
- Class: rviz/PointCloud2
- Color: 255; 255; 255
- Color Transformer: Intensity
- Decay Time: 0
- Enabled: true
- Invert Rainbow: false
- Max Color: 255; 255; 255
- Max Intensity: 128
- Min Color: 0; 0; 0
- Min Intensity: 0
- Name: Velodyne
- Position Transformer: XYZ
- Queue Size: 10
- Selectable: false
- Size (Pixels): 2
- Size (m): 0.009999999776482582
- Style: Points
- Topic: /lio_sam/deskew/cloud_deskewed
- Unreliable: false
- Use Fixed Frame: true
- Use rainbow: true
- Value: true
- - Alpha: 1
- Autocompute Intensity Bounds: true
- Autocompute Value Bounds:
- Max Value: 10
- Min Value: -10
- Value: true
- Axis: Z
- Channel Name: intensity
- Class: rviz/PointCloud2
- Color: 255; 255; 255
- Color Transformer: Intensity
- Decay Time: 0
- Enabled: false
- Invert Rainbow: false
- Max Color: 255; 255; 255
- Max Intensity: 0.7900000214576721
- Min Color: 0; 0; 0
- Min Intensity: 0
- Name: Reg Cloud
- Position Transformer: XYZ
- Queue Size: 10
- Selectable: true
- Size (Pixels): 3
- Size (m): 0.009999999776482582
- Style: Points
- Topic: /lio_sam/mapping/cloud_registered
- Unreliable: false
- Use Fixed Frame: true
- Use rainbow: true
- Value: false
- Enabled: true
- Name: Point Cloud
- - Class: rviz/Group
- Displays:
- - Alpha: 1
- Autocompute Intensity Bounds: true
- Autocompute Value Bounds:
- Max Value: 10
- Min Value: -10
- Value: true
- Axis: Z
- Channel Name: intensity
- Class: rviz/PointCloud2
- Color: 0; 255; 0
- Color Transformer: FlatColor
- Decay Time: 0
- Enabled: true
- Invert Rainbow: false
- Max Color: 255; 255; 255
- Max Intensity: 15.077729225158691
- Min Color: 0; 0; 0
- Min Intensity: 0.019985778257250786
- Name: Edge Feature
- Position Transformer: XYZ
- Queue Size: 10
- Selectable: true
- Size (Pixels): 5
- Size (m): 0.009999999776482582
- Style: Points
- Topic: /lio_sam/feature/cloud_corner
- Unreliable: false
- Use Fixed Frame: true
- Use rainbow: true
- Value: true
- - Alpha: 1
- Autocompute Intensity Bounds: true
- Autocompute Value Bounds:
- Max Value: 10
- Min Value: -10
- Value: true
- Axis: Z
- Channel Name: intensity
- Class: rviz/PointCloud2
- Color: 255; 85; 255
- Color Transformer: FlatColor
- Decay Time: 0
- Enabled: true
- Invert Rainbow: false
- Max Color: 255; 255; 255
- Max Intensity: 15.100607872009277
- Min Color: 0; 0; 0
- Min Intensity: 0.0007188677554950118
- Name: Plannar Feature
- Position Transformer: XYZ
- Queue Size: 10
- Selectable: true
- Size (Pixels): 3
- Size (m): 0.009999999776482582
- Style: Points
- Topic: /lio_sam/feature/cloud_surface
- Unreliable: false
- Use Fixed Frame: true
- Use rainbow: true
- Value: true
- Enabled: false
- Name: Feature Cloud
- - Class: rviz/Group
- Displays:
- - Alpha: 0.30000001192092896
- Autocompute Intensity Bounds: false
- Autocompute Value Bounds:
- Max Value: 7.4858574867248535
- Min Value: -1.2309398651123047
- Value: true
- Axis: Z
- Channel Name: intensity
- Class: rviz/PointCloud2
- Color: 255; 255; 255
- Color Transformer: Intensity
- Decay Time: 300
- Enabled: true
- Invert Rainbow: false
- Max Color: 255; 255; 255
- Max Intensity: 128
- Min Color: 0; 0; 0
- Min Intensity: 0
- Name: Map (cloud)
- Position Transformer: XYZ
- Queue Size: 10
- Selectable: false
- Size (Pixels): 2
- Size (m): 0.009999999776482582
- Style: Points
- Topic: /lio_sam/mapping/cloud_registered
- Unreliable: false
- Use Fixed Frame: true
- Use rainbow: true
- Value: true
- - Alpha: 1
- Autocompute Intensity Bounds: true
- Autocompute Value Bounds:
- Max Value: 36.61034393310547
- Min Value: -2.3476977348327637
- Value: true
- Axis: Z
- Channel Name: intensity
- Class: rviz/PointCloud2
- Color: 255; 255; 255
- Color Transformer: AxisColor
- Decay Time: 0
- Enabled: false
- Invert Rainbow: false
- Max Color: 255; 255; 255
- Max Intensity: 15.100604057312012
- Min Color: 0; 0; 0
- Min Intensity: 0.014545874670147896
- Name: Map (local)
- Position Transformer: XYZ
- Queue Size: 10
- Selectable: true
- Size (Pixels): 2
- Size (m): 0.10000000149011612
- Style: Flat Squares
- Topic: /lio_sam/mapping/map_local
- Unreliable: false
- Use Fixed Frame: true
- Use rainbow: true
- Value: false
- - Alpha: 1
- Autocompute Intensity Bounds: true
- Autocompute Value Bounds:
- Max Value: 10
- Min Value: -10
- Value: true
- Axis: Z
- Channel Name: intensity
- Class: rviz/PointCloud2
- Color: 255; 255; 255
- Color Transformer: Intensity
- Decay Time: 0
- Enabled: false
- Invert Rainbow: false
- Max Color: 255; 255; 255
- Max Intensity: 15.100096702575684
- Min Color: 0; 0; 0
- Min Intensity: 0.007923072203993797
- Name: Map (global)
- Position Transformer: XYZ
- Queue Size: 10
- Selectable: true
- Size (Pixels): 2
- Size (m): 0.009999999776482582
- Style: Points
- Topic: /lio_sam/mapping/map_global
- Unreliable: false
- Use Fixed Frame: true
- Use rainbow: true
- Value: false
- - Alpha: 1
- Buffer Length: 1
- Class: rviz/Path
- Color: 85; 255; 255
- Enabled: true
- Head Diameter: 0.30000001192092896
- Head Length: 0.20000000298023224
- Length: 0.30000001192092896
- Line Style: Billboards
- Line Width: 0.10000000149011612
- Name: Path (global)
- Offset:
- X: 0
- Y: 0
- Z: 0
- Pose Color: 255; 85; 255
- Pose Style: None
- Radius: 0.029999999329447746
- Shaft Diameter: 0.10000000149011612
- Shaft Length: 0.10000000149011612
- Topic: /lio_sam/mapping/path
- Unreliable: false
- Value: true
- - Alpha: 1
- Buffer Length: 1
- Class: rviz/Path
- Color: 255; 85; 255
- Enabled: true
- Head Diameter: 0.30000001192092896
- Head Length: 0.20000000298023224
- Length: 0.30000001192092896
- Line Style: Billboards
- Line Width: 0.10000000149011612
- Name: Path (local)
- Offset:
- X: 0
- Y: 0
- Z: 0
- Pose Color: 255; 85; 255
- Pose Style: None
- Radius: 0.029999999329447746
- Shaft Diameter: 0.10000000149011612
- Shaft Length: 0.10000000149011612
- Topic: /lio_sam/imu/path
- Unreliable: false
- Value: true
- - Alpha: 1
- Autocompute Intensity Bounds: true
- Autocompute Value Bounds:
- Max Value: 20.802837371826172
- Min Value: -0.03934507071971893
- Value: true
- Axis: Z
- Channel Name: intensity
- Class: rviz/PointCloud2
- Color: 255; 255; 255
- Color Transformer: AxisColor
- Decay Time: 0
- Enabled: false
- Invert Rainbow: false
- Max Color: 255; 255; 255
- Max Intensity: 15.100604057312012
- Min Color: 0; 0; 0
- Min Intensity: 0.014545874670147896
- Name: Loop closure
- Position Transformer: XYZ
- Queue Size: 10
- Selectable: true
- Size (Pixels): 2
- Size (m): 0.30000001192092896
- Style: Flat Squares
- Topic: /lio_sam/mapping/icp_loop_closure_corrected_cloud
- Unreliable: false
- Use Fixed Frame: true
- Use rainbow: true
- Value: false
- - Class: rviz/MarkerArray
- Enabled: true
- Marker Topic: /lio_sam/mapping/loop_closure_constraints
- Name: Loop constraint
- Namespaces:
- {}
- Queue Size: 100
- Value: true
- Enabled: true
- Name: Mapping
- Enabled: true
- Global Options:
- Background Color: 0; 0; 0
- Default Light: true
- Fixed Frame: map
- Frame Rate: 30
- Name: root
- Tools:
- - Class: rviz/Interact
- Hide Inactive Objects: true
- - Class: rviz/FocusCamera
- - Class: rviz/Measure
- Value: true
- Views:
- Current:
- Class: rviz/Orbit
- Distance: 97.43701171875
- Enable Stereo Rendering:
- Stereo Eye Separation: 0.05999999865889549
- Stereo Focal Distance: 1
- Swap Stereo Eyes: false
- Value: false
- Focal Point:
- X: 0
- Y: 0
- Z: 0
- Focal Shape Fixed Size: false
- Focal Shape Size: 0.05000000074505806
- Invert Z Axis: false
- Name: Current View
- Near Clip Distance: 0.009999999776482582
- Pitch: 1.1253981590270996
- Target Frame: base_link
- Value: Orbit (rviz)
- Yaw: 3.3316705226898193
- Saved: ~
-Window Geometry:
- Displays:
- collapsed: false
- Height: 1190
- Hide Left Dock: false
- Hide Right Dock: true
- QMainWindow State: 000000ff00000000fd0000000400000000000001a30000043efc0200000009fb0000001200530065006c0065006300740069006f006e00000001e10000009b0000006e00fffffffb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb0000000a0049006d006100670065000000002e000001340000000000000000fb000000100044006900730070006c00610079007301000000470000043e000000f100fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730000000286000000a70000006e00ffffff000000010000011100000435fc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a00560069006500770073000000002e00000435000000c200fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e10000019700000003000004b000000040fc0100000002fb0000000800540069006d00650000000000000004b00000000000000000fb0000000800540069006d00650100000000000004500000000000000000000005f20000043e00000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000
- Selection:
- collapsed: false
- Tool Properties:
- collapsed: false
- Views:
- collapsed: true
- Width: 1948
- X: 725
- Y: 300
diff --git a/launch/include/module_loam.launch b/launch/include/module_loam.launch
deleted file mode 100644
index eba219fd..00000000
--- a/launch/include/module_loam.launch
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/launch/include/module_navsat.launch b/launch/include/module_navsat.launch
deleted file mode 100644
index 16ca1d34..00000000
--- a/launch/include/module_navsat.launch
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/launch/include/module_robot_state_publisher.launch b/launch/include/module_robot_state_publisher.launch
deleted file mode 100644
index c6ac3e2a..00000000
--- a/launch/include/module_robot_state_publisher.launch
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/launch/include/module_rviz.launch b/launch/include/module_rviz.launch
deleted file mode 100644
index 3ec52da3..00000000
--- a/launch/include/module_rviz.launch
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
-
-
-
diff --git a/launch/include/rosconsole/rosconsole_error.conf b/launch/include/rosconsole/rosconsole_error.conf
deleted file mode 100644
index 45663862..00000000
--- a/launch/include/rosconsole/rosconsole_error.conf
+++ /dev/null
@@ -1,2 +0,0 @@
-# Set the default ros output to warning and higher
-log4j.logger.ros = ERROR
\ No newline at end of file
diff --git a/launch/include/rosconsole/rosconsole_info.conf b/launch/include/rosconsole/rosconsole_info.conf
deleted file mode 100644
index 888786c1..00000000
--- a/launch/include/rosconsole/rosconsole_info.conf
+++ /dev/null
@@ -1,2 +0,0 @@
-# Set the default ros output to warning and higher
-log4j.logger.ros = INFO
\ No newline at end of file
diff --git a/launch/include/rosconsole/rosconsole_warn.conf b/launch/include/rosconsole/rosconsole_warn.conf
deleted file mode 100644
index 10f954c4..00000000
--- a/launch/include/rosconsole/rosconsole_warn.conf
+++ /dev/null
@@ -1,2 +0,0 @@
-# Set the default ros output to warning and higher
-log4j.logger.ros = WARN
\ No newline at end of file
diff --git a/launch/run.launch b/launch/run.launch
deleted file mode 100644
index 59a77202..00000000
--- a/launch/run.launch
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/launch/run.launch.py b/launch/run.launch.py
new file mode 100644
index 00000000..39c79514
--- /dev/null
+++ b/launch/run.launch.py
@@ -0,0 +1,73 @@
+import os
+from ament_index_python.packages import get_package_share_directory
+from launch import LaunchDescription
+from launch.actions import DeclareLaunchArgument
+from launch.substitutions import LaunchConfiguration, Command
+from launch_ros.actions import Node
+
+
+def generate_launch_description():
+
+ share_dir = get_package_share_directory('lio_sam')
+ parameter_file = LaunchConfiguration('params_file')
+ xacro_path = os.path.join(share_dir, 'config', 'robot.urdf.xacro')
+ rviz_config_file = os.path.join(share_dir, 'config', 'rviz2.rviz')
+
+ params_declare = DeclareLaunchArgument(
+ 'params_file',
+ default_value=os.path.join(
+ share_dir, 'config', 'params.yaml'),
+ description='FPath to the ROS2 parameters file to use.')
+
+ print("urdf_file_name : {}".format(xacro_path))
+
+ return LaunchDescription([
+ params_declare,
+ Node(
+ package='tf2_ros',
+ executable='static_transform_publisher',
+ arguments='0.0 0.0 0.0 0.0 0.0 0.0 map odom'.split(' '),
+ parameters=[parameter_file],
+ output='screen'
+ ),
+ Node(
+ package='robot_state_publisher',
+ executable='robot_state_publisher',
+ name='robot_state_publisher',
+ output='screen',
+ parameters=[{
+ 'robot_description': Command(['xacro', ' ', xacro_path])
+ }]
+ ),
+ Node(
+ package='lio_sam',
+ executable='lio_sam_imuPreintegration',
+ parameters=[parameter_file],
+ output='screen'
+ ),
+ Node(
+ package='lio_sam',
+ executable='lio_sam_imageProjection',
+ parameters=[parameter_file],
+ output='screen'
+ ),
+ Node(
+ package='lio_sam',
+ executable='lio_sam_featureExtraction',
+ parameters=[parameter_file],
+ output='screen'
+ ),
+ Node(
+ package='lio_sam',
+ executable='lio_sam_mapOptimization',
+ parameters=[parameter_file],
+ output='screen'
+ ),
+ Node(
+ package='rviz2',
+ executable='rviz2',
+ name='rviz2',
+ arguments=['-d', rviz_config_file],
+ output='screen'
+ )
+ ])
diff --git a/msg/CloudInfo.msg b/msg/CloudInfo.msg
new file mode 100644
index 00000000..9060d13d
--- /dev/null
+++ b/msg/CloudInfo.msg
@@ -0,0 +1,29 @@
+# Cloud Info
+std_msgs/Header header
+
+int32[] start_ring_index
+int32[] end_ring_index
+
+int32[] point_col_ind # point column index in range image
+float32[] point_range # point range
+
+int64 imu_available
+int64 odom_available
+
+# Attitude for LOAM initialization
+float32 imu_roll_init
+float32 imu_pitch_init
+float32 imu_yaw_init
+
+# Initial guess from imu pre-integration
+float32 initial_guess_x
+float32 initial_guess_y
+float32 initial_guess_z
+float32 initial_guess_roll
+float32 initial_guess_pitch
+float32 initial_guess_yaw
+
+# Point cloud messages
+sensor_msgs/PointCloud2 cloud_deskewed # original cloud deskewed
+sensor_msgs/PointCloud2 cloud_corner # extracted corner feature
+sensor_msgs/PointCloud2 cloud_surface # extracted surface feature
diff --git a/msg/cloud_info.msg b/msg/cloud_info.msg
deleted file mode 100644
index 51ab297d..00000000
--- a/msg/cloud_info.msg
+++ /dev/null
@@ -1,29 +0,0 @@
-# Cloud Info
-Header header
-
-int32[] startRingIndex
-int32[] endRingIndex
-
-int32[] pointColInd # point column index in range image
-float32[] pointRange # point range
-
-int64 imuAvailable
-int64 odomAvailable
-
-# Attitude for LOAM initialization
-float32 imuRollInit
-float32 imuPitchInit
-float32 imuYawInit
-
-# Initial guess from imu pre-integration
-float32 initialGuessX
-float32 initialGuessY
-float32 initialGuessZ
-float32 initialGuessRoll
-float32 initialGuessPitch
-float32 initialGuessYaw
-
-# Point cloud messages
-sensor_msgs/PointCloud2 cloud_deskewed # original cloud deskewed
-sensor_msgs/PointCloud2 cloud_corner # extracted corner feature
-sensor_msgs/PointCloud2 cloud_surface # extracted surface feature
\ No newline at end of file
diff --git a/package.xml b/package.xml
index 7109c3ac..c5b33502 100644
--- a/package.xml
+++ b/package.xml
@@ -1,5 +1,6 @@
-
+
+
lio_sam
1.0.0
Lidar Odometry
@@ -10,39 +11,48 @@
Tixiao Shan
- catkin
-
- roscpp
- roscpp
- rospy
- rospy
-
- tf
- tf
-
- cv_bridge
- cv_bridge
-
- pcl_conversions
- pcl_conversions
+ ament_cmake
+ rosidl_default_generators
+ rclcpp
+ rclpy
std_msgs
- std_msgs
sensor_msgs
- sensor_msgs
- geometry_msgs
- geometry_msgs
nav_msgs
- nav_msgs
- visualization_msgs
- visualization_msgs
-
- message_generation
- message_generation
- message_runtime
- message_runtime
-
+ geometry_msgs
+ tf2_geometry_msgs
+ tf2_sensor_msgs
+ tf2_eigen
+ tf2_ros
+ tf2
+ OpenCV
+ PCL
GTSAM
- GTSAM
-
+ Eigen
+
+ rosidl_default_runtime
+ rclcpp
+ rclpy
+ std_msgs
+ sensor_msgs
+ nav_msgs
+ geometry_msgs
+ tf2_geometry_msgs
+ tf2_sensor_msgs
+ tf2_eigen
+ tf2_ros
+ tf2
+ OpenCV
+ PCL
+ GTSAM
+ Eigen
+
+ rosidl_interface_packages
+
+ ament_lint_auto
+ ament_lint_common
+
+
+ ament_cmake
+
diff --git a/src/featureExtraction.cpp b/src/featureExtraction.cpp
index 7d444d94..0a6af036 100644
--- a/src/featureExtraction.cpp
+++ b/src/featureExtraction.cpp
@@ -1,5 +1,5 @@
-#include "utility.h"
-#include "lio_sam/cloud_info.h"
+#include "utility.hpp"
+#include "lio_sam/msg/cloud_info.hpp"
struct smoothness_t{
float value;
@@ -17,11 +17,11 @@ class FeatureExtraction : public ParamServer
public:
- ros::Subscriber subLaserCloudInfo;
+ rclcpp::Subscription::SharedPtr subLaserCloudInfo;
- ros::Publisher pubLaserCloudInfo;
- ros::Publisher pubCornerPoints;
- ros::Publisher pubSurfacePoints;
+ rclcpp::Publisher::SharedPtr pubLaserCloudInfo;
+ rclcpp::Publisher::SharedPtr pubCornerPoints;
+ rclcpp::Publisher::SharedPtr pubSurfacePoints;
pcl::PointCloud::Ptr extractedCloud;
pcl::PointCloud::Ptr cornerCloud;
@@ -29,22 +29,28 @@ class FeatureExtraction : public ParamServer
pcl::VoxelGrid downSizeFilter;
- lio_sam::cloud_info cloudInfo;
- std_msgs::Header cloudHeader;
+ lio_sam::msg::CloudInfo cloudInfo;
+ std_msgs::msg::Header cloudHeader;
std::vector cloudSmoothness;
float *cloudCurvature;
int *cloudNeighborPicked;
int *cloudLabel;
- FeatureExtraction()
+ FeatureExtraction(const rclcpp::NodeOptions & options) :
+ ParamServer("lio_sam_featureExtraction", options)
{
- subLaserCloudInfo = nh.subscribe("lio_sam/deskew/cloud_info", 1, &FeatureExtraction::laserCloudInfoHandler, this, ros::TransportHints().tcpNoDelay());
+ subLaserCloudInfo = create_subscription(
+ "lio_sam/deskew/cloud_info", qos,
+ std::bind(&FeatureExtraction::laserCloudInfoHandler, this, std::placeholders::_1));
+
+ pubLaserCloudInfo = create_publisher(
+ "lio_sam/feature/cloud_info", qos);
+ pubCornerPoints = create_publisher(
+ "lio_sam/feature/cloud_corner", 1);
+ pubSurfacePoints = create_publisher(
+ "lio_sam/feature/cloud_surface", 1);
- pubLaserCloudInfo = nh.advertise ("lio_sam/feature/cloud_info", 1);
- pubCornerPoints = nh.advertise("lio_sam/feature/cloud_corner", 1);
- pubSurfacePoints = nh.advertise("lio_sam/feature/cloud_surface", 1);
-
initializationValue();
}
@@ -63,7 +69,7 @@ class FeatureExtraction : public ParamServer
cloudLabel = new int[N_SCAN*Horizon_SCAN];
}
- void laserCloudInfoHandler(const lio_sam::cloud_infoConstPtr& msgIn)
+ void laserCloudInfoHandler(const lio_sam::msg::CloudInfo::SharedPtr msgIn)
{
cloudInfo = *msgIn; // new cloud info
cloudHeader = msgIn->header; // new cloud header
@@ -83,12 +89,12 @@ class FeatureExtraction : public ParamServer
int cloudSize = extractedCloud->points.size();
for (int i = 5; i < cloudSize - 5; i++)
{
- float diffRange = cloudInfo.pointRange[i-5] + cloudInfo.pointRange[i-4]
- + cloudInfo.pointRange[i-3] + cloudInfo.pointRange[i-2]
- + cloudInfo.pointRange[i-1] - cloudInfo.pointRange[i] * 10
- + cloudInfo.pointRange[i+1] + cloudInfo.pointRange[i+2]
- + cloudInfo.pointRange[i+3] + cloudInfo.pointRange[i+4]
- + cloudInfo.pointRange[i+5];
+ float diffRange = cloudInfo.point_range[i-5] + cloudInfo.point_range[i-4]
+ + cloudInfo.point_range[i-3] + cloudInfo.point_range[i-2]
+ + cloudInfo.point_range[i-1] - cloudInfo.point_range[i] * 10
+ + cloudInfo.point_range[i+1] + cloudInfo.point_range[i+2]
+ + cloudInfo.point_range[i+3] + cloudInfo.point_range[i+4]
+ + cloudInfo.point_range[i+5];
cloudCurvature[i] = diffRange*diffRange;//diffX * diffX + diffY * diffY + diffZ * diffZ;
@@ -107,10 +113,9 @@ class FeatureExtraction : public ParamServer
for (int i = 5; i < cloudSize - 6; ++i)
{
// occluded points
- float depth1 = cloudInfo.pointRange[i];
- float depth2 = cloudInfo.pointRange[i+1];
- int columnDiff = std::abs(int(cloudInfo.pointColInd[i+1] - cloudInfo.pointColInd[i]));
-
+ float depth1 = cloudInfo.point_range[i];
+ float depth2 = cloudInfo.point_range[i+1];
+ int columnDiff = std::abs(int(cloudInfo.point_col_ind[i+1] - cloudInfo.point_col_ind[i]));
if (columnDiff < 10){
// 10 pixel diff in range image
if (depth1 - depth2 > 0.3){
@@ -130,10 +135,10 @@ class FeatureExtraction : public ParamServer
}
}
// parallel beam
- float diff1 = std::abs(float(cloudInfo.pointRange[i-1] - cloudInfo.pointRange[i]));
- float diff2 = std::abs(float(cloudInfo.pointRange[i+1] - cloudInfo.pointRange[i]));
+ float diff1 = std::abs(float(cloudInfo.point_range[i-1] - cloudInfo.point_range[i]));
+ float diff2 = std::abs(float(cloudInfo.point_range[i+1] - cloudInfo.point_range[i]));
- if (diff1 > 0.02 * cloudInfo.pointRange[i] && diff2 > 0.02 * cloudInfo.pointRange[i])
+ if (diff1 > 0.02 * cloudInfo.point_range[i] && diff2 > 0.02 * cloudInfo.point_range[i])
cloudNeighborPicked[i] = 1;
}
}
@@ -153,8 +158,8 @@ class FeatureExtraction : public ParamServer
for (int j = 0; j < 6; j++)
{
- int sp = (cloudInfo.startRingIndex[i] * (6 - j) + cloudInfo.endRingIndex[i] * j) / 6;
- int ep = (cloudInfo.startRingIndex[i] * (5 - j) + cloudInfo.endRingIndex[i] * (j + 1)) / 6 - 1;
+ int sp = (cloudInfo.start_ring_index[i] * (6 - j) + cloudInfo.end_ring_index[i] * j) / 6;
+ int ep = (cloudInfo.start_ring_index[i] * (5 - j) + cloudInfo.end_ring_index[i] * (j + 1)) / 6 - 1;
if (sp >= ep)
continue;
@@ -178,14 +183,14 @@ class FeatureExtraction : public ParamServer
cloudNeighborPicked[ind] = 1;
for (int l = 1; l <= 5; l++)
{
- int columnDiff = std::abs(int(cloudInfo.pointColInd[ind + l] - cloudInfo.pointColInd[ind + l - 1]));
+ int columnDiff = std::abs(int(cloudInfo.point_col_ind[ind + l] - cloudInfo.point_col_ind[ind + l - 1]));
if (columnDiff > 10)
break;
cloudNeighborPicked[ind + l] = 1;
}
for (int l = -1; l >= -5; l--)
{
- int columnDiff = std::abs(int(cloudInfo.pointColInd[ind + l] - cloudInfo.pointColInd[ind + l + 1]));
+ int columnDiff = std::abs(int(cloudInfo.point_col_ind[ind + l] - cloudInfo.point_col_ind[ind + l + 1]));
if (columnDiff > 10)
break;
cloudNeighborPicked[ind + l] = 1;
@@ -203,16 +208,14 @@ class FeatureExtraction : public ParamServer
cloudNeighborPicked[ind] = 1;
for (int l = 1; l <= 5; l++) {
-
- int columnDiff = std::abs(int(cloudInfo.pointColInd[ind + l] - cloudInfo.pointColInd[ind + l - 1]));
+ int columnDiff = std::abs(int(cloudInfo.point_col_ind[ind + l] - cloudInfo.point_col_ind[ind + l - 1]));
if (columnDiff > 10)
break;
cloudNeighborPicked[ind + l] = 1;
}
for (int l = -1; l >= -5; l--) {
-
- int columnDiff = std::abs(int(cloudInfo.pointColInd[ind + l] - cloudInfo.pointColInd[ind + l + 1]));
+ int columnDiff = std::abs(int(cloudInfo.point_col_ind[ind + l] - cloudInfo.point_col_ind[ind + l + 1]));
if (columnDiff > 10)
break;
@@ -239,10 +242,10 @@ class FeatureExtraction : public ParamServer
void freeCloudInfoMemory()
{
- cloudInfo.startRingIndex.clear();
- cloudInfo.endRingIndex.clear();
- cloudInfo.pointColInd.clear();
- cloudInfo.pointRange.clear();
+ cloudInfo.start_ring_index.clear();
+ cloudInfo.end_ring_index.clear();
+ cloudInfo.point_col_ind.clear();
+ cloudInfo.point_range.clear();
}
void publishFeatureCloud()
@@ -250,23 +253,29 @@ class FeatureExtraction : public ParamServer
// free cloud info memory
freeCloudInfoMemory();
// save newly extracted features
- cloudInfo.cloud_corner = publishCloud(&pubCornerPoints, cornerCloud, cloudHeader.stamp, lidarFrame);
- cloudInfo.cloud_surface = publishCloud(&pubSurfacePoints, surfaceCloud, cloudHeader.stamp, lidarFrame);
+ cloudInfo.cloud_corner = publishCloud(pubCornerPoints, cornerCloud, cloudHeader.stamp, lidarFrame);
+ cloudInfo.cloud_surface = publishCloud(pubSurfacePoints, surfaceCloud, cloudHeader.stamp, lidarFrame);
// publish to mapOptimization
- pubLaserCloudInfo.publish(cloudInfo);
+ pubLaserCloudInfo->publish(cloudInfo);
}
};
int main(int argc, char** argv)
{
- ros::init(argc, argv, "lio_sam");
+ rclcpp::init(argc, argv);
+ rclcpp::NodeOptions options;
+ options.use_intra_process_comms(true);
+ rclcpp::executors::SingleThreadedExecutor exec;
+
+ auto FE = std::make_shared(options);
+
+ exec.add_node(FE);
- FeatureExtraction FE;
+ RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "\033[1;32m----> Feature Extraction Started.\033[0m");
- ROS_INFO("\033[1;32m----> Feature Extraction Started.\033[0m");
-
- ros::spin();
+ exec.spin();
+ rclcpp::shutdown();
return 0;
-}
\ No newline at end of file
+}
diff --git a/src/imageProjection.cpp b/src/imageProjection.cpp
index ae96dae4..2b3b452d 100644
--- a/src/imageProjection.cpp
+++ b/src/imageProjection.cpp
@@ -1,5 +1,5 @@
-#include "utility.h"
-#include "lio_sam/cloud_info.h"
+#include "utility.hpp"
+#include "lio_sam/msg/cloud_info.hpp"
struct VelodynePointXYZIRT
{
@@ -42,20 +42,20 @@ class ImageProjection : public ParamServer
std::mutex imuLock;
std::mutex odoLock;
- ros::Subscriber subLaserCloud;
- ros::Publisher pubLaserCloud;
-
- ros::Publisher pubExtractedCloud;
- ros::Publisher pubLaserCloudInfo;
+ rclcpp::Subscription::SharedPtr subLaserCloud;
+ rclcpp::Publisher::SharedPtr pubLaserCloud;
+
+ rclcpp::Publisher::SharedPtr pubExtractedCloud;
+ rclcpp::Publisher::SharedPtr pubLaserCloudInfo;
- ros::Subscriber subImu;
- std::deque imuQueue;
+ rclcpp::Subscription::SharedPtr subImu;
+ std::deque imuQueue;
- ros::Subscriber subOdom;
- std::deque odomQueue;
+ rclcpp::Subscription::SharedPtr subOdom;
+ std::deque odomQueue;
- std::deque cloudQueue;
- sensor_msgs::PointCloud2 currentCloudMsg;
+ std::deque cloudQueue;
+ sensor_msgs::msg::PointCloud2 currentCloudMsg;
double *imuTime = new double[queueLength];
double *imuRotX = new double[queueLength];
@@ -79,22 +79,30 @@ class ImageProjection : public ParamServer
float odomIncreY;
float odomIncreZ;
- lio_sam::cloud_info cloudInfo;
+ lio_sam::msg::CloudInfo cloudInfo;
double timeScanCur;
double timeScanEnd;
- std_msgs::Header cloudHeader;
+ std_msgs::msg::Header cloudHeader;
public:
- ImageProjection():
- deskewFlag(0)
+ ImageProjection(const rclcpp::NodeOptions & options) :
+ ParamServer("lio_sam_imageProjection", options), deskewFlag(0)
{
- subImu = nh.subscribe(imuTopic, 2000, &ImageProjection::imuHandler, this, ros::TransportHints().tcpNoDelay());
- subOdom = nh.subscribe(odomTopic+"_incremental", 2000, &ImageProjection::odometryHandler, this, ros::TransportHints().tcpNoDelay());
- subLaserCloud = nh.subscribe(pointCloudTopic, 5, &ImageProjection::cloudHandler, this, ros::TransportHints().tcpNoDelay());
-
- pubExtractedCloud = nh.advertise ("lio_sam/deskew/cloud_deskewed", 1);
- pubLaserCloudInfo = nh.advertise ("lio_sam/deskew/cloud_info", 1);
+ subImu = create_subscription(
+ imuTopic, qos_imu,
+ std::bind(&ImageProjection::imuHandler, this, std::placeholders::_1));
+ subOdom = create_subscription(
+ odomTopic + "_incremental", qos_imu,
+ std::bind(&ImageProjection::odometryHandler, this, std::placeholders::_1));
+ subLaserCloud = create_subscription(
+ pointCloudTopic, qos_lidar,
+ std::bind(&ImageProjection::cloudHandler, this, std::placeholders::_1));
+
+ pubExtractedCloud = create_publisher(
+ "lio_sam/deskew/cloud_deskewed", 1);
+ pubLaserCloudInfo = create_publisher(
+ "lio_sam/deskew/cloud_info", qos);
allocateMemory();
resetParameters();
@@ -111,11 +119,11 @@ class ImageProjection : public ParamServer
fullCloud->points.resize(N_SCAN*Horizon_SCAN);
- cloudInfo.startRingIndex.assign(N_SCAN, 0);
- cloudInfo.endRingIndex.assign(N_SCAN, 0);
+ cloudInfo.start_ring_index.assign(N_SCAN, 0);
+ cloudInfo.end_ring_index.assign(N_SCAN, 0);
- cloudInfo.pointColInd.assign(N_SCAN*Horizon_SCAN, 0);
- cloudInfo.pointRange.assign(N_SCAN*Horizon_SCAN, 0);
+ cloudInfo.point_col_ind.assign(N_SCAN*Horizon_SCAN, 0);
+ cloudInfo.point_range.assign(N_SCAN*Horizon_SCAN, 0);
resetParameters();
}
@@ -142,9 +150,9 @@ class ImageProjection : public ParamServer
~ImageProjection(){}
- void imuHandler(const sensor_msgs::Imu::ConstPtr& imuMsg)
+ void imuHandler(const sensor_msgs::msg::Imu::SharedPtr imuMsg)
{
- sensor_msgs::Imu thisImu = imuConverter(*imuMsg);
+ sensor_msgs::msg::Imu thisImu = imuConverter(*imuMsg);
std::lock_guard lock1(imuLock);
imuQueue.push_back(thisImu);
@@ -167,13 +175,13 @@ class ImageProjection : public ParamServer
// cout << "roll: " << imuRoll << ", pitch: " << imuPitch << ", yaw: " << imuYaw << endl << endl;
}
- void odometryHandler(const nav_msgs::Odometry::ConstPtr& odometryMsg)
+ void odometryHandler(const nav_msgs::msg::Odometry::SharedPtr odometryMsg)
{
std::lock_guard lock2(odoLock);
odomQueue.push_back(*odometryMsg);
}
- void cloudHandler(const sensor_msgs::PointCloud2ConstPtr& laserCloudMsg)
+ void cloudHandler(const sensor_msgs::msg::PointCloud2::SharedPtr laserCloudMsg)
{
if (!cachePointCloud(laserCloudMsg))
return;
@@ -190,7 +198,7 @@ class ImageProjection : public ParamServer
resetParameters();
}
- bool cachePointCloud(const sensor_msgs::PointCloud2ConstPtr& laserCloudMsg)
+ bool cachePointCloud(const sensor_msgs::msg::PointCloud2::SharedPtr& laserCloudMsg)
{
// cache point cloud
cloudQueue.push_back(*laserCloudMsg);
@@ -224,20 +232,20 @@ class ImageProjection : public ParamServer
}
else
{
- ROS_ERROR_STREAM("Unknown sensor type: " << int(sensor));
- ros::shutdown();
+ RCLCPP_ERROR_STREAM(get_logger(), "Unknown sensor type: " << int(sensor));
+ rclcpp::shutdown();
}
// get timestamp
cloudHeader = currentCloudMsg.header;
- timeScanCur = cloudHeader.stamp.toSec();
+ timeScanCur = stamp2Sec(cloudHeader.stamp);
timeScanEnd = timeScanCur + laserCloudIn->points.back().time;
// check dense flag
if (laserCloudIn->is_dense == false)
{
- ROS_ERROR("Point cloud is not in dense format, please remove NaN points first!");
- ros::shutdown();
+ RCLCPP_ERROR(get_logger(), "Point cloud is not in dense format, please remove NaN points first!");
+ rclcpp::shutdown();
}
// check ring channel
@@ -255,8 +263,8 @@ class ImageProjection : public ParamServer
}
if (ringFlag == -1)
{
- ROS_ERROR("Point cloud ring channel not available, please configure your point cloud data!");
- ros::shutdown();
+ RCLCPP_ERROR(get_logger(), "Point cloud ring channel not available, please configure your point cloud data!");
+ rclcpp::shutdown();
}
}
@@ -273,7 +281,7 @@ class ImageProjection : public ParamServer
}
}
if (deskewFlag == -1)
- ROS_WARN("Point cloud timestamp not available, deskew function disabled, system will drift significantly!");
+ RCLCPP_WARN(get_logger(), "Point cloud timestamp not available, deskew function disabled, system will drift significantly!");
}
return true;
@@ -285,9 +293,11 @@ class ImageProjection : public ParamServer
std::lock_guard lock2(odoLock);
// make sure IMU data available for the scan
- if (imuQueue.empty() || imuQueue.front().header.stamp.toSec() > timeScanCur || imuQueue.back().header.stamp.toSec() < timeScanEnd)
+ if (imuQueue.empty() ||
+ stamp2Sec(imuQueue.front().header.stamp) > timeScanCur ||
+ stamp2Sec(imuQueue.back().header.stamp) < timeScanEnd)
{
- ROS_DEBUG("Waiting for IMU data ...");
+ RCLCPP_INFO(get_logger(), "Waiting for IMU data ...");
return false;
}
@@ -300,11 +310,11 @@ class ImageProjection : public ParamServer
void imuDeskewInfo()
{
- cloudInfo.imuAvailable = false;
+ cloudInfo.imu_available = false;
while (!imuQueue.empty())
{
- if (imuQueue.front().header.stamp.toSec() < timeScanCur - 0.01)
+ if (stamp2Sec(imuQueue.front().header.stamp) < timeScanCur - 0.01)
imuQueue.pop_front();
else
break;
@@ -317,13 +327,12 @@ class ImageProjection : public ParamServer
for (int i = 0; i < (int)imuQueue.size(); ++i)
{
- sensor_msgs::Imu thisImuMsg = imuQueue[i];
- double currentImuTime = thisImuMsg.header.stamp.toSec();
+ sensor_msgs::msg::Imu thisImuMsg = imuQueue[i];
+ double currentImuTime = stamp2Sec(thisImuMsg.header.stamp);
// get roll, pitch, and yaw estimation for this scan
if (currentImuTime <= timeScanCur)
- imuRPY2rosRPY(&thisImuMsg, &cloudInfo.imuRollInit, &cloudInfo.imuPitchInit, &cloudInfo.imuYawInit);
-
+ imuRPY2rosRPY(&thisImuMsg, &cloudInfo.imu_roll_init, &cloudInfo.imu_pitch_init, &cloudInfo.imu_yaw_init);
if (currentImuTime > timeScanEnd + 0.01)
break;
@@ -354,16 +363,16 @@ class ImageProjection : public ParamServer
if (imuPointerCur <= 0)
return;
- cloudInfo.imuAvailable = true;
+ cloudInfo.imu_available = true;
}
void odomDeskewInfo()
{
- cloudInfo.odomAvailable = false;
+ cloudInfo.odom_available = false;
while (!odomQueue.empty())
{
- if (odomQueue.front().header.stamp.toSec() < timeScanCur - 0.01)
+ if (stamp2Sec(odomQueue.front().header.stamp) < timeScanCur - 0.01)
odomQueue.pop_front();
else
break;
@@ -372,51 +381,51 @@ class ImageProjection : public ParamServer
if (odomQueue.empty())
return;
- if (odomQueue.front().header.stamp.toSec() > timeScanCur)
+ if (stamp2Sec(odomQueue.front().header.stamp) > timeScanCur)
return;
// get start odometry at the beinning of the scan
- nav_msgs::Odometry startOdomMsg;
+ nav_msgs::msg::Odometry startOdomMsg;
for (int i = 0; i < (int)odomQueue.size(); ++i)
{
startOdomMsg = odomQueue[i];
- if (ROS_TIME(&startOdomMsg) < timeScanCur)
+ if (stamp2Sec(startOdomMsg.header.stamp) < timeScanCur)
continue;
else
break;
}
- tf::Quaternion orientation;
- tf::quaternionMsgToTF(startOdomMsg.pose.pose.orientation, orientation);
+ tf2::Quaternion orientation;
+ tf2::fromMsg(startOdomMsg.pose.pose.orientation, orientation);
double roll, pitch, yaw;
- tf::Matrix3x3(orientation).getRPY(roll, pitch, yaw);
+ tf2::Matrix3x3(orientation).getRPY(roll, pitch, yaw);
// Initial guess used in mapOptimization
- cloudInfo.initialGuessX = startOdomMsg.pose.pose.position.x;
- cloudInfo.initialGuessY = startOdomMsg.pose.pose.position.y;
- cloudInfo.initialGuessZ = startOdomMsg.pose.pose.position.z;
- cloudInfo.initialGuessRoll = roll;
- cloudInfo.initialGuessPitch = pitch;
- cloudInfo.initialGuessYaw = yaw;
+ cloudInfo.initial_guess_x = startOdomMsg.pose.pose.position.x;
+ cloudInfo.initial_guess_y = startOdomMsg.pose.pose.position.y;
+ cloudInfo.initial_guess_z = startOdomMsg.pose.pose.position.z;
+ cloudInfo.initial_guess_roll = roll;
+ cloudInfo.initial_guess_pitch = pitch;
+ cloudInfo.initial_guess_yaw = yaw;
- cloudInfo.odomAvailable = true;
+ cloudInfo.odom_available = true;
// get end odometry at the end of the scan
odomDeskewFlag = false;
- if (odomQueue.back().header.stamp.toSec() < timeScanEnd)
+ if (stamp2Sec(odomQueue.back().header.stamp) < timeScanEnd)
return;
- nav_msgs::Odometry endOdomMsg;
+ nav_msgs::msg::Odometry endOdomMsg;
for (int i = 0; i < (int)odomQueue.size(); ++i)
{
endOdomMsg = odomQueue[i];
- if (ROS_TIME(&endOdomMsg) < timeScanEnd)
+ if (stamp2Sec(endOdomMsg.header.stamp) < timeScanEnd)
continue;
else
break;
@@ -427,8 +436,8 @@ class ImageProjection : public ParamServer
Eigen::Affine3f transBegin = pcl::getTransformation(startOdomMsg.pose.pose.position.x, startOdomMsg.pose.pose.position.y, startOdomMsg.pose.pose.position.z, roll, pitch, yaw);
- tf::quaternionMsgToTF(endOdomMsg.pose.pose.orientation, orientation);
- tf::Matrix3x3(orientation).getRPY(roll, pitch, yaw);
+ tf2::fromMsg(endOdomMsg.pose.pose.orientation, orientation);
+ tf2::Matrix3x3(orientation).getRPY(roll, pitch, yaw);
Eigen::Affine3f transEnd = pcl::getTransformation(endOdomMsg.pose.pose.position.x, endOdomMsg.pose.pose.position.y, endOdomMsg.pose.pose.position.z, roll, pitch, yaw);
Eigen::Affine3f transBt = transBegin.inverse() * transEnd;
@@ -484,7 +493,7 @@ class ImageProjection : public ParamServer
PointType deskewPoint(PointType *point, double relTime)
{
- if (deskewFlag == -1 || cloudInfo.imuAvailable == false)
+ if (deskewFlag == -1 || cloudInfo.imu_available == false)
return *point;
double pointTime = timeScanCur + relTime;
@@ -565,44 +574,48 @@ class ImageProjection : public ParamServer
// extract segmented cloud for lidar odometry
for (int i = 0; i < N_SCAN; ++i)
{
- cloudInfo.startRingIndex[i] = count - 1 + 5;
-
+ cloudInfo.start_ring_index[i] = count - 1 + 5;
for (int j = 0; j < Horizon_SCAN; ++j)
{
if (rangeMat.at(i,j) != FLT_MAX)
{
// mark the points' column index for marking occlusion later
- cloudInfo.pointColInd[count] = j;
+ cloudInfo.point_col_ind[count] = j;
// save range info
- cloudInfo.pointRange[count] = rangeMat.at(i,j);
+ cloudInfo.point_range[count] = rangeMat.at(i,j);
// save extracted cloud
extractedCloud->push_back(fullCloud->points[j + i*Horizon_SCAN]);
// size of extracted cloud
++count;
}
}
- cloudInfo.endRingIndex[i] = count -1 - 5;
+ cloudInfo.end_ring_index[i] = count -1 - 5;
}
}
void publishClouds()
{
cloudInfo.header = cloudHeader;
- cloudInfo.cloud_deskewed = publishCloud(&pubExtractedCloud, extractedCloud, cloudHeader.stamp, lidarFrame);
- pubLaserCloudInfo.publish(cloudInfo);
+ cloudInfo.cloud_deskewed = publishCloud(pubExtractedCloud, extractedCloud, cloudHeader.stamp, lidarFrame);
+ pubLaserCloudInfo->publish(cloudInfo);
}
};
int main(int argc, char** argv)
{
- ros::init(argc, argv, "lio_sam");
+ rclcpp::init(argc, argv);
- ImageProjection IP;
-
- ROS_INFO("\033[1;32m----> Image Projection Started.\033[0m");
+ rclcpp::NodeOptions options;
+ options.use_intra_process_comms(true);
+ rclcpp::executors::MultiThreadedExecutor exec;
- ros::MultiThreadedSpinner spinner(3);
- spinner.spin();
-
+ auto IP = std::make_shared(options);
+ exec.add_node(IP);
+
+ RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "\033[1;32m----> Image Projection Started.\033[0m");
+
+ exec.spin();
+
+ rclcpp::shutdown();
return 0;
}
diff --git a/src/imuPreintegration.cpp b/src/imuPreintegration.cpp
index 5273f7fe..20e66be4 100644
--- a/src/imuPreintegration.cpp
+++ b/src/imuPreintegration.cpp
@@ -1,4 +1,4 @@
-#include "utility.h"
+#include "utility.hpp"
#include
#include
@@ -25,72 +25,60 @@ class TransformFusion : public ParamServer
public:
std::mutex mtx;
- ros::Subscriber subImuOdometry;
- ros::Subscriber subLaserOdometry;
+ rclcpp::Subscription::SharedPtr subImuOdometry;
+ rclcpp::Subscription::SharedPtr subLaserOdometry;
- ros::Publisher pubImuOdometry;
- ros::Publisher pubImuPath;
+ rclcpp::Publisher::SharedPtr pubImuOdometry;
+ rclcpp::Publisher::SharedPtr pubImuPath;
- Eigen::Affine3f lidarOdomAffine;
- Eigen::Affine3f imuOdomAffineFront;
- Eigen::Affine3f imuOdomAffineBack;
+ Eigen::Isometry3d lidarOdomAffine;
+ Eigen::Isometry3d imuOdomAffineFront;
+ Eigen::Isometry3d imuOdomAffineBack;
- tf::TransformListener tfListener;
- tf::StampedTransform lidar2Baselink;
+ std::shared_ptr tfBuffer;
+ std::shared_ptr tfBroadcaster;
+ std::shared_ptr tfListener;
+ tf2::Stamped lidar2Baselink;
double lidarOdomTime = -1;
- deque imuOdomQueue;
+ deque imuOdomQueue;
- TransformFusion()
+ TransformFusion(const rclcpp::NodeOptions & options) : ParamServer("lio_sam_transformFusion", options)
{
- if(lidarFrame != baselinkFrame)
- {
- try
- {
- tfListener.waitForTransform(lidarFrame, baselinkFrame, ros::Time(0), ros::Duration(3.0));
- tfListener.lookupTransform(lidarFrame, baselinkFrame, ros::Time(0), lidar2Baselink);
- }
- catch (tf::TransformException ex)
- {
- ROS_ERROR("%s",ex.what());
- }
- }
+ tfBuffer = std::make_shared(get_clock());
+ tfListener = std::make_shared(*tfBuffer);
+
+ subLaserOdometry = create_subscription(
+ "lio_sam/mapping/odometry", qos,
+ std::bind(&TransformFusion::lidarOdometryHandler, this, std::placeholders::_1));
+ subImuOdometry = create_subscription(
+ odomTopic+"_incremental", qos_imu,
+ std::bind(&TransformFusion::imuOdometryHandler, this, std::placeholders::_1));
- subLaserOdometry = nh.subscribe("lio_sam/mapping/odometry", 5, &TransformFusion::lidarOdometryHandler, this, ros::TransportHints().tcpNoDelay());
- subImuOdometry = nh.subscribe(odomTopic+"_incremental", 2000, &TransformFusion::imuOdometryHandler, this, ros::TransportHints().tcpNoDelay());
+ pubImuOdometry = create_publisher(odomTopic, qos_imu);
+ pubImuPath = create_publisher("lio_sam/imu/path", qos);
- pubImuOdometry = nh.advertise(odomTopic, 2000);
- pubImuPath = nh.advertise ("lio_sam/imu/path", 1);
+ tfBroadcaster = std::make_unique(this);
}
- Eigen::Affine3f odom2affine(nav_msgs::Odometry odom)
+ Eigen::Isometry3d odom2affine(nav_msgs::msg::Odometry odom)
{
- double x, y, z, roll, pitch, yaw;
- x = odom.pose.pose.position.x;
- y = odom.pose.pose.position.y;
- z = odom.pose.pose.position.z;
- tf::Quaternion orientation;
- tf::quaternionMsgToTF(odom.pose.pose.orientation, orientation);
- tf::Matrix3x3(orientation).getRPY(roll, pitch, yaw);
- return pcl::getTransformation(x, y, z, roll, pitch, yaw);
+ tf2::Transform t;
+ tf2::fromMsg(odom.pose.pose, t);
+ return tf2::transformToEigen(tf2::toMsg(t));
}
- void lidarOdometryHandler(const nav_msgs::Odometry::ConstPtr& odomMsg)
+ void lidarOdometryHandler(const nav_msgs::msg::Odometry::SharedPtr odomMsg)
{
std::lock_guard lock(mtx);
lidarOdomAffine = odom2affine(*odomMsg);
- lidarOdomTime = odomMsg->header.stamp.toSec();
+ lidarOdomTime = stamp2Sec(odomMsg->header.stamp);
}
- void imuOdometryHandler(const nav_msgs::Odometry::ConstPtr& odomMsg)
+ void imuOdometryHandler(const nav_msgs::msg::Odometry::SharedPtr odomMsg)
{
- // static tf
- static tf::TransformBroadcaster tfMap2Odom;
- static tf::Transform map_to_odom = tf::Transform(tf::createQuaternionFromRPY(0, 0, 0), tf::Vector3(0, 0, 0));
- tfMap2Odom.sendTransform(tf::StampedTransform(map_to_odom, odomMsg->header.stamp, mapFrame, odometryFrame));
-
std::lock_guard lock(mtx);
imuOdomQueue.push_back(*odomMsg);
@@ -100,54 +88,67 @@ class TransformFusion : public ParamServer
return;
while (!imuOdomQueue.empty())
{
- if (imuOdomQueue.front().header.stamp.toSec() <= lidarOdomTime)
+ if (stamp2Sec(imuOdomQueue.front().header.stamp) <= lidarOdomTime)
imuOdomQueue.pop_front();
else
break;
}
- Eigen::Affine3f imuOdomAffineFront = odom2affine(imuOdomQueue.front());
- Eigen::Affine3f imuOdomAffineBack = odom2affine(imuOdomQueue.back());
- Eigen::Affine3f imuOdomAffineIncre = imuOdomAffineFront.inverse() * imuOdomAffineBack;
- Eigen::Affine3f imuOdomAffineLast = lidarOdomAffine * imuOdomAffineIncre;
- float x, y, z, roll, pitch, yaw;
- pcl::getTranslationAndEulerAngles(imuOdomAffineLast, x, y, z, roll, pitch, yaw);
-
+ Eigen::Isometry3d imuOdomAffineFront = odom2affine(imuOdomQueue.front());
+ Eigen::Isometry3d imuOdomAffineBack = odom2affine(imuOdomQueue.back());
+ Eigen::Isometry3d imuOdomAffineIncre = imuOdomAffineFront.inverse() * imuOdomAffineBack;
+ Eigen::Isometry3d imuOdomAffineLast = lidarOdomAffine * imuOdomAffineIncre;
+ auto t = tf2::eigenToTransform(imuOdomAffineLast);
+ tf2::Stamped tCur;
+ tf2::convert(t, tCur);
+
// publish latest odometry
- nav_msgs::Odometry laserOdometry = imuOdomQueue.back();
- laserOdometry.pose.pose.position.x = x;
- laserOdometry.pose.pose.position.y = y;
- laserOdometry.pose.pose.position.z = z;
- laserOdometry.pose.pose.orientation = tf::createQuaternionMsgFromRollPitchYaw(roll, pitch, yaw);
- pubImuOdometry.publish(laserOdometry);
+ nav_msgs::msg::Odometry laserOdometry = imuOdomQueue.back();
+ laserOdometry.pose.pose.position.x = t.transform.translation.x;
+ laserOdometry.pose.pose.position.y = t.transform.translation.y;
+ laserOdometry.pose.pose.position.z = t.transform.translation.z;
+ laserOdometry.pose.pose.orientation = t.transform.rotation;
+ pubImuOdometry->publish(laserOdometry);
// publish tf
- static tf::TransformBroadcaster tfOdom2BaseLink;
- tf::Transform tCur;
- tf::poseMsgToTF(laserOdometry.pose.pose, tCur);
if(lidarFrame != baselinkFrame)
- tCur = tCur * lidar2Baselink;
- tf::StampedTransform odom_2_baselink = tf::StampedTransform(tCur, odomMsg->header.stamp, odometryFrame, baselinkFrame);
- tfOdom2BaseLink.sendTransform(odom_2_baselink);
+ {
+ try
+ {
+ tf2::fromMsg(tfBuffer->lookupTransform(
+ lidarFrame, baselinkFrame, rclcpp::Time(0)), lidar2Baselink);
+ }
+ catch (tf2::TransformException ex)
+ {
+ RCLCPP_ERROR(get_logger(), "%s", ex.what());
+ }
+ tf2::Stamped tb(
+ tCur * lidar2Baselink, tf2_ros::fromMsg(odomMsg->header.stamp), odometryFrame);
+ tCur = tb;
+ }
+ geometry_msgs::msg::TransformStamped ts;
+ tf2::convert(tCur, ts);
+ ts.child_frame_id = baselinkFrame;
+ tfBroadcaster->sendTransform(ts);
// publish IMU path
- static nav_msgs::Path imuPath;
+ static nav_msgs::msg::Path imuPath;
static double last_path_time = -1;
- double imuTime = imuOdomQueue.back().header.stamp.toSec();
+ double imuTime = stamp2Sec(imuOdomQueue.back().header.stamp);
if (imuTime - last_path_time > 0.1)
{
last_path_time = imuTime;
- geometry_msgs::PoseStamped pose_stamped;
+ geometry_msgs::msg::PoseStamped pose_stamped;
pose_stamped.header.stamp = imuOdomQueue.back().header.stamp;
pose_stamped.header.frame_id = odometryFrame;
pose_stamped.pose = laserOdometry.pose.pose;
imuPath.poses.push_back(pose_stamped);
- while(!imuPath.poses.empty() && imuPath.poses.front().header.stamp.toSec() < lidarOdomTime - 1.0)
+ while(!imuPath.poses.empty() && stamp2Sec(imuPath.poses.front().header.stamp) < lidarOdomTime - 1.0)
imuPath.poses.erase(imuPath.poses.begin());
- if (pubImuPath.getNumSubscribers() != 0)
+ if (pubImuPath->get_subscription_count() != 0)
{
imuPath.header.stamp = imuOdomQueue.back().header.stamp;
imuPath.header.frame_id = odometryFrame;
- pubImuPath.publish(imuPath);
+ pubImuPath->publish(imuPath);
}
}
}
@@ -159,9 +160,9 @@ class IMUPreintegration : public ParamServer
std::mutex mtx;
- ros::Subscriber subImu;
- ros::Subscriber subOdometry;
- ros::Publisher pubImuOdometry;
+ rclcpp::Subscription::SharedPtr subImu;
+ rclcpp::Subscription::SharedPtr subOdometry;
+ rclcpp::Publisher