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_manager_ihp.h
Go to the documentation of this file.
1#pragma once
2
3/*
4 * Copyright (C) 2021 LEIDOS.
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
7 * use this file except in compliance with the License. You may obtain a copy of
8 * the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15 * License for the specific language governing permissions and limitations under
16 * the License.
17 */
18
19/*
20 * Developed by the UCLA Mobility Lab, 10/20/2021.
21 *
22 * Creator: Xu Han
23 * Author: Xu Han, Xin Xia, Jiaqi Ma
24 */
25
26
27#include <carma_v2x_msgs/msg/mobility_operation.hpp>
28#include <carma_v2x_msgs/msg/mobility_request.hpp>
29#include <carma_v2x_msgs/msg/mobility_response.hpp>
30#include <carma_v2x_msgs/msg/plan_type.hpp>
31#include <geometry_msgs/msg/pose_stamped.hpp>
32#include <geometry_msgs/msg/twist_stamped.hpp>
35#include <boost/uuid/uuid_generators.hpp>
36#include <boost/uuid/uuid_io.hpp>
37#include <carma_ros2_utils/timers/TimerFactory.hpp>
38#include "platoon_config_ihp.h"
39
41{
45 struct ActionPlan
46 {
47 bool valid; //is host currently negotiating/executing a join action?
48 unsigned long planStartTime; //time that plan was initiated
49 std::string planId; //ID of this action
50 std::string peerId; //vehicle ID of the candidtate joining vehicle or leader of platoon we are joining
51
52 ActionPlan() : valid(false), planStartTime(0), planId(""), peerId("") {}
53
54 ActionPlan(bool valid, unsigned long planStartTime, std::string planId, std::string peerId):
56 };
57
65 {
69 };
70
77 {
78 STANDBY, // 0;
80 LEADER, // 2;
82 FOLLOWER, // 4;
83 //UCLA: FRONTAL JOIN STATE
85 //UCLA: FRONTAL JOIN STATE
87 //UCLA: CUT-IN JOIN STATE
89 //UCLA: CUT-IN JOIN STATE
90 PREPARETOJOIN // 8;
91 };
92
97 {
98 // Static ID is permanent ID for each vehicle
99 std::string staticId;
100 // Vehicle real time command speed in m/s.
102 // Actual vehicle speed in m/s.
104 // Vehicle current downtrack distance on the current route in m.
106 // Vehicle current crosstrack distance on the current route in m.
108 // The local time stamp when the host vehicle update any informations of this member.
110
112
115 };
116
121 {
122 public:
123
129 PlatoonManager(std::shared_ptr<carma_ros2_utils::timers::TimerFactory> timer_factory);
130
137 void updateHostPose(const double downtrack, const double crosstrack);
138
145 void updateHostSpeeds(const double cmdSpeed, const double actualSpeed);
146
156 void hostMemberUpdates(const std::string& senderId, const std::string& platoonId, const std::string& params,
157 const double& DtD, const double& CtD);
158
168 void neighborMemberUpdates(const std::string& senderId, const std::string& platoonId, const std::string& params,
169 const double& DtD, const double& CtD);
170
184 void updatesOrAddMemberInfo(std::vector<PlatoonMember>& platoon, std::string senderId, double cmdSpeed,
185 double dtDistance, double ctDistance, double curSpeed);
186
190 int getHostPlatoonSize();
191
195 void clearActionPlan();
196
200 void resetHostPlatoon();
201
206
214 bool removeMember(const size_t mem);
215
223 bool removeMemberById(const std::string id);
224
231
247
252
259 void changeFromLeaderToFollower(std::string newPlatoonId, std::string newLeaderId);
260
265
270
275
280
284 double getCurrentSpeed() const;
285
289 double getCommandSpeed() const;
290
294 double getCurrentDowntrackDistance() const;
295
299 double getCurrentCrosstrackDistance() const;
300
304 std::string getHostStaticID() const;
305
310
315
319 double getPredecessorSpeed();
320
324 double getPredecessorPosition();
325
334 double getIHPDesPosFollower(double dt);
335
344 int getClosestIndex(double joinerDtD);
345
356 double getCutInGap(const int gap_leading_index, const double joinerDtD);
357
358 const std::string dummyID = "00000000-0000-0000-0000-000000000000";
359
360 // List of members in the host's own platoon (host will always be represented, so size is never zero)
361 std::vector<PlatoonMember> host_platoon_;
362
363 // Platoon ID of the host's platoon
364 std::string currentPlatoonID = dummyID; //dummy indicates not part of a platoon
365
366 // Vehicle ID of the host's platoon leader (host may be the leader)
367 std::string platoonLeaderID = dummyID; //dummy indicates not part of a platoon
368
369 // Current platooning state of the host vehicle
371
372 //index to the host_platoon_ vector that represents the host vehicle
374
375 // Plan that represents a joining activity only, it is NOT the ID of the platoon itself
377
378 // Is the host a follower in its platoon?
379 bool isFollower = false;
380
381 // List of members in a detected neighbor platoon, which may be empty
382 // CAUTION: we can only represent one neighbor platoon in this version, so if multiple platoons are nearby,
383 // code will get very confused and results are unpredictable.
384 std::vector<PlatoonMember> neighbor_platoon_;
385
386 // Num vehicles in the neighbor platoon, as indicated by the size field in the INFO message
388
389 // Platoon ID of the neighboring platoon
390 std::string targetPlatoonID = dummyID; //ID of a real platoon that we may be attempting to join
391
392 std::string neighborPlatoonID = dummyID; //ID of the neighbor platoon that we may be attempting to join (dummy if neighbor is a solo vehicle)
393
394 // Vehicle ID of the neighbor platoon's leader
395 std::string neighbor_platoon_leader_id_ = dummyID; //dummy indicates unknown
396
397 // Is the record of neighbor platoon members complete (does it contain a record for every member)?
399
400 // Current vehicle pose in map
401 geometry_msgs::msg::PoseStamped pose_msg_;
402
403 // host vehicle's static ID
404 std::string HostMobilityId = "default_host_id";
405
406 // UCLA: add indicator of creating gap
407 bool isCreateGap = false;
408
410
411 // Timer factory used to get current time
412 std::shared_ptr<carma_ros2_utils::timers::TimerFactory> timer_factory_;
413
414 private:
415
416 // local copy of configuration file
418
419 std::string OPERATION_INFO_TYPE = "INFO";
420 std::string OPERATION_STATUS_TYPE = "STATUS";
421 std::string JOIN_AT_REAR_PARAMS = "SIZE:%1%,SPEED:%2%,DTD:%3%";
422 // UCLA: add params for frontal join
423 std::string JOIN_FROM_FRONT_PARAMS = "SIZE:%1%,SPEED:%2%,DTD:%3%";
424 std::string MOBILITY_STRATEGY = "Carma/Platooning";
425
426 double minCutinGap_ = 22.0; // m
427 double maxCutinGap_ = 32.0; // m
430
431 // note: APF related parameters are in config.h.
432
433 double vehicleLength_ = 5.0; // the length of the vehicle, in m.
434 double gapWithPred_ = 0.0; // time headway with predecessor, in s.
435 double downtrack_progress_ = 0; // current downtrack distance, in m.
436
437 // Note: Parameters for IHP platoon trajectory regulation are in config.h.
438
439 std::string algorithmType_ = "APF_ALGORITHM"; // a string that defines the current algorithm to determine the dynamic leader.
440
448 bool insufficientGapWithPredecessor(double distanceToPredVehicle);
449
458 std::vector<double> calculateTimeHeadway(std::vector<double> downtrackDistance, std::vector<double> speed) const;
459
468 int determineDynamicLeaderBasedOnViolation(std::vector<double> timeHeadways);
469
477 int findLowerBoundaryViolationClosestToTheHostVehicle(std::vector<double> timeHeadways) const;
478
486 int findMaximumSpacingViolationClosestToTheHostVehicle(std::vector<double> timeHeadways) const;
487
496 std::vector<double> getTimeHeadwayFromIndex(std::vector<double> timeHeadways, int start) const;
497 };
498}
Class containing the logic for platoon manager. It is responsible for keeping track of the platoon me...
double getCommandSpeed() const
Returns command speed. in m/s.
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...
PlatoonMember getDynamicLeader()
Returns dynamic leader of the host vehicle.
bool removeMember(const size_t mem)
Removes a single member from the internal record of platoon members.
double getDistanceToPredVehicle()
Returns distance to the predessecor vehicle, in m.
bool removeMemberById(const std::string id)
Removes a single member from the internal record of platoon members.
PlatoonManager(std::shared_ptr< carma_ros2_utils::timers::TimerFactory > timer_factory)
Constructor.
std::vector< PlatoonMember > neighbor_platoon_
int allPredecessorFollowing()
This is the implementation of all predecessor following (APF) algorithm for leader selection in a pla...
void updateHostSpeeds(const double cmdSpeed, const double actualSpeed)
Stores the latest info on host vehicle's command & actual speeds.
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...
geometry_msgs::msg::PoseStamped pose_msg_
double getPlatoonRearDowntrackDistance()
Returns downtrack distance of the rear vehicle in platoon, in m.
int getClosestIndex(double joinerDtD)
UCLA: Return joiner's desired position in terms of target platoon index to cut into the platoon....
int getHostPlatoonSize()
Returns total size of the platoon , in number of vehicles.
double getPredecessorPosition()
UCLA: Return the position of the preceding vehicle, in m.
double getCurrentDowntrackDistance() const
Returns current downtrack distance, in m.
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.
void changeFromLeaderToFollower(std::string newPlatoonId, std::string newLeaderId)
Update status when state change from Leader to Follower.
double getPlatoonFrontDowntrackDistance()
UCLA: Return the platoon leader downtrack distance, in m.
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....
void updateHostPose(const double downtrack, const double crosstrack)
Stores the latest info on location of the host vehicle.
void resetHostPlatoon()
Resets all variables that might indicate other members of the host's platoon; sets the host back to s...
bool insufficientGapWithPredecessor(double distanceToPredVehicle)
Check the gap with the predecessor vehicle.
void resetNeighborPlatoon()
Resets all variables that describe a neighbor platoon, so that no neighbor is known.
double getPredecessorSpeed()
UCLA: Return the speed of the preceding vehicle, in m/s.
double getCurrentSpeed() const
Returns current speed, in m/s.
double getCurrentCrosstrackDistance() const
Returns current crosstrack distance, in m.
double getPredecessorTimeHeadwaySum()
UCLA: Return the time headway summation of all predecessors, in s.
double getIHPDesPosFollower(double dt)
UCLA: Return follower's desired position (i.e., downtrack, in m) that maintains the desired intra-pla...
std::vector< PlatoonMember > host_platoon_
std::shared_ptr< carma_ros2_utils::timers::TimerFactory > timer_factory_
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.
std::string getHostStaticID() const
Returns current host static ID as a string.
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.
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.
double getCurrentPlatoonLength()
Returns overall length of the platoon. in m.
void clearActionPlan()
Resets necessary variables to indicate that the current ActionPlan is dead.
void changeFromFollowerToLeader()
Update status when state change from Follower to Leader.
PlatoonState
Platoon States. UCLA: Added additional states (i.e., LEADERABORTING and CANDIDATELEADER) for same-lan...
MobilityRequestResponse
A response to an MobilityRequest message. ACK - indicates that the plugin accepts the MobilityRequest...
Struct for an action plan, which describes a transient joining activity.
ActionPlan(bool valid, unsigned long planStartTime, std::string planId, std::string peerId)
PlatoonMember(std::string staticId, double commandSpeed, double vehicleSpeed, double vehiclePosition, double vehicleCrossTrack, long timestamp)
Stuct containing the algorithm configuration values for the yield_pluginConfig.