-
Notifications
You must be signed in to change notification settings - Fork 625
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(autonomous_emergency_braking): calculate the object's velocity in the search area #8591
base: main
Are you sure you want to change the base?
feat(autonomous_emergency_braking): calculate the object's velocity in the search area #8591
Conversation
Thank you for contributing to the Autoware project! 🚧 If your pull request is in progress, switch it to draft mode. Please ensure:
|
Hi @danielsanchezaran -san, |
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #8591 +/- ##
==========================================
- Coverage 28.00% 28.00% -0.01%
==========================================
Files 1317 1318 +1
Lines 98578 98627 +49
Branches 39776 39800 +24
==========================================
+ Hits 27605 27618 +13
- Misses 70874 70909 +35
- Partials 99 100 +1
*This pull request uses carry forward flags. Click here to find out more. ☔ View full report in Codecov by Sentry. |
@ismetatabay |
@@ -392,7 +394,9 @@ class AEB : public rclcpp::Node | |||
* @param closest_object Data of the closest object |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ismetatabay
Could you modify doxygen explanation?
bool is_point_inside = false; | ||
for (const auto & ego_poly : ego_polys) { | ||
if (bg::within(obj_point, ego_poly)) { | ||
is_point_inside = true; | ||
break; | ||
} | ||
} | ||
if (!is_point_inside) { | ||
return false; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bool is_point_inside = false; | |
for (const auto & ego_poly : ego_polys) { | |
if (bg::within(obj_point, ego_poly)) { | |
is_point_inside = true; | |
break; | |
} | |
} | |
if (!is_point_inside) { | |
return false; | |
} | |
if (!std::any_of(ego_polys.begin(), ego_polys.end(), | |
[&obj_point](const auto & ego_poly) { return bg::within(obj_point, ego_poly); })) { | |
return false; | |
} |
It might be a matter of preference, but wouldn't this approach be more simple for what you're trying to accomplish? There's no problem with the current implementation, so it's fine if you don't change it.
@ismetatabay |
Hi @kyoichi-sugahara-san, thank you so much for your comments. If you could continue reviewing, I would be grateful. I converted it to a draft as you mentioned a problem with the usage of |
@ismetatabay I can confirm from the description that the results have improved, but do you understand why setting the collision result to false when the object's vertices are outside the extended predicted path helps avoid unnecessary activations? Furthermore, if we were to incorporate this change, I think it would be more natural to implement the process of excluding objects that have vertices not contained within the predicted path in the The reason is that it's preferable to separate the filtering process for potential collision objects from the actual collision detection. I apologize if I've overlooked any circumstances and my comments are unreasonable 🙇 |
@kyoichi-sugahara -san, thank you for your comments. I plan to refactor my implementation and keep this PR as a draft. My current implementation steps are as follows: -> Use rough point cloud filtering to keep the velocity information of the closest object in this area. As you mentioned, the |
95837c9
to
d9d3164
Compare
@kyoichi-sugahara -san, my current idea is:
What do you think? Additionally, I found a mistake in the control.launch.xml launch file and I fixed this topic as well.:
|
So, does this mean that AEB will no longer explicitly react to objects existing outside the normal predicted path? From referring to the issue (this is super useful result ❤️), I understand that the problem is that the estimation results are unstable for the first few steps after speed calculation begins, causing unnecessary activation. From my perspective, I feel the following approaches might be valid solutions:
What do you think? |
@kyoichi-sugahara -san, thank you for your comment ❤️ . So, does this mean that AEB will no longer explicitly react to objects existing outside the normal predicted path? AEB maintains the same mechanism for reacting to obstacles in the predicted path. The default current implementation uses My idea is to calculate the object's velocity when it enters the - Introduce a mechanism that doesn't utilize the first few steps when the speed estimation is clearly unstable.
- Prepare separate areas for speed estimation and for detection targets.
|
Yes you are right, and sorry I noticed my comment was based on misunderstanding
I understand your concern but, may be the further object can be ignored in my opinion. Only closest object in the predicted path polygon should be considered.
yes, that's the concern for this idea which I was discussing with @danielsanchezaran today
Thanks! I hope it improves the behavior but still |
@kyoichi-sugahara -san, Thank you so much for your valuable comments and suggestions. My main concern regarding the closest object is that if we calculate and only consider the closest object within separate areas, we might miss the actual target object. I will work on addressing this in the following case: Since NPC1 is the closest object, we will calculate its speed, but it is not our target object. NPC2 is the target object because it is located on our trajectory. I will check on it. |
d2081c2
to
f463428
Compare
458b562
to
9f527ad
Compare
@@ -850,7 +895,14 @@ void AEB::getClosestObjectsOnPath( | |||
obj.distance_to_object = std::abs(dist_ego_to_object); | |||
|
|||
const Point2d obj_point(p.x, p.y); | |||
for (const auto & ego_poly : ego_polys) { | |||
// Check if the object is in the predicted path for AEB or not |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ismetatabay I feel if might be worthwhile to consider using the objects lateral distance instead of their polygons to include and not include them in the speed calculation and classifying them as targets or not.
if the points absolute lat distance is less than vehicle_width / 2 + expand_width_ they are a target and include them in the object list, if not, we check if their lat distance to the ego path is less than ego_width_ /2 + expand_width + speed_calc_marging. So it is not necessary to iterate through the 2 sets of polygons. The added benefit is that we could use the change in lat distance to calculate object lateral speeds in the future, to "predict" if the object will enter or leave the ego path before a collision.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hello @danielsanchezaran -san, agree, I updated the PR accordingly. However, I also made changes to the collision checking steps. I merged objects from both the IMU and MPC, and I also merged path points from the IMU and MPC so that the checking mechanism runs only once. What do you think about that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you @ismetatabay I would like to test the PR and see if there is degradation due to the change from polygon-based collision detection to arc coordinate based, I will take a look at processing time. Please give me some time to review.
Also, I am sorry for being too bothersome, but maybe do you think it is possible to separate this PR into 2? one for the velocity calculation and one for the arc-coordinate based collision detection?
7727ba8
to
7e28209
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR looks very promising, please let me know your opinion about the comments/reviews I made.
I tested the PR is simulation and it looks good, however processing time is a concern (I believe the code should be faster with this PR, but benchmarking is necessary)
ego_imu_path, points_belonging_to_cluster_hulls, | ||
{0.0 / 256.0, 148.0 / 256.0, 205.0 / 256.0, 0.999}, "imu"); | ||
|
||
const auto mpc_path_objects = (!use_predicted_trajectory_ || !predicted_traj_ptr_) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const auto mpc_path_objects = (!use_predicted_trajectory_ || !predicted_traj_ptr_) | |
const auto mpc_path_objects = (!use_predicted_trajectory_ || !predicted_traj_ptr_ || !ego_mpc_path.has_value()) |
If there is no mpc path available the AEB will crash if this check is not added
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done 👍
return merged_objects; | ||
}; | ||
|
||
auto merge_imu_mpc_objects = merge_objects(imu_path_objects, mpc_path_objects); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
auto merge_imu_mpc_objects = merge_objects(imu_path_objects, mpc_path_objects); | |
auto merged_imu_mpc_objects = merge_objects(imu_path_objects, mpc_path_objects); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done 👍
|
||
// calculate the lateral offset between the ego vehicle and the object | ||
const double lateral_offset = | ||
std::abs(autoware::motion_utils::calcLateralOffset(ego_path, obj.position)); | ||
|
||
// check if the object is in the target area | ||
if (lateral_offset > vehicle_info_.vehicle_width_m / 2.0 + expand_width_) { | ||
obj.is_target = false; | ||
} | ||
|
||
// add all objects located in the speed calculation margin to the object list | ||
if ( | ||
lateral_offset < | ||
vehicle_info_.vehicle_width_m / 2.0 + expand_width_ + speed_calculation_expansion_margin_) { | ||
objects.push_back(obj); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// calculate the lateral offset between the ego vehicle and the object | |
const double lateral_offset = | |
std::abs(autoware::motion_utils::calcLateralOffset(ego_path, obj.position)); | |
// check if the object is in the target area | |
if (lateral_offset > vehicle_info_.vehicle_width_m / 2.0 + expand_width_) { | |
obj.is_target = false; | |
} | |
// add all objects located in the speed calculation margin to the object list | |
if ( | |
lateral_offset < | |
vehicle_info_.vehicle_width_m / 2.0 + expand_width_ + speed_calculation_expansion_margin_) { | |
objects.push_back(obj); | |
// If the object is behind the ego, we need to use the backward long offset. The distance should | |
// be a positive number in any case | |
// calculate the lateral offset between the ego vehicle and the object | |
const double lateral_offset = | |
std::abs(autoware::motion_utils::calcLateralOffset(ego_path, obj_position)); | |
// Object is outside region of interest | |
if ( | |
lateral_offset > | |
vehicle_info_.vehicle_width_m / 2.0 + expand_width_ + speed_calculation_expansion_margin_) { | |
continue; | |
} | |
const bool is_object_in_front_of_ego = obj_arc_length > 0.0; | |
const double dist_ego_to_object = (is_object_in_front_of_ego) | |
? obj_arc_length - vehicle_info_.max_longitudinal_offset_m | |
: obj_arc_length + vehicle_info_.min_longitudinal_offset_m; | |
ObjectData obj; | |
obj.stamp = stamp; | |
obj.position = obj_position; | |
obj.velocity = 0.0; | |
obj.distance_to_object = std::abs(dist_ego_to_object); | |
obj.is_target = (lateral_offset < vehicle_info_.vehicle_width_m / 2.0 + expand_width_); | |
objects.push_back(obj); | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, do you reckon it might be possible to choose between using polygon based and arc-coord-based collision detection with a param?
@@ -32,6 +32,7 @@ | |||
|
|||
namespace autoware::motion::control::autonomous_emergency_braking::test | |||
{ | |||
using autoware::universe_utils::Point2d; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are these used?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed 👍
@@ -40,6 +41,7 @@ using geometry_msgs::msg::Pose; | |||
using geometry_msgs::msg::TransformStamped; | |||
using geometry_msgs::msg::Vector3; | |||
using std_msgs::msg::Header; | |||
namespace bg = boost::geometry; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this used?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed 👍
// check if the predicted path has a valid number of points | ||
if (ego_path.size() < 2 || ego_polys.empty() || points_belonging_to_cluster_hulls->empty()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe ego_polys are not used anymore in this scope with this PR, so they should be removed from the function and the function inputs?
Also, the function createObjectDataUsingPredictedObjects() uses polygons to detect objects, maybe we should get rid of polygons when possible or set an option to use either arc coordinates or boost polygons for collision detection? I believe using arc-coordinates for collision detection might be best separated into a different PR, what do you think? would it be too difficult?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for your valuable reviews and comments. I think it would be beneficial to add a new parameter for the collision detection method (polygons or arc coordinates). In my opinion, it would be better to implement this in a separate PR. After this PR, I can work on that 👍
return (o1.is_target && (!o2.is_target || o1.distance_to_object < o2.distance_to_object)); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If o1 and o2 are NOT targets, doesn't that make o2 always the "closest" object regardless of distance? Maybe the logic should include all cases?
return (o1.is_target && (!o2.is_target || o1.distance_to_object < o2.distance_to_object)); | |
}); | |
//target objects have priority | |
if (o1.is_target != o2.is_target) { | |
return o1.is_target; | |
} | |
return o1.distance_to_object < o2.distance_to_object; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree, updated 👍
7f428ab
to
7b85937
Compare
} | ||
} | ||
|
||
// If no target object is found, find the closest object overall |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// If no target object is found, find the closest object overall | |
// If no target object is found, find the closest object overall |
Sorry for the delay in the reviewing @ismetatabay I am finishing some thing regarding AEB ci/cd and it has taken me a little longer than expected to check for degradation, it should be done by tomorrow, on the mean time could you check this? I think the
const auto closest_object_point_itr
calculation part can be deleted, because closest_target_object_itr
already returns the closest object even if there are no targets. So i suggest renaming closest_target_object_itr
to closest_object_itr
and deleting the rest of the redundant code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No worries, let me check it 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed 👍
@ismetatabay it looks like there might be some trouble with using arc coordinates. I cannot really tell why, but detection seems to happen when it should not. I am using the default params. cap-.2024-09-19-18-54-28.online-video-cutter.com.mp4 |
Hello @danielsanchezaran -san, I couldn't reproduce the issue you encountered with the planning simulator. If possible, could you share the bag and map files? so I can check the problem 2024-09-19.13-44-04.mp4 |
@danielsanchezaran |
7b85937
to
329b4f7
Compare
@ismetatabay thank you for your input. I will try and see if I can reproduce the problem reliably or if it is a tuning problem. The ground segmentation does indeed look suspicious, but I also tried setting the minimum cluster height to 0.1 m to mitigate that, with no luck. Would it be possible to you to do some tests using AWsim? or maybe with a rosbag you have with similar conditions (vehicles close to the ego on both sides) |
@ismetatabay I discovered what was the issue. Some of the MPC path points are virtually the same when the ego is starting to move, that causes the calcLatoffset function to misbehave and not caluclate the proper lateral distance. To solve the issue, we can omit mpc path points that are too close to each other:
I would like you to please add this change and also make the minimum distance between points 1e-2 for the IMU path, for consistency. Also, please note that calcLateralOffset might return NaN, so please handle that case by adding a As a note, the calcLateralOffset function checks if 2 points are too close, but the epsilon value used (1e-8 might be too small. I hopefully will make a PR next week to fix it). On the mean time, I will approve this PR, I think it is a great addition to AEB and I am grateful for it, but please fix the issues I pointed out before merging!!!! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Approved, but please fix the issues on my last comment before merging, the rest LGTM
Signed-off-by: ismetatabay <[email protected]>
Signed-off-by: ismetatabay <[email protected]>
Signed-off-by: ismetatabay <[email protected]>
Signed-off-by: ismetatabay <[email protected]>
Signed-off-by: ismetatabay <[email protected]>
Signed-off-by: ismetatabay <[email protected]>
329b4f7
to
eae0170
Compare
@danielsanchezaran Thank you so much for your efforts. Before merging it, I want to test it on a real vehicle as well. I will update you. Have a good weekend! |
Thank you @ismetatabay any idea when you will you be able to do the tests? |
Description
This PR enables the calculation of object velocity within the speed calculation area, using the
speed_calculation_expansion_margin
parameter.Related links
Parent Issue:
How was this PR tested?
Psim
Before This PR:
before_pr_new.mp4
After This PR:
after_pr_new.mp4
Stopping for an obstacle. (obstacle_cruise_planner (motion_stop_planner) is disabled)
after_pr2_new.mp4
Notes for reviewers
None.
Interface changes
None.
ROS Parameter Changes
Additions and removals
speed_calculation_expansion_margin
double
0.5
Effects on system behavior
None.