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(autoware_pose_covariance_modifier): add new node to early fuse gnss and ndt poses #6570

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
ba6ef4f
feat(autoware_pose_covariance_modifier_node): add new node to early f…
Mar 14, 2024
ae60c63
don't change ekf input, change the ndt output name
Mar 14, 2024
3954f20
style(pre-commit): autofix
pre-commit-ci[bot] Mar 14, 2024
ef931ab
fix topic names
meliketanrikulu Mar 14, 2024
070540e
set default false
meliketanrikulu Mar 15, 2024
4aa592d
check position rmse for z
meliketanrikulu Mar 19, 2024
40d6f01
updates after review
meliketanrikulu Apr 2, 2024
7ad97b0
update proposal architecture
meliketanrikulu Apr 2, 2024
7a20279
reduce the reliability of position z
meliketanrikulu Apr 16, 2024
3e4e3f3
set debug param false
meliketanrikulu Apr 17, 2024
f75c1d1
update ndt_covariance_modifier function
meliketanrikulu Apr 19, 2024
2160f0d
add try catch for declarations
meliketanrikulu Apr 19, 2024
8922d85
update README.md
meliketanrikulu Apr 19, 2024
7595500
style(pre-commit): autofix
pre-commit-ci[bot] Apr 19, 2024
dbf8491
move use_autoware_pose_covariance_modifier block in use_ndt_pose
meliketanrikulu Apr 23, 2024
3a6452f
use gnss pose term instead of trusted pose
meliketanrikulu Apr 23, 2024
a4a26bd
rename new_pose_estimator_pub
meliketanrikulu Apr 23, 2024
f4800db
update pose_source equations
meliketanrikulu Apr 23, 2024
d4dff92
fix pose_twist_estimator notation problem
meliketanrikulu Apr 23, 2024
96e5fe6
delete default parameter values and fix camel case
meliketanrikulu Apr 24, 2024
044df72
style(pre-commit): autofix
pre-commit-ci[bot] Apr 24, 2024
7251948
update diagram
meliketanrikulu Apr 24, 2024
77bdca4
Explain the part where NDT error is calculated according to GNSS
meliketanrikulu Apr 24, 2024
322c468
add json files for parameters
meliketanrikulu Apr 24, 2024
d24ad60
Update .prettierrc.yaml
meliketanrikulu Apr 24, 2024
4e5d57a
style(pre-commit): autofix
pre-commit-ci[bot] Apr 24, 2024
0a04598
use stddev instead of rmse
meliketanrikulu Apr 24, 2024
39101a7
use stddev instead of error
meliketanrikulu Apr 25, 2024
57eac65
style(pre-commit): autofix
pre-commit-ci[bot] Apr 25, 2024
48c98ad
update formulas definitions
meliketanrikulu Apr 25, 2024
4f8ceec
update return statement position
meliketanrikulu Apr 25, 2024
ac98abf
Revert "Update .prettierrc.yaml"
meliketanrikulu Apr 25, 2024
943d5bc
Add detailed explanations to README.md
meliketanrikulu Apr 25, 2024
01aadac
attempt to simplify
May 2, 2024
22408e9
style(pre-commit): autofix
pre-commit-ci[bot] May 2, 2024
39fb633
improve the readme
May 3, 2024
54bb564
style(pre-commit): autofix
pre-commit-ci[bot] May 3, 2024
e43c42e
readme
May 3, 2024
74f7f7a
readme tables
May 3, 2024
83e4059
update readme
May 3, 2024
3f4569e
update media
meliketanrikulu May 3, 2024
bde4b82
style(pre-commit): autofix
pre-commit-ci[bot] May 3, 2024
ddcf447
update the tables
May 3, 2024
976ed0a
update media
meliketanrikulu May 3, 2024
0104b4b
interpolation update
May 3, 2024
1ef51b4
style(pre-commit): autofix
pre-commit-ci[bot] May 3, 2024
20e3986
cpp-changes
May 3, 2024
a5a0e28
change everything
May 6, 2024
c48e10b
style(pre-commit): autofix
pre-commit-ci[bot] May 6, 2024
7677df1
concat namespaces
May 6, 2024
b59ef07
test mermaid diagrams
May 6, 2024
8088cba
illustration
May 6, 2024
44bf00f
style(pre-commit): autofix
pre-commit-ci[bot] May 6, 2024
b0e967b
comment
May 6, 2024
331ff8f
style(pre-commit): autofix
pre-commit-ci[bot] May 6, 2024
ca1648b
clean up
May 6, 2024
32f1e3d
remove unused string
May 6, 2024
8135dc0
add ndt stddev bounds as parameter and update launch dir
meliketanrikulu May 7, 2024
64119d3
fix pose_source comparison problem
meliketanrikulu May 7, 2024
0d99ad5
fix duplicate debug part in NDT callback
meliketanrikulu May 7, 2024
1887611
update comments and readme
May 8, 2024
77cbdfb
fix pub topic names
May 8, 2024
2efbb92
style(pre-commit): autofix
pre-commit-ci[bot] May 8, 2024
4d75ad4
update node name in launch to fit new guidelines
May 8, 2024
bf40cca
fix CI
meliketanrikulu May 8, 2024
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
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<?xml version="1.0"?>
<launch>
<arg name="output_pose_with_covariance_topic" default="/localization/pose_estimator/pose_with_covariance"/>
<group>
<include file="$(find-pkg-share ndt_scan_matcher)/launch/ndt_scan_matcher.launch.xml">
<arg name="input_pointcloud" value="/localization/util/downsample/pointcloud"/>
Expand All @@ -8,7 +9,7 @@
<arg name="input_service_trigger_node" value="/localization/pose_estimator/trigger_node"/>

