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(pose_instability_detector): change validation algorithm #7042

Merged
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
2fc7c9f
Create define_static_threshold()
TaikiYamada4 May 9, 2024
e6dd378
Revised dead reckoning methodology
TaikiYamada4 May 17, 2024
7a8514e
style(pre-commit): autofix
pre-commit-ci[bot] May 17, 2024
065c6e4
Change threshold calculation to use the online time difference
TaikiYamada4 May 20, 2024
588f889
Simplify threshold calculation.
TaikiYamada4 May 20, 2024
a3ec94e
style(pre-commit): autofix
pre-commit-ci[bot] May 20, 2024
329fe10
Rewrite lateral_threshold and vertical threshold
TaikiYamada4 May 21, 2024
88d1693
Consider dead reckoning noise, update README.md.
TaikiYamada4 May 31, 2024
6a1653a
Added sentences to README.md
TaikiYamada4 May 31, 2024
cd088b6
Filled README.md
TaikiYamada4 Jun 3, 2024
d8e9de2
Merge branch 'main' into feat/pose_instability_detector/sophisticate_…
TaikiYamada4 Jun 3, 2024
9edb0e2
style(pre-commit): autofix
pre-commit-ci[bot] Jun 3, 2024
3bbde52
Add #include <algorithm>
TaikiYamada4 Jun 3, 2024
2d689fc
style(pre-commit): autofix
pre-commit-ci[bot] Jun 3, 2024
25f21b7
Fixed pose_instability_detector.schema.json
TaikiYamada4 Jun 3, 2024
d2668a0
Revised calculation of the process noise of dead reckoning.
TaikiYamada4 Jun 4, 2024
5523a50
style(pre-commit): autofix
pre-commit-ci[bot] Jun 4, 2024
db5ac50
Fixed typo and lack of information
TaikiYamada4 Jun 4, 2024
6b3d5ee
Revised redundant time substitutions
TaikiYamada4 Jun 4, 2024
a04f8b8
Revised dead reckoning algorithm for orientation.
TaikiYamada4 Jun 4, 2024
7520e23
style(pre-commit): autofix
pre-commit-ci[bot] Jun 4, 2024
40b803c
Added information about lateral thresholld calculation in README.md
TaikiYamada4 Jun 4, 2024
4faf70e
Removed all dead reckoning related process noise stuff
TaikiYamada4 Jun 4, 2024
f85a4da
Removed parameters and desciprtion of dead reckoning process noise stuff
TaikiYamada4 Jun 5, 2024
546a58d
style(pre-commit): autofix
pre-commit-ci[bot] Jun 5, 2024
75062e0
Fixed integration logic for angular twist
TaikiYamada4 Jun 6, 2024
a462cf3
Let the hpp file be exportable, and follow the guidelines when export…
TaikiYamada4 Jun 6, 2024
ff5218c
style(pre-commit): autofix
pre-commit-ci[bot] Jun 6, 2024
1c458d3
Merge branch 'main' into feat/pose_instability_detector/sophisticate_…
TaikiYamada4 Jun 6, 2024
b81bc44
Merge branch 'main' into feat/pose_instability_detector/sophisticate_…
TaikiYamada4 Jun 6, 2024
3cc3834
Fix typo
TaikiYamada4 Jun 6, 2024
a772b15
Delete include from package.xml
TaikiYamada4 Jun 6, 2024
52e7511
Make test codes work. Create a threshold structure so that other pack…
TaikiYamada4 Jun 6, 2024
aa614ae
style(pre-commit): autofix
pre-commit-ci[bot] Jun 6, 2024
7593b58
Merge branch 'main' into feat/pose_instability_detector/sophisticate_…
TaikiYamada4 Jun 7, 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
10 changes: 10 additions & 0 deletions localization/pose_instability_detector/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ project(pose_instability_detector)
find_package(autoware_cmake REQUIRED)
autoware_package()

include_directories(src)

ament_auto_add_library(${PROJECT_NAME} SHARED
src/pose_instability_detector.cpp
)
Expand All @@ -22,6 +24,14 @@ if(BUILD_TESTING)
)
endif()

install(
DIRECTORY src/
DESTINATION include/pose_instability_detector
FILES_MATCHING PATTERN "*.hpp"
)

ament_export_include_directories(include)

