Carma-platform v4.2.0
CARMA Platform is built on robot operating system (ROS) and utilizes open source software (OSS) that enables Cooperative Driving Automation (CDA) features to allow Automated Driving Systems to interact and cooperate with infrastructure and other vehicles through communication.
platoon_strategic_ihp::PlatoonManager Class Reference

Class containing the logic for platoon manager. It is responsible for keeping track of the platoon members and role of the host vehicle in the platoon. More...

#include <platoon_manager_ihp.h>

Collaboration diagram for platoon_strategic_ihp::PlatoonManager:
Collaboration graph

Public Member Functions

 PlatoonManager (std::shared_ptr< carma_ros2_utils::timers::TimerFactory > timer_factory)
 Constructor. More...
 
void updateHostPose (const double downtrack, const double crosstrack)
 Stores the latest info on location of the host vehicle. More...
 
void updateHostSpeeds (const double cmdSpeed, const double actualSpeed)
 Stores the latest info on host vehicle's command & actual speeds. More...
 
void hostMemberUpdates (const std::string &senderId, const std::string &platoonId, const std::string &params, const double &DtD, const double &CtD)
 Update information for members of the host's platoon based on a mobility operation STATUS message. More...
 
void neighborMemberUpdates (const std::string &senderId, const std::string &platoonId, const std::string &params, const double &DtD, const double &CtD)
 Update information for members of a neighboring platoon based on a mobility operation STATUS message. More...
 
void updatesOrAddMemberInfo (std::vector< PlatoonMember > &platoon, std::string senderId, double cmdSpeed, double dtDistance, double ctDistance, double curSpeed)
 Updates the list of vehicles in the specified platoon, based on info available from a mobility operation STATUS message from one of that platoon's vehicles. It ensures the list of vehicles is properly sorted in order of appearance from front to rear in the platoon. If the host is in the platoon, it will update host info as well. More...
 
int getHostPlatoonSize ()
 Returns total size of the platoon , in number of vehicles. More...
 
void clearActionPlan ()
 Resets necessary variables to indicate that the current ActionPlan is dead. More...
 
void resetHostPlatoon ()
 Resets all variables that might indicate other members of the host's platoon; sets the host back to solo vehicle. More...
 
void resetNeighborPlatoon ()
 Resets all variables that describe a neighbor platoon, so that no neighbor is known. More...
 
bool removeMember (const size_t mem)
 Removes a single member from the internal record of platoon members. More...
 
bool removeMemberById (const std::string id)
 Removes a single member from the internal record of platoon members. More...
 
PlatoonMember getDynamicLeader ()
 Returns dynamic leader of the host vehicle. More...
 
int allPredecessorFollowing ()
 This is the implementation of all predecessor following (APF) algorithm for leader selection in a platoon. This function will recognize who is acting as the current leader of the subject vehicle. The current leader of the subject vehicle will be any ONE of the vehicles in front of it. Having a vehicle further downstream function as the leader is more efficient and more stable; however, having a vehicle closer to the subject vehicle function as the leader is safer. For this reason, the subject vehicle will monitor all time headways between every single set of consecutive vehicles starting from itself to the leader. If the time headways are within some safe thresholds then vehicles further downstream may function as the leader. Otherwise, for the sake of safety, vehicles closer to the subject vehicle, potentially even the predecessor, will function as the leader. More...
 
void changeFromFollowerToLeader ()
 Update status when state change from Follower to Leader. More...
 
void changeFromLeaderToFollower (std::string newPlatoonId, std::string newLeaderId)
 Update status when state change from Leader to Follower. More...
 
int getNumberOfVehicleInFront ()
 Get number of vehicles in front of host vehicle inside platoon. More...
 
double getCurrentPlatoonLength ()
 Returns overall length of the platoon. in m. More...
 
double getPlatoonRearDowntrackDistance ()
 Returns downtrack distance of the rear vehicle in platoon, in m. More...
 
double getDistanceToPredVehicle ()
 Returns distance to the predessecor vehicle, in m. More...
 
double getCurrentSpeed () const
 Returns current speed, in m/s. More...
 
double getCommandSpeed () const
 Returns command speed. in m/s. More...
 
double getCurrentDowntrackDistance () const
 Returns current downtrack distance, in m. More...
 
double getCurrentCrosstrackDistance () const
 Returns current crosstrack distance, in m. More...
 
std::string getHostStaticID () const
 Returns current host static ID as a string. More...
 
double getPlatoonFrontDowntrackDistance ()
 UCLA: Return the platoon leader downtrack distance, in m. More...
 
double getPredecessorTimeHeadwaySum ()
 UCLA: Return the time headway summation of all predecessors, in s. More...
 
double getPredecessorSpeed ()
 UCLA: Return the speed of the preceding vehicle, in m/s. More...
 
double getPredecessorPosition ()
 UCLA: Return the position of the preceding vehicle, in m. More...
 
double getIHPDesPosFollower (double dt)
 UCLA: Return follower's desired position (i.e., downtrack, in m) that maintains the desired intra-platoon time gap, based on IHP platoon trajectory regulation algorithm. More...
 
int getClosestIndex (double joinerDtD)
 UCLA: Return joiner's desired position in terms of target platoon index to cut into the platoon. CAUTION: ASSUMES that the neighbor platoon info is fully populated! More...
 
double getCutInGap (const int gap_leading_index, const double joinerDtD)
 UCLA: Return the current actual gap size in the target platoon for cut-in join, in m. Note: The origin of the vehicle (for downtrack distance calculation) is located at the rear axle. CAUTION: ASSUMES that the neighbor platoon info is fully populated! More...
 

Public Attributes

const std::string dummyID = "00000000-0000-0000-0000-000000000000"
 
std::vector< PlatoonMemberhost_platoon_
 
std::string currentPlatoonID = dummyID
 
std::string platoonLeaderID = dummyID
 
PlatoonState current_platoon_state = PlatoonState::STANDBY
 
size_t hostPosInPlatoon_ = 0
 
ActionPlan current_plan = ActionPlan()
 
bool isFollower = false
 
std::vector< PlatoonMemberneighbor_platoon_
 
size_t neighbor_platoon_info_size_ = 0
 
std::string targetPlatoonID = dummyID
 
std::string neighborPlatoonID = dummyID
 
std::string neighbor_platoon_leader_id_ = dummyID
 
bool is_neighbor_record_complete_ = false
 
geometry_msgs::msg::PoseStamped pose_msg_
 
std::string HostMobilityId = "default_host_id"
 
bool isCreateGap = false
 
size_t dynamic_leader_index_ = 0
 
std::shared_ptr< carma_ros2_utils::timers::TimerFactory > timer_factory_
 

Private Member Functions

bool insufficientGapWithPredecessor (double distanceToPredVehicle)
 Check the gap with the predecessor vehicle. More...
 
std::vector< double > calculateTimeHeadway (std::vector< double > downtrackDistance, std::vector< double > speed) const
 Calculate the time headaway of each platoon member and save as a vector. More...
 
int determineDynamicLeaderBasedOnViolation (std::vector< double > timeHeadways)
 Determine the proper vehicle to follow based the time headway of each member. Note that the host will always choose the closest violator (i.e. time headaway too small or too large) to follow. More...
 
int findLowerBoundaryViolationClosestToTheHostVehicle (std::vector< double > timeHeadways) const
 Find the closest vehicle to the host vehicle that violates the (time headaway) lower boundary condition. More...
 
int findMaximumSpacingViolationClosestToTheHostVehicle (std::vector< double > timeHeadways) const
 Find the closest vehicle to the host vehicle that violates the (time headaway) maximum spacing condition. More...
 
std::vector< double > getTimeHeadwayFromIndex (std::vector< double > timeHeadways, int start) const
 Return a sub-vector of the platoon-wise time headaways vector that start with a given index.
More...
 

Private Attributes

PlatoonPluginConfig config_
 
std::string OPERATION_INFO_TYPE = "INFO"
 
std::string OPERATION_STATUS_TYPE = "STATUS"
 
std::string JOIN_AT_REAR_PARAMS = "SIZE:%1%,SPEED:%2%,DTD:%3%"
 
std::string JOIN_FROM_FRONT_PARAMS = "SIZE:%1%,SPEED:%2%,DTD:%3%"
 
std::string MOBILITY_STRATEGY = "Carma/Platooning"
 
double minCutinGap_ = 22.0
 
double maxCutinGap_ = 32.0
 
std::string previousFunctionalDynamicLeaderID_ = ""
 
int previousFunctionalDynamicLeaderIndex_ = -1
 
double vehicleLength_ = 5.0
 
double gapWithPred_ = 0.0
 
double downtrack_progress_ = 0
 
std::string algorithmType_ = "APF_ALGORITHM"
 

Detailed Description

Class containing the logic for platoon manager. It is responsible for keeping track of the platoon members and role of the host vehicle in the platoon.

Definition at line 120 of file platoon_manager_ihp.h.

Constructor & Destructor Documentation

◆ PlatoonManager()

platoon_strategic_ihp::PlatoonManager::PlatoonManager ( std::shared_ptr< carma_ros2_utils::timers::TimerFactory >  timer_factory)

Constructor.

Parameters
timer_factoryAn interface which can be used to get access to the current time

Implementation notes:

  1. platoon vector indexing: A vector of platoon members (vehicles), sorted by downtrack distance in descending order (i.e., [dtd_1 > dtd_2 > ... > dtd_n] ).
  2. speed vector indexing: A vector that only contains speed (m/s) of each platoon member. Same order with platoon list (i.e., [platoon_front, follwer_1, ..., follower_n]).
  3. downtrackDistance vector indexing: A vector that only contains downtrack distance (m) of each platoon member. Same order with platoon list (i.e., [platoon_front, follwer_1, ..., follower_n])
  4. timeHeadway vector indexing A vector that only contains time headaway (s) behind each platoon member (i.e., the time gap between host vehicle and its following vehicle). Same order with platoon list. For APF, when gap too small, the dynamic leader will be the front vehicle of the small gap. If gap too large, the dynamic leader wil be the rear vehicle of the large gap.

Definition at line 51 of file platoon_manager_ihp.cpp.

