Skip to content

Commit 54f18af

Browse files
committed
feat: add lanelet direction filter
Signed-off-by: yoshiri <yoshiyoshidetteiu@gmail.com>
1 parent 0cc85c2 commit 54f18af

File tree

3 files changed

+90
-12
lines changed

3 files changed

+90
-12
lines changed

perception/detected_object_validation/config/object_lanelet_filter.param.yaml

+11-1
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,20 @@
22
ros__parameters:
33
filter_target_label:
44
UNKNOWN : true
5-
CAR : false
5+
CAR : true
66
TRUCK : false
77
BUS : false
88
TRAILER : false
99
MOTORCYCLE : false
1010
BICYCLE : false
1111
PEDESTRIAN : false
12+
13+
filter_settings:
14+
# polygon overlap based filter
15+
polygon_overlap_filter:
16+
enabled: true
17+
# velocity direction based filter
18+
lanelet_direction_filter:
19+
enabled: true
20+
velocity_yaw_threshold: 0.785398 # [rad] (45 deg)
21+
object_speed_threshold: 3.0 # [m/s]

perception/detected_object_validation/include/detected_object_validation/detected_object_filter/object_lanelet_filter.hpp

+11
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
#include "detected_object_validation/utils/utils.hpp"
1919

20+
#include <lanelet2_extension/utility/utilities.hpp>
2021
#include <rclcpp/rclcpp.hpp>
2122
#include <tier4_autoware_utils/geometry/geometry.hpp>
2223
#include <tier4_autoware_utils/ros/debug_publisher.hpp>
@@ -62,6 +63,13 @@ class ObjectLaneletFilterNode : public rclcpp::Node
6263
tf2_ros::TransformListener tf_listener_;
6364

6465
utils::FilterTargetLabel filter_target_;
66+
struct FilterSettings
67+
{
68+
bool polygon_overlap_filter;
69+
bool lanelet_direction_filter;
70+
double lanelet_direction_filter_velocity_yaw_threshold;
71+
double lanelet_direction_filter_object_speed_threshold;
72+
} filter_settings_;
6573