<arg name="output_pose_topic" value="/localization/pose_estimator/pose"/>
<arg name="output_pose_with_covariance_topic" value="/localization/pose_estimator/pose_with_covariance"/>
<arg name="output_pose_with_covariance_topic" value="$(var output_pose_with_covariance_topic)"/>

<arg name="client_map_loader" value="/map/get_differential_pointcloud_map"/>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<?xml version="1.0"?>
<launch>
<arg name="use_autoware_pose_covariance_modifier" default="false"/>
<!-- only when running with a real vehicle, the pose_initializer judges the stop -->
<let name="stop_check_enabled" if="$(eval &quot;'$(var system_run_mode)'=='online'&quot;)" value="true"/>
<let name="stop_check_enabled" if="$(eval &quot;'$(var system_run_mode)'=='logging_simulation'&quot;)" value="false"/>
Expand Down Expand Up @@ -29,7 +30,20 @@
<!-- NDT Scan Matcher Launch (as pose estimator) -->
<group if="$(var use_ndt_pose)">
<push-ros-namespace namespace="pose_estimator"/>
<include file="$(find-pkg-share tier4_localization_launch)/launch/pose_twist_estimator/ndt_scan_matcher.launch.xml"/>
<let
name="ndt_output_pose_with_cov_topic_name"
if="$(eval &quot;'$(var use_autoware_pose_covariance_modifier)'=='true'&quot;)"
value="/localization/pose_estimator/ndt_scan_matcher/pose_with_covariance"
/>
<let name="ndt_output_pose_with_cov_topic_name" unless="$(eval &quot;'$(var use_autoware_pose_covariance_modifier)'=='true'&quot;)" value="/localization/pose_estimator/pose_with_covariance"/>
<include file="$(find-pkg-share tier4_localization_launch)/launch/pose_twist_estimator/ndt_scan_matcher.launch.xml">
<arg name="output_pose_with_covariance_topic" value="$(var ndt_output_pose_with_cov_topic_name)"/>
</include>

<!-- Autoware Pose Covariance Modifier Node Launch -->
<group if="$(var use_autoware_pose_covariance_modifier)">
<include file="$(find-pkg-share autoware_pose_covariance_modifier)/launch/pose_covariance_modifier.launch.xml"/>
</group>
</group>

<!-- YabLoc Launch (as pose estimator) -->
Expand Down
19 changes: 19 additions & 0 deletions localization/autoware_pose_covariance_modifier/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
cmake_minimum_required(VERSION 3.14)
project(autoware_pose_covariance_modifier)

find_package(autoware_cmake REQUIRED)
autoware_package()

ament_auto_add_library(${PROJECT_NAME} SHARED
src/pose_covariance_modifier.cpp
)

rclcpp_components_register_node(${PROJECT_NAME}
PLUGIN "autoware::pose_covariance_modifier::PoseCovarianceModifierNode"
EXECUTABLE ${PROJECT_NAME}_node
)

ament_auto_package(INSTALL_TO_SHARE
config
launch
)
213 changes: 213 additions & 0 deletions localization/autoware_pose_covariance_modifier/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
# Autoware Pose Covariance Modifier Node

## Purpose

This package makes it possible to use GNSS and NDT poses together in real time localization.

## Function

This package takes in GNSS (Global Navigation Satellite System)
and NDT (Normal Distribution Transform) poses with covariances.

It outputs a single pose with covariance:

- Directly the GNSS pose and its covariance.
- Directly the NDT pose and its covariance.
- Both GNSS and NDT poses with modified covariances.