51 : timer_factory_(std::move(timer_factory))
52 {
53 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("platoon_strategic_ihp"), "Top of PlatoonManager ctor.");
54 }
std::shared_ptr< carma_ros2_utils::timers::TimerFactory > timer_factory_

Member Function Documentation

◆ allPredecessorFollowing()

int platoon_strategic_ihp::PlatoonManager::allPredecessorFollowing ( )

This is the implementation of all predecessor following (APF) algorithm for leader selection in a platoon. This function will recognize who is acting as the current leader of the subject vehicle. The current leader of the subject vehicle will be any ONE of the vehicles in front of it. Having a vehicle further downstream function as the leader is more efficient and more stable; however, having a vehicle closer to the subject vehicle function as the leader is safer. For this reason, the subject vehicle will monitor all time headways between every single set of consecutive vehicles starting from itself to the leader. If the time headways are within some safe thresholds then vehicles further downstream may function as the leader. Otherwise, for the sake of safety, vehicles closer to the subject vehicle, potentially even the predecessor, will function as the leader.

Returns
the index of the leader in the platoon list.

‍***** Case Zero *****‍///

‍***** Case One *****‍///

‍***** Case Two *****‍///

‍***** Case Three *****‍///

‍***** Case Four *****‍///

‍***** Case Five *****‍///

‍***** Case Six *****‍///

‍***** Case Seven *****‍///

‍***** Case Eight *****‍///

‍***** Case Nine *****‍///

Definition at line 428 of file platoon_manager_ihp.cpp.

428 {
429
431 // If the host vehicle is the second follower of a platoon, it will always follow the platoon leader in the front
433 {
434 // If the host is the second vehicle, then follow the leader.
435 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("platoon_strategic_ihp"), "As the second vehicle in the platoon, it will always follow the leader. Case Zero");
436 return 0;
437 }
439 // If there weren't a leader in the previous time step, follow the first vehicle (i.e., the platoon leader) as default.
441 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("platoon_strategic_ihp"), "APF algorithm did not found a dynamic leader in previous time step. Case one");
442 return 0;
443 }
444
445 //***** Formulate speed and downtrack vector *****//
446 // Update host vehicle info when update member info, so platoon list include host vehicle, direct use platoon size for downtrack/speed vector.
447 // Record downtrack distance (m) of each member
448 std::vector<double> downtrackDistance(hostPosInPlatoon_);
449 for(size_t i = 0; i < hostPosInPlatoon_; i++) {
450 downtrackDistance[i] = host_platoon_[i].vehiclePosition; // m
451 }
452 // Record speed (m/s) of each member
453 std::vector<double> speed(host_platoon_.size());
454 for(size_t i = 0; i < host_platoon_.size(); i++) {
455 speed[i] = host_platoon_[i].vehicleSpeed; // m/s
456 }
457
458
460 // If the distance headway between the subject vehicle and its predecessor is an issue
461 // according to the "min_gap" and "max_gap" thresholds, then it should follow its predecessor
462 // The following line will not throw exception because the length of downtrack array is larger than two in this case
463 double distHeadwayWithPredecessor = downtrackDistance[hostPosInPlatoon_ - 1] - downtrackDistance[hostPosInPlatoon_];
464 gapWithPred_ = distHeadwayWithPredecessor;
465 if(insufficientGapWithPredecessor(distHeadwayWithPredecessor)) {
466 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("platoon_strategic_ihp"), "APF algorithm decides there is an issue with the gap with preceding vehicle: " << distHeadwayWithPredecessor << " m. Case Two");
467 return hostPosInPlatoon_ - 1;
468 }
469 else{
470 // implementation of the main part of APF algorithm
471 // calculate the time headway between every consecutive pair of vehicles
472 std::vector<double> timeHeadways = calculateTimeHeadway(downtrackDistance, speed);
473 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("platoon_strategic_ihp"), "APF calculate time headways: " );
474 for (const auto& value : timeHeadways)
475 {
476 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("platoon_strategic_ihp"), "APF time headways: " << value);
477 }
478 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("platoon_strategic_ihp"), "APF found the previous dynamic leader is " << previousFunctionalDynamicLeaderID_);
479 // if the previous dynamic leader is the first vehicle in the platoon
480
482
484 // If there is a violation, the return value is the desired dynamic leader index
485 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("platoon_strategic_ihp"), "APF use violations on lower boundary or maximum spacing to choose dynamic leader. Case Three.");
486 return determineDynamicLeaderBasedOnViolation(timeHeadways);
487 }
488 else{
489 // if the previous dynamic leader is not the first vehicle
490 // get the time headway between every consecutive pair of vehicles from index Of Previous dynamic Leader
491 std::vector<double> partialTimeHeadways = getTimeHeadwayFromIndex(timeHeadways, previousFunctionalDynamicLeaderIndex_);
492 for (const auto& value : partialTimeHeadways)
493 {
494 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("platoon_strategic_ihp"), "APF partial time headways: " << value);
495 }
496 int closestLowerBoundaryViolation = findLowerBoundaryViolationClosestToTheHostVehicle(partialTimeHeadways);
497 int closestMaximumSpacingViolation = findMaximumSpacingViolationClosestToTheHostVehicle(partialTimeHeadways);
498 // if there are no violations anywhere between the subject vehicle and the current dynamic leader,
499 // then depending on the time headways of the ENTIRE platoon, the subject vehicle may switch
500 // dynamic leader further downstream. This is because the subject vehicle has determined that there are
501 // no time headways between itself and the current dynamic leader which would cause the platoon to be unsafe.
502 // if there are violations somewhere betweent the subject vehicle and the current dynamic leader,
503 // then rather than assigning dynamic leadership further DOWNSTREAM, we must go further UPSTREAM in the following lines
504 if(closestLowerBoundaryViolation == -1 && closestMaximumSpacingViolation == -1) {
505 // In order for the subject vehicle to assign dynamic leadership further downstream,
506 // two criteria must be satisfied: first the leading vehicle and its immediate follower must
507 // have a time headway greater than "upper_boundary." The purpose of this criteria is to
508 // introduce a hysteresis in order to eliminate the possibility of a vehicle continually switching back
509 // and forth between two dynamic leaders because one of the time headways is hovering right around
510 // the "lower_boundary" threshold; second the leading vehicle and its predecessor must have
511 // a time headway less than "min_spacing" second. Just as with "upper_boundary", "min_spacing" exists to
512 // introduce a hysteresis where dynamic leaders are continually being switched.
514 bool condition2 = timeHeadways[previousFunctionalDynamicLeaderIndex_ - 1] < config_.headawayStableUpperBond;
515
517 //we may switch dynamic leader further downstream
518 if(condition1 && condition2) {
519 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("platoon_strategic_ihp"), "APF found two conditions for assigning local dynamic leadership further downstream are satisfied. Case Four");
520 return determineDynamicLeaderBasedOnViolation(timeHeadways);
521 } else {
522
524 // We may not switch dynamic leadership to another vehicle further downstream because some criteria are not satisfied
525 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("platoon_strategic_ihp"), "APF found two conditions for assigning local dynamic leadership further downstream are not satisfied. Case Five.");
526 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("platoon_strategic_ihp"), "condition1: " << condition1 << " & condition2: " << condition2);
528 }
529 } else if(closestLowerBoundaryViolation != -1 && closestMaximumSpacingViolation == -1) {
530 // The rest four cases have roughly the same logic: locate the closest violation and assign dynamic leadership accordingly
531
533 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("platoon_strategic_ihp"), "APF found closestLowerBoundaryViolation on partial time headways. Case Six.");
534 return previousFunctionalDynamicLeaderIndex_ - 1 + closestLowerBoundaryViolation;
535
536 } else if(closestLowerBoundaryViolation == -1 && closestMaximumSpacingViolation != -1) {
537
539 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("platoon_strategic_ihp"), "APF found closestMaximumSpacingViolation on partial time headways. Case Seven.");
540 return previousFunctionalDynamicLeaderIndex_ + closestMaximumSpacingViolation;
541 } else{
542 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("platoon_strategic_ihp"), "APF found closestMaximumSpacingViolation and closestLowerBoundaryViolation on partial time headways.");
543 if(closestLowerBoundaryViolation > closestMaximumSpacingViolation) {
544
546 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("platoon_strategic_ihp"), "closest LowerBoundaryViolation is higher than closestMaximumSpacingViolation on partial time headways. Case Eight.");
547 return previousFunctionalDynamicLeaderIndex_ - 1 + closestLowerBoundaryViolation;
548 } else if(closestLowerBoundaryViolation < closestMaximumSpacingViolation) {
549
551 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("platoon_strategic_ihp"), "closestMaximumSpacingViolation is higher than closestLowerBoundaryViolation on partial time headways. Case Nine.");
552 return previousFunctionalDynamicLeaderIndex_ + closestMaximumSpacingViolation;
553 } else {
554 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("platoon_strategic_ihp"), "APF dynamic Leader selection parameter is wrong!");
555 return 0;
556 }
557 }
558 }
559
560 }
561 }
int findMaximumSpacingViolationClosestToTheHostVehicle(std::vector< double > timeHeadways) const
Find the closest vehicle to the host vehicle that violates the (time headaway) maximum spacing condit...
int getNumberOfVehicleInFront()
Get number of vehicles in front of host vehicle inside platoon.
int determineDynamicLeaderBasedOnViolation(std::vector< double > timeHeadways)
Determine the proper vehicle to follow based the time headway of each member. Note that the host will...
bool insufficientGapWithPredecessor(double distanceToPredVehicle)
Check the gap with the predecessor vehicle.
std::vector< PlatoonMember > host_platoon_
std::vector< double > getTimeHeadwayFromIndex(std::vector< double > timeHeadways, int start) const
Return a sub-vector of the platoon-wise time headaways vector that start with a given index.
int findLowerBoundaryViolationClosestToTheHostVehicle(std::vector< double > timeHeadways) const
Find the closest vehicle to the host vehicle that violates the (time headaway) lower boundary conditi...
std::vector< double > calculateTimeHeadway(std::vector< double > downtrackDistance, std::vector< double > speed) const
Calculate the time headaway of each platoon member and save as a vector.

