simulation_framework::evaluator::TimeToCollisionCalculator Class Reference
Last update: 19.09.2025class TimeToCollisionCalculator More...
#include <ttc_calculator.h>
Public Member Functions | |
| std::chrono::milliseconds | Calculate (const osi3::GroundTruth &ground_truth) const |
Detailed Description
class TimeToCollisionCalculator
TimeToCollisionCalculator class to calculate the time of Ego to collision with other traffic car based on osi GroundTruth Algorithm explaination:
- find out the Ego vehicle index within MovingObject list from GroundTruth and compute the BoundingBox
- find out the nearest with possible colliding traffic vehicle index within MovingObject list from GroundTruth and compute the BoundingBox.
- calculate the distance between ego and nearest possible colliding traffic vehicle, with consideraion of dimensions of ego and traffic car with approximation using half length from both.
- check if two bounding boxes are overlapping, if yes return ttc value to 0 (zero) meaning collision happens; if no, go to No.5.
- calculate current TTC based on velocity difference (2d velocity vector Norm difference) and distance. If velocity difference has a negative value, which means the nearest traffic car is driving faster than ego, ttc value will be returned as std::chrono::milliseconds::max()
Definition at line 41 of file ttc_calculator.h.
Member Function Documentation
◆ Calculate()
| std::chrono::milliseconds simulation_framework::evaluator::TimeToCollisionCalculator::Calculate | ( | const osi3::GroundTruth & | ground_truth | ) | const |
Definition at line 15 of file ttc_calculator.cpp.
16{
17 auto host_vehicle_index = std::make_optional<int>();
18
19 const auto& host_vehicle_id = ground_truth.host_vehicle_id();
20 const auto moving_objects_count = ground_truth.moving_object_size();
21
22 for (int i = 0; i < moving_objects_count; ++i)
23 {
24 if (host_vehicle_id.value() == ground_truth.moving_object(i).id().value())
25 {
26 host_vehicle_index.value() = i;
27 break;
28 }
29 }
30
31 if (!host_vehicle_index.has_value())
32 {
33 return std::chrono::milliseconds::max();
34 }
35
36 const auto& host_vehicle_base = ground_truth.moving_object(host_vehicle_index.value()).base();
37 BoundingBox bounding_box_ego{host_vehicle_base.position().x(),
38 host_vehicle_base.position().y(),
39 host_vehicle_base.dimension().width(),
40 host_vehicle_base.dimension().length(),
41 host_vehicle_base.orientation().yaw(),
42 host_vehicle_base.velocity().x(),
43 host_vehicle_base.velocity().y()};
44 BoundingBox bounding_box_target{};
45 std::optional<int> target_vehicle_index = std::make_optional<int>();
46
47 auto minimum_distance_to_host{std::numeric_limits<double>::infinity()};
48
49 for (int i = 0; i < moving_objects_count; ++i)
50 {
51 if (host_vehicle_index == i)
52 {
53 continue;
54 }
55
56 const auto& vehicle_base = ground_truth.moving_object(i).base();
57 BoundingBox bounding_box_vehicle{vehicle_base.position().x(),
58 vehicle_base.position().y(),
59 vehicle_base.dimension().width(),
60 vehicle_base.dimension().length(),
61 vehicle_base.orientation().yaw(),
62 vehicle_base.velocity().x(),
63 vehicle_base.velocity().y()};
64
65 if (!CanPotentiallyHit(bounding_box_ego, bounding_box_vehicle))
66 {
67 continue;
68 }
69
70 auto host_to_vehicle_distance = Calculate2dVectorNorm({bounding_box_ego.x, bounding_box_ego.y},
71 {bounding_box_vehicle.x, bounding_box_vehicle.y}) -
72 (bounding_box_ego.length * 0.5 + bounding_box_vehicle.length * 0.5);
73
74 if (minimum_distance_to_host > host_to_vehicle_distance)
75 {
76 minimum_distance_to_host = host_to_vehicle_distance;
77 target_vehicle_index.value() = i;
78 bounding_box_target = bounding_box_vehicle;
79 }
80 }
81
82 if (!target_vehicle_index.has_value())
83 {
84 return std::chrono::milliseconds::max();
85 }
86
87 const double host_to_target_relative_velocity =
88 Calculate2dVectorNorm({bounding_box_ego.velocity_x, bounding_box_ego.velocity_y}, {}) -
89 Calculate2dVectorNorm({bounding_box_target.velocity_x, bounding_box_target.velocity_y}, {});
90
91 double distance_to_target = minimum_distance_to_host;
92
93 if ((bounding_box_ego.x - bounding_box_target.x) > 0.0)
94 {
95 distance_to_target = -minimum_distance_to_host;
96 }
97
98 std::chrono::milliseconds time_to_collision{std::chrono::milliseconds::max()};
99
100 if (AreBoundingBoxesOverlapped(bounding_box_ego, bounding_box_target))
101 {
103 return std::chrono::milliseconds{0};
104 }
105
106 if (host_to_target_relative_velocity != 0.0 &&
107 (std::signbit(distance_to_target) == std::signbit(host_to_target_relative_velocity)))
108 {
109 // Introducing the following factor to get milliseconds instead of seconds
110 uint64_t time_conversion_factor = 1000u;
111 time_to_collision = std::chrono::milliseconds{static_cast<uint64_t>(
112 std::abs(distance_to_target / host_to_target_relative_velocity) * time_conversion_factor)};
113 }
114
115 return time_to_collision;
116};
The documentation for this class was generated from the following files: