25#include <rclcpp/logging.hpp>
39 std::shared_ptr<carma_ros2_utils::timers::TimerFactory> timer_factory)
40 : mobility_request_publisher_(mobility_request_publisher),
41 mobility_response_publisher_(mobility_response_publisher), mobility_operation_publisher_(mobility_operation_publisher),
42 platooning_info_publisher_(platooning_info_publisher), wm_(wm), config_(config), timer_factory_(timer_factory), pm_(timer_factory_)
44 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Top of PlatoonStrategicIHP ctor.");
57 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"ctor complete. hostStaticId = " << hostStaticId);
69 throw std::invalid_argument(
"No map projector available for ecef conversion");
72 carma_v2x_msgs::msg::LocationECEF location;
75 lanelet::BasicPoint3d ecef_point =
map_projector_->projectECEF({pose_msg.pose.position.x, pose_msg.pose.position.y, 0.0}, 1);
76 location.ecef_x = ecef_point.x() * 100.0;
77 location.ecef_y = ecef_point.y() * 100.0;
78 location.ecef_z = ecef_point.z() * 100.0;
117 pose_msg_ = geometry_msgs::msg::PoseStamped(*msg);
121 lanelet::BasicPoint2d current_loc(
pose_msg_.pose.position.x,
pose_msg_.pose.position.y);
155 for(
size_t i = 0;
i < path.size(); ++
i)
157 if(path[
i].
id() == target_id)
168 double target_speed = 0.0;
170 lanelet::Optional<carma_wm::TrafficRulesConstPtr> traffic_rules =
wm_->getTrafficRules();
173 target_speed =(*traffic_rules)->speedLimit(llt).speedLimit.value();
177 throw std::invalid_argument(
"Valid traffic rules object could not be built");
180 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"target speed (limit) " << target_speed);
188 lanelet::BasicPoint2d current_loc(
pose_msg_.pose.position.x,
pose_msg_.pose.position.y);
190 auto current_lanelets = lanelet::geometry::findNearest(
wm_->getMap()->laneletLayer, current_loc, 10);
191 lanelet::ConstLanelet current_lanelet = current_lanelets[0].second;
194 lanelet::ConstLineString3d left_bound = current_lanelet.leftBound();
195 lanelet::ConstLineString3d right_bound = current_lanelet.leftBound();
198 double dx = abs (left_bound[0].
x() - right_bound[0].
x());
199 double dy = abs (left_bound[0].
y() - right_bound[0].
y());
200 double laneWidth = sqrt(dx*dx + dy*dy);
201 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"calculated lane width: " << laneWidth);
218 if (downtrack > currentDtd && samelane)
220 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Found a platoon in front. We are able to join");
225 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Ignoring platoon that is either behind host or in another lane.");
226 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"The front platoon dtd is " << downtrack <<
" and we are current at " << currentDtd);
238 if (downtrack < currentDtd && samelane)
240 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Found a platoon at behind. We are able to join");
245 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Ignoring platoon that is either ahead of us or in another lane.");
246 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"The front platoon dtd is " << downtrack <<
" and we are current at " << currentDtd);
256 throw std::invalid_argument(
"No map projector available for ecef conversion");
259 lanelet::BasicPoint3d map_point =
map_projector_->projectECEF( { (double)ecef_point.ecef_x/100.0, (
double)ecef_point.ecef_y/100.0, (double)ecef_point.ecef_z/100.0 } , -1);
261 lanelet::BasicPoint2d output {map_point.x(), map_point.y()};
271 map_projector_ = std::make_shared<lanelet::projection::LocalFrameProjector>(msg->data.c_str());
292 carma_v2x_msgs::msg::MobilityOperation msg;
294 msg.m_header.recipient_id =
"";
296 msg.m_header.sender_id = hostStaticId;
297 msg.m_header.timestamp =
timer_factory_->now().nanoseconds() / 1000000;
310 std::string statusParams = fmter.str();
311 msg.strategy_params = statusParams;
312 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Composed a mobility operation message with params " << msg.strategy_params);
324 carma_v2x_msgs::msg::MobilityOperation msg;
326 msg.m_header.recipient_id =
"";
328 msg.m_header.sender_id = hostStaticId;
329 msg.m_header.timestamp =
timer_factory_->now().nanoseconds() / 1000000;;
337 fmter% CurrentPlatoonLength;
344 std::string infoParams = fmter.str();
345 msg.strategy_params = infoParams;
346 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Composed a mobility operation message with params " << msg.strategy_params);
363 double rearVehicleDtd =
pm_.
host_platoon_[lastVehicleIndex].vehiclePosition;
370 bool lateralCheck = joining_crosstrack >= frontVehicleCtd - two_lane_cross_error ||
371 joining_crosstrack <= frontVehicleCtd + two_lane_cross_error;
373 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"The longitudinalCheck result is: " << longitudinalCheck );
374 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"The lateralCheck result is: " << lateralCheck );
376 if (longitudinalCheck && lateralCheck)
378 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Joining vehicle is nearby. It is able to join.");
383 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"The joining vehicle is not close by, the join request will not be approved.");
384 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"The joining vehicle downtrack is " << joining_downtrack <<
" and the host (platoon leader) downtrack is " << frontVehicleDtd);
385 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"The joining vehicle crosstrack is " << joining_crosstrack <<
" and the host (platoon leader) crosstrack is " << frontVehicleCtd);
403 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"The longitudinalCheck result is: " << longitudinalCheck );
404 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"The lateralCheck result is: " << lateralCheck );
406 if (longitudinalCheck && lateralCheck)
409 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Found a platoon nearby. We are able to join.");
414 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Ignoring platoon.");
415 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"The platoon leader dtd is " << frontVehicleDtd <<
" and we are current at " <<
current_downtrack_);
416 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"The platoon leader ctd is " << frontVehicleCtd <<
" and we are current at " <<
current_crosstrack_);
431 carma_planning_msgs::msg::PlatooningInfo status_msg;
435 status_msg.state = carma_planning_msgs::msg::PlatooningInfo::DISABLED;
439 status_msg.state =
pm_.
getHostPlatoonSize() == 1 ? carma_planning_msgs::msg::PlatooningInfo::SEARCHING : carma_planning_msgs::msg::PlatooningInfo::LEADING;
443 status_msg.state = carma_planning_msgs::msg::PlatooningInfo::CONNECTING_TO_NEW_FOLLOWER;
447 status_msg.state = carma_planning_msgs::msg::PlatooningInfo::CONNECTING_TO_NEW_LEADER;
451 status_msg.state = carma_planning_msgs::msg::PlatooningInfo::FOLLOWING;
456 status_msg.state = carma_planning_msgs::msg::PlatooningInfo::CONNECTING_TO_NEW_LEADER;
461 status_msg.state = carma_planning_msgs::msg::PlatooningInfo::CONNECTING_TO_NEW_FOLLOWER;
466 status_msg.state = carma_planning_msgs::msg::PlatooningInfo::CONNECTING_TO_NEW_FOLLOWER;
471 status_msg.state = carma_planning_msgs::msg::PlatooningInfo::CONNECTING_TO_NEW_LEADER;
485 status_msg.leader_id = platoon_leader.
staticId;
487 status_msg.leader_cmd_speed = platoon_leader.
commandSpeed;
489 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"pm platoonsize: " <<
pm_.
getHostPlatoonSize() <<
", platoon_leader " << platoon_leader.
staticId);
492 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"The host vehicle have " << numOfVehiclesGaps <<
" vehicles between itself and its leader (includes the leader)");
495 lanelet::BasicPoint2d current_loc(
pose_msg_.pose.position.x,
pose_msg_.pose.position.y);
497 auto llts =
wm_->getLaneletsFromPoint(current_loc, 1);
503 auto geofence_gaps = llts[0].regulatoryElementsAs<lanelet::DigitalMinimumGap>();
505 if (!geofence_gaps.empty())
507 lanelet_digitalgap = geofence_gaps[0]->getMinimumGap();
513 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"No lanelets in this location!!!: ");
516 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"lanelet_digitalgap: " << lanelet_digitalgap);
519 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"max desired_headway " << desired_headway);
521 status_msg.desired_gap = std::max(
config_.
standStillHeadway * numOfVehiclesGaps, desired_headway * numOfVehiclesGaps) + (numOfVehiclesGaps - 1) * 5.0;
522 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"The desired gap with the leader is " << status_msg.desired_gap);
533 double regular_gap = status_msg.desired_gap;
534 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"regular_gap: " << regular_gap);
535 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"current_speed_: " <<
current_speed_);
536 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"speed based gap: " << desired_headway);
542 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"status_msg.actual_gap: " << status_msg.actual_gap);
549 status_msg.host_platoon_position = 0;
563 carma_v2x_msgs::msg::MobilityOperation msg;
579 RCLCPP_ERROR(rclcpp::get_logger(
"platoon_strategic_ihp"),
"UNKNOWN strategy param string!!!");
580 msg.strategy_params =
"";
588 carma_v2x_msgs::msg::MobilityOperation msg;
598 carma_v2x_msgs::msg::MobilityOperation msg;
606 carma_v2x_msgs::msg::MobilityOperation msg;
618 carma_v2x_msgs::msg::MobilityOperation msg;
631 carma_v2x_msgs::msg::MobilityOperation msg;
644 carma_v2x_msgs::msg::MobilityOperation msg;
651 carma_v2x_msgs::msg::MobilityOperation msg;
667 RCLCPP_ERROR(rclcpp::get_logger(
"platoon_strategic_ihp"),
"UNKNOWN strategy param string!!!");
668 msg.strategy_params =
"";
687 std::vector<std::string> inputsParams;
690 std::vector<std::string> ecef_x_parsed;
692 double ecef_x = std::stod(ecef_x_parsed[1]);
694 std::vector<std::string> ecef_y_parsed;
696 double ecef_y = std::stod(ecef_y_parsed[1]);
698 std::vector<std::string> ecef_z_parsed;
700 double ecef_z = std::stod(ecef_z_parsed[1]);
702 carma_v2x_msgs::msg::LocationECEF ecef_loc;
703 ecef_loc.ecef_x = ecef_x;
704 ecef_loc.ecef_y = ecef_y;
705 ecef_loc.ecef_z = ecef_z;
719 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Entered mob_op_cb_STATUS");
720 std::string strategyParams = msg.strategy_params;
721 std::string vehicleID = msg.m_header.sender_id;
722 std::string platoonId = msg.m_header.plan_id;
723 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"strategyParams = " << strategyParams);
724 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"platoonId = " << platoonId <<
", sender ID = " << vehicleID);
731 double dtd =
wm_->routeTrackPos(incoming_pose).downtrack;
732 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"DTD calculated from ecef is: " << dtd);
734 double ctd =
wm_->routeTrackPos(incoming_pose).crosstrack;
735 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"CTD calculated from ecef is: " << ctd);
740 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Incoming platoonID matches target platoon id");
754 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Received mob op for platoon " << platoonId <<
" that doesn't match our platoon: " <<
pm_.
currentPlatoonID
768 std::vector<std::string> inputsParams;
772 std::vector<std::string> target_platoon_length;
774 double platoon_length = std::stod(target_platoon_length[1]);
776 return platoon_length;
788 std::vector<std::string> inputsParams;
791 std::vector<std::string> ecef_x_parsed;
793 double ecef_x = std::stod(ecef_x_parsed[1]);
795 std::vector<std::string> ecef_y_parsed;
797 double ecef_y = std::stod(ecef_y_parsed[1]);
799 std::vector<std::string> ecef_z_parsed;
801 double ecef_z = std::stod(ecef_z_parsed[1]);
803 carma_v2x_msgs::msg::LocationECEF ecef_loc;
804 ecef_loc.ecef_x = ecef_x;
805 ecef_loc.ecef_y = ecef_y;
806 ecef_loc.ecef_z = ecef_z;
819 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"mob_op_cb received msg with sender ID " << msg->m_header.sender_id
820 <<
", plan ID " << msg->m_header.plan_id);
821 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"...strategy " << msg->strategy <<
", strategy params " << msg->strategy_params);
824 std::string strategy = msg->strategy;
827 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Ignoring mobility operation message for " << strategy <<
" strategy.");
834 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Ignoring message since host is stopped.");
839 std::string strategyParams = msg->strategy_params;
842 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"strategyParams: " << strategyParams <<
"isPlatoonStatusMsg: " << isPlatoonStatusMsg <<
"isPlatoonInfoMsg: " << isPlatoonInfoMsg);
843 if (isPlatoonStatusMsg)
847 else if (isPlatoonInfoMsg)
853 std::vector<std::string> inputsParams;
855 std::vector<std::string> p_size;
857 int platoon_size = std::stoi(p_size[1]);
858 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"neighbor platoon_size from INFO: " << platoon_size);
877 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Invalid Mob Op received");
930 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"STANDBY state no further action on message from " << msg.m_header.sender_id);
936 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"CANDIDATEFOLLOWER state no further action on message from " << msg.m_header.sender_id);
947 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"FOLLOWER state no further action on message from " << msg.m_header.sender_id);
953 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"LEADERWAITING state no further action on message from " << msg.m_header.sender_id);
975 std::string strategyParams = msg.strategy_params;
976 std::string senderId = msg.m_header.sender_id;
977 std::string platoonId = msg.m_header.plan_id;
984 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Top of mob_op_cb_leader, isInNegotiation = " << isInNegotiation);
987 if (isPlatoonInfoMsg && !isInNegotiation)
995 carma_v2x_msgs::msg::LocationECEF ecef_loc;
1000 double frontVehicleDtd =
wm_->routeTrackPos(incoming_pose).downtrack;
1003 double frontVehicleCtd =
wm_->routeTrackPos(incoming_pose).crosstrack;
1005 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Neighbor platoon frontVehicleDtd from ecef: " << frontVehicleDtd <<
", frontVehicleCtd from ecef: " << frontVehicleCtd);
1019 double rearVehicleDtd = frontVehicleDtd - platoon_length;
1020 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"rear veh dtd from platoon length: " << rearVehicleDtd);
1024 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"rear veh dtd from neighbor platoon: " << rearVehicleDtd);
1028 double rearVehicleCtd = frontVehicleCtd;
1029 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Neighbor platoon rearVehicleDtd: " << rearVehicleDtd <<
", rearVehicleCtd: " << rearVehicleCtd);
1032 std::vector<std::string> inputsParams;
1036 std::vector<std::string> targetPlatoonSize_parsed;
1038 int targetPlatoonSize = std::stoi(targetPlatoonSize_parsed[1]);
1039 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"target Platoon Size: " << targetPlatoonSize);
1040 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Found a vehicle/platoon with id = " << platoonId <<
" within range.");
1046 carma_v2x_msgs::msg::MobilityRequest request;
1048 request.m_header.recipient_id = senderId;
1050 request.m_header.timestamp =
timer_factory_->now().nanoseconds()/1000000;
1053 request.urgency = 50;
1063 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Neighbor platoon is right in front of us");
1065 request.plan_type.type = carma_v2x_msgs::msg::PlanType::JOIN_PLATOON_AT_REAR;
1074 int dummy_join_index = -2;
1075 fmter %platoon_size;
1080 fmter %dummy_join_index;
1081 request.strategy_params = fmter.str();
1083 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Publishing request to leader " << senderId <<
" with params " << request.strategy_params <<
" and plan id = " << request.m_header.plan_id);
1092 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Detected neighbor as a real platoon & storing its ID: " << platoonId);
1102 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Neighbor platoon leader is right behind us");
1105 request.plan_type.type = carma_v2x_msgs::msg::PlanType::JOIN_PLATOON_FROM_FRONT;
1113 int dummy_join_index = -2;
1114 fmter %platoon_size;
1119 fmter %dummy_join_index;
1120 request.strategy_params = fmter.str();
1122 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Publishing front join request to the leader " << senderId <<
" with params " << request.strategy_params <<
" and plan id = " << request.m_header.plan_id);
1132 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Since neighbor is a fake platoon, storing " <<
pm_.
targetPlatoonID <<
" as its platoon ID");
1137 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Storing real neighbor platoon's ID as target: " <<
pm_.
targetPlatoonID);
1146 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"starting cut-in join process");
1147 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"rearVehicleDtd " << rearVehicleDtd);
1148 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"rearVehicleCtd " << rearVehicleCtd);
1154 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Detected neighbor as a real platoon & storing its ID: " << platoonId);
1159 auto target_rear_pose =
wm_->pointFromRouteTrackPos(target_trackpose);
1160 if (target_rear_pose)
1164 auto target_lanelets = lanelet::geometry::findNearest(
wm_->getMap()->laneletLayer, target_rear_pose.get(), 1);
1165 if (!target_lanelets.empty())
1167 long target_rear_pose_lanelet_id = target_lanelets[0].second.id();
1168 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"target_rear_pose_lanelet_id: " << target_rear_pose_lanelet_id);
1172 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"target_rear_pose_lanelet not found!!");
1178 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"No target pose is found, so we cannot prodeed with a cutin join request.");
1198 request.plan_type.type = carma_v2x_msgs::msg::PlanType::PLATOON_CUT_IN_JOIN;
1201 int join_index = -2;
1203 fmter %platoon_size;
1209 request.strategy_params = fmter.str();
1211 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Publishing request to the leader " << senderId <<
" with params " << request.strategy_params <<
" and plan id = " << request.m_header.plan_id);
1220 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Ignore platoon with platoon id: " << platoonId <<
" because it is too far away to join.");
1231 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"LEADERABORTING state no further action on message from " << msg.m_header.sender_id);
1237 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"CANDIDATELEADER state no further action on message from " << msg.m_header.sender_id);
1243 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"LEADWITHOPERATION state no further action on message from " << msg.m_header.sender_id);
1256 std::string strategyParams = msg.strategy_params;
1257 std::string senderId = msg.m_header.sender_id;
1274 carma_v2x_msgs::msg::LocationECEF ecef_loc;
1279 double frontVehicleDtd =
wm_->routeTrackPos(incoming_pose).downtrack;
1282 double frontVehicleCtd =
wm_->routeTrackPos(incoming_pose).crosstrack;
1286 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"rearVehicleIndex: " << rearVehicleIndex);
1288 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Neighbor rearVehicleDtd from ecef: " << rearVehicleDtd);
1299 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Lane change has been authorized. isSameLaneWithPlatoon = " << isSameLaneWithPlatoon);
1300 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"crosstrack diff" << abs(frontVehicleCtd -
current_crosstrack_));
1301 if (isSameLaneWithPlatoon)
1307 carma_v2x_msgs::msg::MobilityRequest request;
1309 request.m_header.recipient_id = senderId;
1311 request.m_header.timestamp =
timer_factory_->now().nanoseconds()/1000000;
1317 request.plan_type.type = carma_v2x_msgs::msg::PlanType::CUT_IN_FRONT_DONE;
1321 request.plan_type.type = carma_v2x_msgs::msg::PlanType::CUT_IN_MID_OR_REAR_DONE;
1327 fmter %host_platoon_size;
1333 request.strategy_params = fmter.str();
1334 request.urgency = 50;
1342 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"new platoon id: " <<
pm_.
currentPlatoonID);
1345 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Published Mobility request to revert to same-lane operation");
1349 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Lane Change not completed");
1362 std::string strategy = msg.strategy;
1365 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Ignoring mobility operation message for " << strategy <<
" strategy.");
1413 return mobility_response;
1419 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"STANDBY state does nothing with msg from " << msg.m_header.sender_id);
1427 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Received mobility request with type " << msg.plan_type.type <<
" but ignored.");
1443 carma_v2x_msgs::msg::PlanType plan_type = msg.plan_type;
1444 std::string reccipientID = msg.m_header.recipient_id;
1445 std::string reqSenderID = msg.m_header.sender_id;
1448 bool isCutInJoin = plan_type.type == carma_v2x_msgs::msg::PlanType::PLATOON_CUT_IN_JOIN;
1449 bool isGapCreated = plan_type.type == carma_v2x_msgs::msg::PlanType::STOP_CREATE_GAP;
1455 if (isCutInJoin && isHostRecipent)
1458 std::string strategyParams = msg.strategy_params;
1459 std::vector<std::string> inputsParams;
1461 std::vector<std::string> join_index_parsed;
1463 int req_sender_join_index = std::stoi(join_index_parsed[1]);
1464 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Requesting join_index parsed: " << req_sender_join_index);
1468 if (
static_cast<size_t>(req_sender_join_index) ==
pm_.
host_platoon_.size()-1)
1471 RCLCPP_WARN(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Requested cut-in from rear, start approve cut-in and wait for lane change.");
1472 RCLCPP_WARN(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Due to the rear join nature, there is no need to slow down or create gap.");
1477 else if (req_sender_join_index >= 0 &&
static_cast<size_t>(req_sender_join_index) <
pm_.
host_platoon_.size()-1)
1481 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Requested cut-in index is: " << req_sender_join_index <<
", approve cut-in and start create gap.");
1488 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Abnormal cut-in index, abort operation.");
1495 else if (isGapCreated)
1497 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Gap is created, revert to normal operating speed.");
1516 bool isCandidateJoin = msg.plan_type.type == carma_v2x_msgs::msg::PlanType::PLATOON_FOLLOWER_JOIN;
1519 double obj_cross_track =
wm_->routeTrackPos(incoming_pose).crosstrack;
1521 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"current_cross_track error = " << abs(obj_cross_track -
current_crosstrack_));
1522 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"inTheSameLane = " << inTheSameLane);
1527 if (isTargetVehicle && isCandidateJoin)
1531 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Target vehicle " <<
pm_.
current_plan.
peerId <<
" is actually joining.");
1532 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Changing to PlatoonLeaderState and send ACK to target vehicle");
1545 newMember.
staticId = msg.m_header.sender_id;
1547 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"New member being added to platoon vector whose size is currently " <<
pm_.
host_platoon_.size());
1549 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"pm_ now thinks platoon size is " <<
pm_.
getHostPlatoonSize());
1558 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Received platoon request with vehicle id = " << msg.m_header.sender_id <<
" but in wrong lane. NACK");
1589 carma_v2x_msgs::msg::PlanType plan_type = msg.plan_type;
1596 bool isFrontJoin = plan_type.type == carma_v2x_msgs::msg::PlanType::JOIN_PLATOON_FROM_FRONT;
1597 bool isRearJoin = plan_type.type == carma_v2x_msgs::msg::PlanType::JOIN_PLATOON_AT_REAR;
1598 bool isCutInJoin = plan_type.type == carma_v2x_msgs::msg::PlanType::PLATOON_CUT_IN_JOIN;
1599 bool isDepart = (plan_type.type == carma_v2x_msgs::msg::PlanType::PLATOON_DEPARTURE);
1602 if (isFrontJoin || isRearJoin || isCutInJoin || isDepart)
1605 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Ignoring incoming request since we are already negotiating a join.");
1611 RCLCPP_WARN_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Received request with bogus message type " << plan_type.type <<
"; ignoring");
1620 carma_v2x_msgs::msg::MobilityHeader msgHeader = msg.m_header;
1621 std::string params = msg.strategy_params;
1622 std::string applicantId = msgHeader.sender_id;
1623 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Received mobility JOIN request from " << applicantId <<
" and PlanId = " << msgHeader.plan_id);
1624 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"The strategy parameters are " << params);
1625 if (params.length() == 0)
1627 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"The strategy parameters are empty, return no response");
1632 std::vector<std::string> inputsParams;
1636 std::vector<std::string> applicantSize_parsed;
1638 int applicantSize = std::stoi(applicantSize_parsed[1]);
1639 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"applicantSize: " << applicantSize);
1642 std::vector<std::string> applicantCurrentSpeed_parsed;
1644 double applicantCurrentSpeed = std::stod(applicantCurrentSpeed_parsed[1]);
1645 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"applicantCurrentSpeed: " << applicantCurrentSpeed);
1649 double applicantCurrentDtd =
wm_->routeTrackPos(incoming_pose).downtrack;
1650 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"applicantCurrentmemberUpdates from ecef pose: " << applicantCurrentDtd);
1653 double applicantCurrentCtd =
wm_->routeTrackPos(incoming_pose).crosstrack;
1654 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"applicantCurrentCtd from ecef pose: " << applicantCurrentCtd);
1656 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"isInLane = " << isInLane);
1666 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"The received mobility JOIN request from " << applicantId <<
" and PlanId = " << msgHeader.plan_id <<
" is a same-lane REAR-JOIN request !");
1669 if (hasEnoughRoomInPlatoon && isInLane)
1671 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"The current platoon has enough room for the applicant with size " << applicantSize);
1673 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"The current platoon rear dtd is " << currentRearDtd);
1675 double currentTimeGap = currentGap / applicantCurrentSpeed;
1676 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"The gap between current platoon rear and applicant is " << currentGap <<
"m or " << currentTimeGap <<
"s");
1679 RCLCPP_WARN(rclcpp::get_logger(
"platoon_strategic_ihp"),
"We should not receive any request from the vehicle in front of us. NACK it.");
1685 if (isDistanceCloseEnough)
1687 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"The applicant is close enough and we will allow it to try to join");
1688 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Change to LeaderWaitingState and waiting for " << msg.m_header.sender_id <<
" to join");
1699 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"The applicant is too far away from us. NACK.");
1705 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"The current platoon does not have enough room for applicant of size " << applicantSize <<
". NACK");
1711 else if (isFrontJoin)
1714 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"The received mobility JOIN request from " << applicantId <<
" and PlanId = " << msgHeader.plan_id <<
" is a same-lane FRONT-JOIN request !");
1717 if (hasEnoughRoomInPlatoon && isInLane)
1719 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"The current platoon has enough room for the applicant with size " << applicantSize);
1723 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"The current platoon front dtd is " << currentFrontDtd);
1726 double currentTimeGap = currentGap / applicantCurrentSpeed;
1727 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"The gap between current platoon front and applicant is " << currentGap <<
"m or " << currentTimeGap <<
"s");
1731 RCLCPP_WARN(rclcpp::get_logger(
"platoon_strategic_ihp"),
"The current time gap is not suitable for frontal join. NACK it.");
1741 if (isDistanceCloseEnough && isPlatoonNotSingle)
1743 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"The applicant is close enough for frontal join, send acceptance response");
1744 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Change to LeaderAborting state and waiting for " << msg.m_header.sender_id <<
" to join as the new platoon leader");
1769 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"The joining gap (" << currentGap <<
" m) is too far away from us or the target platoon size (" <<
pm_.
getHostPlatoonSize() <<
") is one. NACK.");
1775 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"The current platoon does not have enough room for applicant of size " << applicantSize <<
". NACK");
1781 else if (isCutInJoin)
1784 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"The received mobility JOIN request from " << applicantId <<
" and PlanId = " << msgHeader.plan_id <<
" is a CUT-IN-JOIN request !");
1790 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"The current platoon has enough room for the applicant with size " << applicantSize);
1791 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"The applicant is close enough for cut-in join, send acceptance response");
1792 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Change to Leading with operation state and waiting for " << msg.m_header.sender_id <<
" to change lane");
1802 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"The current platoon does not have enough room or the applicant is too far away from us. NACK the request.");
1803 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"The current applicant size: " << applicantSize <<
".");
1804 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"The applicant downtrack is: " <<
current_downtrack_ <<
".");
1805 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"The applicant crosstrack is: " <<
current_crosstrack_ <<
".");
1815 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Received mobility request with type " << msg.plan_type.type <<
" and ignored.");
1825 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Received mobility request with type " << msg.plan_type.type <<
" but ignored.");
1833 bool isCandidateJoin = msg.plan_type.type == carma_v2x_msgs::msg::PlanType::PLATOON_FRONT_JOIN;
1836 double obj_cross_track =
wm_->routeTrackPos(incoming_pose).crosstrack;
1838 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"current_cross_track error = " << abs(obj_cross_track -
current_crosstrack_));
1839 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"obj_cross_track = " << obj_cross_track);
1840 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"current_crosstrack_ = " <<
current_crosstrack_);
1841 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"inTheSameLane = " << inTheSameLane);
1842 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"isTargetVehicle = " << isTargetVehicle);
1843 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"isCandidateJoin = " << isCandidateJoin);
1844 if (isCandidateJoin && inTheSameLane && isTargetVehicle)
1846 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Old platoon leader " <<
pm_.
current_plan.
peerId <<
" has agreed to joining.");
1847 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Changing to PlatoonLeaderState and send ACK to the previous leader vehicle");
1861 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Received platoon request with vehicle id = " << msg.m_header.sender_id);
1862 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"The request type is " << msg.plan_type.type <<
" and we choose to ignore");
1885 carma_v2x_msgs::msg::PlanType plan_type = msg.plan_type;
1886 std::string strategyParams = msg.strategy_params;
1887 std::string reqSenderID = msg.m_header.sender_id;
1892 double applicantCurrentDtd =
wm_->routeTrackPos(incoming_pose).downtrack;
1893 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Applicant downtrack from ecef pose: " << applicantCurrentDtd);
1896 std::vector<std::string> inputsParams;
1899 std::vector<std::string> join_index_parsed;
1901 int req_sender_join_index = std::stoi(join_index_parsed[1]);
1902 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Requesting join_index parsed: " << req_sender_join_index);
1904 if (plan_type.type == carma_v2x_msgs::msg::PlanType::PLATOON_CUT_IN_JOIN)
1908 if (req_sender_join_index == -1)
1915 if (isFrontJoinerInPosition)
1917 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"The joining vehicle is cutting in from front. Gap is already sufficient.");
1924 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"The joining vehicle is cutting in from front.");
1925 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Host (leader) slow down notified, joining vehicle can prepare to join");
1931 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Front join geometry violation. NACK. cutinDtdDifference = " << cutinDtdDifference);
1938 else if (
static_cast<size_t>(req_sender_join_index) ==
pm_.
host_platoon_.size()-1)
1944 double rearGap = platoonEndVehicleDtd - applicantCurrentDtd;
1947 if (isRearJoinerInPosition)
1949 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Published Mobility cut-in-rear-Join request to relavent platoon member, host is leader.");
1950 RCLCPP_WARN(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Published Mobility cut-in-rear-Join request to relavent platoon members to signal gap creation.");
1956 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Rear join geometry violation. NACK. rearGap = " << rearGap);
1966 double gapFollowingVehicleDtd =
pm_.
host_platoon_[req_sender_join_index].vehiclePosition;
1967 double gapFollowerDiff = applicantCurrentDtd - gapFollowingVehicleDtd;
1968 bool isMidJoinerInPosition = gapFollowerDiff >=0 && gapFollowerDiff <= 3*
config_.
vehicleLength;
1972 if (isMidJoinerInPosition)
1975 carma_v2x_msgs::msg::MobilityRequest request;
1978 std::string recipient_ID =
pm_.
host_platoon_[req_sender_join_index+1].staticId;
1980 request.m_header.timestamp =
timer_factory_->now().nanoseconds() / 1000000;;
1982 request.plan_type.type = carma_v2x_msgs::msg::PlanType::PLATOON_CUT_IN_JOIN;
1988 fmter %platoon_size;
1993 fmter %req_sender_join_index;
1995 request.strategy_params = fmter.str();
1996 request.urgency = 50;
2001 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Published Mobility cut-in-mid-Join request to relavent platoon members to signal gap creation, host is leader.");
2002 RCLCPP_WARN(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Published Mobility cut-in-mid-Join request to relavent platoon members to signal gap creation.");
2003 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"The joining vehicle is cutting in at index: "<< req_sender_join_index <<
". Notify gap rear vehicle with ID: " << recipient_ID <<
" to slow down");
2008 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Mid join geometry violation. NACK. gapFollwerDiff = " << gapFollowerDiff);
2016 else if (plan_type.type == carma_v2x_msgs::msg::PlanType::STOP_CREATE_GAP)
2025 else if (plan_type.type == carma_v2x_msgs::msg::PlanType::CUT_IN_FRONT_DONE)
2027 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Cut-in from front lane change finished, leader revert to same-lane maneuver.");
2043 else if (plan_type.type == carma_v2x_msgs::msg::PlanType::CUT_IN_MID_OR_REAR_DONE)
2045 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Cut-in from mid/rear lane change finished, leader revert to same-lane maneuver.");
2055 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"CUT-IN join maneuver is already in operation, NACK incoming join requests from other candidates.");
2056 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Plan Type: " << plan_type.type );
2061 RCLCPP_WARN_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"End of method reached! Apparent logic fault above.");
2062 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"End of method reached! Apparent logic fault above.");
2071 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Received mobility request with type " << msg.plan_type.type <<
" but ignored.");
2086 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"mob_resp_cb: isCurrPlanValid = " << isCurrPlanValid <<
", isForCurrentPlan = " <<
2087 isForCurrentPlan <<
", isFromTargetVehicle = " << isFromTargetVehicle);
2088 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"sender ID = " << msg->m_header.sender_id <<
", current peer ID = " <<
pm_.
current_plan.
peerId);
2089 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"incoming plan ID = " << msg->m_header.plan_id <<
"current plan ID = " <<
pm_.
current_plan.
planId);
2091 if (!(isCurrPlanValid && isForCurrentPlan && isFromTargetVehicle))
2097 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
" Ignore the received response message as it was not intended for the host vehicle.");
2146 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"STANDBY state does nothing with msg from " << msg.m_header.sender_id);
2151 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Callback for candidate follower ");
2157 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"isForCurrentPlan " << isForCurrentPlan);
2160 if (isForCurrentPlan)
2162 if (msg.is_accepted)
2167 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"pm_.currentPlatoonID: " <<
pm_.
currentPlatoonID);
2168 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"pm_.targetPlatoonID: " <<
pm_.
currentPlatoonID);
2173 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"pm_.currentPlatoonID now: " <<
pm_.
currentPlatoonID);
2182 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"The leader " << msg.m_header.sender_id <<
" agreed on our join. Change to follower state.");
2183 RCLCPP_WARN(rclcpp::get_logger(
"platoon_strategic_ihp"),
"changed to follower");
2189 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"The leader " << msg.m_header.sender_id <<
" does not agree on our join. Change back to leader state.");
2190 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Trying again..");
2204 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Ignore received response message because it is not for the current plan.");
2209 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Ignore received response message because we are not in any negotiation process.");
2220 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"LEADERWAITING state does nothing with msg from " << msg.m_header.sender_id);
2238 carma_v2x_msgs::msg::PlanType plan_type = msg.plan_type;
2241 bool isFrontJoin = (plan_type.type == carma_v2x_msgs::msg::PlanType::JOIN_PLATOON_FROM_FRONT);
2245 if (isFrontJoin && msg.is_accepted)
2248 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Received positive response for front-join plan id = " <<
pm_.
current_plan.
planId);
2249 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Change to CandidateFollower state and prepare to update platoon information");
2276 carma_v2x_msgs::msg::PlanType plan_type = msg.plan_type;
2277 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"plan_type.type = " << plan_type.type);
2280 bool isCutInJoin = plan_type.type == carma_v2x_msgs::msg::PlanType::PLATOON_CUT_IN_JOIN && !
config_.
test_front_join;
2281 bool isRearJoin = plan_type.type == carma_v2x_msgs::msg::PlanType::JOIN_PLATOON_AT_REAR && !
config_.
test_front_join;
2282 bool isFrontJoin = plan_type.type == carma_v2x_msgs::msg::PlanType::JOIN_PLATOON_FROM_FRONT ||
config_.
test_front_join;
2283 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Joining type: isRearJoin = " << isRearJoin);
2284 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Joining type: isFrontJoin = " << isFrontJoin);
2285 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Joining type: isCutInJoin = " << isCutInJoin);
2290 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"My plan id = " <<
pm_.
current_plan.
planId <<
" and response plan Id = " << msg.m_header.plan_id);
2291 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Expected peer id = " <<
pm_.
current_plan.
peerId <<
" and response sender Id = " << msg.m_header.sender_id);
2297 if (isRearJoin && msg.is_accepted)
2299 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Received positive response for plan id = " <<
pm_.
current_plan.
planId);
2300 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Change to CandidateFollower state and notify trajectory failure in order to replan");
2309 else if (isFrontJoin && msg.is_accepted)
2311 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Received positive response for plan id = " <<
pm_.
current_plan.
planId);
2312 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Change to CandidateLeader state and prepare to become new leader. ");
2326 else if (isCutInJoin && msg.is_accepted)
2328 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Received positive response for plan id = " <<
pm_.
current_plan.
planId);
2329 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Change to Prepare to join state and prepare to change lane. ");
2344 RCLCPP_WARN_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Host received response for joining vehicles, remain idling as the host is a current platoon leader.");
2348 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Received negative response for plan id = " <<
pm_.
current_plan.
planId <<
". Resetting plan & platoon info.");
2356 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Ignore the response message because planID match: " << (
pm_.
current_plan.
planId == msg.m_header.plan_id));
2357 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"My plan id = " <<
pm_.
current_plan.
planId <<
" and response plan Id = " << msg.m_header.plan_id);
2358 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"And peer id match " << (
pm_.
current_plan.
peerId == msg.m_header.sender_id));
2359 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Expected peer id = " <<
pm_.
current_plan.
peerId <<
" and response sender Id = " << msg.m_header.sender_id);
2378 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Callback for leader aborting !");
2384 bool isForFrontJoin = msg.plan_type.type == carma_v2x_msgs::msg::PlanType::PLATOON_FRONT_JOIN;
2386 if (msg.plan_type.type == carma_v2x_msgs::msg::PlanType::UNKNOWN){
2387 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"*** plan type UNKNOWN");
2388 }
else if (msg.plan_type.type == carma_v2x_msgs::msg::PlanType::JOIN_PLATOON_FROM_FRONT){
2389 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"*** plan type JOIN_PLATOON_FROM_FRONT");
2390 }
else if (msg.plan_type.type == carma_v2x_msgs::msg::PlanType::PLATOON_CUT_IN_JOIN){
2391 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"*** plan type PLATOON_CUT_IN_JOIN");
2393 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"*** plan type not captured.");
2397 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"msg.m_header.sender_id " << msg.m_header.sender_id);
2398 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Plan Type " << msg.plan_type.type);
2399 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"isForFrontJoin " << isForFrontJoin);
2400 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"isForCurrentPlan " << isForCurrentPlan);
2401 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"isFromTargetVehicle " << isFromTargetVehicle);
2404 if (isForCurrentPlan && isFromTargetVehicle && isForFrontJoin)
2406 if (msg.is_accepted)
2412 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"The new leader " << msg.m_header.sender_id <<
" agreed on the frontal join. Change to follower state.");
2413 RCLCPP_WARN(rclcpp::get_logger(
"platoon_strategic_ihp"),
"changed to follower");
2421 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"The new leader " << msg.m_header.sender_id <<
" does not agree on the frontal join. Change back to leader state.");
2427 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Failed to remove candidate leader from the platoon!");
2436 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Ignore received response message because it is not for the current plan.");
2441 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Ignore received response message because we are not in any negotiation process.");
2448 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"CANDIDATELEADER state does nothing with msg from " << msg.m_header.sender_id);
2454 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"LEADWITHOPERATION state does nothing with msg from " << msg.m_header.sender_id);
2465 carma_v2x_msgs::msg::PlanType plan_type = msg.plan_type;
2466 bool isCreatingGap = plan_type.type == carma_v2x_msgs::msg::PlanType::PLATOON_CUT_IN_JOIN;
2467 bool isFinishLaneChangeFront = plan_type.type == carma_v2x_msgs::msg::PlanType::CUT_IN_FRONT_DONE;
2468 bool isFinishLaneChangeMidorRear = plan_type.type == carma_v2x_msgs::msg::PlanType::CUT_IN_MID_OR_REAR_DONE;
2469 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"isCreatingGap = " << isCreatingGap <<
", is_neighbor_record_complete = " <<
pm_.
is_neighbor_record_complete_);
2471 if (!msg.is_accepted)
2473 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Request " << msg.m_header.plan_id <<
" was rejected by leader.");
2474 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Action Plan reset.");
2475 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Trying again....");
2487 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Gap is now sufficiently large.");
2488 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"in mob_resp_cb safeToLaneChange_: " <<
safeToLaneChange_);
2491 carma_v2x_msgs::msg::MobilityRequest request;
2495 request.m_header.timestamp =
timer_factory_->now().nanoseconds() / 1000000;;
2497 request.plan_type.type = carma_v2x_msgs::msg::PlanType::STOP_CREATE_GAP;
2499 request.urgency = 50;
2504 fmter %platoon_size;
2511 request.strategy_params = fmter.str();
2513 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Published Mobility Candidate-Join request to the leader to stop creating gap");
2517 else if (isFinishLaneChangeFront)
2519 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Cut-in from front lane change finished, the joining vehicle revert to same-lane maneuver.");
2522 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"pm_.currentPlatoonID: " <<
pm_.
currentPlatoonID);
2523 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"pm_.targetPlatoonID: " <<
pm_.
targetPlatoonID);
2527 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"pm_.currentPlatoonID now: " <<
pm_.
currentPlatoonID);
2534 else if (isFinishLaneChangeMidorRear)
2536 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Cut-in from mid or rear, the lane change finished, the joining vehicle revert to same-lane maneuver.");
2545 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"End of mob_resp_cb_preparetojoin");
2559 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Ignoring message since host speed is below platooning speed.");
2564 std::string strategy = msg->strategy;
2567 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Ignoring mobility operation message for " << strategy <<
" strategy.");
2571 carma_v2x_msgs::msg::MobilityResponse response;
2573 response.m_header.recipient_id = msg->m_header.sender_id;
2574 response.m_header.plan_id = msg->m_header.plan_id;
2575 response.m_header.timestamp =
timer_factory_->now().nanoseconds() / 1000000;
2578 response.plan_type.type = msg->plan_type.type;
2583 response.is_accepted =
true;
2588 response.is_accepted =
false;
2593 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
" NO response to mobility request. ");
2602 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Run LeaderWaiting State ");
2608 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"LeaderWaitingState is timeout, changing back to PlatoonLeaderState.");
2613 carma_v2x_msgs::msg::MobilityOperation status;
2616 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"publish status message");
2622 std::this_thread::sleep_for(std::chrono::milliseconds(sleepDuration));
2627 unsigned long tsStart =
timer_factory_->now().nanoseconds() / 1000000;
2637 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"time since last heart beat: " << tsStart -
prevHeartBeatTime_);
2638 if (isTimeForHeartBeat)
2640 carma_v2x_msgs::msg::MobilityOperation infoOperation;
2644 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Published heart beat platoon INFO mobility operation message");
2651 if (isCurrentPlanTimeout)
2653 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Give up current on waiting plan with planId: " <<
pm_.
current_plan.
planId);
2660 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"hasFollower" << hasFollower);
2664 carma_v2x_msgs::msg::MobilityOperation statusOperation;
2668 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Published platoon STATUS operation message as a Leader with Follower");
2675 std::this_thread::sleep_for(std::chrono::milliseconds(sleepDuration));
2684 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"run follower");
2692 carma_v2x_msgs::msg::MobilityOperation status;
2698 if (vehicleInFront == 0)
2703 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"noLeaderUpdatesCounter = " <<
noLeaderUpdatesCounter <<
" and change to leader state");
2718 std::this_thread::sleep_for(std::chrono::milliseconds(sleepDuration));
2731 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"timeout1: " << tsStart -
candidatestateStartTime);
2732 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"waitingStateTimeout: " <<
waitingStateTimeout * 1000);
2733 if (isCurrentStateTimeout)
2735 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"The current candidate follower state is timeout. Change back to leader state.");
2743 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"pm_.current_plan.planStartTime: " <<
pm_.
current_plan.
planStartTime);
2745 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"NEGOTIATION_TIMEOUT: " <<
NEGOTIATION_TIMEOUT);
2751 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"The current plan did not receive any response. Abort and change to leader state.");
2752 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Changed the state back to Leader");
2759 double currentGap = 0.0;
2763 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"curent gap calculated from back of neighbor platoon: " << currentGap);
2764 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"pm_.neighbor_platoon_.back().vehiclePosition " <<
pm_.
neighbor_platoon_.back().vehiclePosition);
2770 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"curent gap when there is no neighbor platoon: " << currentGap);
2773 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Based on desired join time gap, the desired join distance gap is " << desiredJoinGap2 <<
" ms");
2774 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Since we have max allowed gap as " <<
config_.
desiredJoinGap <<
" m then max join gap became " << maxJoinGap <<
" m");
2775 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"The current gap from radar is " << currentGap <<
" m");
2778 carma_v2x_msgs::msg::MobilityRequest request;
2780 long currentTime =
timer_factory_->now().nanoseconds() / 1000000;
2781 request.m_header.plan_id = planId;
2784 request.m_header.timestamp = currentTime;
2786 request.plan_type.type = carma_v2x_msgs::msg::PlanType::PLATOON_FOLLOWER_JOIN;
2788 request.strategy_params =
"";
2789 request.urgency = 50;
2792 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Published Mobility Candidate-Join request to the leader");
2793 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"current plan peer id: " <<
pm_.
current_plan.
peerId);
2810 carma_v2x_msgs::msg::MobilityOperation status;
2813 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Published platoon STATUS operation message as Candidate Follower");
2821 std::this_thread::sleep_for(std::chrono::milliseconds(sleepDuration));
2835 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"timeout1: " << tsStart -
candidatestateStartTime);
2836 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"waitingStateTimeout: " <<
waitingStateTimeout * 1000);
2837 if (isCurrentStateTimeout)
2839 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"The current leader aborting state is timeout. Change back to leader state.");
2856 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Based on desired join time gap, the desired join distance gap is " << desiredJoinGap2 <<
" m");
2857 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Since we have max allowed gap as " <<
config_.
desiredJoinGap <<
" m then max join gap became " << maxJoinGap <<
" m");
2858 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"The current gap to joiner is " << currentGap <<
" m");
2875 carma_v2x_msgs::msg::MobilityRequest request;
2877 long currentTime =
timer_factory_->now().nanoseconds() / 1000000;
2878 request.m_header.plan_id = planId;
2881 request.m_header.timestamp = currentTime;
2886 int dummy_join_index = -2;
2887 fmter %platoon_size;
2892 fmter %dummy_join_index;
2893 request.strategy_params = fmter.str();
2896 request.plan_type.type = carma_v2x_msgs::msg::PlanType::PLATOON_FRONT_JOIN;
2898 request.urgency = 50;
2901 RCLCPP_WARN(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Published Mobility Candidate-Join request to the new leader");
2908 carma_v2x_msgs::msg::MobilityOperation status;
2911 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Published platoon STATUS operation message");
2917 std::this_thread::sleep_for(std::chrono::milliseconds(sleepDuration));
2923 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Run Candidate Leader State ");
2929 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"CandidateLeader state is timeout, changing back to PlatoonLeaderState.");
2936 carma_v2x_msgs::msg::MobilityOperation status;
2939 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"publish status message");
2944 std::this_thread::sleep_for(std::chrono::milliseconds(sleepDuration));
2953 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"time since last heart beat: " << tsStart -
prevHeartBeatTime_);
2954 if (isTimeForHeartBeat)
2956 carma_v2x_msgs::msg::MobilityOperation infoOperation;
2968 carma_v2x_msgs::msg::MobilityOperation statusOperation;
2976 std::this_thread::sleep_for(std::chrono::milliseconds(sleepDuration));
2995 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"timeout1: " << tsStart -
candidatestateStartTime);
2996 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"waitingStateTimeout: " <<
waitingStateTimeout * 1000);
2997 if (isCurrentStateTimeout)
2999 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"The current prepare to join state is timeout. Change back to leader state and abort lane change.");
3015 carma_v2x_msgs::msg::MobilityOperation status;
3018 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Published platoon STATUS operation message");
3024 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"calculated join index: " <<
target_join_index_);
3027 carma_v2x_msgs::msg::MobilityRequest request;
3029 long currentTime =
timer_factory_->now().nanoseconds() / 1000000;
3030 request.m_header.plan_id = planId;
3033 request.m_header.timestamp = currentTime;
3034 request.plan_type.type = carma_v2x_msgs::msg::PlanType::PLATOON_CUT_IN_JOIN;
3036 request.urgency = 50;
3041 fmter %platoon_size;
3047 request.strategy_params = fmter.str();
3049 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Published Mobility cut-in join request to leader " << request.m_header.recipient_id <<
" with planId = " << planId);
3107 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"standby state, nothing to do");
3112 RCLCPP_ERROR_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"///// unhandled state " <<
pm_.
current_platoon_state);
3127 carma_planning_msgs::msg::Maneuver maneuver_msg;
3128 maneuver_msg.type = carma_planning_msgs::msg::Maneuver::LANE_FOLLOWING;
3129 maneuver_msg.lane_following_maneuver.parameters.negotiation_type = carma_planning_msgs::msg::ManeuverParameters::PLATOONING;
3130 maneuver_msg.lane_following_maneuver.parameters.presence_vector = carma_planning_msgs::msg::ManeuverParameters::HAS_TACTICAL_PLUGIN;
3131 maneuver_msg.lane_following_maneuver.parameters.planning_tactical_plugin =
"platooning_tactical_plugin";
3132 maneuver_msg.lane_following_maneuver.parameters.planning_strategic_plugin =
"platoon_strategic_ihp";
3133 maneuver_msg.lane_following_maneuver.start_dist = current_dist;
3134 maneuver_msg.lane_following_maneuver.start_speed = current_speed;
3135 maneuver_msg.lane_following_maneuver.start_time = current_time;
3136 maneuver_msg.lane_following_maneuver.end_dist = end_dist;
3137 maneuver_msg.lane_following_maneuver.end_speed = target_speed;
3140 maneuver_msg.lane_following_maneuver.end_time = current_time + rclcpp::Duration(
config_.
time_step*1e9);
3141 maneuver_msg.lane_following_maneuver.lane_ids = {
std::to_string(lane_id) };
3143 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"in compose maneuver lane id:"<< lane_id);
3145 lanelet::ConstLanelet current_lanelet =
wm_->getMap()->laneletLayer.get(lane_id);
3146 if(!
wm_->getMapRoutingGraph()->following(current_lanelet,
false).empty())
3149 auto next_lanelet_id =
wm_->getMapRoutingGraph()->following(current_lanelet,
false).front().id();
3150 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"next_lanelet_id:"<< next_lanelet_id);
3151 maneuver_msg.lane_following_maneuver.lane_ids.push_back(
std::to_string(next_lanelet_id));
3155 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"No following lanelets");
3158 current_time = maneuver_msg.lane_following_maneuver.end_time;
3159 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Creating lane follow start dist:"<<current_dist<<
" end dist:"<<end_dist);
3160 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Duration:"<< rclcpp::Time(maneuver_msg.lane_following_maneuver.end_time).seconds() - rclcpp::Time(maneuver_msg.lane_following_maneuver.start_time).seconds());
3161 return maneuver_msg;
3167 carma_planning_msgs::msg::Maneuver maneuver_msg;
3169 maneuver_msg.type = carma_planning_msgs::msg::Maneuver::LANE_CHANGE;
3170 maneuver_msg.lane_change_maneuver.parameters.negotiation_type = carma_planning_msgs::msg::ManeuverParameters::PLATOONING;
3171 maneuver_msg.lane_change_maneuver.parameters.presence_vector = carma_planning_msgs::msg::ManeuverParameters::HAS_TACTICAL_PLUGIN;
3172 maneuver_msg.lane_change_maneuver.parameters.planning_tactical_plugin =
"cooperative_lanechange";
3173 maneuver_msg.lane_change_maneuver.parameters.planning_strategic_plugin =
"platoon_strategic_ihp";
3174 maneuver_msg.lane_change_maneuver.start_dist = current_dist;
3175 maneuver_msg.lane_change_maneuver.start_speed = current_speed;
3176 maneuver_msg.lane_change_maneuver.start_time = current_time;
3177 maneuver_msg.lane_change_maneuver.end_dist = end_dist;
3178 maneuver_msg.lane_change_maneuver.end_speed = target_speed;
3180 maneuver_msg.lane_following_maneuver.parameters.maneuver_id =
boost::uuids::to_string(boost::uuids::random_generator()());
3183 double cur_plus_target = current_speed + target_speed;
3184 if (cur_plus_target < 0.00001)
3186 maneuver_msg.lane_change_maneuver.end_time = current_time + rclcpp::Duration(
config_.
time_step*1e9);
3191 maneuver_msg.lane_change_maneuver.end_time = current_time + rclcpp::Duration(20.0*1e9);
3196 maneuver_msg.lane_change_maneuver.starting_lane_id = {
std::to_string(starting_lane_id) };
3197 maneuver_msg.lane_change_maneuver.ending_lane_id = {
std::to_string(ending_lane_id) };
3199 current_time = maneuver_msg.lane_change_maneuver.end_time;
3200 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Creating lane change start dist:"<<current_dist<<
" end dist:"<<end_dist);
3201 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Duration:"<< rclcpp::Time(maneuver_msg.lane_change_maneuver.end_time).seconds() - rclcpp::Time(maneuver_msg.lane_change_maneuver.start_time).seconds());
3202 return maneuver_msg;
3208 if(maneuver.type == carma_planning_msgs::msg::Maneuver::LANE_FOLLOWING){
3209 speed = maneuver.lane_following_maneuver.end_speed;
3210 current_progress = maneuver.lane_following_maneuver.end_dist;
3211 if (maneuver.lane_following_maneuver.lane_ids.empty())
3213 RCLCPP_WARN_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Lane id of lane following maneuver not set. Using 0");
3218 lane_id = stoi(maneuver.lane_following_maneuver.lane_ids[0]);
3227 lanelet::BasicPoint2d current_loc(
pose_msg_.pose.position.x,
pose_msg_.pose.position.y);
3230 auto current_lanelets = lanelet::geometry::findNearest(
wm_->getMap()->laneletLayer, current_loc, 10);
3232 lanelet::ConstLanelet current_lanelet;
3235 for (
auto llt: current_lanelets)
3237 if (
wm_->getRoute()->contains(llt.second))
3239 current_lanelet = llt.second;
3245 if(current_lanelets.size() == 0)
3247 RCLCPP_WARN_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Cannot find any lanelet in map!");
3252 auto shortest_path =
wm_->getRoute()->shortestPath();
3255 double current_progress =
wm_->routeTrackPos(current_loc).downtrack;
3261 double target_speed;
3265 double total_maneuver_length = current_progress +
config_.
time_step * target_speed;
3269 double route_length =
wm_->getRouteEndTrackPos().downtrack;
3270 total_maneuver_length = std::min(total_maneuver_length, route_length);
3273 if(req.prior_plan.maneuvers.size()!= 0)
3275 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Provided with initial plan...");
3276 time_progress = req.prior_plan.planning_completion_time;
3277 int end_lanelet = 0;
3278 updateCurrentStatus(req.prior_plan.maneuvers.back(), speed_progress, current_progress, end_lanelet);
3281 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Starting Loop");
3282 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"total_maneuver_length: " << total_maneuver_length <<
" route_length: " << route_length);
3285 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"in mvr callback safeToLaneChange: " <<
safeToLaneChange_);
3288 lanelet::Id current_lanelet_id = current_lanelet.id();
3292 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"current_lanelet_id: " << current_lanelet_id);
3298 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"target_crosstrack: " << target_crosstrack);
3301 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"crosstrackDiff: " << crosstrackDiff);
3302 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"isLaneChangeFinished: " << isLaneChangeFinished);
3305 if(!isLaneChangeFinished)
3308 while (current_progress < total_maneuver_length)
3310 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Lane Change Maneuver for Cut-in join ! ");
3311 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"current_progress: "<< current_progress);
3312 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"speed_progress: " << speed_progress);
3313 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"target_speed: " << target_speed);
3314 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"time_progress: " << rclcpp::Time(time_progress).seconds());
3317 double end_dist = total_maneuver_length;
3318 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"end_dist: " << end_dist);
3320 double dist_diff = end_dist - current_progress;
3321 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"dist_diff: " << dist_diff);
3327 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"lc_end_dist before buffer: " << lc_end_dist);
3329 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"lc_end_dist after buffer: " << lc_end_dist);
3333 auto target_lanelets = lanelet::geometry::findNearest(
wm_->getMap()->laneletLayer,
target_cutin_pose_, 1);
3334 if (target_lanelets.empty())
3336 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"The target cutin pose is not on a valid lanelet. So no lane change!");
3339 lanelet::Id target_lanelet_id = target_lanelets[0].second.id();
3340 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"target_lanelet_id: " << target_lanelet_id);
3342 lanelet::ConstLanelet starting_lanelet =
wm_->getMap()->laneletLayer.get(current_lanelet_id);
3343 lanelet::ConstLanelet ending_lanelet =
wm_->getMap()->laneletLayer.get(target_lanelet_id);
3346 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"lanechangePossible: " << lanechangePossible);
3348 if (lanechangePossible)
3350 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Lane change possible, planning it.. " );
3352 speed_progress, target_speed, current_lanelet_id, target_lanelet_id , time_progress));
3357 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Lane change impossible, planning lanefollow instead ... " );
3359 speed_progress, target_speed, current_lanelet_id, time_progress));
3364 current_progress += dist_diff;
3366 time_progress = resp.new_plan.maneuvers.back().lane_change_maneuver.end_time;
3367 speed_progress = target_speed;
3368 if(current_progress >= total_maneuver_length)
3380 while (current_progress < total_maneuver_length)
3382 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Same Lane Maneuver for platoon join ! ");
3383 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"current_progress: "<< current_progress);
3384 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"speed_progress: " << speed_progress);
3385 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"target_speed: " << target_speed);
3386 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"time_progress: " << rclcpp::Time(time_progress).seconds());
3387 double end_dist = total_maneuver_length;
3388 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"end_dist: " << end_dist);
3389 double dist_diff = end_dist - current_progress;
3390 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"dist_diff: " << dist_diff);
3391 if(end_dist < current_progress)
3398 speed_progress, target_speed, current_lanelet_id, time_progress));
3400 current_progress += dist_diff;
3401 time_progress = resp.new_plan.maneuvers.back().lane_following_maneuver.end_time;
3402 speed_progress = target_speed;
3403 if(current_progress >= total_maneuver_length)
3414 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Planning Same Lane Maneuver! ");
3415 while (current_progress < total_maneuver_length)
3417 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Same Lane Maneuver for platoon join ! ");
3418 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"current_progress: "<< current_progress);
3419 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"speed_progress: " << speed_progress);
3420 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"target_speed: " << target_speed);
3421 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"time_progress: " << rclcpp::Time(time_progress).seconds());
3422 double end_dist = total_maneuver_length;
3423 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"end_dist: " << end_dist);
3424 double dist_diff = end_dist - current_progress;
3425 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"dist_diff: " << dist_diff);
3426 if (end_dist < current_progress)
3432 speed_progress, target_speed,current_lanelet_id, time_progress));
3435 current_progress += dist_diff;
3436 time_progress = resp.new_plan.maneuvers.back().lane_following_maneuver.end_time;
3437 speed_progress = target_speed;
3438 if(current_progress >= total_maneuver_length)
3446 if(resp.new_plan.maneuvers.size() == 0)
3448 RCLCPP_WARN_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Cannot plan maneuver because no route is found");
3454 resp.new_plan.maneuvers = {};
3455 RCLCPP_WARN_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Platoon size 1 so Empty maneuver sent");
3459 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Planning maneuvers: ");
3460 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"safeToLaneChange_: " <<
safeToLaneChange_);
3461 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"pm_.getHostPlatoonSize(): " <<
pm_.
getHostPlatoonSize());
3467 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"change the state from standby to leader at start-up");
3470 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"current_downtrack: " <<
current_downtrack_);
3477 lanelet::ConstLanelet starting_lanelet =
wm_->getMap()->laneletLayer.get(start_lanelet_id);
3478 lanelet::ConstLanelet ending_lanelet =
wm_->getMap()->laneletLayer.get(target_lanelet_id);
3479 lanelet::ConstLanelet current_lanelet = starting_lanelet;
3480 bool shared_boundary_found =
false;
3482 while(!shared_boundary_found)
3485 if(current_lanelet.leftBound() == ending_lanelet.rightBound())
3487 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Lanelet " <<
std::to_string(current_lanelet.id()) <<
" shares left boundary with " <<
std::to_string(ending_lanelet.id()));
3488 shared_boundary_found =
true;
3490 else if(current_lanelet.rightBound() == ending_lanelet.leftBound())
3492 RCLCPP_DEBUG_STREAM(rclcpp::get_logger(
"platoon_strategic_ihp"),
"Lanelet " <<
std::to_string(current_lanelet.id()) <<
" shares right boundary with " <<
std::to_string(ending_lanelet.id()));
3493 shared_boundary_found =
true;
3499 if(
wm_->getMapRoutingGraph()->following(current_lanelet,
false).empty())
3505 current_lanelet =
wm_->getMapRoutingGraph()->following(current_lanelet,
false).front();
3506 if(current_lanelet.id() == starting_lanelet.id())
Position in a track based coordinate system where the axis are downtrack and crosstrack....
Class containing the logic for platoon manager. It is responsible for keeping track of the platoon me...
std::string platoonLeaderID
std::string neighborPlatoonID
int getNumberOfVehicleInFront()
Get number of vehicles in front of host vehicle inside platoon.
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.
size_t neighbor_platoon_info_size_
double getDistanceToPredVehicle()
Returns distance to the predessecor vehicle, in m.
std::string HostMobilityId
std::vector< PlatoonMember > neighbor_platoon_
size_t dynamic_leader_index_
std::string currentPlatoonID
void updateHostSpeeds(const double cmdSpeed, const double actualSpeed)
Stores the latest info on host vehicle's command & actual speeds.
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.
bool is_neighbor_record_complete_
double getPredecessorPosition()
UCLA: Return the position of the preceding vehicle, in m.
std::string neighbor_platoon_leader_id_
void hostMemberUpdates(const std::string &senderId, const std::string &platoonId, const std::string ¶ms, 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.
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...
std::string targetPlatoonID
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.
PlatoonState current_platoon_state
double getPredecessorTimeHeadwaySum()
UCLA: Return the time headway summation of all predecessors, in s.
std::vector< PlatoonMember > host_platoon_
const std::string dummyID
std::string getHostStaticID() const
Returns current host static ID as a string.
void neighborMemberUpdates(const std::string &senderId, const std::string &platoonId, const std::string ¶ms, 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.
int candidate_follower_delay_count_
MobilityResponseCB mobility_response_publisher_
void mob_op_cb_leaderaborting(const carma_v2x_msgs::msg::MobilityOperation &msg)
Function to process mobility operation in leaderaborting state.
carma_v2x_msgs::msg::LocationECEF pose_to_ecef(geometry_msgs::msg::PoseStamped pose_msg)
Function to convert pose from map frame to ecef location.
bool isJoiningVehicleNearPlatoon(double joining_downtrack, double joining_crosstrack)
The method for platoon leader to determine if the joining vehicle is closeby. (Note: Used when host v...
void mob_resp_cb_leadwithoperation(const carma_v2x_msgs::msg::MobilityResponse &msg)
Function to process mobility response in leadwithoperation state (cut-in join)
PlatoonStrategicIHPPlugin(carma_wm::WorldModelConstPtr wm, PlatoonPluginConfig config, MobilityResponseCB mobility_response_publisher, MobilityRequestCB mobility_request_publisher, MobilityOperationCB mobility_operation_publisher, PlatooningInfoCB platooning_info_publisher, std::shared_ptr< carma_ros2_utils::timers::TimerFactory > timer_factory)
Constructor.
MobilityRequestResponse mob_req_cb_preparetojoin(const carma_v2x_msgs::msg::MobilityRequest &msg)
Function to process mobility request in preparetojoin state (cut-in join)
MobilityRequestResponse mob_req_cb_leadwithoperation(const carma_v2x_msgs::msg::MobilityRequest &msg)
Function to process mobility request in leadwithoperation state (cut-in join)
MobilityOperationCB mobility_operation_publisher_
void georeference_cb(const std_msgs::msg::String::UniquePtr msg)
Callback for the georeference.
bool isVehicleRightInFront(double downtrack, double crosstrack)
Function to determine if a target vehicle is in the front of host vehicle note: This is only applicab...
carma_v2x_msgs::msg::MobilityOperation composeMobilityOperationLeaderAborting()
Function to compose mobility operation in LeaderAborting state.
void mob_op_cb_candidateleader(const carma_v2x_msgs::msg::MobilityOperation &msg)
Function to process mobility operation in candidateleader state.
const std::string OPERATION_STATUS_TYPE
MobilityRequestResponse mob_req_cb_follower(const carma_v2x_msgs::msg::MobilityRequest &msg)
Function to process mobility request in follower state.
std::shared_ptr< carma_ros2_utils::timers::TimerFactory > timer_factory_
carma_v2x_msgs::msg::MobilityOperation composeMobilityOperationLeadWithOperation(const std::string &type)
Function to compose mobility operation in LeadWithOperation (cut-in join)
void setPMState(PlatoonState desiredState)
UCLA Setter: function to set pm_.platoon_state.
PlatoonPluginConfig config_
carma_v2x_msgs::msg::LocationECEF mob_op_find_ecef_from_STATUS_params(std::string strategyParams)
Function to process mobility operation for STATUS params.
int noLeaderUpdatesCounter
const std::string OPERATION_INFO_PARAMS
carma_v2x_msgs::msg::MobilityOperation composeMobilityOperationFollower()
Function to compose mobility operation in follower state.
const std::string PLATOONING_STRATEGY
void run_follower()
Run Follower State.
double mob_op_find_platoon_length_from_INFO_params(std::string strategyParams)
Function to process mobility operation INFO params to find platoon length in m.
carma_v2x_msgs::msg::MobilityOperation composeMobilityOperationPrepareToJoin()
Function to compose mobility operation in PrepareToJoin (cut-in join)
int numLeaderAbortingCalls_
MobilityRequestResponse handle_mob_req(const carma_v2x_msgs::msg::MobilityRequest &msg)
Function to the process and respond to the mobility request.
const std::string OPERATION_INFO_TYPE
MobilityRequestResponse mob_req_cb_leader(const carma_v2x_msgs::msg::MobilityRequest &msg)
Function to process mobility request in leader state.
int LEADER_TIMEOUT_COUNTER_LIMIT
void mob_req_cb(const carma_v2x_msgs::msg::MobilityRequest::UniquePtr msg)
Callback function for Mobility Request Message.
double waitingStateTimeout
void mob_op_cb_leaderwaiting(const carma_v2x_msgs::msg::MobilityOperation &msg)
Function to process mobility operation in leader waiting state.
carma_v2x_msgs::msg::MobilityOperation composeMobilityOperationCandidateLeader()
Function to compose mobility operation in CandidateLeader.
void updateCurrentStatus(carma_planning_msgs::msg::Maneuver maneuver, double &speed, double ¤t_progress, int &lane_id)
Update maneuver status based on prior plan.
carma_v2x_msgs::msg::MobilityOperation composeMobilityOperationCandidateFollower()
Function to compose mobility operation in candidate follower state.
void mob_op_cb_leadwithoperation(const carma_v2x_msgs::msg::MobilityOperation &msg)
Function to process mobility operation in LeadWithOperation state (cut-in join)
carma_planning_msgs::msg::Maneuver composeManeuverMessage(double current_dist, double end_dist, double current_speed, double target_speed, int lane_id, rclcpp::Time ¤t_time)
Find lanelet index from path.
std::shared_ptr< lanelet::projection::LocalFrameProjector > map_projector_
carma_planning_msgs::msg::Plugin plugin_discovery_msg_
void mob_resp_cb_candidateleader(const carma_v2x_msgs::msg::MobilityResponse &msg)
Function to process mobility response in candidateleader state.
MobilityRequestResponse mob_req_cb_candidatefollower(const carma_v2x_msgs::msg::MobilityRequest &msg)
Function to process mobility request in candidate follower state.
double findSpeedLimit(const lanelet::ConstLanelet &llt)
Function to find speed limit of a lanelet.
void mob_op_cb_candidatefollower(const carma_v2x_msgs::msg::MobilityOperation &msg)
Function to process mobility operation in candidate follower state.
std::string georeference_
MobilityRequestResponse mob_req_cb_leaderwaiting(const carma_v2x_msgs::msg::MobilityRequest &msg)
Function to process mobility request in leader waiting state.
double current_crosstrack_
void run_leader_waiting()
Run Leader Waiting State.
void run_candidate_follower()
Run Candidate Follower State.
void mob_resp_cb_leader(const carma_v2x_msgs::msg::MobilityResponse &msg)
Function to process mobility response in leader state.
void mob_resp_cb_follower(const carma_v2x_msgs::msg::MobilityResponse &msg)
Function to process mobility response in follower state.
carma_planning_msgs::msg::Maneuver composeLaneChangeManeuverMessage(double current_dist, double end_dist, double current_speed, double target_speed, int starting_lane_id, int ending_lane_id, rclcpp::Time ¤t_time)
Find start(current) and target(end) lanelet index from path to generate lane change maneuver message.
void setConfig(const PlatoonPluginConfig &config)
Set the current config.
MobilityRequestResponse mob_req_cb_standby(const carma_v2x_msgs::msg::MobilityRequest &msg)
Function to process mobility request in standby state.
void run_leader_aborting()
Run Leader Aborting State.
lanelet::BasicPoint2d ecef_to_map_point(carma_v2x_msgs::msg::LocationECEF ecef_point)
Function to convert ecef location to a 2d point in map frame.
bool is_lanechange_possible(lanelet::Id start_lanelet_id, lanelet::Id target_lanelet_id)
Function to check if lanechange is possible.
void run_prepare_to_join()
UCLA Run prepare to join State.
void mob_resp_cb_preparetojoin(const carma_v2x_msgs::msg::MobilityResponse &msg)
Function to process mobility response in preparetojoin state.
MobilityRequestResponse mob_req_cb_candidateleader(const carma_v2x_msgs::msg::MobilityRequest &msg)
Function to process mobility request in candidateleader state.
carma_v2x_msgs::msg::MobilityOperation composeMobilityOperationLeaderWaiting()
Function to compose mobility operation in leader waiting state.
PlatoonManager getHostPM()
UCLA Getter: for PlatoonManager class.
void mob_op_cb(const carma_v2x_msgs::msg::MobilityOperation::UniquePtr msg)
Callback function for Mobility Operation Message.
void run_candidate_leader()
Run Candidate Leader State.
long candidatestateStartTime
double current_downtrack_
geometry_msgs::msg::PoseStamped pose_msg_
bool isVehicleNearTargetPlatoon(double rearVehicleDtd, double frontVehicleDtd, double frontVehicleCtd)
Function to determine if the host vehicle is close to the target platoon (used for cut-in join scenar...
void cmd_cb(const geometry_msgs::msg::TwistStamped::UniquePtr msg)
Callback for the control command.
void pose_cb(const geometry_msgs::msg::PoseStamped::UniquePtr msg)
Callback function for current pose.
carma_v2x_msgs::msg::MobilityOperation composeMobilityOperationSTATUS()
Function to compose mobility operation message with STATUS params.
void mob_resp_cb(const carma_v2x_msgs::msg::MobilityResponse::UniquePtr msg)
Callback function for Mobility Response Message.
void mob_resp_cb_standby(const carma_v2x_msgs::msg::MobilityResponse &msg)
Function to process mobility response in standby state.
lanelet::BasicPoint2d target_cutin_pose_
carma_v2x_msgs::msg::LocationECEF mob_op_find_ecef_from_INFO_params(std::string strategyParams)
Function to process mobility operation INFO params to find platoon leader's ecef location.
void setHostECEF(carma_v2x_msgs::msg::LocationECEF pose_ecef_point)
UCLA Update the private variable pose_ecef_point_.
unsigned long prevHeartBeatTime_
int findLaneletIndexFromPath(int target_id, lanelet::routing::LaneletPath &path)
Find lanelet index from path.
carma_v2x_msgs::msg::MobilityOperation composeMobilityOperationINFO()
Function to compose mobility operation message with INFO params.
void run_lead_with_operation()
UCLA Run lead with operation State.
PlatooningInfoCB platooning_info_publisher_
bool onSpin()
Spin callback function.
const std::string OPERATION_STATUS_PARAMS
carma_planning_msgs::msg::PlatooningInfo composePlatoonInfoMsg()
Compose Platoon information message.
void mob_resp_cb_candidatefollower(const carma_v2x_msgs::msg::MobilityResponse &msg)
Function to process mobility response in candidate follower state.
const std::string JOIN_PARAMS
void run_leader()
Run Leader State.
carma_v2x_msgs::msg::LocationECEF pose_ecef_point_
double findLaneWidth()
Find lanelet width from local position.
void twist_cb(const geometry_msgs::msg::TwistStamped::UniquePtr msg)
Callback for the twist subscriber, which will store latest twist locally.
void mob_op_cb_standby(const carma_v2x_msgs::msg::MobilityOperation &msg)
Function to process mobility operation in standby state.
MobilityRequestResponse mob_req_cb_leaderaborting(const carma_v2x_msgs::msg::MobilityRequest &msg)
Function to process mobility request in leaderaborting state.
void mob_op_cb_follower(const carma_v2x_msgs::msg::MobilityOperation &msg)
Function to process mobility operation in follower state.
void mob_resp_cb_leaderwaiting(const carma_v2x_msgs::msg::MobilityResponse &msg)
Function to process mobility response in leader waiting state.
MobilityRequestCB mobility_request_publisher_
const double STOPPED_SPEED
int statusMessageInterval_
carma_wm::WorldModelConstPtr wm_
void updatePlatoonList(std::vector< PlatoonMember > platoon_list)
UCLA Setter: Update platoon list (Unit Test).
void mob_op_cb_STATUS(const carma_v2x_msgs::msg::MobilityOperation &msg)
Function to process mobility operation message with STATUS params, read ecef location and update plat...
void mob_resp_cb_leaderaborting(const carma_v2x_msgs::msg::MobilityResponse &msg)
Function to process mobility response in leaderaborting state.
bool plan_maneuver_cb(carma_planning_msgs::srv::PlanManeuvers::Request &req, carma_planning_msgs::srv::PlanManeuvers::Response &resp)
Callback function to the maneuver request.
unsigned long NEGOTIATION_TIMEOUT
unsigned long infoMessageInterval_
bool isVehicleRightBehind(double downtrack, double crosstrack)
Function to determine if the given downtrack distance (m) is behind the host vehicle.
carma_v2x_msgs::msg::MobilityOperation composeMobilityOperationLeader(const std::string &type)
Function to compose mobility operation in leader state.
void mob_op_cb_leader(const carma_v2x_msgs::msg::MobilityOperation &msg)
Function to process mobility operation in leader state.
void mob_op_cb_preparetojoin(const carma_v2x_msgs::msg::MobilityOperation &msg)
Function to process mobility operation in PrepareToJoin state (cut-in join)
auto to_string(const UtmZone &zone) -> std::string
std::shared_ptr< const WorldModel > WorldModelConstPtr
PlatoonState
Platoon States. UCLA: Added additional states (i.e., LEADERABORTING and CANDIDATELEADER) for same-lan...
std::function< void(const carma_v2x_msgs::msg::MobilityOperation &)> MobilityOperationCB
std::function< void(const carma_planning_msgs::msg::PlatooningInfo &)> PlatooningInfoCB
std::function< void(const carma_v2x_msgs::msg::MobilityResponse &)> MobilityResponseCB
std::function< void(const carma_v2x_msgs::msg::MobilityRequest &)> MobilityRequestCB
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.
unsigned long planStartTime
Stuct containing the algorithm configuration values for the yield_pluginConfig.
double desiredJoinTimeGap
double minPlatooningSpeed
double maxCrosstrackError
int maxLeaderAbortingCalls
double maxAllowedJoinTimeGap
double longitudinalCheckThresold