References calculateTimeHeadway(), config_, determineDynamicLeaderBasedOnViolation(), findLowerBoundaryViolationClosestToTheHostVehicle(), findMaximumSpacingViolationClosestToTheHostVehicle(), gapWithPred_, getNumberOfVehicleInFront(), getTimeHeadwayFromIndex(), platoon_strategic_ihp::PlatoonPluginConfig::headawayStableLowerBond, platoon_strategic_ihp::PlatoonPluginConfig::headawayStableUpperBond, host_platoon_, hostPosInPlatoon_, process_bag::i, insufficientGapWithPredecessor(), previousFunctionalDynamicLeaderID_, and previousFunctionalDynamicLeaderIndex_.

Referenced by getDynamicLeader().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ calculateTimeHeadway()

std::vector< double > platoon_strategic_ihp::PlatoonManager::calculateTimeHeadway ( std::vector< double >  downtrackDistance,
std::vector< double >  speed 
) const
private

Calculate the time headaway of each platoon member and save as a vector.

Parameters
downtrackDistancea vector containing the downtrack distances of all members.
speeda vector containing the speeds of all members.
Returns
A vector containing the time headaway of all platoon members, each headway is in s.

Definition at line 585 of file platoon_manager_ihp.cpp.

585 {
586 std::vector<double> timeHeadways(downtrackDistance.size() - 1);
587 // Due to downtrack descending order, the platoon member with smaller index has larger downtrack, hence closer to the front of the platoon.
588 for (size_t i = 0; i < timeHeadways.size(); i++){
589 // Calculate time headaway between the vehicle behind.
590 if (speed[i+1] >= config_.ss_theta) // speed is in m/s
591 {
592 timeHeadways[i] = (downtrackDistance[i] - downtrackDistance[i+1]) / speed[i+1]; // downtrack is in m, speed is in m/s.
593 }
594 // If no one behind or following car stoped, return infinity.
595 else
596 {
597 timeHeadways[i] = std::numeric_limits<double>::infinity();
598 }
599 }
600 return timeHeadways; // time is in s.
601 }
double ss_theta
Parameter sets for IHP platoon trajectory regulation algorithm. Please refer to the updated design do...

References config_, process_bag::i, and platoon_strategic_ihp::PlatoonPluginConfig::ss_theta.

Referenced by allPredecessorFollowing().

Here is the caller graph for this function:

◆ changeFromFollowerToLeader()

void platoon_strategic_ihp::PlatoonManager::changeFromFollowerToLeader ( )

Update status when state change from Follower to Leader.

Definition at line 672 of file platoon_manager_ihp.cpp.

672 {
673
674 // Get current host info - assumes departing leader or front of platoon hasn't already been removed from the vector
675 PlatoonMember hostInfo = host_platoon_[hostPosInPlatoon_];
676
677 // Clear the front part of the platoon info, since we are splitting off from it; leaves host as element 0
678 if (hostPosInPlatoon_ > 0)
679 {
681 }else
682 {
683 RCLCPP_WARN(rclcpp::get_logger("platoon_strategic_ihp"), "### Host becoming leader, but is already at index 0 in host_platoon_ vector! Vector unchanged.");
684 }
685
687 isFollower = false;
688 currentPlatoonID = boost::uuids::to_string(boost::uuids::random_generator()());
691 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("platoon_strategic_ihp"), "The platoon manager is changed from follower state to leader state. New platoon ID = " << currentPlatoonID);
692 }
auto to_string(const UtmZone &zone) -> std::string
Definition: utm_zone.cpp:21

References currentPlatoonID, host_platoon_, hostPosInPlatoon_, isFollower, previousFunctionalDynamicLeaderID_, previousFunctionalDynamicLeaderIndex_, and carma_cooperative_perception::to_string().

Referenced by platoon_strategic_ihp::PlatoonStrategicIHPPlugin::run_follower().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ changeFromLeaderToFollower()

void platoon_strategic_ihp::PlatoonManager::changeFromLeaderToFollower ( std::string  newPlatoonId,
std::string  newLeaderId 
)

Update status when state change from Leader to Follower.

Parameters
newPlatoonIdnew ID of the platoon
newLeaderIdID of the new lead vehicle

Definition at line 699 of file platoon_manager_ihp.cpp.

699 {
700
701 // Save the current host info
702 PlatoonMember hostInfo = host_platoon_[hostPosInPlatoon_];
703
704 // Clear contents of the platoon vector and rebuild it with the two known members at this time, leader & host.
705 // Remaining leader info and info about any other members will get populated as messages come in.
706 PlatoonMember newLeader = PlatoonMember();
707 newLeader.staticId = newLeaderId;
708 host_platoon_.clear();
709 host_platoon_.push_back(newLeader); //can get location info updated later with a STATUS or INFO message
710 host_platoon_.push_back(hostInfo);
711
712 hostPosInPlatoon_ = 1; //since host was previously leader it is now guaranteed to be 2nd in the line (index 1)
713 isFollower = true;
714 currentPlatoonID = newPlatoonId;
715
716 // Clear the record of neighbor platoon, since we likely just joined it
718
719 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("platoon_strategic_ihp"), "The platoon manager is changed from leader state to follower state. Platoon vector re-initialized. Plan ID = " << newPlatoonId);
720 }
void resetNeighborPlatoon()
Resets all variables that describe a neighbor platoon, so that no neighbor is known.

References currentPlatoonID, host_platoon_, hostPosInPlatoon_, isFollower, resetNeighborPlatoon(), and platoon_strategic_ihp::PlatoonMember::staticId.

Referenced by platoon_strategic_ihp::PlatoonStrategicIHPPlugin::mob_resp_cb_candidatefollower(), and platoon_strategic_ihp::PlatoonStrategicIHPPlugin::mob_resp_cb_leaderaborting().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ clearActionPlan()

void platoon_strategic_ihp::PlatoonManager::clearActionPlan ( )

Resets necessary variables to indicate that the current ActionPlan is dead.

Definition at line 285 of file platoon_manager_ihp.cpp.

References current_plan, dummyID, platoon_strategic_ihp::ActionPlan::peerId, platoon_strategic_ihp::ActionPlan::planId, targetPlatoonID, and platoon_strategic_ihp::ActionPlan::valid.

Referenced by platoon_strategic_ihp::PlatoonStrategicIHPPlugin::mob_req_cb_candidateleader(), platoon_strategic_ihp::PlatoonStrategicIHPPlugin::mob_req_cb_leaderwaiting(), platoon_strategic_ihp::PlatoonStrategicIHPPlugin::mob_resp_cb_candidatefollower(), platoon_strategic_ihp::PlatoonStrategicIHPPlugin::mob_resp_cb_leader(), platoon_strategic_ihp::PlatoonStrategicIHPPlugin::mob_resp_cb_leaderaborting(), platoon_strategic_ihp::PlatoonStrategicIHPPlugin::run_candidate_follower(), platoon_strategic_ihp::PlatoonStrategicIHPPlugin::run_candidate_leader(), platoon_strategic_ihp::PlatoonStrategicIHPPlugin::run_leader(), platoon_strategic_ihp::PlatoonStrategicIHPPlugin::run_leader_aborting(), platoon_strategic_ihp::PlatoonStrategicIHPPlugin::run_leader_waiting(), and platoon_strategic_ihp::PlatoonStrategicIHPPlugin::run_prepare_to_join().

Here is the caller graph for this function:

◆ determineDynamicLeaderBasedOnViolation()

int platoon_strategic_ihp::PlatoonManager::determineDynamicLeaderBasedOnViolation ( std::vector< double >  timeHeadways)
private

Determine the proper vehicle to follow based the time headway of each member. Note that the host will always choose the closest violator (i.e. time headaway too small or too large) to follow.

Parameters
timeHeadwaysA vector containing the time headaway of all platoon members.
Returns
An index indicating the proper vehicle to follow (i.e., leader). If choose to follow platoon leader, return 0.

Note: For both condition, the host will always choose to follow the vechile that has a relatively larger gap in front.

max-vilation (follow veh2): [veh3] -------— [veh2] ----------------------------— [veh1] -------— [veh0] ^ gap2 gap1(max violation) gap0

min-vilation (follow veh1): [veh3] --------—[veh2]—[veh1] -------— [veh0] ^ gap2 gap1 gap0 (min violation)

Definition at line 604 of file platoon_manager_ihp.cpp.

604 {
605
619 // Find the closest violations.
620 int closestLowerBoundaryViolation = findLowerBoundaryViolationClosestToTheHostVehicle(timeHeadways);
621 int closestMaximumSpacingViolation = findMaximumSpacingViolationClosestToTheHostVehicle(timeHeadways);
622
623 // Compare the violation locations, always following the closer violation vehicle (larger index) first, then the furthur ones.
624 if(closestLowerBoundaryViolation > closestMaximumSpacingViolation) {
625 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("platoon_strategic_ihp"), "APF found violation on closestLowerBoundaryViolation at " << closestLowerBoundaryViolation);
626 return closestLowerBoundaryViolation; // Min violation, following the vehicle that is in font of the violating gap.
627 }
628 else if(closestLowerBoundaryViolation < closestMaximumSpacingViolation){
629 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("platoon_strategic_ihp"), "APF found violation on closestMaximumSpacingViolation at " << closestMaximumSpacingViolation);
630 return closestMaximumSpacingViolation + 1; // Max violation, follow the vehicle that is behinf the violating gap.
631 }
632 else{
633 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("platoon_strategic_ihp"), "APF found no violations on both closestLowerBoundaryViolation and closestMaximumSpacingViolation");
634 return 0;
635 }
636 }

References findLowerBoundaryViolationClosestToTheHostVehicle(), and findMaximumSpacingViolationClosestToTheHostVehicle().

Referenced by allPredecessorFollowing().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ findLowerBoundaryViolationClosestToTheHostVehicle()

int platoon_strategic_ihp::PlatoonManager::findLowerBoundaryViolationClosestToTheHostVehicle ( std::vector< double >  timeHeadways) const
private

Find the closest vehicle to the host vehicle that violates the (time headaway) lower boundary condition.

