7namespace traffic_manager {
9using namespace constants::PathBufferUpdate;
10using namespace constants::LaneChange;
11using namespace constants::WaypointSelection;
12using namespace constants::SpeedThreshold;
13using namespace constants::Collision;
14using namespace constants::MotionPlan;
17 const std::vector<ActorId> &vehicle_id_list,
23 std::vector<ActorId>& marked_for_removal,
26 : vehicle_id_list(vehicle_id_list),
27 buffer_map(buffer_map),
28 simulation_state(simulation_state),
29 track_traffic(track_traffic),
31 parameters(parameters),
32 marked_for_removal(marked_for_removal),
33 output_array(output_array),
34 random_device(random_device){}
42 const float vehicle_speed = vehicle_velocity_vector.
Length();
49 const float horizon_square =
SQUARE(horizon_length);
57 if (!waypoint_buffer.empty() &&
58 cg::Math::DistanceSquared(waypoint_buffer.front()->GetLocation(),
61 auto number_of_pops = waypoint_buffer.size();
62 for (uint64_t j = 0u; j < number_of_pops; ++j) {
67 bool is_at_junction_entrance =
false;
68 if (!waypoint_buffer.empty()) {
70 float dot_product =
DeviationDotProduct(vehicle_location, heading_vector, waypoint_buffer.front()->GetLocation());
71 while (dot_product <= 0.0f && !waypoint_buffer.empty()) {
73 if (!waypoint_buffer.empty()) {
74 dot_product =
DeviationDotProduct(vehicle_location, heading_vector, waypoint_buffer.front()->GetLocation());
78 if (!waypoint_buffer.empty()) {
82 bool front_waypoint_junction = front_waypoint->CheckJunction();
83 is_at_junction_entrance = !front_waypoint_junction && look_ahead_point->CheckJunction();
84 if (!is_at_junction_entrance) {
85 std::vector<SimpleWaypointPtr> last_passed_waypoints = front_waypoint->GetPreviousWaypoint();
86 if (last_passed_waypoints.size() == 1) {
87 is_at_junction_entrance = !last_passed_waypoints.front()->CheckJunction() && front_waypoint_junction;
90 if (is_at_junction_entrance
92 &&
local_map->GetMapName() ==
"Carla/Maps/Town03"
94 is_at_junction_entrance =
false;
99 while (!is_at_junction_entrance
100 && !waypoint_buffer.empty()
101 && waypoint_buffer.back()->DistanceSquared(waypoint_buffer.front()) > horizon_square + horizon_square
102 && !waypoint_buffer.back()->CheckJunction()) {
108 if (waypoint_buffer.empty()) {
115 bool force_lane_change = lane_change_info.
change_lane;
116 bool lane_change_direction = lane_change_info.
direction;
124 const bool is_random_left_change = perc_random_leftlanechange >=
random_device.
next();
125 const bool is_random_right_change = perc_random_rightlanechange >=
random_device.
next();
128 if (is_keep_right || is_random_right_change) {
129 force_lane_change =
true;
130 lane_change_direction =
true;
132 if (is_random_left_change) {
133 if (!force_lane_change) {
134 force_lane_change =
true;
135 lane_change_direction =
false;
147 bool done_with_previous_lane_change =
true;
148 if (!recently_not_executed_lane_change) {
149 float distance_frm_previous = cg::Math::DistanceSquared(
last_lane_change_swpt.at(actor_id)->GetLocation(), vehicle_location);
150 done_with_previous_lane_change = distance_frm_previous > lane_change_distance;
154 bool front_waypoint_not_junction = !front_waypoint->CheckJunction();
156 if (auto_or_force_lane_change
157 && front_waypoint_not_junction
158 && (recently_not_executed_lane_change || done_with_previous_lane_change)) {
161 force_lane_change, lane_change_direction);
163 if (change_over_point !=
nullptr) {
169 auto number_of_pops = waypoint_buffer.size();
170 for (uint64_t j = 0u; j < number_of_pops; ++j) {
180 if (!imported_path.empty()) {
182 ImportPath(imported_path, waypoint_buffer, actor_id, horizon_square);
184 }
else if (!imported_actions.empty()) {
186 ImportRoute(imported_actions, waypoint_buffer, actor_id, horizon_square);
192 while (waypoint_buffer.back()->DistanceSquared(waypoint_buffer.front()) <= horizon_square) {
194 std::vector<SimpleWaypointPtr> next_waypoints = furthest_waypoint->GetNextWaypoint();
195 uint64_t selection_index = 0u;
197 if (next_waypoints.size() > 1) {
199 selection_index =
static_cast<uint64_t
>(r_sample*next_waypoints.size()*0.01);
200 }
else if (next_waypoints.size() == 0) {
202 std::cout <<
"This map has dead-end roads, please change the set_open_street_map parameter to true" << std::endl;
209 if (next_wp_selection->GetId() == waypoint_buffer.front()->GetId()){
221 if (is_at_junction_entrance) {
224 output.
safe_point = safe_space_end_points.second;
235 const bool is_at_junction_entrance,
236 Buffer &waypoint_buffer) {
241 if (is_at_junction_entrance
244 bool entered_junction =
false;
245 bool past_junction =
false;
246 bool safe_point_found =
false;
252 for (
unsigned long i = 0u; i < waypoint_buffer.size() && !safe_point_found; ++i) {
253 current_waypoint = waypoint_buffer.at(i);
254 if (!entered_junction && current_waypoint->CheckJunction()) {
255 entered_junction =
true;
256 junction_begin_point = current_waypoint;
258 if (entered_junction && !past_junction && !current_waypoint->CheckJunction()) {
259 past_junction =
true;
260 junction_end_point = current_waypoint;
262 if (past_junction && junction_end_point->DistanceSquared(current_waypoint) > safe_distance_squared) {
263 safe_point_found =
true;
264 safe_point_after_junction = current_waypoint;
269 if (!safe_point_found) {
272 while (!past_junction && !abort) {
273 NodeList next_waypoints = current_waypoint->GetNextWaypoint();
274 if (!next_waypoints.empty()) {
275 current_waypoint = next_waypoints.front();
277 if (!current_waypoint->CheckJunction()) {
278 past_junction =
true;
279 junction_end_point = current_waypoint;
286 while (!safe_point_found && !abort) {
287 std::vector<SimpleWaypointPtr> next_waypoints = current_waypoint->GetNextWaypoint();
288 if ((junction_end_point->DistanceSquared(current_waypoint) > safe_distance_squared)
289 || next_waypoints.size() > 1
290 || current_waypoint->CheckJunction()) {
292 safe_point_found =
true;
293 safe_point_after_junction = current_waypoint;
295 if (!next_waypoints.empty()) {
296 current_waypoint = next_waypoints.front();
305 if (junction_end_point !=
nullptr &&
306 safe_point_after_junction !=
nullptr &&
309 junction_end_point =
nullptr;
310 safe_point_after_junction =
nullptr;
315 else if (!is_at_junction_entrance
334 const float vehicle_speed,
335 bool force,
bool direction) {
345 if (!waypoint_buffer.empty()) {
355 bool obstacle_too_close =
false;
356 float minimum_squared_distance = std::numeric_limits<float>::infinity();
357 ActorId obstacle_actor_id = 0u;
358 for (
auto i = blocking_vehicles.begin();
359 i != blocking_vehicles.end() && !obstacle_too_close && !force;
361 const ActorId &other_actor_id = *i;
366 const cg::Location other_location = other_current_waypoint->GetLocation();
368 const cg::Vector3D reference_heading = current_waypoint->GetForwardVector();
369 cg::Vector3D reference_to_other = other_location - current_waypoint->GetLocation();
370 const cg::Vector3D other_heading = other_current_waypoint->GetForwardVector();
372 WaypointPtr current_raw_waypoint = current_waypoint->GetWaypoint();
373 WaypointPtr other_current_raw_waypoint = other_current_waypoint->GetWaypoint();
377 if (!current_waypoint->CheckJunction()
378 && !other_current_waypoint->CheckJunction()
379 && other_current_raw_waypoint->GetRoadId() == current_raw_waypoint->GetRoadId()
380 && other_current_raw_waypoint->GetLaneId() == current_raw_waypoint->GetLaneId()
381 && cg::Math::Dot(reference_heading, reference_to_other) > 0.0f
383 float squared_distance = cg::Math::DistanceSquared(vehicle_location, other_location);
388 minimum_squared_distance = squared_distance;
389 obstacle_actor_id = other_actor_id;
392 obstacle_too_close =
true;
399 if (!obstacle_too_close && obstacle_actor_id != 0u && !force) {
402 const auto other_neighbouring_lanes = {other_current_waypoint->GetLeftWaypoint(),
403 other_current_waypoint->GetRightWaypoint()};
406 bool distant_left_lane_free =
false;
407 bool distant_right_lane_free =
false;
410 bool left_right =
true;
411 for (
auto &candidate_lane_wp : other_neighbouring_lanes) {
412 if (candidate_lane_wp !=
nullptr &&
416 distant_left_lane_free =
true;
418 distant_right_lane_free =
true;
420 left_right = !left_right;
425 if (distant_right_lane_free && right_waypoint !=
nullptr
427 change_over_point = right_waypoint;
428 }
else if (distant_left_lane_free && left_waypoint !=
nullptr
430 change_over_point = left_waypoint;
433 if (direction && right_waypoint !=
nullptr) {
434 change_over_point = right_waypoint;
435 }
else if (!direction && left_waypoint !=
nullptr) {
436 change_over_point = left_waypoint;
440 if (change_over_point !=
nullptr) {
443 while (change_over_point->DistanceSquared(starting_point) <
SQUARE(change_over_distance) &&
444 !change_over_point->CheckJunction()) {
445 change_over_point = change_over_point->GetNextWaypoint().front();
450 return change_over_point;
456 auto number_of_pops = waypoint_buffer.size();
457 for (uint64_t j = 0u; j < number_of_pops - 1; ++j) {
469 while (!imported_path.empty() && waypoint_buffer.back()->DistanceSquared(waypoint_buffer.front()) <= horizon_square) {
474 std::vector<SimpleWaypointPtr> next_waypoints = latest_waypoint->GetNextWaypoint();
475 uint64_t selection_index = 0u;
478 if (next_waypoints.size() > 1) {
479 const float imported_road_id = imported->GetWaypoint()->GetRoadId();
480 float min_distance = std::numeric_limits<float>::infinity();
481 for (uint64_t k = 0u; k < next_waypoints.size(); ++k) {
483 while (!junction_end_point->CheckJunction()) {
484 junction_end_point = junction_end_point->GetNextWaypoint().front();
486 while (junction_end_point->CheckJunction()) {
487 junction_end_point = junction_end_point->GetNextWaypoint().front();
489 while (next_waypoints.at(k)->DistanceSquared(junction_end_point) < 50.0f) {
490 junction_end_point = junction_end_point->GetNextWaypoint().front();
492 float jep_road_id = junction_end_point->GetWaypoint()->GetRoadId();
493 if (jep_road_id == imported_road_id) {
497 float distance = junction_end_point->DistanceSquared(imported);
498 if (distance < min_distance) {
499 min_distance = distance;
503 }
else if (next_waypoints.size() == 0) {
505 std::cout <<
"This map has dead-end roads, please change the set_open_street_map parameter to true" << std::endl;
513 if (next_wp_selection->DistanceSquared(imported) < 30.0f) {
514 imported_path.erase(imported_path.begin());
515 std::vector<SimpleWaypointPtr> possible_waypoints = next_wp_selection->GetNextWaypoint();
516 if (std::find(possible_waypoints.begin(), possible_waypoints.end(), imported) != possible_waypoints.end()) {
521 latest_imported = imported_path.front();
522 imported =
local_map->GetWaypoint(latest_imported);
527 if (imported_path.empty()) {
539 auto number_of_pops = waypoint_buffer.size();
540 for (uint64_t j = 0u; j < number_of_pops - 1; ++j) {
548 while (!imported_actions.empty() && waypoint_buffer.back()->DistanceSquared(waypoint_buffer.front()) <= horizon_square) {
551 RoadOption latest_road_option = latest_waypoint->GetRoadOption();
553 std::vector<SimpleWaypointPtr> next_waypoints = latest_waypoint->GetNextWaypoint();
554 uint16_t selection_index = 0u;
555 if (next_waypoints.size() > 1) {
556 for (uint16_t i=0; i<next_waypoints.size(); ++i) {
557 if (next_waypoints.at(i)->GetRoadOption() == next_road_option) {
561 if (i == next_waypoints.size() - 1) {
562 std::cout <<
"We couldn't find the RoadOption you were looking for. This route might diverge from the one expected." << std::endl;
566 }
else if (next_waypoints.size() == 0) {
568 std::cout <<
"This map has dead-end roads, please change the set_open_street_map parameter to true" << std::endl;
578 if (latest_road_option != next_wp_selection->GetRoadOption() && next_road_option == next_wp_selection->GetRoadOption()) {
579 imported_actions.erase(imported_actions.begin());
580 next_road_option =
static_cast<RoadOption>(imported_actions.front());
583 if (imported_actions.empty()) {
593 auto waypoint_buffer =
buffer_map.at(actor_id);
595 bool is_lane_change =
false;
598 is_lane_change =
true;
601 bool left_heading = (heading_vector.
x * relative_vector.
y - heading_vector.
y * relative_vector.
x) > 0.0f;
605 for (
auto &swpt : waypoint_buffer) {
608 if (!is_lane_change) {
610 return std::make_pair(road_opt, swpt->GetWaypoint());
615 auto distance_lane_change = cg::Math::DistanceSquared(actual_location, lane_change);
616 auto distance_other_action = cg::Math::DistanceSquared(actual_location, swpt->GetLocation());
617 if (distance_lane_change < distance_other_action)
return next_action;
618 else return std::make_pair(road_opt, swpt->GetWaypoint());
627 auto waypoint_buffer =
buffer_map.at(actor_id);
630 bool is_lane_change =
false;
632 RoadOption last_road_opt = buffer_front->GetRoadOption();
633 action_buffer.push_back(std::make_pair(last_road_opt, buffer_front->GetWaypoint()));
636 is_lane_change =
true;
639 bool left_heading = (heading_vector.
x * relative_vector.
y - heading_vector.
y * relative_vector.
x) > 0.0f;
643 for (
auto &wpt : waypoint_buffer) {
644 RoadOption current_road_opt = wpt->GetRoadOption();
645 if (current_road_opt != last_road_opt) {
646 action_buffer.push_back(std::make_pair(current_road_opt, wpt->GetWaypoint()));
647 last_road_opt = current_road_opt;
650 if (is_lane_change) {
652 auto distance_lane_change = cg::Math::DistanceSquared(waypoint_buffer.front()->GetLocation(), lane_change.second->GetTransform().location);
653 for (uint16_t i = 0; i < action_buffer.size(); ++i) {
654 auto distance_action = cg::Math::DistanceSquared(waypoint_buffer.front()->GetLocation(), waypoint_buffer.at(i)->GetLocation());
657 if (i == action_buffer.size()-1) {
658 action_buffer.push_back(lane_change);
660 }
else if (distance_action > distance_lane_change) {
661 action_buffer.insert(action_buffer.begin()+i, lane_change);
666 return action_buffer;
#define SQUARE(a)
This file contains various constants used in traffic manager arranged into sensible namespaces for re...
float SquaredLength() const
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
LocalizationStage(const std::vector< ActorId > &vehicle_id_list, BufferMap &buffer_map, const SimulationState &simulation_state, TrackTraffic &track_traffic, const LocalMapPtr &local_map, Parameters ¶meters, std::vector< ActorId > &marked_for_removal, LocalizationFrame &output_array, RandomGenerator &random_device)
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
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::pair< SimpleWaypointPtr, SimpleWaypointPtr > SimpleWaypointPair
LaneChangeSWptMap last_lane_change_swpt
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.
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.
float GetKeepRightPercentage(const ActorId &actor_id)
Method to query percentage probability of keep right rule for a vehicle.
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 MIN_JUNCTION_LENGTH
carla::SharedPtr< cc::Waypoint > WaypointPtr
void PopWaypoint(ActorId actor_id, TrackTraffic &track_traffic, Buffer &buffer, bool front_or_back)
std::vector< SimpleWaypointPtr > NodeList
std::vector< uint8_t > Route
std::vector< cg::Location > Path
std::vector< Action > ActionBuffer
std::deque< std::shared_ptr< SimpleWaypoint > > Buffer
void PushWaypoint(ActorId actor_id, TrackTraffic &track_traffic, Buffer &buffer, SimpleWaypointPtr &waypoint)
std::shared_ptr< InMemoryMap > LocalMapPtr
std::shared_ptr< SimpleWaypoint > SimpleWaypointPtr
std::pair< RoadOption, WaypointPtr > Action
TargetWPInfo GetTargetWaypoint(const Buffer &waypoint_buffer, const float &target_point_distance)
std::vector< LocalizationData > LocalizationFrame
std::unordered_map< carla::ActorId, Buffer > BufferMap
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.
SimpleWaypointPtr safe_point
bool is_at_junction_entrance
SimpleWaypointPtr junction_end_point