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(map based prediction, crosswalk)!: transplantation of pedestrians' behavior prediction against green signal #6338

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
14 changes: 10 additions & 4 deletions perception/map_based_prediction/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,11 @@ This module treats **Pedestrians** and **Bicycles** as objects using the crosswa

If there are a reachable crosswalk entry points within the `prediction_time_horizon` and the objects satisfies above condition, this module outputs additional predicted path to cross the opposite side via the crosswalk entry point.

This module takes into account the corresponding traffic light information.
When RED signal is indicated, we assume the target object will not walk across.
In additon, if the target object is stopping (not moving) against GREEN signal, we assume the target object will not walk across either.
This prediction comes from the assumption that the object should move if the traffic light is green and the object is intended to cross.

<div align="center">
<img src="images/outside_road.svg" width=90%>
</div>
Expand All @@ -205,10 +210,11 @@ If the target object is inside the road or crosswalk, this module outputs one or

### Input

| Name | Type | Description |
| -------------------------------------------------- | ---------------------------------------------------- | ---------------------------------------- |
| `~/perception/object_recognition/tracking/objects` | `autoware_auto_perception_msgs::msg::TrackedObjects` | tracking objects without predicted path. |
| `~/vector_map` | `autoware_auto_mapping_msgs::msg::HADMapBin` | binary data of Lanelet2 Map. |
| Name | Type | Description |
| -------------------------------------------------------- | ---------------------------------------------------- | ---------------------------------------------------------- |
| `~/perception/object_recognition/tracking/objects` | `autoware_auto_perception_msgs::msg::TrackedObjects` | tracking objects without predicted path. |
| `~/vector_map` | `autoware_auto_mapping_msgs::msg::HADMapBin` | binary data of Lanelet2 Map. |
| '~/perception/traffic_light_recognition/traffic_signals' | 'autoware_perception_msgs::msg::TrafficSignalArray;' | rearranged information on the corresponding traffic lights |

### Output

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,12 @@
use_vehicle_acceleration: false # whether to consider current vehicle acceleration when predicting paths or not
speed_limit_multiplier: 1.5 # When using vehicle acceleration. Set vehicle's maximum predicted speed as the legal speed limit in that lanelet times this value
acceleration_exponential_half_life: 2.5 # [s] When using vehicle acceleration. The decaying acceleration model considers that the current vehicle acceleration will be halved after this many seconds
use_crosswalk_signal: true
crosswalk_with_signal:
use_crosswalk_signal: true
threshold_velocity_assumed_as_stopping: 0.25 # [m/s] velocity threshold for the module to judge whether the objects is stopped
# If the pedestrian does not move for X seconds against green signal, the module judge that the pedestrian has no intention to walk.
distance_set_for_no_intention_to_walk: [1.0, 5.0] # [m] ascending order, keys of map
timeout_set_for_no_intention_to_walk: [1.0, 0.0] # [s] values of map
# parameter for shoulder lane prediction
prediction_time_horizon_rate_for_validate_shoulder_lane_length: 0.8

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@

#include <algorithm>
#include <deque>
#include <map>
#include <memory>
#include <optional>
#include <string>
Expand Down Expand Up @@ -131,6 +132,7 @@ class MapBasedPredictionNode : public rclcpp::Node

// Object History
std::unordered_map<std::string, std::deque<ObjectData>> objects_history_;
std::map<std::pair<std::string, lanelet::Id>, rclcpp::Time> stopped_times_against_green_;

// Lanelet Map Pointers
std::shared_ptr<lanelet::LaneletMap> lanelet_map_ptr_;
Expand Down Expand Up @@ -190,6 +192,9 @@ class MapBasedPredictionNode : public rclcpp::Node
double acceleration_exponential_half_life_;

bool use_crosswalk_signal_;
double threshold_velocity_assumed_as_stopping_;
std::vector<double> distance_set_for_no_intention_to_walk_;
std::vector<double> timeout_set_for_no_intention_to_walk_;

// Stop watch
StopWatch<std::chrono::milliseconds> stop_watch_;
Expand All @@ -214,7 +219,8 @@ class MapBasedPredictionNode : public rclcpp::Node

PredictedObject getPredictedObjectAsCrosswalkUser(const TrackedObject & object);