> - This package doesn't modify the pose information it receives.
> - It only modifies NDT covariance values under certain conditions.

## Assumptions

- The NDT matcher provides a pose with a fixed covariance.
- The NDT matcher is unable to provide a dynamic, reliable covariance value.

## Requirements

- The GNSS/INS module must provide standard deviation values (its error / RMSE) for the position and orientation.
- It probably needs RTK support to provide accurate position and orientation information.
- You need to have a geo-referenced map.
- GNSS/INS module and the base_link frame must be calibrated well enough.
- In an environment where GNSS/INS and NDT systems work well, the `base_link` poses from both systems should be close to
each other.

## Description

GNSS and NDT nodes provide the pose with covariance data utilized in an Extended Kalman Filter (EKF).

Accurate covariance values are crucial for the effectiveness of the EKF in estimating the state.

The GNSS system generates reliable standard deviation values, which can be transformed into covariance measures.

But we currently don't have a reliable way to determine the covariance values for the NDT poses.
And the NDT matching system in Autoware outputs poses with preset covariance values.

For this reason, this package is designed to manage the selection of the pose source,
based on the standard deviation values provided by the GNSS system.

It also tunes the covariance values of the NDT poses, based on the GNSS standard deviation values.

## Flowcharts

### Without this package

Only NDT pose is used in localization. GNSS pose is only used for initialization.

```mermaid
graph TD
ndt_scan_matcher["ndt_scan_matcher"] --> |"/localization/pose_estimator/pose_with_covariance"| ekf_localizer["ekf_localizer"]

classDef cl_node fill:#FFF2CC,stroke-width:3px,stroke:#D6B656;

class ndt_scan_matcher cl_node;
class ekf_localizer cl_node;
```

### With this package

Both NDT and GNSS poses are used in localization, depending on the standard deviation values coming from the GNSS
system.

Here is a flowchart depicting the process and the predefined thresholds:

```mermaid
graph TD
gnss_poser["gnss_poser"] --> |"/sensing/gnss/\npose_with_covariance"| pose_covariance_modifier_node
ndt_scan_matcher["ndt_scan_matcher"] --> |"/localization/pose_estimator/ndt_scan_matcher/\npose_with_covariance"| pose_covariance_modifier_node

subgraph pose_covariance_modifier_node ["Pose Covariance Modifier Node"]
pc1{{"gnss_pose_yaw\nstddev"}}
pc1 -->|"<= 0.3 rad"| pc2{{"gnss_pose_z\nstddev"}}
pc2 -->|"<= 0.1 m"| pc3{{"gnss_pose_xy\nstddev"}}
pc2 -->|"> 0.1 m"| ndt_pose("NDT Pose")
pc3 -->|"<= 0.1 m"| gnss_pose("GNSS Pose")
pc3 -->|"0.1 m < x <= 0.2 m"| gnss_ndt_pose("`Both GNSS and NDT Pose
(_with modified covariance_)`")
pc3 -->|"> 0.2 m"| ndt_pose
pc1 -->|"> 0.3 rad"| ndt_pose
end

pose_covariance_modifier_node -->|"/localization/pose_estimator/pose_with_covariance"| ekf_localizer["ekf_localizer"]

classDef cl_node fill:#FFF2CC,stroke-width:3px,stroke:#D6B656;
classDef cl_conditional fill:#FFE6CC,stroke-width:3px,stroke:#D79B00;
classDef cl_output fill:#D5E8D4,stroke-width:3px,stroke:#82B366;

class gnss_poser cl_node;
class ndt_scan_matcher cl_node;
class ekf_localizer cl_node;
class pose_covariance_modifier_node cl_node;

class pc1 cl_conditional;
class pc2 cl_conditional;
class pc3 cl_conditional;

class ndt_pose cl_output;
class gnss_pose cl_output;
class gnss_ndt_pose cl_output;
```

## How to use this package

> **This package is disabled by default in Autoware, you need to manually enable it.**

