7 namespace traffic_manager {
9 using namespace constants::PathBufferUpdate;
10 using namespace constants::LaneChange;
11 using namespace constants::WaypointSelection;
12 using namespace constants::SpeedThreshold;
13 using namespace constants::Collision;
14 using 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() &&
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) {
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
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());
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;
float GetRandomRightLaneChangePercentage(const ActorId &actor_id)
Method to query percentage probability of a random left lane change for a vehicle.
static const float HORIZON_RATE
TargetWPInfo GetTargetWaypoint(const Buffer &waypoint_buffer, const float &target_point_distance)
static const float MAXIMUM_LANE_OBSTACLE_DISTANCE
void PopWaypoint(ActorId actor_id, TrackTraffic &track_traffic, Buffer &buffer, bool front_or_back)
LocalizationFrame & output_array
static const float SAFE_DISTANCE_AFTER_JUNCTION
Action ComputeNextAction(const ActorId &actor_id)
RandomGenerator & random_device
static const float MAXIMUM_LANE_OBSTACLE_CURVATURE
SimpleWaypointPtr safe_point
Route GetImportedRoute(const ActorId &actor_id) const
Method to get a custom route.
std::unordered_map< ActorId, SimpleWaypointPair > vehicles_at_junction_entrance
bool GetUploadRoute(const ActorId &actor_id) const
Method to get if we are uploading a route.
bool is_at_junction_entrance
std::vector< ActorId > & marked_for_removal
static const float MAX_START_DISTANCE
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...
bool GetOSMMode() const
Method to get Open Street Map mode.
float SquaredLength() const
std::vector< cg::Location > Path
static T Clamp(T a, T min=T(0), T max=T(1))
void ExtendAndFindSafeSpace(const ActorId actor_id, const bool is_at_junction_entrance, Buffer &waypoint_buffer)
static const float MIN_LANE_CHANGE_SPEED
void UpdateGridPosition(const ActorId actor_id, const Buffer &buffer)
bool GetAutoLaneChange(const ActorId &actor_id) const
Method to query auto lane change rule for a vehicle.
std::shared_ptr< InMemoryMap > LocalMapPtr
This class holds the state of all the vehicles in the simlation.
This file contains definitions of common data structures used in traffic manager. ...
void PushWaypoint(ActorId actor_id, TrackTraffic &track_traffic, Buffer &buffer, SimpleWaypointPtr &waypoint)
std::deque< std::shared_ptr< SimpleWaypoint > > Buffer
const std::vector< ActorId > & vehicle_id_list
SimpleWaypointPtr AssignLaneChange(const ActorId actor_id, const cg::Location vehicle_location, const float vehicle_speed, bool force, bool direction)
static auto DistanceSquared(const Vector3D &a, const Vector3D &b)
std::unordered_map< carla::ActorId, Buffer > BufferMap
static const float MINIMUM_HORIZON_LENGTH
cg::Location GetLocation(const ActorId actor_id) const
bool GetUploadPath(const ActorId &actor_id) const
Method to get if we are uploading a path.
void UpdateUploadPath(const ActorId &actor_id, const Path path)
Method to update an already set list of points.
static const float MIN_WPT_DISTANCE
TrackTraffic & track_traffic
void ImportPath(Path &imported_path, Buffer &waypoint_buffer, const ActorId actor_id, const float horizon_square)
float GetKeepRightPercentage(const ActorId &actor_id)
Method to query percentage probability of keep right rule for a vehicle.
std::pair< RoadOption, WaypointPtr > Action
void UpdateImportedRoute(const ActorId &actor_id, const Route route)
Method to update an already set route.
static const float HIGHWAY_SPEED
#define SQUARE(a)
This file contains various constants used in traffic manager arranged into sensible namespaces for re...
SimpleWaypointPtr junction_end_point
carla::SharedPtr< cc::Waypoint > WaypointPtr
ActorIdSet GetOverlappingVehicles(ActorId actor_id) const
std::vector< uint8_t > Route
std::vector< SimpleWaypointPtr > NodeList
static const float MAX_WPT_DISTANCE
void RemoveActor(const ActorId actor_id) override
const LocalMapPtr & local_map
static const float MINIMUM_LANE_CHANGE_DISTANCE
void Update(const unsigned long index) override
cg::Vector3D GetHeading(const ActorId actor_id) const
LaneChangeSWptMap last_lane_change_swpt
const SimulationState & simulation_state
static auto Dot(const Vector3D &a, const Vector3D &b)
std::vector< LocalizationData > LocalizationFrame
std::shared_ptr< SimpleWaypoint > SimpleWaypointPtr
void ImportRoute(Route &imported_actions, Buffer &waypoint_buffer, const ActorId actor_id, const float horizon_square)
static const float FIFTYPERC
void RemoveImportedRoute(const ActorId &actor_id, const bool remove_path)
Method to remove a route.
std::pair< SimpleWaypointPtr, SimpleWaypointPtr > SimpleWaypointPair
void RemoveUploadPath(const ActorId &actor_id, const bool remove_path)
Method to remove a list of points.
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)
std::vector< Action > ActionBuffer
ActorIdSet vehicles_at_junction
float GetRandomLeftLaneChangePercentage(const ActorId &actor_id)
Method to query percentage probability of a random right lane change for a vehicle.
static const float MIN_JUNCTION_LENGTH
ActorIdSet GetPassingVehicles(uint64_t waypoint_id) const
cg::Vector3D GetVelocity(const ActorId actor_id) const
ActionBuffer ComputeActionBuffer(const ActorId &actor_id)
ChangeLaneInfo GetForceLaneChange(const ActorId &actor_id)
Method to query lane change command for a vehicle.
static const float HIGH_SPEED_HORIZON_RATE
static const float JUNCTION_LOOK_AHEAD
static const float INTER_LANE_CHANGE_DISTANCE
Path GetCustomPath(const ActorId &actor_id) const
Method to get a custom path.