Parameters
timeHeadwaysA vector containing the time headaway of all platoon members.
Returns
An index indicating the closest violating vehicle. If no violator, return -1.

Definition at line 639 of file platoon_manager_ihp.cpp.

639 {
640 // Due to descending downtrack order, the search starts from the platoon rear, which corresponds to last in list.
641 for(int i = timeHeadways.size()-1; i >= 0; i--) {
642 if(timeHeadways[i] < config_.minAllowableHeadaway) // in s
643 {
644 return i;
645 }
646 }
647 return -1;
648 }

References config_, process_bag::i, and platoon_strategic_ihp::PlatoonPluginConfig::minAllowableHeadaway.

Referenced by allPredecessorFollowing(), and determineDynamicLeaderBasedOnViolation().

Here is the caller graph for this function:

◆ findMaximumSpacingViolationClosestToTheHostVehicle()

int platoon_strategic_ihp::PlatoonManager::findMaximumSpacingViolationClosestToTheHostVehicle ( std::vector< double >  timeHeadways) const
private

Find the closest vehicle to the host vehicle that violates the (time headaway) maximum spacing condition.

Parameters
timeHeadwaysA vector containing the time headaway of all platoon members.
Returns
An index indicating the closest violating vehicle. If no violator, return -1.

Definition at line 651 of file platoon_manager_ihp.cpp.

651 {
652 // UCLA: Add maxAllowableHeadaway adjuster to increase the threshold during gap creating period.
653 double maxAllowableHeadaway_adjusted = config_.maxAllowableHeadaway;
654 if (isCreateGap) {
655 // adjust maximum allowed headway to allow for a bigger gap
656 maxAllowableHeadaway_adjusted = maxAllowableHeadaway_adjusted*(1 + config_.createGapAdjuster);
657 }
658
659 // Due to descending downtrack order, the search starts from the platoon rear, which corresponds to last in list.
660 for(int i = timeHeadways.size()-1; i >= 0 ; i--) {
661 if(timeHeadways[i] > maxAllowableHeadaway_adjusted) // in s
662 {
663 return i;
664 }
665 }
666 return -1;
667 }

References config_, platoon_strategic_ihp::PlatoonPluginConfig::createGapAdjuster, process_bag::i, isCreateGap, and platoon_strategic_ihp::PlatoonPluginConfig::maxAllowableHeadaway.

Referenced by allPredecessorFollowing(), and determineDynamicLeaderBasedOnViolation().

Here is the caller graph for this function:

◆ getClosestIndex()

int platoon_strategic_ihp::PlatoonManager::getClosestIndex ( double  joinerDtD)

UCLA: Return joiner's desired position in terms of target platoon index to cut into the platoon. CAUTION: ASSUMES that the neighbor platoon info is fully populated!

Parameters
joinerDtDThe current downtrack distance (with regards to host vehicle) of the joiner vehicle.
Returns
: cut-in index: The index of the gap-leading vehicle within the platoon. If front join, return -1.

Definition at line 911 of file platoon_manager_ihp.cpp.

912 {
913 /*
914 A naive way to find the closest member that is in front of the host that point to the gap to join the platoon.
915 Note: The potential gap leading vehicle should be in front of the joiner (i.e., gap leading vehicle's dtd > joiner's dtd).
916 If the joiner is already in front of the platoon leader, this function will return -1 (i.e., cut-in front).
917 */
918
919 double min_diff = 99999.0;
920 int cut_in_index = -1; //-2 is meaningless default
921
922 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("platoon_strategic_ihp"), "neighbor_platoon_.size(): " << neighbor_platoon_.size());
923
924 // Loop through all target platoon members
925 for(size_t i = 0; i < neighbor_platoon_.size(); i++)
926 {
927 double current_member_dtd = neighbor_platoon_[i].vehiclePosition;
928 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("platoon_strategic_ihp"), "current_member_dtd: "<< current_member_dtd);
929 double curent_dtd_diff = current_member_dtd - joinerDtD;
930 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("platoon_strategic_ihp"), "curent_dtd_diff: "<< curent_dtd_diff);
931 // update min index
932 if (curent_dtd_diff > 0 && curent_dtd_diff < min_diff)
933 {
934 min_diff = current_member_dtd;
935 cut_in_index = i;
936 }
937 }
938
939 return cut_in_index;
940 }
std::vector< PlatoonMember > neighbor_platoon_

References process_bag::i, and neighbor_platoon_.

Referenced by platoon_strategic_ihp::PlatoonStrategicIHPPlugin::run_prepare_to_join().

Here is the caller graph for this function:

◆ getCommandSpeed()

double platoon_strategic_ihp::PlatoonManager::getCommandSpeed ( ) const

Returns command speed. in m/s.

Definition at line 738 of file platoon_manager_ihp.cpp.

739 {
740 return host_platoon_[hostPosInPlatoon_].commandSpeed;
741 }

References host_platoon_, and hostPosInPlatoon_.

Referenced by hostMemberUpdates().

Here is the caller graph for this function:

◆ getCurrentCrosstrackDistance()

double platoon_strategic_ihp::PlatoonManager::getCurrentCrosstrackDistance ( ) const

Returns current crosstrack distance, in m.

Definition at line 750 of file platoon_manager_ihp.cpp.

751 {
752 return host_platoon_[hostPosInPlatoon_].vehicleCrossTrack;
753 }

References host_platoon_, and hostPosInPlatoon_.

Referenced by hostMemberUpdates().

Here is the caller graph for this function:

◆ getCurrentDowntrackDistance()

double platoon_strategic_ihp::PlatoonManager::getCurrentDowntrackDistance ( ) const

Returns current downtrack distance, in m.

Definition at line 744 of file platoon_manager_ihp.cpp.

745 {
746 return host_platoon_[hostPosInPlatoon_].vehiclePosition;
747 }

References host_platoon_, and hostPosInPlatoon_.

Referenced by getIHPDesPosFollower(), getPredecessorTimeHeadwaySum(), and hostMemberUpdates().

Here is the caller graph for this function:

◆ getCurrentPlatoonLength()

double platoon_strategic_ihp::PlatoonManager::getCurrentPlatoonLength ( )

Returns overall length of the platoon. in m.

Definition at line 762 of file platoon_manager_ihp.cpp.

762 {
763 //this works even if platoon size is 1 (can't be 0)
764 return host_platoon_[0].vehiclePosition - host_platoon_[host_platoon_.size() - 1].vehiclePosition + config_.vehicleLength;
765 }

References config_, host_platoon_, and platoon_strategic_ihp::PlatoonPluginConfig::vehicleLength.

Referenced by platoon_strategic_ihp::PlatoonStrategicIHPPlugin::composeMobilityOperationINFO().

Here is the caller graph for this function:

◆ getCurrentSpeed()

double platoon_strategic_ihp::PlatoonManager::getCurrentSpeed ( ) const

Returns current speed, in m/s.

Definition at line 733 of file platoon_manager_ihp.cpp.

733 {
734 return host_platoon_[hostPosInPlatoon_].vehicleSpeed;
735 }

References host_platoon_, and hostPosInPlatoon_.

Referenced by getIHPDesPosFollower(), and hostMemberUpdates().

Here is the caller graph for this function:

◆ getCutInGap()

double platoon_strategic_ihp::PlatoonManager::getCutInGap ( const int  gap_leading_index,
const double  joinerDtD 
)

UCLA: Return the current actual gap size in the target platoon for cut-in join, in m. Note: The origin of the vehicle (for downtrack distance calculation) is located at the rear axle. CAUTION: ASSUMES that the neighbor platoon info is fully populated!

Parameters
gap_leading_indexThe platoon index of the gap-leading vehicle.
joinerDtDThe current downtrack distance (with regards to host vehicle route) of the joiner vehicle.
Returns
: cut-in gap: The desired gap size for cut-in join, in m.

Definition at line 943 of file platoon_manager_ihp.cpp.

944 {
945 /*
946 Locate the target cut-in join gap size based on the index.
947 */
948
949 // Initiate variables
950 double gap_size = -0.999;
951 size_t index = 0;
952 if (gap_leading_index >= 0)
953 {
954 index = static_cast<size_t>(gap_leading_index);
955 }
956
957 // cut-in from front
958 if (gap_leading_index == -1)
959 {
960 double gap_rear_dtd = neighbor_platoon_[0].vehiclePosition;
961 gap_size = joinerDtD - gap_rear_dtd - config_.vehicleLength;
962 }
963 // cut-in from behind
964 else if (index == neighbor_platoon_.size() - 1)
965 {
966 double gap_leading_dtd = neighbor_platoon_[index].vehiclePosition;
967 gap_size = gap_leading_dtd - joinerDtD - config_.vehicleLength;;
968 }
969 // cut-in in the middle
970 else
971 {
972 double gap_leading_dtd = neighbor_platoon_[index].vehiclePosition;
973 double gap_rear_dtd = neighbor_platoon_[index + 1].vehiclePosition;
974 gap_size = gap_leading_dtd - gap_rear_dtd - config_.vehicleLength;
975 }
976
977 // return gap_size value
978 return gap_size;
979 }

References config_, neighbor_platoon_, and platoon_strategic_ihp::PlatoonPluginConfig::vehicleLength.

◆ getDistanceToPredVehicle()

double platoon_strategic_ihp::PlatoonManager::getDistanceToPredVehicle ( )

Returns distance to the predessecor vehicle, in m.

Definition at line 728 of file platoon_manager_ihp.cpp.

728 {
729 return gapWithPred_;
730 }

References gapWithPred_.

Referenced by platoon_strategic_ihp::PlatoonStrategicIHPPlugin::run_candidate_follower(), and platoon_strategic_ihp::PlatoonStrategicIHPPlugin::run_leader_aborting().

Here is the caller graph for this function:

◆ getDynamicLeader()

PlatoonMember platoon_strategic_ihp::PlatoonManager::getDynamicLeader ( )

Returns dynamic leader of the host vehicle.

Returns
The current dynamic leader as a vehcile object.

it might happened when the subject vehicle gets far away from the preceding vehicle, in which case the host vehicle will follow the one in front.

Definition at line 388 of file platoon_manager_ihp.cpp.

388 {
389 PlatoonMember dynamicLeader;
390 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("platoon_strategic_ihp"), "host_platoon_ size: " << host_platoon_.size());
391 if(isFollower)
392 {
393 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("platoon_strategic_ihp"), "Leader initially set as first vehicle in platoon");
394 // return the first vehicle in the platoon as default if no valid algorithm applied
395 // due to downtrack descending order, the platoon front veihcle is the first in list.
396 dynamicLeader = host_platoon_[0];
397 if (algorithmType_ == "APF_ALGORITHM"){
398 size_t newLeaderIndex = allPredecessorFollowing();
399
400 dynamic_leader_index_ = (int)newLeaderIndex;
401 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("platoon_strategic_ihp"), "dynamic_leader_index_: " << dynamic_leader_index_);
402 if(newLeaderIndex < host_platoon_.size()) { //this must always be true!
403 dynamicLeader = host_platoon_[newLeaderIndex];
404 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("platoon_strategic_ihp"), "APF output: " << dynamicLeader.staticId);
406 previousFunctionalDynamicLeaderID_ = dynamicLeader.staticId;
407 }
408 else //something is terribly wrong in the logic!
409 {
410 RCLCPP_WARN_STREAM(rclcpp::get_logger("platoon_strategic_ihp"), "newLeaderIndex = " << newLeaderIndex << " is invalid coming from allPredecessorFollowing!");
415 dynamicLeader = host_platoon_[getNumberOfVehicleInFront() - 1];
416 // update index and ID
418 previousFunctionalDynamicLeaderID_ = dynamicLeader.staticId;
419 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("platoon_strategic_ihp"), "Based on the output of APF algorithm we start to follow our predecessor.");
420 }
421 }
422 }
423 return dynamicLeader;
424
425 }
int allPredecessorFollowing()
This is the implementation of all predecessor following (APF) algorithm for leader selection in a pla...

References algorithmType_, allPredecessorFollowing(), dynamic_leader_index_, getNumberOfVehicleInFront(), host_platoon_, isFollower, previousFunctionalDynamicLeaderID_, previousFunctionalDynamicLeaderIndex_, and platoon_strategic_ihp::PlatoonMember::staticId.

Referenced by platoon_strategic_ihp::PlatoonStrategicIHPPlugin::composePlatoonInfoMsg().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getHostPlatoonSize()

int platoon_strategic_ihp::PlatoonManager::getHostPlatoonSize ( )

◆ getHostStaticID()

std::string platoon_strategic_ihp::PlatoonManager::getHostStaticID ( ) const

Returns current host static ID as a string.

Definition at line 756 of file platoon_manager_ihp.cpp.

757 {
758 return HostMobilityId;
759 }

References HostMobilityId.

Referenced by hostMemberUpdates(), platoon_strategic_ihp::PlatoonStrategicIHPPlugin::mob_req_cb_follower(), and updatesOrAddMemberInfo().

Here is the caller graph for this function:

◆ getIHPDesPosFollower()

double platoon_strategic_ihp::PlatoonManager::getIHPDesPosFollower ( double  dt)

UCLA: Return follower's desired position (i.e., downtrack, in m) that maintains the desired intra-platoon time gap, based on IHP platoon trajectory regulation algorithm.

\params dt: The planning time step, in s.

Returns
: Host vehicle's desired position as downtrack distance, in m.

Calculate desired position based on previous vehicle's trajectory for followers.

TODO: The platoon trajectory regulation is derived with the assumption that all vehicle have identical length (i.e., 5m). Future development is needed to include variable vehicle length into consideration.

Definition at line 819 of file platoon_manager_ihp.cpp.

820 {
829 // 1. read dtd vector
830 // dtd vector
831 std::vector<double> downtrackDistance(host_platoon_.size());
832 for (size_t i = 0; i < host_platoon_.size(); i++)
833 {
834 downtrackDistance[i] = host_platoon_[i].vehiclePosition;
835 }
836 // speed vector
837 std::vector<double> speed(host_platoon_.size());
838 for (size_t i = 0; i < host_platoon_.size(); i++)
839 {
840 speed[i] = host_platoon_[i].vehicleSpeed;
841 }
842
843 // 2. find the summation of "veh_len/veh_speed" for all predecessors
844 double tmp_time_hdw = 0.0;
845 double cur_dtd;
846 for (size_t index = 0; index < downtrackDistance.size(); index++)
847 {
848 cur_dtd = downtrackDistance[index];
849 if (cur_dtd > getCurrentDowntrackDistance())
850 {
851 // greater dtd ==> in front of host veh
852 tmp_time_hdw += config_.vehicleLength / (speed[index] + 0.00001);
853 }
854 }
855
856 // 3. read host veh and front veh info
857 // Predecessor vehicle data.
858 double pred_spd = speed[getNumberOfVehicleInFront()-1]; // m/s
859 double pred_pos = downtrackDistance[getNumberOfVehicleInFront()-1]; // m
860
861 // host data.
862 double ego_spd = getCurrentSpeed(); // m/s
863 double ego_pos = getCurrentDowntrackDistance(); // m
864
865 // platoon position index
866 int pos_idx = getNumberOfVehicleInFront();
867
868 double desirePlatoonGap = config_.intra_tau; //s
869
870 // IHP desired position calculation methods
871 double pos_g; // desired downtrack position calculated with time-gap, in m.
872 double pos_h; // desired downtrack position calculated with distance headaway, in m.
873
874 // 4. IHP gap regualtion
875
876 // intermediate variables
877 double timeGapAndStepRatio = desirePlatoonGap/time_step; // The ratio between desired platoon time gap and the current time_step.
878 double totalTimeGap = desirePlatoonGap*pos_idx; // The overall time gap from host vehicle to the platoon leader, in s.
879
880 // calcilate pos_gap and pos_headway
881 if ((pred_spd <= ego_spd) && (ego_spd <= config_.ss_theta))
882 {
883 // ---> 4.1 pos_g
884 pos_g = (pred_pos - config_.vehicleLength - config_.standstill + ego_pos*timeGapAndStepRatio) / (1 + timeGapAndStepRatio);
885 // ---> 4.2 pos_h
886 double pos_h_nom = (pred_pos - config_.standstill + ego_pos*(totalTimeGap + tmp_time_hdw)/time_step);
887 double pos_h_denom = (1 + ((totalTimeGap + tmp_time_hdw)/time_step));
888 pos_h = pos_h_nom/pos_h_denom;
889
890 }
891 else
892 {
893 // ---> 4.1 pos_g
894 pos_g = (pred_pos - config_.vehicleLength + ego_pos*(timeGapAndStepRatio)) / (1 + timeGapAndStepRatio);
895 // ---> 4.2 pos_h
896 double pos_h_nom = (pred_pos + ego_pos*(totalTimeGap + tmp_time_hdw)/time_step);
897 double pos_h_denom = (1 + ((totalTimeGap + tmp_time_hdw)/time_step));
898 pos_h = pos_h_nom/pos_h_denom;
899 }
900
901 // ---> 4.3 desire speed and desire location
902 double pos_des = config_.gap_weight*pos_g + (1.0 - config_.gap_weight)*pos_h;
903 // double des_spd = (pos_des - ego_pos) / time_step;
904
905 // ---> 4.4 return IHP calculated desired location
906 return pos_des;
907 }
double getCurrentDowntrackDistance() const
Returns current downtrack distance, in m.
double getCurrentSpeed() const
Returns current speed, in m/s.

References config_, platoon_strategic_ihp::PlatoonPluginConfig::gap_weight, getCurrentDowntrackDistance(), getCurrentSpeed(), getNumberOfVehicleInFront(), host_platoon_, process_bag::i, platoon_strategic_ihp::PlatoonPluginConfig::intra_tau, platoon_strategic_ihp::PlatoonPluginConfig::ss_theta, platoon_strategic_ihp::PlatoonPluginConfig::standstill, and platoon_strategic_ihp::PlatoonPluginConfig::vehicleLength.

Here is the call graph for this function:

◆ getNumberOfVehicleInFront()

int platoon_strategic_ihp::PlatoonManager::getNumberOfVehicleInFront ( )

Get number of vehicles in front of host vehicle inside platoon.

Definition at line 723 of file platoon_manager_ihp.cpp.

723 {
724 return hostPosInPlatoon_;
725 }

References hostPosInPlatoon_.

Referenced by allPredecessorFollowing(), platoon_strategic_ihp::PlatoonStrategicIHPPlugin::composePlatoonInfoMsg(), getDynamicLeader(), getIHPDesPosFollower(), getPredecessorPosition(), and platoon_strategic_ihp::PlatoonStrategicIHPPlugin::run_follower().

Here is the caller graph for this function:

◆ getPlatoonFrontDowntrackDistance()

double platoon_strategic_ihp::PlatoonManager::getPlatoonFrontDowntrackDistance ( )

UCLA: Return the platoon leader downtrack distance, in m.

Definition at line 382 of file platoon_manager_ihp.cpp.

382 {
383 // due to downtrack descending order, the firest vehicle in list is the platoon front vehicle.
384 return host_platoon_[0].vehiclePosition;
385 }

References host_platoon_.

Referenced by platoon_strategic_ihp::PlatoonStrategicIHPPlugin::mob_req_cb_leader().

Here is the caller graph for this function:

◆ getPlatoonRearDowntrackDistance()

double platoon_strategic_ihp::PlatoonManager::getPlatoonRearDowntrackDistance ( )

Returns downtrack distance of the rear vehicle in platoon, in m.

Definition at line 375 of file platoon_manager_ihp.cpp.

375 {
376 // due to downtrack descending order, the 1ast vehicle in list is the platoon rear vehicle.
377 // Even if host is solo, platoon size is 1 so this works.
378 return host_platoon_[host_platoon_.size()-1].vehiclePosition;
379 }

References host_platoon_.

Referenced by platoon_strategic_ihp::PlatoonStrategicIHPPlugin::mob_req_cb_leader().

Here is the caller graph for this function:

◆ getPredecessorPosition()

double platoon_strategic_ihp::PlatoonManager::getPredecessorPosition ( )

UCLA: Return the position of the preceding vehicle, in m.

Definition at line 809 of file platoon_manager_ihp.cpp.

810 {
811 // Read host index.
812 int host_platoon_index = getNumberOfVehicleInFront();
813
814 // Return speed
815 return host_platoon_[host_platoon_index].vehiclePosition; // m
816 }

References getNumberOfVehicleInFront(), and host_platoon_.

Referenced by platoon_strategic_ihp::PlatoonStrategicIHPPlugin::composePlatoonInfoMsg().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getPredecessorSpeed()

double platoon_strategic_ihp::PlatoonManager::getPredecessorSpeed ( )

UCLA: Return the speed of the preceding vehicle, in m/s.

Definition at line 803 of file platoon_manager_ihp.cpp.

804 {
805 return host_platoon_[hostPosInPlatoon_].vehicleSpeed; // m/s
806 }

References host_platoon_, and hostPosInPlatoon_.

Referenced by platoon_strategic_ihp::PlatoonStrategicIHPPlugin::composePlatoonInfoMsg().

Here is the caller graph for this function:

◆ getPredecessorTimeHeadwaySum()

double platoon_strategic_ihp::PlatoonManager::getPredecessorTimeHeadwaySum ( )

UCLA: Return the time headway summation of all predecessors, in s.

Definition at line 769 of file platoon_manager_ihp.cpp.

770 {
771 // 1. read dtd vector
772 // dtd vector
773 std::vector<double> downtrackDistance(host_platoon_.size());
774 for (size_t i = 0; i < host_platoon_.size(); i++)
775 {
776 downtrackDistance[i] = host_platoon_[i].vehiclePosition;
777 }
778 // speed vector
779 std::vector<double> speed(host_platoon_.size());
780 for (size_t i = 0; i < host_platoon_.size(); i++)
781 {
782 speed[i] = host_platoon_[i].vehicleSpeed;
783 }
784
785 // 2. find the summation of "veh_len/veh_speed" for all predecessors
786 double tmp_time_hdw = 0.0;
787 double cur_dtd;
788 for (size_t index = 0; index < downtrackDistance.size(); index++)
789 {
790 cur_dtd = downtrackDistance[index];
791 if (cur_dtd > getCurrentDowntrackDistance())
792 {
793 // greater dtd ==> in front of host veh
794 tmp_time_hdw += config_.vehicleLength / (speed[index] + 0.00001);
795 }
796 }
797
798 // Return the calcualted value
799 return tmp_time_hdw;
800 }

References config_, getCurrentDowntrackDistance(), host_platoon_, process_bag::i, and platoon_strategic_ihp::PlatoonPluginConfig::vehicleLength.

Referenced by platoon_strategic_ihp::PlatoonStrategicIHPPlugin::composePlatoonInfoMsg().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getTimeHeadwayFromIndex()

std::vector< double > platoon_strategic_ihp::PlatoonManager::getTimeHeadwayFromIndex ( std::vector< double >  timeHeadways,
int  start 
) const
private

Return a sub-vector of the platoon-wise time headaways vector that start with a given index.

Parameters
timeHeadwaysA vector containing the time headaway of all platoon members. start: An integer indicates the starting position.
Returns
An sub-vector start with given index.

Definition at line 564 of file platoon_manager_ihp.cpp.

564 {
565 std::vector<double> result(timeHeadways.begin() + start-1, timeHeadways.end());
566 return result;
567 }

Referenced by allPredecessorFollowing().

Here is the caller graph for this function:

◆ hostMemberUpdates()

void platoon_strategic_ihp::PlatoonManager::hostMemberUpdates ( const std::string &  senderId,
const std::string &  platoonId,
const std::string &  params,
const double &  DtD,
const double &  CtD 
)

Update information for members of the host's platoon based on a mobility operation STATUS message.

Parameters
senderIdstatic id of the broadcasting vehicle
platoonIdplatoon id
paramsmessage strategy parameters
DtDdowntrack distance along host's route, m
CtDcrosstrack distance in roadway at host's location, m

Definition at line 73 of file platoon_manager_ihp.cpp.

75 {
76
77 // parse params, read member data
78 std::vector<std::string> inputsParams;
79 boost::algorithm::split(inputsParams, params, boost::is_any_of(","));
80 // read command speed, m/s
81 std::vector<std::string> cmd_parsed;
82 boost::algorithm::split(cmd_parsed, inputsParams[0], boost::is_any_of(":"));
83 double cmdSpeed = std::stod(cmd_parsed[1]);
84 // get DtD directly instead of parsing message, m
85 double dtDistance = DtD;
86 // get CtD directly
87 double ctDistance = CtD;
88 // read current speed, m/s
89 std::vector<std::string> cur_parsed;
90 boost::algorithm::split(cur_parsed, inputsParams[1], boost::is_any_of(":"));
91 double curSpeed = std::stod(cur_parsed[1]);
92
93 // If we are currently in a follower state:
94 // 1. We will update platoon ID based on leader's STATUS
95 // 2. We will update platoon members info based on platoon ID for all members
96 if (isFollower)
97 {
98 // Sanity check
99 if (platoonLeaderID.compare(host_platoon_[0].staticId) != 0)
100 {
101 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("platoon_strategic_ihp"), "///// platoonLeaderID NOT PROPERLY ASSIGNED! Value = " << platoonLeaderID
102 << ", host_platoon_[0].staticId = " << host_platoon_[0].staticId);
103 }
104
105 // read message status
106 bool isFromLeader = platoonLeaderID == senderId;
107 bool needPlatoonIdChange = isFromLeader && (currentPlatoonID != platoonId);
108
109 if(needPlatoonIdChange)
110 {
111 // TODO: better to have leader explicitly inform us that it is merging into another platoon, rather than require us to deduce it here.
112 // This condition may also result from missing some message traffic, new leader in this platoon, or other confusion/incorrect code.
113 // Consider using a new STATUS msg param that tells members of new platoon ID and new leader ID when a change is made.
114 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("platoon_strategic_ihp"), "It seems that the current leader is joining another platoon.");
115 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("platoon_strategic_ihp"), "So the platoon ID is changed from " << currentPlatoonID << " to " << platoonId);
116 currentPlatoonID = platoonId;
117 updatesOrAddMemberInfo(host_platoon_, senderId, cmdSpeed, dtDistance, ctDistance, curSpeed);
118 }
119 else if (currentPlatoonID == platoonId)
120 {
121 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("platoon_strategic_ihp"), "This STATUS messages is from our platoon. Updating the info...");
122 updatesOrAddMemberInfo(host_platoon_, senderId, cmdSpeed, dtDistance, ctDistance, curSpeed);
123 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("platoon_strategic_ihp"), "The first vehicle in our list is now " << host_platoon_[0].staticId);
124 }
125 else //sender is in a different platoon
126 {
127 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("platoon_strategic_ihp"), "This STATUS message is not from a vehicle we care about. Ignore this message with id: " << senderId);
128 }
129 }
130 else //host is leader
131 {
132 // If we are currently in any leader state, we only update platoon member based on platoon ID
133 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("platoon_strategic_ihp"), "Host is leader: currentPlatoonID = " << currentPlatoonID << ", incoming platoonId = " << platoonId);
134 if (currentPlatoonID == platoonId)
135 {
136 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("platoon_strategic_ihp"), "This STATUS messages is from our platoon. Updating the info...");
137 updatesOrAddMemberInfo(host_platoon_, senderId, cmdSpeed, dtDistance, ctDistance, curSpeed);
138 }
139 else
140 {
141 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("platoon_strategic_ihp"), "Platoon IDs not matched");
142 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("platoon_strategic_ihp"), "currentPlatoonID: " << currentPlatoonID);
143 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("platoon_strategic_ihp"), "incoming platoonId: " << platoonId);
144 }
145 }
146
147 // update host vehicle information each time new member is updated. Now platoon contains host vehicle.
148 std::string hostStaticId = getHostStaticID();
149 double hostcmdSpeed = getCommandSpeed();
150 double hostDtD = getCurrentDowntrackDistance();
151 double hostCtD = getCurrentCrosstrackDistance();
152 double hostCurSpeed = getCurrentSpeed();
153 updatesOrAddMemberInfo(host_platoon_, hostStaticId, hostcmdSpeed, hostDtD, hostCtD, hostCurSpeed);
154 }
double getCommandSpeed() const
Returns command speed. in m/s.
void updatesOrAddMemberInfo(std::vector< PlatoonMember > &platoon, std::string senderId, double cmdSpeed, double dtDistance, double ctDistance, double curSpeed)
Updates the list of vehicles in the specified platoon, based on info available from a mobility operat...
double getCurrentCrosstrackDistance() const
Returns current crosstrack distance, in m.
std::string getHostStaticID() const
Returns current host static ID as a string.

References currentPlatoonID, getCommandSpeed(), getCurrentCrosstrackDistance(), getCurrentDowntrackDistance(), getCurrentSpeed(), getHostStaticID(), host_platoon_, isFollower, platoonLeaderID, process_traj_logs::split, and updatesOrAddMemberInfo().

Referenced by platoon_strategic_ihp::PlatoonStrategicIHPPlugin::mob_op_cb_STATUS().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ insufficientGapWithPredecessor()

bool platoon_strategic_ihp::PlatoonManager::insufficientGapWithPredecessor ( double  distanceToPredVehicle)
private

Check the gap with the predecessor vehicle.

Parameters
distanceToPredVehicleThe distance between the host to the predecessor vehicle.
Returns
(bool) if the predecessor is to close.

Definition at line 570 of file platoon_manager_ihp.cpp.

570 {
571
572 // For normal operation, gap > minGap is necessary.
573 bool frontGapIsTooSmall = distanceToPredVehicle < config_.minCutinGap;
574
575 // Host vehicle was following predecessor vehicle. --> The predecessor vehicle was violating gap threshold.
576 bool previousLeaderIsPredecessor = previousFunctionalDynamicLeaderID_ == host_platoon_[host_platoon_.size() - 1].staticId;
577
578 // Gap greater than maxGap_ is necessary for host to stop choosing predecessor as dynamic leader.
579 bool frontGapIsNotLargeEnough = distanceToPredVehicle < config_.maxCutinGap && previousLeaderIsPredecessor;
580
581 return (frontGapIsTooSmall || frontGapIsNotLargeEnough);
582 }

References config_, host_platoon_, platoon_strategic_ihp::PlatoonPluginConfig::maxCutinGap, platoon_strategic_ihp::PlatoonPluginConfig::minCutinGap, and previousFunctionalDynamicLeaderID_.

Referenced by allPredecessorFollowing().

Here is the caller graph for this function:

◆ neighborMemberUpdates()

void platoon_strategic_ihp::PlatoonManager::neighborMemberUpdates ( const std::string &  senderId,
const std::string &  platoonId,
const std::string &  params,
const double &  DtD,
const double &  CtD 
)

Update information for members of a neighboring platoon based on a mobility operation STATUS message.

Parameters
senderIdstatic id of the broadcasting vehicle
platoonIdplatoon id
paramsmessage strategy parameters
DtDdowntrack distance along host's route, m
CtDcrosstrack distance in roadway at host's location, m

Definition at line 157 of file platoon_manager_ihp.cpp.

159 {
160
161 // parse params, read member data
162 std::vector<std::string> inputsParams;
163 boost::algorithm::split(inputsParams, params, boost::is_any_of(","));
164 // read command speed, m/s
165 std::vector<std::string> cmd_parsed;
166 boost::algorithm::split(cmd_parsed, inputsParams[0], boost::is_any_of(":"));
167 double cmdSpeed = std::stod(cmd_parsed[1]);
168 // get DtD directly instead of parsing message, m
169 double dtDistance = DtD;
170 // get CtD directly
171 double ctDistance = CtD;
172 // read current speed, m/s
173 std::vector<std::string> cur_parsed;
174 boost::algorithm::split(cur_parsed, inputsParams[1], boost::is_any_of(":"));
175 double curSpeed = std::stod(cur_parsed[1]);
176
177 if (neighborPlatoonID == platoonId)
178 {
179 updatesOrAddMemberInfo(neighbor_platoon_, senderId, cmdSpeed, dtDistance, ctDistance, curSpeed);
180 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("platoon_strategic_ihp"), "This STATUS messages is from the target platoon. Updating the info...");
181 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("platoon_strategic_ihp"), "The first vehicle in that platoon is now " << neighbor_platoon_[0].staticId);
182
183 // If we have data on all members of a neighboring platoon, set a complete record flag
186 {
188 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("platoon_strategic_ihp"), "Neighbor record is complete!");
189 }
190 }
191 else //sender is in a different platoon
192 {
193 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("platoon_strategic_ihp"), "This STATUS message is not from a vehicle we care about. Ignore this message from sender: "
194 << senderId << " about platoon: " << platoonId);
195 }
196 }

References is_neighbor_record_complete_, neighbor_platoon_, neighbor_platoon_info_size_, neighborPlatoonID, process_traj_logs::split, and updatesOrAddMemberInfo().

Referenced by platoon_strategic_ihp::PlatoonStrategicIHPPlugin::mob_op_cb_STATUS().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ removeMember()

bool platoon_strategic_ihp::PlatoonManager::removeMember ( const size_t  mem)

Removes a single member from the internal record of platoon members.

Parameters
memindex of the member to be removed (zero-based)
Returns
true if removal was successful, false otherwise

Definition at line 322 of file platoon_manager_ihp.cpp.

323 {
324 // Don't remove ourselves!
325 if (hostPosInPlatoon_ == mem)
326 {
327 return false;
328 }
329
330 // Don't remove a member that isn't there
331 else if (host_platoon_.size() <= 1 || mem >= host_platoon_.size())
332 {
333 return false;
334 }
335
336 if (mem < hostPosInPlatoon_)
337 {
339 }
340 host_platoon_.erase(host_platoon_.begin() + mem, host_platoon_.begin() + mem + 1);
341
342 // If host is the only remaining member then clean up the other platoon data
343 if (host_platoon_.size() == 1)
344 {
348 }
349
350 return true;
351 }

References currentPlatoonID, dummyID, host_platoon_, hostPosInPlatoon_, and platoonLeaderID.

Referenced by platoon_strategic_ihp::PlatoonStrategicIHPPlugin::mob_resp_cb_leaderaborting(), and removeMemberById().

Here is the caller graph for this function:

◆ removeMemberById()

bool platoon_strategic_ihp::PlatoonManager::removeMemberById ( const std::string  id)

Removes a single member from the internal record of platoon members.

Parameters
idthe vehicle ID of the member to be removed
Returns
true if removal was successful, false otherwise

Definition at line 353 of file platoon_manager_ihp.cpp.

354 {
355 // Don't remove ourselves!
356 if (id.compare(HostMobilityId) == 0)
357 {
358 return false;
359 }
360
361 // Search for the member with a matching ID and remove it
362 for (size_t m = 0; m < host_platoon_.size(); ++m)
363 {
364 if (id.compare(host_platoon_[m].staticId) == 0)
365 {
366 return removeMember(m);
367 }
368 }
369
370 // Indicate the member was not found
371 return false;
372 }
bool removeMember(const size_t mem)
Removes a single member from the internal record of platoon members.

References host_platoon_, HostMobilityId, and removeMember().

Here is the call graph for this function:

◆ resetHostPlatoon()

void platoon_strategic_ihp::PlatoonManager::resetHostPlatoon ( )

Resets all variables that might indicate other members of the host's platoon; sets the host back to solo vehicle.

Definition at line 295 of file platoon_manager_ihp.cpp.

296 {
297 // Remove any elements in the platoon vector other than the host vehicle
298 if (host_platoon_.size() > hostPosInPlatoon_ + 1)
299 {
301 }
303
304 // Clean up other variables
308 isCreateGap = false;
310 }

References currentPlatoonID, dummyID, dynamic_leader_index_, host_platoon_, hostPosInPlatoon_, isCreateGap, and platoonLeaderID.

Referenced by platoon_strategic_ihp::PlatoonStrategicIHPPlugin::mob_req_cb_candidateleader(), platoon_strategic_ihp::PlatoonStrategicIHPPlugin::mob_resp_cb_candidatefollower(), platoon_strategic_ihp::PlatoonStrategicIHPPlugin::mob_resp_cb_leader(), platoon_strategic_ihp::PlatoonStrategicIHPPlugin::run_candidate_leader(), and platoon_strategic_ihp::PlatoonStrategicIHPPlugin::run_prepare_to_join().

Here is the caller graph for this function:

◆ resetNeighborPlatoon()

◆ updateHostPose()

void platoon_strategic_ihp::PlatoonManager::updateHostPose ( const double  downtrack,
const double  crosstrack 
)

Stores the latest info on location of the host vehicle.

Parameters
downtrackdistance downtrack from beginning of route, m
crosstrackdistance crosstrack from roadway centerline, m

Definition at line 58 of file platoon_manager_ihp.cpp.

59 {
60 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("platoon_strategic_ihp"), "Host (index " << hostPosInPlatoon_ << "): downtrack = " << downtrack << ", crosstrack = " << crosstrack);
61 host_platoon_[hostPosInPlatoon_].vehiclePosition = downtrack;
62 host_platoon_[hostPosInPlatoon_].vehicleCrossTrack = crosstrack;
63 }

References host_platoon_, and hostPosInPlatoon_.

Referenced by platoon_strategic_ihp::PlatoonStrategicIHPPlugin::onSpin(), and platoon_strategic_ihp::PlatoonStrategicIHPPlugin::pose_cb().

Here is the caller graph for this function:

◆ updateHostSpeeds()

void platoon_strategic_ihp::PlatoonManager::updateHostSpeeds ( const double  cmdSpeed,
const double  actualSpeed 
)

Stores the latest info on host vehicle's command & actual speeds.

Parameters
cmdSpeedcurrent commanded speed, m/s
actualSpeedcurrent measured speed, m/s

Definition at line 66 of file platoon_manager_ihp.cpp.

67 {
68 host_platoon_[hostPosInPlatoon_].commandSpeed = cmdSpeed;
69 host_platoon_[hostPosInPlatoon_].vehicleSpeed = actualSpeed;
70 }

References host_platoon_, and hostPosInPlatoon_.

Referenced by platoon_strategic_ihp::PlatoonStrategicIHPPlugin::onSpin().

Here is the caller graph for this function:

◆ updatesOrAddMemberInfo()

void platoon_strategic_ihp::PlatoonManager::updatesOrAddMemberInfo ( std::vector< PlatoonMember > &  platoon,
std::string  senderId,
double  cmdSpeed,
double  dtDistance,
double  ctDistance,
double  curSpeed 
)

Updates the list of vehicles in the specified platoon, based on info available from a mobility operation STATUS message from one of that platoon's vehicles. It ensures the list of vehicles is properly sorted in order of appearance from front to rear in the platoon. If the host is in the platoon, it will update host info as well.