6674
bool filterObject(
6775
const autoware_auto_perception_msgs::msg::DetectedObject & transformed_object,
@@ -73,6 +81,9 @@ class ObjectLaneletFilterNode : public rclcpp::Node
7381
lanelet::ConstLanelets getIntersectedLanelets(
7482
const LinearRing2d &, const lanelet::ConstLanelets &);
7583
bool isPolygonOverlapLanelets(const Polygon2d &, const lanelet::ConstLanelets &);
84+
bool isSameDirectionWithLanelets(
85+
const lanelet::ConstLanelets & lanelets,
86+
const autoware_auto_perception_msgs::msg::DetectedObject & object);
7687
geometry_msgs::msg::Polygon setFootprint(
7788
const autoware_auto_perception_msgs::msg::DetectedObject &);
7889

perception/detected_object_validation/src/object_lanelet_filter.cpp

+68-11
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,15 @@ ObjectLaneletFilterNode::ObjectLaneletFilterNode(const rclcpp::NodeOptions & nod
4343
filter_target_.MOTORCYCLE = declare_parameter<bool>("filter_target_label.MOTORCYCLE", false);
4444
filter_target_.BICYCLE = declare_parameter<bool>("filter_target_label.BICYCLE", false);
4545
filter_target_.PEDESTRIAN = declare_parameter<bool>("filter_target_label.PEDESTRIAN", false);
46+
// Set filter settings
47+
filter_settings_.polygon_overlap_filter =
48+
declare_parameter<bool>("filter_settings.polygon_overlap_filter.enabled");
49+
filter_settings_.lanelet_direction_filter =
50+
declare_parameter<bool>("filter_settings.lanelet_direction_filter.enabled");
51+
filter_settings_.lanelet_direction_filter_velocity_yaw_threshold =
52+
declare_parameter<double>("filter_settings.lanelet_direction_filter.velocity_yaw_threshold");
53+
filter_settings_.lanelet_direction_filter_object_speed_threshold =
54+
declare_parameter<double>("filter_settings.lanelet_direction_filter.object_speed_threshold");
4655

4756
// Set publisher/subscriber
4857
map_sub_ = this->create_subscription<autoware_auto_mapping_msgs::msg::HADMapBin>(
@@ -127,21 +136,33 @@ bool ObjectLaneletFilterNode::filterObject(
127136
{
128137
const auto & label = transformed_object.classification.front().label;
129138
if (filter_target_.isTarget(label)) {
139+
bool filter_pass = true;
130140
// 1. is polygon overlap with road lanelets or shoulder lanelets
131-
Polygon2d polygon;
132-
const auto footprint = setFootprint(transformed_object);
133-
for (const auto & point : footprint.points) {
134-
const geometry_msgs::msg::Point32 point_transformed = tier4_autoware_utils::transformPoint(
135-
point, transformed_object.kinematics.pose_with_covariance.pose);
136-
polygon.outer().emplace_back(point_transformed.x, point_transformed.y);
141+
if (filter_settings_.polygon_overlap_filter) {
142+
Polygon2d polygon;
143+
const auto footprint = setFootprint(transformed_object);
144+
for (const auto & point : footprint.points) {
145+
const geometry_msgs::msg::Point32 point_transformed = tier4_autoware_utils::transformPoint(
146+
point, transformed_object.kinematics.pose_with_covariance.pose);
147+
polygon.outer().emplace_back(point_transformed.x, point_transformed.y);
148+
}
149+
polygon.outer().push_back(polygon.outer().front());
150+
const bool is_polygon_overlap =
151+
isPolygonOverlapLanelets(polygon, intersected_road_lanelets) ||
152+
isPolygonOverlapLanelets(polygon, intersected_shoulder_lanelets);
153+
filter_pass = filter_pass && is_polygon_overlap;
154+
}
155+
156+
// 2. check if objects velocity is the same with the lanelet direction
157+
if (filter_settings_.lanelet_direction_filter) {
158+
const bool is_same_direction =
159+
isSameDirectionWithLanelets(intersected_road_lanelets, transformed_object) ||
160+
isSameDirectionWithLanelets(intersected_shoulder_lanelets, transformed_object);
161+
filter_pass = filter_pass && is_same_direction;
137162
}
138-
polygon.outer().push_back(polygon.outer().front());
139-
const bool is_polygon_overlap =
140-
isPolygonOverlapLanelets(polygon, intersected_road_lanelets) ||
141-
isPolygonOverlapLanelets(polygon, intersected_shoulder_lanelets);
142163

143164
// push back to output object
144-
if (is_polygon_overlap) {
165+
if (filter_pass) {
145166
output_object_msg.objects.emplace_back(input_object);
146167
return true;
147168
}
@@ -221,6 +242,42 @@ bool ObjectLaneletFilterNode::isPolygonOverlapLanelets(
221242
return false;
222243
}
223244

245+
bool ObjectLaneletFilterNode::isSameDirectionWithLanelets(
246+
const lanelet::ConstLanelets & lanelets,
247+
const autoware_auto_perception_msgs::msg::DetectedObject & object)
248+
{
249+
const double object_yaw = tf2::getYaw(object.kinematics.pose_with_covariance.pose.orientation);
250+
const double object_velocity_norm = std::hypot(
251+
object.kinematics.twist_with_covariance.twist.linear.x,
252+
object.kinematics.twist_with_covariance.twist.linear.y);
253+
const double object_velocity_yaw = std::atan2(
254+
object.kinematics.twist_with_covariance.twist.linear.y,
255+
object.kinematics.twist_with_covariance.twist.linear.x) +
256+
object_yaw;
257+
258+
if (object_velocity_norm < filter_settings_.lanelet_direction_filter_object_speed_threshold) {
259+
return true;
260+
}
261+
for (const auto & lanelet : lanelets) {
262+
const bool is_in_lanelet =
263+
lanelet::utils::isInLanelet(object.kinematics.pose_with_covariance.pose, lanelet, 0.0);
264+
if (!is_in_lanelet) {
265+
continue;
266+
}
267+
const double lane_yaw = lanelet::utils::getLaneletAngle(
268+
lanelet, object.kinematics.pose_with_covariance.pose.position);
269+
const double delta_yaw = object_velocity_yaw - lane_yaw;
270+
const double normalized_delta_yaw = tier4_autoware_utils::normalizeRadian(delta_yaw);
271+
const double abs_norm_delta_yaw = std::fabs(normalized_delta_yaw);
272+
273+
if (abs_norm_delta_yaw < filter_settings_.lanelet_direction_filter_velocity_yaw_threshold) {
274+
return true;
275+
}
276+
}
277+
278+
return false;
279+
}
280+
224281
} // namespace object_lanelet_filter
225282

226283
#include <rclcpp_components/register_node_macro.hpp>

0 commit comments

Comments
 (0)