8namespace traffic_manager {
10using namespace constants::PathBufferUpdate;
11using namespace constants::LaneChange;
12using namespace constants::WaypointSelection;
13using namespace constants::SpeedThreshold;
14using namespace constants::Collision;
15using namespace constants::MotionPlan;
18 const std::vector<ActorId> &vehicle_id_list,
23 std::unordered_map<
ActorId, std::pair<float, bool>> &large_vehicles,
25 std::vector<ActorId>& marked_for_removal,
28 : vehicle_id_list(vehicle_id_list),
29 buffer_map(buffer_map),
30 simulation_state(simulation_state),
31 track_traffic(track_traffic),
33 parameters(parameters),
34 marked_for_removal(marked_for_removal),
35 output_array(output_array),
36 random_device(random_device),
37 large_vehicles(large_vehicles) {}
45 const float vehicle_speed = vehicle_velocity_vector.
Length();
52 const float horizon_square =
SQUARE(horizon_length);
60 if (!waypoint_buffer.empty() &&
61 cg::Math::DistanceSquared(waypoint_buffer.front()->GetLocation(),
64 auto number_of_pops = waypoint_buffer.size();
65 for (uint64_t j = 0u; j < number_of_pops; ++j) {
70 bool is_at_junction_entrance =
false;
71 if (!waypoint_buffer.empty()) {
73 float dot_product =
DeviationDotProduct(vehicle_location, heading_vector, waypoint_buffer.front()->GetLocation());
74 while (dot_product <= 0.0f && !waypoint_buffer.empty()) {
76 if (!waypoint_buffer.empty()) {
77 dot_product =
DeviationDotProduct(vehicle_location, heading_vector, waypoint_buffer.front()->GetLocation());
81 if (!waypoint_buffer.empty()) {
85 bool front_waypoint_junction = front_waypoint->CheckJunction();
86 is_at_junction_entrance = !front_waypoint_junction && look_ahead_point->CheckJunction();
87 if (!is_at_junction_entrance) {
88 std::vector<SimpleWaypointPtr> last_passed_waypoints = front_waypoint->GetPreviousWaypoint();
89 if (last_passed_waypoints.size() == 1) {
90 is_at_junction_entrance = !last_passed_waypoints.front()->CheckJunction() && front_waypoint_junction;
93 if (is_at_junction_entrance
95 &&
local_map->GetMapName() ==
"Carla/Maps/Town03"
97 is_at_junction_entrance =
false;
102 while (!is_at_junction_entrance
103 && !waypoint_buffer.empty()
104 && waypoint_buffer.back()->DistanceSquared(waypoint_buffer.front()) > horizon_square + horizon_square
105 && !waypoint_buffer.back()->CheckJunction()) {
111 if (waypoint_buffer.empty()) {
113 if (closest_waypoint ==
nullptr) {
126 if (cg::Math::Dot(closest_waypoint->GetForwardVector(), heading_vector) < 0.0f) {
127 float best_dot = 0.0f;
129 local_map->GetWaypointsInDelta(vehicle_location, 8u, 4.0f)) {
130 const float dot = cg::Math::Dot(candidate->GetForwardVector(), heading_vector);
131 if (dot > best_dot) {
133 closest_waypoint = candidate;
142 bool force_lane_change = lane_change_info.
change_lane;
143 bool lane_change_direction = lane_change_info.
direction;
150 const bool is_rht = waypoint_buffer.front()->GetWaypoint()->IsRHT();
153 const bool is_random_right_change = perc_random_rightlanechange >=
random_device.
next();
154 const bool is_random_left_change = perc_random_leftlanechange >=
random_device.
next();
156 const bool is_left_lane_change = is_rht ? is_random_left_change : is_keep_slow || is_random_left_change;
157 const bool is_right_lane_change = is_rht ? is_keep_slow || is_random_right_change : is_random_right_change;
160 if (is_left_lane_change && is_right_lane_change){
161 force_lane_change =
true;
163 }
else if (is_right_lane_change) {
164 force_lane_change =
true;
165 lane_change_direction =
true;
166 }
else if (is_left_lane_change) {
167 force_lane_change =
true;
168 lane_change_direction =
false;
176 bool done_with_previous_lane_change =
true;
177 if (!recently_not_executed_lane_change) {
178 float distance_frm_previous = cg::Math::DistanceSquared(
last_lane_change_swpt.at(actor_id)->GetLocation(), vehicle_location);
179 done_with_previous_lane_change = distance_frm_previous > lane_change_distance;
183 bool front_waypoint_not_junction = !front_waypoint->CheckJunction();
185 if (auto_or_force_lane_change
186 && front_waypoint_not_junction
187 && (recently_not_executed_lane_change || done_with_previous_lane_change)) {
190 force_lane_change, lane_change_direction);
192 if (change_over_point !=
nullptr) {
198 auto number_of_pops = waypoint_buffer.size();
199 for (uint64_t j = 0u; j < number_of_pops; ++j) {
209 if (!imported_path.empty()) {
211 ImportPath(imported_path, waypoint_buffer, actor_id, horizon_square);
213 }
else if (!imported_actions.empty()) {
215 ImportRoute(imported_actions, waypoint_buffer, actor_id, horizon_square);
221 while (waypoint_buffer.back()->DistanceSquared(waypoint_buffer.front()) <= horizon_square) {
223 std::vector<SimpleWaypointPtr> next_waypoints = furthest_waypoint->GetNextWaypoint();
224 uint64_t selection_index = 0u;
226 if (next_waypoints.size() > 1) {
228 selection_index =
static_cast<uint64_t
>(r_sample*next_waypoints.size()*0.01);
229 }
else if (next_waypoints.size() == 0) {
231 std::cout <<
"This map has dead-end roads, please change the set_open_street_map parameter to true" << std::endl;
238 if (next_wp_selection->GetId() == waypoint_buffer.front()->GetId()){
252 if (is_at_junction_entrance) {
255 output.
safe_point = safe_space_end_points.second;
266 const bool is_at_junction_entrance,
267 Buffer &waypoint_buffer) {
272 if (is_at_junction_entrance
275 bool entered_junction =
false;
276 bool past_junction =
false;
277 bool safe_point_found =
false;
283 for (
unsigned long i = 0u; i < waypoint_buffer.size() && !safe_point_found; ++i) {
284 current_waypoint = waypoint_buffer.at(i);
285 if (!entered_junction && current_waypoint->CheckJunction()) {
286 entered_junction =
true;
287 junction_begin_point = current_waypoint;
289 if (entered_junction && !past_junction && !current_waypoint->CheckJunction()) {
290 past_junction =
true;
291 junction_end_point = current_waypoint;
293 if (past_junction && junction_end_point->DistanceSquared(current_waypoint) > safe_distance_squared) {
294 safe_point_found =
true;
295 safe_point_after_junction = current_waypoint;
300 if (!safe_point_found) {
303 while (!past_junction && !abort) {
304 NodeList next_waypoints = current_waypoint->GetNextWaypoint();
305 if (!next_waypoints.empty()) {
306 current_waypoint = next_waypoints.front();
308 if (!current_waypoint->CheckJunction()) {
309 past_junction =
true;
310 junction_end_point = current_waypoint;
317 while (!safe_point_found && !abort) {
318 std::vector<SimpleWaypointPtr> next_waypoints = current_waypoint->GetNextWaypoint();
319 if ((junction_end_point->DistanceSquared(current_waypoint) > safe_distance_squared)
320 || next_waypoints.size() > 1
321 || current_waypoint->CheckJunction()) {
323 safe_point_found =
true;
324 safe_point_after_junction = current_waypoint;
326 if (!next_waypoints.empty()) {
327 current_waypoint = next_waypoints.front();
336 if (junction_end_point !=
nullptr &&
337 safe_point_after_junction !=
nullptr &&
340 junction_end_point =
nullptr;
341 safe_point_after_junction =
nullptr;
346 else if (!is_at_junction_entrance
354 const bool is_at_junction_entrance,
355 Buffer &waypoint_buffer) {
362 const bool is_at_junction{waypoint_buffer.front()->CheckJunction()};
364 if (is_at_junction_entrance
372 const SimpleWaypointPtr middle_waypoint = waypoint_buffer.at(waypoint_buffer.size() / 2);
375 first_waypoint->GetLocation(),
376 middle_waypoint->GetLocation(),
377 last_waypoint->GetLocation());
383 bool entered_junction{
false};
384 float junction_length{0.0f};
385 bool is_straight_path{
true};
387 for (
unsigned long i = 0u; i < waypoint_buffer.size(); ++i) {
388 current_waypoint = waypoint_buffer.at(i);
390 if (!entered_junction && current_waypoint->CheckJunction()) {
391 entered_junction =
true;
394 if (i > 0 && entered_junction) {
396 const float new_distance = current_waypoint->Distance(prev_waypoint->GetLocation());
397 junction_length += new_distance;
399 if (is_straight_path) {
400 const RoadOption junction_type = current_waypoint->GetRoadOption();
403 is_straight_path =
false;
406 is_straight_path =
false;
411 if (entered_junction && !current_waypoint->CheckJunction()) {
415 if (!is_straight_path) {
456 const float vehicle_speed,
457 bool force,
bool direction) {
465 return change_over_point;
470 if (!waypoint_buffer.empty()) {
480 bool obstacle_too_close =
false;
481 float minimum_squared_distance = std::numeric_limits<float>::infinity();
482 ActorId obstacle_actor_id = 0u;
483 for (
auto i = blocking_vehicles.begin();
484 i != blocking_vehicles.end() && !obstacle_too_close && !force;
486 const ActorId &other_actor_id = *i;
491 const cg::Location other_location = other_current_waypoint->GetLocation();
493 const cg::Vector3D reference_heading = current_waypoint->GetForwardVector();
494 cg::Vector3D reference_to_other = other_location - current_waypoint->GetLocation();
495 const cg::Vector3D other_heading = other_current_waypoint->GetForwardVector();
497 WaypointPtr current_raw_waypoint = current_waypoint->GetWaypoint();
498 WaypointPtr other_current_raw_waypoint = other_current_waypoint->GetWaypoint();
502 if (!current_waypoint->CheckJunction()
503 && !other_current_waypoint->CheckJunction()
504 && other_current_raw_waypoint->GetRoadId() == current_raw_waypoint->GetRoadId()
505 && other_current_raw_waypoint->GetLaneId() == current_raw_waypoint->GetLaneId()
506 && cg::Math::Dot(reference_heading, reference_to_other) > 0.0f
508 float squared_distance = cg::Math::DistanceSquared(vehicle_location, other_location);
513 minimum_squared_distance = squared_distance;
514 obstacle_actor_id = other_actor_id;
517 obstacle_too_close =
true;
524 if (!obstacle_too_close && obstacle_actor_id != 0u && !force) {
527 const auto other_neighbouring_lanes = {other_current_waypoint->GetLeftWaypoint(),
528 other_current_waypoint->GetRightWaypoint()};
531 bool distant_left_lane_free =
false;
532 bool distant_right_lane_free =
false;
535 bool left_right =
true;
536 for (
auto &candidate_lane_wp : other_neighbouring_lanes) {
537 if (candidate_lane_wp !=
nullptr &&
541 distant_left_lane_free =
true;
543 distant_right_lane_free =
true;
545 left_right = !left_right;
550 if (distant_right_lane_free && right_waypoint !=
nullptr
552 change_over_point = right_waypoint;
553 }
else if (distant_left_lane_free && left_waypoint !=
nullptr
555 change_over_point = left_waypoint;
558 if (direction && right_waypoint !=
nullptr) {
559 change_over_point = right_waypoint;
560 }
else if (!direction && left_waypoint !=
nullptr) {
561 change_over_point = left_waypoint;
565 if (change_over_point !=
nullptr) {
568 while (change_over_point->DistanceSquared(starting_point) <
SQUARE(change_over_distance) &&
569 !change_over_point->CheckJunction()) {
570 change_over_point = change_over_point->GetNextWaypoint().front();
575 return change_over_point;
581 auto number_of_pops = waypoint_buffer.size();
582 for (uint64_t j = 0u; j < number_of_pops - 1; ++j) {
594 while (!imported_path.empty() && waypoint_buffer.back()->DistanceSquared(waypoint_buffer.front()) <= horizon_square) {
599 std::vector<SimpleWaypointPtr> next_waypoints = latest_waypoint->GetNextWaypoint();
600 uint64_t selection_index = 0u;
603 if (next_waypoints.size() > 1) {
604 const float imported_road_id = imported->GetWaypoint()->GetRoadId();
605 float min_distance = std::numeric_limits<float>::infinity();
606 for (uint64_t k = 0u; k < next_waypoints.size(); ++k) {
608 while (!junction_end_point->CheckJunction()) {
609 junction_end_point = junction_end_point->GetNextWaypoint().front();
611 while (junction_end_point->CheckJunction()) {
612 junction_end_point = junction_end_point->GetNextWaypoint().front();
614 while (next_waypoints.at(k)->DistanceSquared(junction_end_point) < 50.0f) {
615 junction_end_point = junction_end_point->GetNextWaypoint().front();
617 float jep_road_id = junction_end_point->GetWaypoint()->GetRoadId();
618 if (jep_road_id == imported_road_id) {
622 float distance = junction_end_point->DistanceSquared(imported);
628 }
else if (next_waypoints.size() == 0) {
630 std::cout <<
"This map has dead-end roads, please change the set_open_street_map parameter to true" << std::endl;
638 if (next_wp_selection->DistanceSquared(imported) < 30.0f) {
639 imported_path.erase(imported_path.begin());
640 std::vector<SimpleWaypointPtr> possible_waypoints = next_wp_selection->GetNextWaypoint();
641 if (std::find(possible_waypoints.begin(), possible_waypoints.end(), imported) != possible_waypoints.end()) {
646 latest_imported = imported_path.front();
647 imported =
local_map->GetWaypoint(latest_imported);
652 if (imported_path.empty()) {
664 auto number_of_pops = waypoint_buffer.size();
665 for (uint64_t j = 0u; j < number_of_pops - 1; ++j) {
673 while (!imported_actions.empty() && waypoint_buffer.back()->DistanceSquared(waypoint_buffer.front()) <= horizon_square) {
676 RoadOption latest_road_option = latest_waypoint->GetRoadOption();
678 std::vector<SimpleWaypointPtr> next_waypoints = latest_waypoint->GetNextWaypoint();
679 uint16_t selection_index = 0u;
680 if (next_waypoints.size() > 1) {
681 for (uint16_t i=0; i<next_waypoints.size(); ++i) {
682 if (next_waypoints.at(i)->GetRoadOption() == next_road_option) {
686 if (i == next_waypoints.size() - 1) {
687 std::cout <<
"We couldn't find the RoadOption you were looking for. This route might diverge from the one expected." << std::endl;
691 }
else if (next_waypoints.size() == 0) {
693 std::cout <<
"This map has dead-end roads, please change the set_open_street_map parameter to true" << std::endl;
703 if (latest_road_option != next_wp_selection->GetRoadOption() && next_road_option == next_wp_selection->GetRoadOption()) {
704 imported_actions.erase(imported_actions.begin());
705 next_road_option =
static_cast<RoadOption>(imported_actions.front());
708 if (imported_actions.empty()) {
721 auto waypoint_buffer =
buffer_map.at(actor_id);
723 bool is_lane_change =
false;
726 is_lane_change =
true;
729 bool left_heading = (heading_vector.
x * relative_vector.
y - heading_vector.
y * relative_vector.
x) > 0.0f;
733 for (
auto &swpt : waypoint_buffer) {
736 if (!is_lane_change) {
738 return std::make_pair(road_opt, swpt->GetWaypoint());
743 auto distance_lane_change = cg::Math::DistanceSquared(actual_location, lane_change);
744 auto distance_other_action = cg::Math::DistanceSquared(actual_location, swpt->GetLocation());
745 if (distance_lane_change < distance_other_action)
return next_action;
746 else return std::make_pair(road_opt, swpt->GetWaypoint());
757 return action_buffer;
759 auto waypoint_buffer =
buffer_map.at(actor_id);
761 bool is_lane_change =
false;
763 RoadOption last_road_opt = buffer_front->GetRoadOption();
764 action_buffer.push_back(std::make_pair(last_road_opt, buffer_front->GetWaypoint()));
767 is_lane_change =
true;
770 bool left_heading = (heading_vector.
x * relative_vector.
y - heading_vector.
y * relative_vector.
x) > 0.0f;
774 for (
auto &wpt : waypoint_buffer) {
775 RoadOption current_road_opt = wpt->GetRoadOption();
776 if (current_road_opt != last_road_opt) {
777 action_buffer.push_back(std::make_pair(current_road_opt, wpt->GetWaypoint()));
778 last_road_opt = current_road_opt;
781 if (is_lane_change) {
783 auto distance_lane_change = cg::Math::DistanceSquared(waypoint_buffer.front()->GetLocation(), lane_change.second->GetTransform().location);
784 for (uint16_t i = 0; i < action_buffer.size(); ++i) {
785 auto distance_action = cg::Math::DistanceSquared(waypoint_buffer.front()->GetLocation(), waypoint_buffer.at(i)->GetLocation());
788 if (i == action_buffer.size()-1) {
789 action_buffer.push_back(lane_change);
791 }
else if (distance_action > distance_lane_change) {
792 action_buffer.insert(action_buffer.begin()+i, lane_change);
797 return action_buffer;
#define SQUARE(a)
This file contains various constants used in traffic manager arranged into sensible namespaces for re...
LocalizationStage(const std::vector< ActorId > &vehicle_id_list, BufferMap &buffer_map, const SimulationState &simulation_state, TrackTraffic &track_traffic, const LocalMapPtr &local_map, std::unordered_map< ActorId, std::pair< float, bool > > &large_vehicles, Parameters ¶meters, std::vector< ActorId > &marked_for_removal, LocalizationFrame &output_array, RandomGenerator &random_device)
ActionBuffer ComputeActionBuffer(const ActorId &actor_id)
void ImportRoute(Route &imported_actions, Buffer &waypoint_buffer, const ActorId actor_id, const float horizon_square)
ActorIdSet vehicles_at_junction
std::unordered_set< ActorId > large_vehicles_at_junction
void ImportPath(Path &imported_path, Buffer &waypoint_buffer, const ActorId actor_id, const float horizon_square)
void ExtendAndFindSafeSpace(const ActorId actor_id, const bool is_at_junction_entrance, Buffer &waypoint_buffer)
Action ComputeNextAction(const ActorId &actor_id)
std::unordered_map< ActorId, SimpleWaypointPair > vehicles_at_junction_entrance
const SimulationState & simulation_state
RandomGenerator & random_device
const std::vector< ActorId > & vehicle_id_list
TrackTraffic & track_traffic
void HandleLargeVehicleJunction(const ActorId actor_id, const bool is_at_junction_entrance, Buffer &waypoint_buffer)
SimpleWaypointPtr AssignLaneChange(const ActorId actor_id, const cg::Location vehicle_location, const float vehicle_speed, bool force, bool direction)
const LocalMapPtr & local_map
LocalizationFrame & output_array
std::vector< ActorId > & marked_for_removal
void Update(const unsigned long index) override
void RemoveActor(const ActorId actor_id) override
std::unordered_map< ActorId, std::pair< float, bool > > & large_vehicles
std::pair< SimpleWaypointPtr, SimpleWaypointPtr > SimpleWaypointPair
LaneChangeSWptMap last_lane_change_swpt
std::unordered_set< ActorId > large_vehicles_at_junction_entrance
float GetRandomLeftLaneChangePercentage(const ActorId &actor_id)
Method to query percentage probability of a random right lane change for a vehicle.
ChangeLaneInfo GetForceLaneChange(const ActorId &actor_id)
Method to query lane change command for a vehicle.
Route GetImportedRoute(const ActorId &actor_id) const
Method to get a custom route.
float GetKeepSlowLanePercentage(const ActorId &actor_id)
Method to query percentage probability of keep slow lane rule for a vehicle.
bool GetUploadRoute(const ActorId &actor_id) const
Method to get if we are uploading a route.
void UpdateUploadPath(const ActorId &actor_id, const Path path)
Method to update an already set list of points.
bool GetOSMMode() const
Method to get Open Street Map mode.
void UpdateImportedRoute(const ActorId &actor_id, const Route route)
Method to update an already set route.
bool GetUploadPath(const ActorId &actor_id) const
Method to get if we are uploading a path.
float GetRandomRightLaneChangePercentage(const ActorId &actor_id)
Method to query percentage probability of a random left lane change for a vehicle.
void RemoveImportedRoute(const ActorId &actor_id, const bool remove_path)
Method to remove a route.
bool GetAutoLaneChange(const ActorId &actor_id) const
Method to query auto lane change rule for a vehicle.
Path GetCustomPath(const ActorId &actor_id) const
Method to get a custom path.
void RemoveUploadPath(const ActorId &actor_id, const bool remove_path)
Method to remove a list of points.
This class holds the state of all the vehicles in the simlation.
cg::Location GetLocation(const ActorId actor_id) const
cg::Vector3D GetHeading(const ActorId actor_id) const
cg::Vector3D GetVelocity(const ActorId actor_id) const
void UpdateGridPosition(const ActorId actor_id, const Buffer &buffer)
ActorIdSet GetPassingVehicles(uint64_t waypoint_id) const
ActorIdSet GetOverlappingVehicles(ActorId actor_id) const
static const float MIN_LANE_CHANGE_SPEED
static const float MAX_WPT_DISTANCE
static const float INTER_LANE_CHANGE_DISTANCE
static const float MAXIMUM_LANE_OBSTACLE_CURVATURE
static const float FIFTYPERC
static const float MAXIMUM_LANE_OBSTACLE_DISTANCE
static const float MINIMUM_LANE_CHANGE_DISTANCE
static const float MIN_WPT_DISTANCE
static const float MAX_START_DISTANCE
static const float HORIZON_RATE
static const float HIGH_SPEED_HORIZON_RATE
static const float MINIMUM_HORIZON_LENGTH
static const float HIGHWAY_SPEED
static const float SAFE_DISTANCE_AFTER_JUNCTION
static const float LARGE_VEHICLES_JUNCTION_MAX_RADIUS
static const float MIN_JUNCTION_LENGTH
carla::SharedPtr< cc::Waypoint > WaypointPtr
std::deque< std::shared_ptr< SimpleWaypoint > > Buffer
std::shared_ptr< InMemoryMap > LocalMapPtr
void PopWaypoint(ActorId actor_id, TrackTraffic &track_traffic, Buffer &buffer, bool front_or_back)
std::vector< uint8_t > Route
std::unordered_map< carla::ActorId, Buffer > BufferMap
std::vector< SimpleWaypointPtr > NodeList
std::vector< cg::Location > Path
void PushWaypoint(ActorId actor_id, TrackTraffic &track_traffic, Buffer &buffer, SimpleWaypointPtr &waypoint)
float GetThreePointCircleRadius(cg::Location first_location, cg::Location middle_location, cg::Location last_location)
Returns the radius of the circle defined by three points in the XY plane.
TargetWPInfo GetTargetWaypoint(const Buffer &waypoint_buffer, const float &target_point_distance)
std::pair< RoadOption, WaypointPtr > Action
std::vector< Action > ActionBuffer
std::vector< LocalizationData > LocalizationFrame
std::shared_ptr< SimpleWaypoint > SimpleWaypointPtr
float DeviationDotProduct(const cg::Location &reference_location, const cg::Vector3D &heading_vector, const cg::Location &target_location)
Returns the dot product between the vehicle's heading vector and the vector along the direction to th...
This file contains definitions of common data structures used in traffic manager.
constexpr float SquaredLength() const
SimpleWaypointPtr safe_point
bool localized
False when the localization stage could not place the vehicle on the map – a map without a single dri...
bool is_at_junction_entrance
SimpleWaypointPtr junction_end_point