void removeOldObjectsHistory(const double current_time);
void removeOldObjectsHistory(
const double current_time, const TrackedObjects::ConstSharedPtr in_objects);

LaneletsData getCurrentLanelets(const TrackedObject & object);
bool checkCloseLaneletCondition(
Expand Down Expand Up @@ -262,6 +268,9 @@ class MapBasedPredictionNode : public rclcpp::Node
const PredictedPath & predicted_path, const std::vector<PredictedPath> & predicted_paths);
std::optional<lanelet::Id> getTrafficSignalId(const lanelet::ConstLanelet & way_lanelet);
std::optional<TrafficSignalElement> getTrafficSignalElement(const lanelet::Id & id);
bool calcIntentionToCrossWithTrafficSgnal(
const TrackedObject & object, const lanelet::ConstLanelet & crosswalk,
const lanelet::Id & signal_id);

visualization_msgs::msg::Marker getDebugMarker(
const TrackedObject & object, const Maneuver & maneuver, const size_t obj_num);
Expand Down
98 changes: 89 additions & 9 deletions perception/map_based_prediction/src/map_based_prediction_node.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2021 Tier IV, Inc.

Check notice on line 1 in perception/map_based_prediction/src/map_based_prediction_node.cpp

View check run for this annotation

CodeScene Delta Analysis / CodeScene Cloud Delta Analysis (main)

ℹ Getting worse: Lines of Code in a Single File

The lines of code increases from 1693 to 1763, improve code health by reducing it to 1000. The number of Lines of Code in a single file. More Lines of Code lowers the code health.

Check notice on line 1 in perception/map_based_prediction/src/map_based_prediction_node.cpp

View check run for this annotation

CodeScene Delta Analysis / CodeScene Cloud Delta Analysis (main)

ℹ Getting worse: Overall Code Complexity

The mean cyclomatic complexity increases from 6.30 to 6.40, threshold = 4. This file has many conditional statements (e.g. if, for, while) across its implementation, leading to lower code health. Avoid adding more conditionals.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -788,7 +788,13 @@
acceleration_exponential_half_life_ =
declare_parameter<double>("acceleration_exponential_half_life");

use_crosswalk_signal_ = declare_parameter<bool>("use_crosswalk_signal");
use_crosswalk_signal_ = declare_parameter<bool>("crosswalk_with_signal.use_crosswalk_signal");
threshold_velocity_assumed_as_stopping_ =
declare_parameter<double>("crosswalk_with_signal.threshold_velocity_assumed_as_stopping");
distance_set_for_no_intention_to_walk_ = declare_parameter<std::vector<double>>(

Check warning on line 794 in perception/map_based_prediction/src/map_based_prediction_node.cpp

View check run for this annotation

Codecov / codecov/patch

perception/map_based_prediction/src/map_based_prediction_node.cpp#L791-L794

Added lines #L791 - L794 were not covered by tests
"crosswalk_with_signal.distance_set_for_no_intention_to_walk");
timeout_set_for_no_intention_to_walk_ = declare_parameter<std::vector<double>>(

Check warning on line 796 in perception/map_based_prediction/src/map_based_prediction_node.cpp

View check run for this annotation

Codecov / codecov/patch

perception/map_based_prediction/src/map_based_prediction_node.cpp#L796

Added line #L796 was not covered by tests
"crosswalk_with_signal.timeout_set_for_no_intention_to_walk");

Check warning on line 797 in perception/map_based_prediction/src/map_based_prediction_node.cpp

View check run for this annotation

CodeScene Delta Analysis / CodeScene Cloud Delta Analysis (main)

❌ Getting worse: Large Method

MapBasedPredictionNode::MapBasedPredictionNode increases from 78 to 84 lines of code, threshold = 70. Large functions with many lines of code are generally harder to understand and lower the code health. Avoid adding more lines to this function.

path_generator_ = std::make_shared<PathGenerator>(
prediction_time_horizon_, lateral_control_time_horizon_, prediction_sampling_time_interval_,
Expand Down Expand Up @@ -912,7 +918,7 @@

// Remove old objects information in object history
const double objects_detected_time = rclcpp::Time(in_objects->header.stamp).seconds();
removeOldObjectsHistory(objects_detected_time);
removeOldObjectsHistory(objects_detected_time, in_objects);

Check warning on line 921 in perception/map_based_prediction/src/map_based_prediction_node.cpp

View check run for this annotation

Codecov / codecov/patch

perception/map_based_prediction/src/map_based_prediction_node.cpp#L921

Added line #L921 was not covered by tests

// result output
PredictedObjects output;
Expand Down Expand Up @@ -1229,16 +1235,13 @@
}
}
}