Parameters
platoonthe list of vehicles in the platoon in question
senderIdvehicle ID that sent the current info
cmdSpeedthe commanded speed of the sending vehicle
dtDistancethe downtrack location (from beginning of host's route) of the sending vehicle, m
ctDistancethe crosstrack location (from center of roadway at host's current route location) of sending vehicle, m
curSpeedthe current actual speed of the sending vehicle, m/s

Definition at line 199 of file platoon_manager_ihp.cpp.

201 {
202 bool isExisted = false;
203 bool sortNeeded = false;
204
205 // update/add this info into the list
206 for (size_t i = 0; i < platoon.size(); ++i){
207 if(platoon[i].staticId == senderId) {
208 if (abs(dtDistance - platoon[i].vehiclePosition)/(platoon[i].vehiclePosition + 0.01) > config_.significantDTDchange)
209 {
210 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("platoon_strategic_ihp"), "DTD of member " << platoon[i].staticId << " is changed significantly, so a new sort is needed");
211
212 sortNeeded = true;
213 }
214 platoon[i].commandSpeed = cmdSpeed; // m/s
215 platoon[i].vehiclePosition = dtDistance; // m
216 platoon[i].vehicleCrossTrack = ctDistance; // m
217 platoon[i].vehicleSpeed = curSpeed; // m/s
218 platoon[i].timestamp = timer_factory_->now().nanoseconds()/1000000;
219 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("platoon_strategic_ihp"), "Receive and update platooning info on member " << i << ", ID:" << platoon[i].staticId);
220 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("platoon_strategic_ihp"), " CommandSpeed = " << platoon[i].commandSpeed);
221 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("platoon_strategic_ihp"), " Actual Speed = " << platoon[i].vehicleSpeed);
222 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("platoon_strategic_ihp"), " Downtrack Location = " << platoon[i].vehiclePosition);
223 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("platoon_strategic_ihp"), " Crosstrack dist = " << platoon[i].vehicleCrossTrack);
224
225 if (senderId == HostMobilityId)
226 {
228 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("platoon_strategic_ihp"), " This is the HOST vehicle");
229 }
230 isExisted = true;
231 }
232 }
233
234 if (sortNeeded)
235 {
236 // sort the platoon member based on dowtrack distance (m) in an descending order.
237 std::sort(std::begin(platoon), std::end(platoon), [](const PlatoonMember &a, const PlatoonMember &b){return a.vehiclePosition > b.vehiclePosition;});
238 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("platoon_strategic_ihp"), "Platoon is re-sorted due to large difference in dtd update.");
239 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("platoon_strategic_ihp"), " Platoon order is now:");
240 for (size_t i = 0; i < platoon.size(); ++i)
241 {
242 std::string hostFlag = " ";
243 if (platoon[i].staticId == getHostStaticID())
244 {
246 hostFlag = "Host";
247 }
248 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("platoon_strategic_ihp"), " " << platoon[i].staticId << "its DTD: " << platoon[i].vehiclePosition << " " << hostFlag);
249 }
250 }
251
252 // if not already exist, add to platoon list.
253 if(!isExisted) {
254 long cur_t = timer_factory_->now().nanoseconds()/1000000; // time in millisecond
255
256 PlatoonMember newMember = PlatoonMember(senderId, cmdSpeed, curSpeed, dtDistance, ctDistance, cur_t);
257 platoon.push_back(newMember);
258 // sort the platoon member based on downtrack distance (m) in an descending order.
259 std::sort(std::begin(platoon), std::end(platoon), [](const PlatoonMember &a, const PlatoonMember &b){return a.vehiclePosition > b.vehiclePosition;});
260
261 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("platoon_strategic_ihp"), "Add a new vehicle into our platoon list " << newMember.staticId << " platoon.size now = " << platoon.size());
262 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("platoon_strategic_ihp"), " Platoon order is now:");
263 for (size_t i = 0; i < platoon.size(); ++i)
264 {
265 std::string hostFlag = " ";
266 if (platoon[i].staticId == getHostStaticID())
267 {
269 hostFlag = "Host";
270 }
271 RCLCPP_DEBUG_STREAM(rclcpp::get_logger("platoon_strategic_ihp"), " " << platoon[i].staticId << "its DTD: " << platoon[i].vehiclePosition << " " << hostFlag);
272 }
273 }
274 }

References config_, getHostStaticID(), HostMobilityId, hostPosInPlatoon_, process_bag::i, platoon_strategic_ihp::PlatoonPluginConfig::significantDTDchange, platoon_strategic_ihp::PlatoonMember::staticId, timer_factory_, and platoon_strategic_ihp::PlatoonMember::vehiclePosition.

Referenced by hostMemberUpdates(), and neighborMemberUpdates().

Here is the call graph for this function:
Here is the caller graph for this function:

Member Data Documentation

◆ algorithmType_

std::string platoon_strategic_ihp::PlatoonManager::algorithmType_ = "APF_ALGORITHM"
private

Definition at line 439 of file platoon_manager_ihp.h.

Referenced by getDynamicLeader().

◆ config_

◆ current_plan

◆ current_platoon_state

PlatoonState platoon_strategic_ihp::PlatoonManager::current_platoon_state = PlatoonState::STANDBY

Definition at line 370 of file platoon_manager_ihp.h.

Referenced by platoon_strategic_ihp::PlatoonStrategicIHPPlugin::composePlatoonInfoMsg(), platoon_strategic_ihp::PlatoonStrategicIHPPlugin::handle_mob_req(), platoon_strategic_ihp::PlatoonStrategicIHPPlugin::mob_op_cb(), platoon_strategic_ihp::PlatoonStrategicIHPPlugin::mob_req_cb_candidateleader(), platoon_strategic_ihp::PlatoonStrategicIHPPlugin::mob_req_cb_leader(), platoon_strategic_ihp::PlatoonStrategicIHPPlugin::mob_req_cb_leaderwaiting(), platoon_strategic_ihp::PlatoonStrategicIHPPlugin::mob_req_cb_leadwithoperation(), platoon_strategic_ihp::PlatoonStrategicIHPPlugin::mob_resp_cb(), platoon_strategic_ihp::PlatoonStrategicIHPPlugin::mob_resp_cb_candidatefollower(), platoon_strategic_ihp::PlatoonStrategicIHPPlugin::mob_resp_cb_follower(), platoon_strategic_ihp::PlatoonStrategicIHPPlugin::mob_resp_cb_leader(), platoon_strategic_ihp::PlatoonStrategicIHPPlugin::mob_resp_cb_leaderaborting(), platoon_strategic_ihp::PlatoonStrategicIHPPlugin::mob_resp_cb_preparetojoin(), platoon_strategic_ihp::PlatoonStrategicIHPPlugin::onSpin(), platoon_strategic_ihp::PlatoonStrategicIHPPlugin::plan_maneuver_cb(), platoon_strategic_ihp::PlatoonStrategicIHPPlugin::pose_cb(), platoon_strategic_ihp::PlatoonStrategicIHPPlugin::run_candidate_follower(), platoon_strategic_ihp::PlatoonStrategicIHPPlugin::run_candidate_leader(), platoon_strategic_ihp::PlatoonStrategicIHPPlugin::run_follower(), platoon_strategic_ihp::PlatoonStrategicIHPPlugin::run_leader_aborting(), platoon_strategic_ihp::PlatoonStrategicIHPPlugin::run_leader_waiting(), platoon_strategic_ihp::PlatoonStrategicIHPPlugin::run_prepare_to_join(), and platoon_strategic_ihp::PlatoonStrategicIHPPlugin::setPMState().

◆ currentPlatoonID

◆ downtrack_progress_

double platoon_strategic_ihp::PlatoonManager::downtrack_progress_ = 0
private

Definition at line 435 of file platoon_manager_ihp.h.

◆ dummyID

◆ dynamic_leader_index_

size_t platoon_strategic_ihp::PlatoonManager::dynamic_leader_index_ = 0

◆ gapWithPred_

double platoon_strategic_ihp::PlatoonManager::gapWithPred_ = 0.0
private

Definition at line 434 of file platoon_manager_ihp.h.

Referenced by allPredecessorFollowing(), and getDistanceToPredVehicle().

◆ host_platoon_

◆ HostMobilityId

◆ hostPosInPlatoon_

◆ is_neighbor_record_complete_

◆ isCreateGap

◆ isFollower

bool platoon_strategic_ihp::PlatoonManager::isFollower = false

◆ JOIN_AT_REAR_PARAMS

std::string platoon_strategic_ihp::PlatoonManager::JOIN_AT_REAR_PARAMS = "SIZE:%1%,SPEED:%2%,DTD:%3%"
private

Definition at line 421 of file platoon_manager_ihp.h.

◆ JOIN_FROM_FRONT_PARAMS

std::string platoon_strategic_ihp::PlatoonManager::JOIN_FROM_FRONT_PARAMS = "SIZE:%1%,SPEED:%2%,DTD:%3%"
private

Definition at line 423 of file platoon_manager_ihp.h.

◆ maxCutinGap_

double platoon_strategic_ihp::PlatoonManager::maxCutinGap_ = 32.0
private

Definition at line 427 of file platoon_manager_ihp.h.

◆ minCutinGap_

double platoon_strategic_ihp::PlatoonManager::minCutinGap_ = 22.0
private

Definition at line 426 of file platoon_manager_ihp.h.

◆ MOBILITY_STRATEGY

std::string platoon_strategic_ihp::PlatoonManager::MOBILITY_STRATEGY = "Carma/Platooning"
private

Definition at line 424 of file platoon_manager_ihp.h.

◆ neighbor_platoon_

◆ neighbor_platoon_info_size_

size_t platoon_strategic_ihp::PlatoonManager::neighbor_platoon_info_size_ = 0

◆ neighbor_platoon_leader_id_

◆ neighborPlatoonID

◆ OPERATION_INFO_TYPE

std::string platoon_strategic_ihp::PlatoonManager::OPERATION_INFO_TYPE = "INFO"
private

Definition at line 419 of file platoon_manager_ihp.h.

◆ OPERATION_STATUS_TYPE

std::string platoon_strategic_ihp::PlatoonManager::OPERATION_STATUS_TYPE = "STATUS"
private

Definition at line 420 of file platoon_manager_ihp.h.

◆ platoonLeaderID

◆ pose_msg_

geometry_msgs::msg::PoseStamped platoon_strategic_ihp::PlatoonManager::pose_msg_

Definition at line 401 of file platoon_manager_ihp.h.

◆ previousFunctionalDynamicLeaderID_

std::string platoon_strategic_ihp::PlatoonManager::previousFunctionalDynamicLeaderID_ = ""
private

◆ previousFunctionalDynamicLeaderIndex_

int platoon_strategic_ihp::PlatoonManager::previousFunctionalDynamicLeaderIndex_ = -1
private

◆ targetPlatoonID

◆ timer_factory_

std::shared_ptr<carma_ros2_utils::timers::TimerFactory> platoon_strategic_ihp::PlatoonManager::timer_factory_

Definition at line 412 of file platoon_manager_ihp.h.

Referenced by updatesOrAddMemberInfo().

◆ vehicleLength_

double platoon_strategic_ihp::PlatoonManager::vehicleLength_ = 5.0
private

Definition at line 433 of file platoon_manager_ihp.h.


The documentation for this class was generated from the following files: