@@ -43,6 +43,15 @@ ObjectLaneletFilterNode::ObjectLaneletFilterNode(const rclcpp::NodeOptions & nod
43
43
filter_target_.MOTORCYCLE = declare_parameter<bool >(" filter_target_label.MOTORCYCLE" , false );
44
44
filter_target_.BICYCLE = declare_parameter<bool >(" filter_target_label.BICYCLE" , false );
45
45
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" );
46
55
47
56
// Set publisher/subscriber
48
57
map_sub_ = this ->create_subscription <autoware_auto_mapping_msgs::msg::HADMapBin>(
@@ -127,21 +136,33 @@ bool ObjectLaneletFilterNode::filterObject(
127
136
{
128
137
const auto & label = transformed_object.classification .front ().label ;
129
138
if (filter_target_.isTarget (label)) {
139
+ bool filter_pass = true ;
130
140
// 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;
137
162
}
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);
142
163
143
164
// push back to output object
144
- if (is_polygon_overlap ) {
165
+ if (filter_pass ) {
145
166
output_object_msg.objects .emplace_back (input_object);
146
167
return true ;
147
168
}
@@ -221,6 +242,42 @@ bool ObjectLaneletFilterNode::isPolygonOverlapLanelets(
221
242
return false ;
222
243
}
223
244
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
+
224
281
} // namespace object_lanelet_filter
225
282
226
283
#include < rclcpp_components/register_node_macro.hpp>
0 commit comments