SakodaShintaro marked this conversation as resolved.
Show resolved Hide resolved
ament_auto_package(
INSTALL_TO_SHARE
launch
Expand Down
141 changes: 136 additions & 5 deletions localization/pose_instability_detector/README.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,111 @@
# pose_instability_detector

The `pose_instability_detector` package includes a node designed to monitor the stability of `/localization/kinematic_state`, which is an output topic of the Extended Kalman Filter (EKF).
The `pose_instability_detector` is a node designed to monitor the stability of `/localization/kinematic_state`, which is an output topic of the Extended Kalman Filter (EKF).

This node triggers periodic timer callbacks to compare two poses:

- The pose obtained by integrating the twist values from the last received message on `/localization/kinematic_state` over a duration specified by `interval_sec`.
- The pose calculated by dead reckoning starting from the pose of `/localization/kinematic_state` obtained `timer_period` seconds ago.
- The latest pose from `/localization/kinematic_state`.

The results of this comparison are then output to the `/diagnostics` topic.

![overview](./media/pose_instability_detector_overview.png)

![rqt_runtime_monitor](./media/rqt_runtime_monitor.png)

If this node outputs WARN messages to `/diagnostics`, it means that the EKF output is significantly different from the integrated twist values.
In other words, WARN outputs indicate that the vehicle has moved to a place outside the expected range based on the twist values.
This discrepancy suggests that there may be an issue with either the estimated pose or the input twist.

The following diagram provides an overview of what the timeline of this process looks like:
The following diagram provides an overview of how the procedure looks like:

![procedure](./media/pose_instabilty_detector_procedure.svg)

## Dead reckoning algorithm

Dead reckoning is a method of estimating the position of a vehicle based on its previous position and velocity.
The procedure for dead reckoning is as follows:

1. Capture the necessary twist values from the `/input/twist` topic.
2. Integrate the twist values to calculate the pose transition.
3. Apply the pose transition to the previous pose to obtain the current pose.

### Collecting twist values

The `pose_instability_detector` node collects the twist values from the `~/input/twist` topic to perform dead reckoning.
Ideally, `pose_instability_detector` needs the twist values between the previous pose and the current pose.
Therefore, `pose_instability_detector` snips the twist buffer and apply interpolations and extrapolations to obtain the twist values at the desired time.

![how_to_snip_necessary_twist](./media/how_to_snip_twist.png)

### Linear transition and angular transition

After the twist values are collected, the node calculates the linear transition and angular transition based on the twist values and add them to the previous pose.

## Threshold definition

The `pose_instability_detector` node compares the pose calculated by dead reckoning with the latest pose from the EKF output.
These two pose are ideally the same, but in reality, they are not due to the error in the twist values the pose observation.
If these two poses are significantly different so that the absolute value exceeds the threshold, the node outputs a WARN message to the `/diagnostics` topic.
There are six thresholds (x, y, z, roll, pitch, and yaw) to determine whether the poses are significantly different, and these thresholds are determined by the following subsections.

### `diff_position_x`

This threshold examines the difference in the longitudinal axis between the two poses, and check whether the vehicle goes beyond the expected error.
This threshold is a sum of "maximum longitudinal error due to velocity scale factor error" and "pose estimation error tolerance".

$$
\tau_x = v_{\rm max}\frac{\beta_v}{100} \Delta t + \epsilon_x\\
$$

![timeline](./media/timeline.drawio.svg)
| Symbol | Description | Unit |
| ------------- | -------------------------------------------------------------------------------- | ----- |
| $\tau_x$ | Threshold for the difference in the longitudinal axis | $m$ |
| $v_{\rm max}$ | Maximum velocity | $m/s$ |
| $\beta_v$ | Scale factor tolerance for the maximum velocity | $\%$ |
| $\Delta t$ | Time interval | $s$ |
| $\epsilon_x$ | Pose estimator (e. g. ndt_scan_matcher) error tolerance in the longitudinal axis | $m$ |

### `diff_position_y` and `diff_position_z`

These thresholds examine the difference in the lateral and vertical axes between the two poses, and check whether the vehicle goes beyond the expected error.
The `pose_instability_detector` calculates the possible range where the vehicle goes, and get the maximum difference between the nominal dead reckoning pose and the maximum limit pose.

![lateral_threshold_calculation](./media/lateral_threshold_calculation.png)

Addition to this, the `pose_instability_detector` node considers the pose estimation error tolerance to determine the threshold.

$$
\tau_y = l + \epsilon_y
$$

| Symbol | Description | Unit |
| ------------ | ----------------------------------------------------------------------------------------------- | ---- |
| $\tau_y$ | Threshold for the difference in the lateral axis | $m$ |
| $l$ | Maximum lateral distance described in the image above (See the appendix how this is calculated) | $m$ |
| $\epsilon_y$ | Pose estimator (e. g. ndt_scan_matcher) error tolerance in the lateral axis | $m$ |

Note that `pose_instability_detector` sets the threshold for the vertical axis as the same as the lateral axis. Only the pose estimator error tolerance is different.

### `diff_angle_x`, `diff_angle_y`, and `diff_angle_z`

These thresholds examine the difference in the roll, pitch, and yaw angles between the two poses.
This threshold is a sum of "maximum angular error due to velocity scale factor error and bias error" and "pose estimation error tolerance".

$$
\tau_\phi = \tau_\theta = \tau_\psi = \left(\omega_{\rm max}\frac{\beta_\omega}{100} + b \right) \Delta t + \epsilon_\psi
$$

| Symbol | Description | Unit |
| ------------------ | ------------------------------------------------------------------------ | ------------- |
| $\tau_\phi$ | Threshold for the difference in the roll angle | ${\rm rad}$ |
| $\tau_\theta$ | Threshold for the difference in the pitch angle | ${\rm rad}$ |
| $\tau_\psi$ | Threshold for the difference in the yaw angle | ${\rm rad}$ |
| $\omega_{\rm max}$ | Maximum angular velocity | ${\rm rad}/s$ |
| $\beta_\omega$ | Scale factor tolerance for the maximum angular velocity | $\%$ |
| $b$ | Bias tolerance of the angular velocity | ${\rm rad}/s$ |
| $\Delta t$ | Time interval | $s$ |
| $\epsilon_\psi$ | Pose estimator (e. g. ndt_scan_matcher) error tolerance in the yaw angle | ${\rm rad}$ |

## Parameters

Expand All @@ -34,4 +125,44 @@ The following diagram provides an overview of what the timeline of this process
| `~/debug/diff_pose` | geometry_msgs::msg::PoseStamped | diff_pose |
| `/diagnostics` | diagnostic_msgs::msg::DiagnosticArray | Diagnostics |

![rqt_runtime_monitor](./media/rqt_runtime_monitor.png)
## Appendix

On calculating the maximum lateral distance $l$, the `pose_instability_detector` node will estimate the following poses.

| Pose | heading velocity $v$ | angular velocity $\omega$ |
| ------------------------------- | ------------------------------------------------ | -------------------------------------------------------------- |
| Nominal dead reckoning pose | $v_{\rm max}$ | $\omega_{\rm max}$ |
| Dead reckoning pose of corner A | $\left(1+\frac{\beta_v}{100}\right) v_{\rm max}$ | $\left(1+\frac{\beta_\omega}{100}\right) \omega_{\rm max} + b$ |
| Dead reckoning pose of corner B | $\left(1-\frac{\beta_v}{100}\right) v_{\rm max}$ | $\left(1+\frac{\beta_\omega}{100}\right) \omega_{\rm max} + b$ |
| Dead reckoning pose of corner C | $\left(1-\frac{\beta_v}{100}\right) v_{\rm max}$ | $\left(1-\frac{\beta_\omega}{100}\right) \omega_{\rm max} - b$ |
| Dead reckoning pose of corner D | $\left(1+\frac{\beta_v}{100}\right) v_{\rm max}$ | $\left(1-\frac{\beta_\omega}{100}\right) \omega_{\rm max} - b$ |

Given a heading velocity $v$ and $\omega$, the 2D theoritical variation seen from the previous pose is calculated as follows:
KYabuuchi marked this conversation as resolved.
Show resolved Hide resolved

$$
\begin{align*}
\left[
\begin{matrix}
\Delta x\\
\Delta y
\end{matrix}
\right]
&=
\left[
\begin{matrix}
\int_{0}^{\Delta t} v \cos(\omega t) dt\\
\int_{0}^{\Delta t} v \sin(\omega t) dt
\end{matrix}
\right]
\\
&=
\left[
\begin{matrix}
\frac{v}{\omega} \sin(\omega \Delta t)\\
\frac{v}{\omega} \left(1 - \cos(\omega \Delta t)\right)
\end{matrix}
\right]
\end{align*}
$$

We calculate this variation for each corner and get the maximum value of the lateral distance $l$ by comparing the distance between the nominal dead reckoning pose and the corner poses.
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
/**:
ros__parameters:
interval_sec: 0.5 # [sec]
threshold_diff_position_x: 1.0 # [m]
threshold_diff_position_y: 1.0 # [m]
threshold_diff_position_z: 1.0 # [m]
threshold_diff_angle_x: 1.0 # [rad]
threshold_diff_angle_y: 1.0 # [rad]
threshold_diff_angle_z: 1.0 # [rad]
timer_period: 0.5 # [sec]

heading_velocity_maximum: 16.667 # [m/s]
heading_velocity_scale_factor_tolerance: 3.0 # [%]

angular_velocity_maximum: 0.523 # [rad/s]
angular_velocity_scale_factor_tolerance: 0.2 # [%]
angular_velocity_bias_tolerance: 0.00698 # [rad/s]

pose_estimator_longitudinal_tolerance: 0.11 # [m]
pose_estimator_lateral_tolerance: 0.11 # [m]
pose_estimator_vertical_tolerance: 0.11 # [m]
pose_estimator_angular_tolerance: 0.0175 # [rad]
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading