Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(ndt_scan_matcher): dynamic map loading #2339

Merged
merged 56 commits into from
Feb 3, 2023
Merged
Show file tree
Hide file tree
Changes from 45 commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
6116167
first commit
kminoda Nov 21, 2022
fc06c34
ci(pre-commit): autofix
pre-commit-ci[bot] Nov 21, 2022
76ef350
import map update module in core
kminoda Nov 22, 2022
de4c8ed
Merge branch 'feature/dynamic_map_loading' of github.com:kminoda/auto…
kminoda Nov 22, 2022
36c2c7b
ci(pre-commit): autofix
pre-commit-ci[bot] Nov 22, 2022
cd00a81
minor fixes. Now map update module launches!!!
kminoda Nov 22, 2022
7a01c6c
resolve conflict
kminoda Nov 22, 2022
6dd6347
ci(pre-commit): autofix
pre-commit-ci[bot] Nov 22, 2022
0f45450
Merge branch 'main' into feature/dynamic_map_loading
kminoda Dec 13, 2022
b263820
debugged
kminoda Dec 14, 2022
e3f83d6
revert unnecessary fix
kminoda Dec 16, 2022
c702184
minor fixes
kminoda Dec 16, 2022
638a621
update launch file
kminoda Dec 16, 2022
3019843
update comment
kminoda Dec 16, 2022
2931767
ci(pre-commit): autofix
pre-commit-ci[bot] Dec 16, 2022
dbf7d81
update comment
kminoda Dec 16, 2022
e2aed6d
Merge remote-tracking branch 'origin' into feature/dynamic_map_loading
kminoda Dec 19, 2022
5ae3f28
update comment
kminoda Dec 19, 2022
506d0af
ci(pre-commit): autofix
pre-commit-ci[bot] Dec 19, 2022
6f4ff79
update comment
kminoda Dec 19, 2022
8942f7a
ci(pre-commit): autofix
pre-commit-ci[bot] Dec 19, 2022
283e6b3
update for ndt_omp
kminoda Dec 20, 2022
4532fef
resolve conflict
kminoda Jan 5, 2023
76ef2f4
changed parameter names
kminoda Jan 5, 2023
e2ae1d8
ci(pre-commit): autofix
pre-commit-ci[bot] Jan 5, 2023
057ccb0
apply pre-commit-
kminoda Jan 5, 2023
fb77826
ci(pre-commit): autofix
pre-commit-ci[bot] Jan 5, 2023
2f5cf8b
update readme
kminoda Jan 5, 2023
7085813
ci(pre-commit): autofix
pre-commit-ci[bot] Jan 5, 2023
a88f0fb
update readme
kminoda Jan 5, 2023
9e5cea6
ci(pre-commit): autofix
pre-commit-ci[bot] Jan 5, 2023
fd3b484
simplify client implementation
kminoda Jan 5, 2023
3a2082f
remove unnecessary comments
kminoda Jan 5, 2023
0be1e62
ci(pre-commit): autofix
pre-commit-ci[bot] Jan 5, 2023
6d78517
removed unused member variables
kminoda Jan 5, 2023
67585f8
set default use_dynamic_map_loading to true
kminoda Jan 5, 2023
3effed0
Merge remote-tracking branch 'origin' into feature/dynamic_map_loading
kminoda Jan 6, 2023
bf09518
changed readme
kminoda Jan 6, 2023
bcfed68
ci(pre-commit): autofix
pre-commit-ci[bot] Jan 6, 2023
13dd04b
reflected comments
kminoda Jan 6, 2023
0844435
use std::optional instead of shared_ptr
kminoda Jan 6, 2023
f8da47b
ci(pre-commit): autofix
pre-commit-ci[bot] Jan 6, 2023
50b3855
fix parameter description
kminoda Jan 10, 2023
950ac42
revert launch output config
kminoda Jan 10, 2023
103ff18
change default subscriber name
kminoda Jan 10, 2023
30ec6f6
remove unnecessary setInputSource
kminoda Jan 10, 2023
8d5db45
Merge branch 'main' into feature/dynamic_map_loading
kminoda Jan 11, 2023
026ea61
add gif
kminoda Jan 11, 2023
bd01c6a
ci(pre-commit): autofix
pre-commit-ci[bot] Jan 11, 2023
ee26d57
minor fix
kminoda Jan 11, 2023
f61552f
Update localization/ndt_scan_matcher/src/map_update_module.cpp
kminoda Jan 11, 2023
ac3f043
update literals
kminoda Jan 11, 2023
de0ef18
update map_loader default parameters
kminoda Jan 19, 2023
9544d47
Merge branch 'main' into feature/dynamic_map_loading
kminoda Jan 20, 2023
fbaac69
update readme
kminoda Jan 27, 2023
1503f7d
ci(pre-commit): autofix
pre-commit-ci[bot] Jan 27, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions localization/ndt_scan_matcher/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ ament_auto_add_executable(ndt_scan_matcher
src/tf2_listener_module.cpp
src/map_module.cpp
src/pose_initialization_module.cpp
src/map_update_module.cpp
)