To enable this package, you need to change the `use_autoware_pose_covariance_modifier` parameter to `true` within
the [pose_twist_estimator.launch.xml](../../launch/tier4_localization_launch/launch/pose_twist_estimator/pose_twist_estimator.launch.xml#L3).

### Without this condition (default)

- The output of the [ndt_scan_matcher](../../localization/ndt_scan_matcher) is directly sent
to [ekf_localizer](../../localization/ekf_localizer).
- It has a preset covariance value.
- **topic name:** `/localization/pose_estimator/pose_with_covariance`
- The GNSS pose does not enter the ekf_localizer.
- This node does not launch.

### With this condition

- The output of the [ndt_scan_matcher](../../localization/ndt_scan_matcher) is renamed
- **from:** `/localization/pose_estimator/pose_with_covariance`.
- **to:** `/localization/pose_estimator/ndt_scan_matcher/pose_with_covariance`.
- The `ndt_scan_matcher` output enters the `autoware_pose_covariance_modifier`.
- The output of this package goes to [ekf_localizer](../../localization/ekf_localizer) with:
- **topic name:** `/localization/pose_estimator/pose_with_covariance`.

## Node

### Subscribed topics

| Name | Type | Description |
| -------------------------------- | ----------------------------------------------- | ---------------------- |
| `input_gnss_pose_with_cov_topic` | `geometry_msgs::msg::PoseWithCovarianceStamped` | Input GNSS pose topic. |
| `input_ndt_pose_with_cov_topic` | `geometry_msgs::msg::PoseWithCovarianceStamped` | Input NDT pose topic. |

### Published topics

| Name | Type | Description |
| ----------------------------------- | ----------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| `output_pose_with_covariance_topic` | `geometry_msgs::msg::PoseWithCovarianceStamped` | Output pose topic. This topic is used by the ekf_localizer package. |
| `selected_pose_type` | `std_msgs::msg::String` | Declares which pose sources are used in the output of this package |
| `output/ndt_position_stddev` | `std_msgs::msg::Float64` | Output pose ndt average standard deviation in position xy. It is published only when the enable_debug_topics is true. |
| `output/gnss_position_stddev` | `std_msgs::msg::Float64` | Output pose gnss average standard deviation in position xy. It is published only when the enable_debug_topics is true. |

### Parameters

The parameters are set
in [config/pose_covariance_modifier.param.yaml](config/pose_covariance_modifier.param.yaml) .

{{ json_to_markdown("
localization/autoware_pose_covariance_modifier/schema/pose_covariance_modifier.schema.json") }}

## FAQ

### How are varying frequency rates handled?

The GNSS and NDT pose topics may have different frequencies.
The GNSS pose topic may have a higher frequency than the NDT.

Let's assume that the inputs have the following frequencies:

| Source | Frequency |
| ------ | --------- |
| GNSS | 200 Hz |
| NDT | 10 Hz |

This package publishes the output poses as they come in, depending on the mode.

End result:

| Mode | Output Freq |
| ---------- | ----------- |
| GNSS Only | 200 Hz |
| GNSS + NDT | 210 Hz |
| NDT Only | 10 Hz |

### How and when are the NDT covariance values overwritten?

| Mode | Outputs, Covariance |
| ---------- | ------------------------------------------- |
| GNSS Only | GNSS, Unmodified |
| GNSS + NDT | **GNSS:** Unmodified, **NDT:** Interpolated |
| NDT Only | NDT, Unmodified |

NDT covariance values overwritten only for the `GNSS + NDT` mode.

This enables a smooth transition between `GNSS Only` and `NDT Only` modes.

In this mode, both NDT and GNSS poses are published from this node.

#### NDT covariance calculation

As the `gnss_std_dev` increases within its bounds, `ndt_std_dev` should proportionally decrease within its own bounds.

To achieve this, we first linearly interpolate:

- Base value: `gnss_std_dev`
- Base range: [`threshold_gnss_stddev_xy_bound_lower`, `threshold_gnss_stddev_xy_bound_upper`]
- Target range: [`ndt_std_dev_bound_lower`, `ndt_std_dev_bound_upper`]
- Target value: `ndt_std_dev_target`

- Final value = `ndt_std_dev_bound_lower` + `ndt_std_dev_bound_upper` - `ndt_std_dev_target` (to get the inverse)

<img width="300" src="doc/range_lerp.svg" alt="range to range lerp animation">
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/**:
ros__parameters:
# If GNSS yaw standard deviation values are larger than this, trust only NDT
threshold_gnss_stddev_yaw_deg_max: 0.3

# If GNSS position Z standard deviation values are larger than this, trust only NDT
threshold_gnss_stddev_z_max: 0.1

# If GNSS position XY standard deviation values are lower than this, trust only GNSS
threshold_gnss_stddev_xy_bound_lower: 0.1

# If GNSS position XY standard deviation values are higher than this, trust only NDT
threshold_gnss_stddev_xy_bound_upper: 0.25

# Lower bound value for standard deviation of NDT positions (x, y, z) when used with GNSS
ndt_std_dev_bound_lower: 0.14

# Upper bound value for standard deviation of NDT positions (x, y, z) when used with GNSS
ndt_std_dev_bound_upper: 0.30

# If GNSS data is not received for this duration, trust only NDT
gnss_pose_timeout_sec: 1.0

enable_debug_topics: true
Loading
Loading