// try to find the edge points for all crosswalks and generate path to the crosswalk edge
for (const auto & crosswalk : crosswalks_) {
const auto crosswalk_signal_id_opt = getTrafficSignalId(crosswalk);
if (crosswalk_signal_id_opt.has_value() && use_crosswalk_signal_) {
const auto signal_color = [&] {
const auto elem_opt = getTrafficSignalElement(crosswalk_signal_id_opt.value());
return elem_opt ? elem_opt.value().color : TrafficSignalElement::UNKNOWN;
}();

if (signal_color == TrafficSignalElement::RED) {
if (!calcIntentionToCrossWithTrafficSgnal(

Check warning on line 1243 in perception/map_based_prediction/src/map_based_prediction_node.cpp

View check run for this annotation

Codecov / codecov/patch

perception/map_based_prediction/src/map_based_prediction_node.cpp#L1243

Added line #L1243 was not covered by tests
object, crosswalk, crosswalk_signal_id_opt.value())) {

Check notice on line 1244 in perception/map_based_prediction/src/map_based_prediction_node.cpp

View check run for this annotation

CodeScene Delta Analysis / CodeScene Cloud Delta Analysis (main)

✅ Getting better: Complex Method

MapBasedPredictionNode::getPredictedObjectAsCrosswalkUser decreases in cyclomatic complexity from 26 to 25, threshold = 9. This function has many conditional statements (e.g. if, for, while), leading to lower code health. Avoid adding more conditionals and code to it without refactoring.
continue;
}
}
Expand Down Expand Up @@ -1330,7 +1333,8 @@
return;
}

void MapBasedPredictionNode::removeOldObjectsHistory(const double current_time)
void MapBasedPredictionNode::removeOldObjectsHistory(

Check warning on line 1336 in perception/map_based_prediction/src/map_based_prediction_node.cpp

View check run for this annotation

Codecov / codecov/patch

perception/map_based_prediction/src/map_based_prediction_node.cpp#L1336

Added line #L1336 was not covered by tests
const double current_time, const TrackedObjects::ConstSharedPtr in_objects)
{
std::vector<std::string> invalid_object_id;
for (auto iter = objects_history_.begin(); iter != objects_history_.end(); ++iter) {
Expand Down Expand Up @@ -1371,6 +1375,19 @@
for (const auto & key : invalid_object_id) {
objects_history_.erase(key);
}

for (auto it = stopped_times_against_green_.begin(); it != stopped_times_against_green_.end();) {
const bool isDisappeared = std::none_of(

Check warning on line 1380 in perception/map_based_prediction/src/map_based_prediction_node.cpp

View check run for this annotation

Codecov / codecov/patch

perception/map_based_prediction/src/map_based_prediction_node.cpp#L1379-L1380

Added lines #L1379 - L1380 were not covered by tests
in_objects->objects.begin(), in_objects->objects.end(),
[&it](autoware_auto_perception_msgs::msg::TrackedObject obj) {
return tier4_autoware_utils::toHexString(obj.object_id) == it->first.first;

Check warning on line 1383 in perception/map_based_prediction/src/map_based_prediction_node.cpp

View check run for this annotation

Codecov / codecov/patch

perception/map_based_prediction/src/map_based_prediction_node.cpp#L1382-L1383

Added lines #L1382 - L1383 were not covered by tests
});
if (isDisappeared) {
it = stopped_times_against_green_.erase(it);

Check warning on line 1386 in perception/map_based_prediction/src/map_based_prediction_node.cpp

View check run for this annotation

Codecov / codecov/patch

perception/map_based_prediction/src/map_based_prediction_node.cpp#L1385-L1386

Added lines #L1385 - L1386 were not covered by tests
} else {
++it;
}
}

Check notice on line 1390 in perception/map_based_prediction/src/map_based_prediction_node.cpp

View check run for this annotation

CodeScene Delta Analysis / CodeScene Cloud Delta Analysis (main)

ℹ Getting worse: Bumpy Road Ahead

MapBasedPredictionNode::removeOldObjectsHistory increases from 2 to 3 logical blocks with deeply nested code, threshold is one single block per function. The Bumpy Road code smell is a function that contains multiple chunks of nested conditional logic. The deeper the nesting and the more bumps, the lower the code health.

Check warning on line 1390 in perception/map_based_prediction/src/map_based_prediction_node.cpp

View check run for this annotation

CodeScene Delta Analysis / CodeScene Cloud Delta Analysis (main)

❌ Getting worse: Complex Method

MapBasedPredictionNode::removeOldObjectsHistory increases in cyclomatic complexity from 11 to 13, threshold = 9. This function has many conditional statements (e.g. if, for, while), leading to lower code health. Avoid adding more conditionals and code to it without refactoring.
}

LaneletsData MapBasedPredictionNode::getCurrentLanelets(const TrackedObject & object)
Expand Down Expand Up @@ -2268,6 +2285,69 @@
return std::nullopt;
}

bool MapBasedPredictionNode::calcIntentionToCrossWithTrafficSgnal(

Check warning on line 2288 in perception/map_based_prediction/src/map_based_prediction_node.cpp

View check run for this annotation

Codecov / codecov/patch

perception/map_based_prediction/src/map_based_prediction_node.cpp#L2288

Added line #L2288 was not covered by tests
const TrackedObject & object, const lanelet::ConstLanelet & crosswalk,
const lanelet::Id & signal_id)
{
const auto signal_color = [&] {
const auto elem_opt = getTrafficSignalElement(signal_id);
return elem_opt ? elem_opt.value().color : TrafficSignalElement::UNKNOWN;

Check warning on line 2294 in perception/map_based_prediction/src/map_based_prediction_node.cpp

View check run for this annotation

Codecov / codecov/patch

perception/map_based_prediction/src/map_based_prediction_node.cpp#L2293-L2294

Added lines #L2293 - L2294 were not covered by tests
}();

const auto key = std::make_pair(tier4_autoware_utils::toHexString(object.object_id), signal_id);

Check warning on line 2297 in perception/map_based_prediction/src/map_based_prediction_node.cpp

View check run for this annotation

Codecov / codecov/patch

perception/map_based_prediction/src/map_based_prediction_node.cpp#L2297

Added line #L2297 was not covered by tests
if (
signal_color == TrafficSignalElement::GREEN &&

Check warning on line 2299 in perception/map_based_prediction/src/map_based_prediction_node.cpp

View check run for this annotation

Codecov / codecov/patch

perception/map_based_prediction/src/map_based_prediction_node.cpp#L2299

Added line #L2299 was not covered by tests
tier4_autoware_utils::calcNorm(object.kinematics.twist_with_covariance.twist.linear) <
threshold_velocity_assumed_as_stopping_) {
stopped_times_against_green_.try_emplace(key, this->get_clock()->now());

Check warning on line 2302 in perception/map_based_prediction/src/map_based_prediction_node.cpp

View check run for this annotation

Codecov / codecov/patch

perception/map_based_prediction/src/map_based_prediction_node.cpp#L2301-L2302

Added lines #L2301 - L2302 were not covered by tests

const auto timeout_no_intention_to_walk = [&]() {
auto InterpolateMap = [](

Check warning on line 2305 in perception/map_based_prediction/src/map_based_prediction_node.cpp

View check run for this annotation

Codecov / codecov/patch

perception/map_based_prediction/src/map_based_prediction_node.cpp#L2304-L2305

Added lines #L2304 - L2305 were not covered by tests
const std::vector<double> & key_set,
const std::vector<double> & value_set, const double query) {
if (query <= key_set.front()) {
return value_set.front();
} else if (query >= key_set.back()) {
return value_set.back();

Check warning on line 2311 in perception/map_based_prediction/src/map_based_prediction_node.cpp

View check run for this annotation

Codecov / codecov/patch

perception/map_based_prediction/src/map_based_prediction_node.cpp#L2308-L2311

Added lines #L2308 - L2311 were not covered by tests
}
for (size_t i = 0; i < key_set.size() - 1; ++i) {
if (key_set.at(i) <= query && query <= key_set.at(i + 1)) {

Check warning on line 2314 in perception/map_based_prediction/src/map_based_prediction_node.cpp

View check run for this annotation

Codecov / codecov/patch

perception/map_based_prediction/src/map_based_prediction_node.cpp#L2313-L2314

Added lines #L2313 - L2314 were not covered by tests
auto ratio =
(query - key_set.at(i)) / std::max(key_set.at(i + 1) - key_set.at(i), 1.0e-5);
ratio = std::clamp(ratio, 0.0, 1.0);
return value_set.at(i) + ratio * (value_set.at(i + 1) - value_set.at(i));

Check warning on line 2318 in perception/map_based_prediction/src/map_based_prediction_node.cpp

View check run for this annotation

Codecov / codecov/patch

perception/map_based_prediction/src/map_based_prediction_node.cpp#L2316-L2318

Added lines #L2316 - L2318 were not covered by tests
}
}
return value_set.back();

Check warning on line 2321 in perception/map_based_prediction/src/map_based_prediction_node.cpp

View check run for this annotation

Codecov / codecov/patch

perception/map_based_prediction/src/map_based_prediction_node.cpp#L2321

Added line #L2321 was not covered by tests
};

const auto obj_position = object.kinematics.pose_with_covariance.pose.position;

Check warning on line 2324 in perception/map_based_prediction/src/map_based_prediction_node.cpp

View check run for this annotation

Codecov / codecov/patch

perception/map_based_prediction/src/map_based_prediction_node.cpp#L2324

Added line #L2324 was not covered by tests
const double distance_to_crosswalk = boost::geometry::distance(
crosswalk.polygon2d().basicPolygon(),
lanelet::BasicPoint2d(obj_position.x, obj_position.y));
return InterpolateMap(
distance_set_for_no_intention_to_walk_, timeout_set_for_no_intention_to_walk_,
distance_to_crosswalk);
}();

Check warning on line 2331 in perception/map_based_prediction/src/map_based_prediction_node.cpp

View check run for this annotation

Codecov / codecov/patch

perception/map_based_prediction/src/map_based_prediction_node.cpp#L2326-L2331

Added lines #L2326 - L2331 were not covered by tests

if (
(this->get_clock()->now() - stopped_times_against_green_.at(key)).seconds() >

Check warning on line 2334 in perception/map_based_prediction/src/map_based_prediction_node.cpp

View check run for this annotation

Codecov / codecov/patch

perception/map_based_prediction/src/map_based_prediction_node.cpp#L2333-L2334

Added lines #L2333 - L2334 were not covered by tests
timeout_no_intention_to_walk) {
return false;
}

} else {
stopped_times_against_green_.erase(key);
// If the pedestrian disappears, another function erases the old data.
}

if (signal_color == TrafficSignalElement::RED) {
return false;

Check warning on line 2345 in perception/map_based_prediction/src/map_based_prediction_node.cpp

View check run for this annotation

Codecov / codecov/patch

perception/map_based_prediction/src/map_based_prediction_node.cpp#L2344-L2345

Added lines #L2344 - L2345 were not covered by tests
}

return true;
}

Check notice on line 2349 in perception/map_based_prediction/src/map_based_prediction_node.cpp

View check run for this annotation

CodeScene Delta Analysis / CodeScene Cloud Delta Analysis (main)

ℹ New issue: Bumpy Road Ahead

MapBasedPredictionNode::calcIntentionToCrossWithTrafficSgnal has 2 blocks with nested conditional logic. Any nesting of 2 or deeper is considered. Threshold is one single, nested block per function. The Bumpy Road code smell is a function that contains multiple chunks of nested conditional logic. The deeper the nesting and the more bumps, the lower the code health.

Check warning on line 2349 in perception/map_based_prediction/src/map_based_prediction_node.cpp

View check run for this annotation

CodeScene Delta Analysis / CodeScene Cloud Delta Analysis (main)

❌ New issue: Complex Method

MapBasedPredictionNode::calcIntentionToCrossWithTrafficSgnal has a cyclomatic complexity of 11, threshold = 9. This function has many conditional statements (e.g. if, for, while), leading to lower code health. Avoid adding more conditionals and code to it without refactoring.

} // namespace map_based_prediction

#include <rclcpp_components/register_node_macro.hpp>
Expand Down
Loading
Loading