link_directories(${PCL_LIBRARY_DIRS})
Expand Down
55 changes: 54 additions & 1 deletion localization/ndt_scan_matcher/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ One optional function is regularization. Please see the regularization chapter i
| `max_iterations` | int | The number of iterations required to calculate alignment |
| `converged_param_type` | int | The type of indicators for scan matching score (0: TP, 1: NVTL) |
| `converged_param_transform_probability` | double | Threshold for deciding whether to trust the estimation result |
| `neighborhood_search_method` | int | neighborhood search method (0=KDTREE, 1=DIRECT26, 2=DIRECT7, 3=DIRECT1) |
| `num_threads` | int | Number of threads used for parallel computing |

(TP: Transform Probability, NVTL: Nearest Voxel Transform Probability)
Expand Down Expand Up @@ -169,3 +168,57 @@ The color of the trajectory indicates the error (meter) from the reference traje
- The right figure shows that the regularization suppresses the longitudinal error.

<img src="./media/trajectory_without_regularization.png" alt="drawing" width="300"/> <img src="./media/trajectory_with_regularization.png" alt="drawing" width="300"/>

## Dynamic map loading

Autoware supports dynamic map loading feature for `ndt_scan_matcher`. Using this feature, NDT dynamically requests for the surrounding pointcloud map to `pointcloud_map_loader`, and then receive and preprocess the map in an online fashion.

Using the feature, `ndt_scan_matcher` can theoretically handle any large size maps in terms of memory usage. (Note that it is still possible that there exists a limitation due to other factors, e.g. floating-point error)

### Additional interfaces

#### Additional inputs

| Name | Type | Description |
| ---------------- | ------------------------- | ----------------------------------------------------------- |
| `input_ekf_odom` | `nav_msgs::msg::Odometry` | Vehicle localization results (used for map update decision) |

#### Additional outputs

| Name | Type | Description |
| ----------------------------- | ------------------------------- | ------------------------------------------------- |
| `debug/loaded_pointcloud_map` | `sensor_msgs::msg::PointCloud2` | pointcloud maps used for localization (for debug) |

#### Additional client

| Name | Type | Description |
| ------------------- | ------------------------------------------------------ | ------------------ |
| `client_map_loader` | `autoware_map_msgs::srv::GetDifferentialPointCloudMap` | map loading client |

### Parameters

| Name | Type | Description |
| ------------------------------------- | ------ | -------------------------------------------------------------------- |
| `use_dynamic_map_loading` | bool | Flag to enable dynamic map loading feature for NDT (TRUE by default) |
| `dynamic_map_loading_update_distance` | double | Distance traveled to load new map(s) |
| `dynamic_map_loading_map_radius` | double | Map loading radius for every update |
| `lidar_radius` | double | LiDAR radius used for localization (only used for diagnosis) |

### Enabling the dynamic map loading feature

To use dynamic map loading feature for `ndt_scan_matcher`, you also need to appropriately configure some other settings outside of this node.
Follow the next two instructions.

1. enable dynamic map loading interface in `pointcloud_map_loader` (by setting `enable_differential_load` to true in the package)
2. split the PCD files into grids (recommended split size: 20[m] x 20[m])

Here is a split PCD map for `sample-map-rosbag` from Autoware tutorial: [`sample-map-rosbag_split.zip`](https://github.com/autowarefoundation/autoware.universe/files/10349104/sample-map-rosbag_split.zip)

| PCD files | `use_dynamic_map_loading` | `enable_differential_load` | How NDT loads map(s) |
| :---------: | :-----------------------: | :------------------------: | :------------------: |
| single file | true | true | at once (standard) |
| single file | true | false | **does NOT work** |
| single file | false | true/false | at once (standard) |
| splitted | true | true | dynamically |
| splitted | true | false | **does NOT work** |
| splitted | false | true/false | at once (standard) |
17 changes: 12 additions & 5 deletions localization/ndt_scan_matcher/config/ndt_scan_matcher.param.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
/**:
ros__parameters:
# Use dynamic map loading
use_dynamic_map_loading: true

# Vehicle reference frame
base_frame: "base_link"
Expand Down Expand Up @@ -41,10 +43,6 @@
# Tolerance of distance difference between two initial poses used for linear interpolation. [m]
initial_pose_distance_tolerance_m: 10.0

# neighborhood search method
# 0=KDTREE, 1=DIRECT26, 2=DIRECT7, 3=DIRECT1
neighborhood_search_method: 0

yukkysaito marked this conversation as resolved.
Show resolved Hide resolved
# Number of threads used for parallel computing
num_threads: 4

Expand All @@ -63,5 +61,14 @@
# Regularization switch
regularization_enabled: false

# Regularization scale factor
# regularization scale factor
regularization_scale_factor: 0.01

# Dynamic map loading distance
dynamic_map_loading_update_distance: 20.0

# Dynamic map loading loading radius
dynamic_map_loading_map_radius: 150.0

# Radius of input LiDAR range (used for diagnostics of dynamic map loading)
lidar_radius: 100.0
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@

#include <sensor_msgs/msg/point_cloud2.hpp>

#include <multigrid_pclomp/multigrid_ndt_omp.h>
#include <pcl/point_types.h>
#include <pcl_conversions/pcl_conversions.h>
#include <pclomp/ndt_omp.h>

#include <memory>

Expand All @@ -30,7 +30,7 @@ class MapModule
using PointSource = pcl::PointXYZ;
using PointTarget = pcl::PointXYZ;
using NormalDistributionsTransform =
pclomp::NormalDistributionsTransform<PointSource, PointTarget>;
pclomp::MultiGridNormalDistributionsTransform<PointSource, PointTarget>;

public:
MapModule(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
// Copyright 2022 Autoware Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef NDT_SCAN_MATCHER__MAP_UPDATE_MODULE_HPP_
#define NDT_SCAN_MATCHER__MAP_UPDATE_MODULE_HPP_

#include "ndt_scan_matcher/debug.hpp"
#include "ndt_scan_matcher/particle.hpp"
#include "ndt_scan_matcher/tf2_listener_module.hpp"
#include "ndt_scan_matcher/util_func.hpp"

#include <rclcpp/rclcpp.hpp>
#include <tier4_autoware_utils/ros/marker_helper.hpp>

#include <autoware_map_msgs/srv/get_differential_point_cloud_map.hpp>
#include <geometry_msgs/msg/pose_with_covariance_stamped.hpp>
#include <nav_msgs/msg/odometry.hpp>
#include <tier4_localization_msgs/srv/pose_with_covariance_stamped.hpp>
#include <visualization_msgs/msg/marker_array.hpp>

#include <fmt/format.h>
#include <multigrid_pclomp/multigrid_ndt_omp.h>
#include <pcl_conversions/pcl_conversions.h>

#include <map>
#include <memory>
#include <optional>
#include <string>
#include <vector>

class MapUpdateModule
{
using PointSource = pcl::PointXYZ;
using PointTarget = pcl::PointXYZ;
using NormalDistributionsTransform =
pclomp::MultiGridNormalDistributionsTransform<PointSource, PointTarget>;

public:
MapUpdateModule(
rclcpp::Node * node, std::mutex * ndt_ptr_mutex,
std::shared_ptr<NormalDistributionsTransform> ndt_ptr,
std::shared_ptr<Tf2ListenerModule> tf2_listener_module, std::string map_frame,
rclcpp::CallbackGroup::SharedPtr main_callback_group,
std::shared_ptr<std::map<std::string, std::string>> state_ptr);

private:
void service_ndt_align(
const tier4_localization_msgs::srv::PoseWithCovarianceStamped::Request::SharedPtr req,
tier4_localization_msgs::srv::PoseWithCovarianceStamped::Response::SharedPtr res);
void callback_ekf_odom(nav_msgs::msg::Odometry::ConstSharedPtr odom_ptr);
void map_update_timer_callback();

void update_ndt(
const std::vector<autoware_map_msgs::msg::PointCloudMapCellWithID> & maps_to_add,
const std::vector<std::string> & map_ids_to_remove);
void update_map(const geometry_msgs::msg::Point & position);
bool should_update_map(const geometry_msgs::msg::Point & position) const;
void publish_partial_pcd_map();
geometry_msgs::msg::PoseWithCovarianceStamped align_using_monte_carlo(
const std::shared_ptr<NormalDistributionsTransform> & ndt_ptr,
const geometry_msgs::msg::PoseWithCovarianceStamped & initial_pose_with_cov);
void publish_point_cloud(
const rclcpp::Time & sensor_ros_time, const std::string & frame_id,
const std::shared_ptr<const pcl::PointCloud<PointSource>> & sensor_points_mapTF_ptr);

rclcpp::Publisher<sensor_msgs::msg::PointCloud2>::SharedPtr loaded_pcd_pub_;
rclcpp::Publisher<visualization_msgs::msg::MarkerArray>::SharedPtr
ndt_monte_carlo_initial_pose_marker_pub_;
rclcpp::Publisher<sensor_msgs::msg::PointCloud2>::SharedPtr sensor_aligned_pose_pub_;

rclcpp::Service<tier4_localization_msgs::srv::PoseWithCovarianceStamped>::SharedPtr service_;
rclcpp::Client<autoware_map_msgs::srv::GetDifferentialPointCloudMap>::SharedPtr
pcd_loader_client_;
rclcpp::TimerBase::SharedPtr map_update_timer_;

rclcpp::Subscription<nav_msgs::msg::Odometry>::SharedPtr ekf_odom_sub_;

rclcpp::CallbackGroup::SharedPtr map_callback_group_;

std::shared_ptr<NormalDistributionsTransform> ndt_ptr_;
std::mutex * ndt_ptr_mutex_;
std::string map_frame_;
rclcpp::Logger logger_;
rclcpp::Clock::SharedPtr clock_;
std::shared_ptr<Tf2ListenerModule> tf2_listener_module_;
std::shared_ptr<std::map<std::string, std::string>> state_ptr_;

int initial_estimate_particles_num_;
std::optional<geometry_msgs::msg::Point> last_update_position_ = std::nullopt;
std::optional<geometry_msgs::msg::Point> current_position_ = std::nullopt;
const double dynamic_map_loading_update_distance_;
const double dynamic_map_loading_map_radius_;
const double lidar_radius_;
};

#endif // NDT_SCAN_MATCHER__MAP_UPDATE_MODULE_HPP_
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#define FMT_HEADER_ONLY

#include "ndt_scan_matcher/map_module.hpp"
#include "ndt_scan_matcher/map_update_module.hpp"
#include "ndt_scan_matcher/pose_initialization_module.hpp"
#include "ndt_scan_matcher/tf2_listener_module.hpp"

Expand All @@ -34,8 +35,8 @@
#include <visualization_msgs/msg/marker_array.hpp>

#include <fmt/format.h>
#include <multigrid_pclomp/multigrid_ndt_omp.h>
#include <pcl/point_types.h>
#include <pclomp/ndt_omp.h>
#include <tf2/transform_datatypes.h>

#ifdef ROS_DISTRO_GALACTIC
Expand Down Expand Up @@ -71,7 +72,7 @@ class NDTScanMatcher : public rclcpp::Node
using PointSource = pcl::PointXYZ;
using PointTarget = pcl::PointXYZ;
using NormalDistributionsTransform =
pclomp::NormalDistributionsTransform<PointSource, PointTarget>;
pclomp::MultiGridNormalDistributionsTransform<PointSource, PointTarget>;

public:
NDTScanMatcher();
Expand Down Expand Up @@ -195,6 +196,7 @@ class NDTScanMatcher : public rclcpp::Node
std::shared_ptr<Tf2ListenerModule> tf2_listener_module_;
std::unique_ptr<MapModule> map_module_;
std::unique_ptr<PoseInitializationModule> pose_init_module_;
std::unique_ptr<MapUpdateModule> map_update_module_;
};

#endif // NDT_SCAN_MATCHER__NDT_SCAN_MATCHER_CORE_HPP_
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@
#include <tier4_localization_msgs/srv/pose_with_covariance_stamped.hpp>
#include <visualization_msgs/msg/marker_array.hpp>

#include <multigrid_pclomp/multigrid_ndt_omp.h>
#include <pcl_conversions/pcl_conversions.h>
#include <pclomp/ndt_omp.h>

#include <map>
#include <memory>
Expand All @@ -39,7 +39,7 @@ class PoseInitializationModule
using PointSource = pcl::PointXYZ;
using PointTarget = pcl::PointXYZ;
using NormalDistributionsTransform =
pclomp::NormalDistributionsTransform<PointSource, PointTarget>;
pclomp::MultiGridNormalDistributionsTransform<PointSource, PointTarget>;

public:
PoseInitializationModule(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,13 @@
<arg name="input_map_points_topic" default="/pointcloud_map" description="Map points topic"/>
<arg name="input_regularization_pose_topic" default="/sensing/gnss/pose_with_covariance" description="Regularization pose topic"/>
<arg name="input_service_trigger_node" default="trigger_node" description="Trigger node service name"/>
<arg name="input_ekf_odom" default="/localization/kinematic_state" description="Input EKF odometry"/>

<arg name="output_pose_topic" default="ndt_pose" description="Estimated self position"/>
<arg name="output_pose_with_covariance_topic" default="ndt_pose_with_covariance" description="Estimated self position with covariance"/>

<arg name="client_map_loader" default="/map/get_differential_pointcloud_map" description="Trigger node service name"/>

<arg name="node_name" default="ndt_scan_matcher" description="Use a different name for this node"/>

<node pkg="ndt_scan_matcher" exec="ndt_scan_matcher" name="$(var node_name)" output="log">
Expand All @@ -23,6 +26,9 @@
<remap from="ndt_pose_with_covariance" to="$(var output_pose_with_covariance_topic)"/>
<remap from="regularization_pose_with_covariance" to="$(var input_regularization_pose_topic)"/>
<remap from="trigger_node_srv" to="$(var input_service_trigger_node)"/>
<remap from="pcd_loader_service" to="$(var client_map_loader)"/>
<remap from="ekf_odom" to="$(var input_ekf_odom)"/>

<param from="$(var param_file)"/>
</node>
</launch>
1 change: 1 addition & 0 deletions localization/ndt_scan_matcher/package.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

<build_depend>autoware_cmake</build_depend>

<depend>autoware_map_msgs</depend>
<depend>diagnostic_msgs</depend>
<depend>fmt</depend>
<depend>geometry_msgs</depend>
Expand Down
Loading