29 case Operation::PICKUP:
return "PICKUP";
30 case Operation::DROPOFF:
return "DROPOFF";
31 case Operation::ENTER_STAGING_AREA:
return "ENTER_STAGING_AREA";
32 case Operation::EXIT_STAGING_AREA:
return "EXIT_STAGING_AREA";
33 case Operation::ENTER_PORT:
return "ENTER_PORT";
34 case Operation::EXIT_PORT:
return "EXIT_PORT";
35 case Operation::PORT_CHECKPOINT:
return "PORT_CHECKPOINT";
36 case Operation::HOLDING_AREA:
return "HOLDING_AREA";
38 RCLCPP_WARN_STREAM(rclcpp::get_logger(
"OperationID"),
"Conversion of an unsupported operation enum value to a string.");
39 return "UNSUPPORTED_OPERATION_ID";
44 rclcpp::Clock::SharedPtr clock,
45 std::function<
void(carma_v2x_msgs::msg::MobilityOperation)> mobility_operations_publisher,
46 std::function<
void(carma_msgs::msg::UIInstructions)> ui_instructions_publisher,
47 std::function<
bool(std::shared_ptr<carma_planning_msgs::srv::SetActiveRoute::Request>)> call_set_active_route)
48 : logger_(logger), clock_(clock),
49 publish_mobility_operation_(mobility_operations_publisher),
50 publish_ui_instructions_(ui_instructions_publisher),
51 call_set_active_route_service_(call_set_active_route),
86 if (is_route_generation_successful) {
93 RCLCPP_DEBUG_STREAM(
logger_->get_logger(),
"Route generation failed. Routing could not be completed.");
94 throw std::invalid_argument(
"Route generation failed. Routing could not be completed.");
99 auto route_req = std::make_shared<carma_planning_msgs::srv::SetActiveRoute::Request>();
100 if (dest_latitude && dest_longitude) {
101 route_req->choice = carma_planning_msgs::srv::SetActiveRoute::Request::DESTINATION_POINTS_ARRAY;
104 carma_v2x_msgs::msg::Position3D destination_point;
107 destination_point.elevation_exists =
false;
109 route_req->destination_points.push_back(destination_point);
112 RCLCPP_DEBUG_STREAM(
logger_->get_logger(),
"No destination points were received. Routing could not be completed.");
113 throw std::invalid_argument(
"No destination points were received. Routing could not be completed");
121 std::string popup_text =
"";
125 popup_text +=
"The pickup action was completed successfully. ";
128 popup_text +=
"The dropoff action was completed successfully. ";
131 popup_text +=
"The inspection was completed successfully. ";
135 popup_text +=
"A new Port Drayage route with operation type '" + current_operation +
"' has been received. "
136 "Select YES to engage the system on the route, or select NO to remain "
140 carma_msgs::msg::UIInstructions ui_instructions_msg;
141 ui_instructions_msg.stamp =
clock_->now();
142 ui_instructions_msg.msg = popup_text;
143 ui_instructions_msg.type = carma_msgs::msg::UIInstructions::ACK_REQUIRED;
146 return ui_instructions_msg;
150 carma_v2x_msgs::msg::MobilityOperation msg;
152 msg.m_header.plan_id =
"";
153 msg.m_header.sender_id =
cmv_id_;
154 msg.m_header.recipient_id =
"";
155 msg.m_header.timestamp =
clock_->now().nanoseconds()/1000000;
160 using boost::property_tree::ptree;
168 pt.put_child(
"location", location);
178 pt.put(
"operation", pickup_operation);
182 pt.put(
"operation", enter_port_operation);
200 RCLCPP_WARN_STREAM(
logger_->get_logger(),
"CMV has arrived at a received destination, but does not have an action_id to broadcast.");
210 RCLCPP_WARN_STREAM(
logger_->get_logger(),
"CMV has arrived at loading area, but does not have a cargo_id to broadcast.");
214 RCLCPP_WARN_STREAM(
logger_->get_logger(),
"CMV has arrived at a loading area, but it is already carrying cargo.");
224 RCLCPP_WARN_STREAM(
logger_->get_logger(),
"CMV has arrived at a dropoff area, but does not have a cargo_id to broadcast.");
235 std::stringstream body_stream;
236 boost::property_tree::json_parser::write_json(body_stream, pt);
237 msg.strategy_params = body_stream.str();
246 using boost::property_tree::ptree;
248 std::istringstream strategy_params_ss(msg->strategy_params);
249 boost::property_tree::json_parser::read_json(strategy_params_ss, pt);
251 std::string mobility_operation_cmv_id = pt.get<std::string>(
"cmv_id");
254 if(mobility_operation_cmv_id ==
cmv_id_) {
261 RCLCPP_DEBUG_STREAM(
logger_->get_logger(),
"Processing new port drayage MobilityOperation message for cmv_id " << mobility_operation_cmv_id);
268 RCLCPP_DEBUG_STREAM(
logger_->get_logger(),
"Ignoring received port drayage MobilityOperation message intended for cmv_id " << mobility_operation_cmv_id);
278 if (previous_port_drayage_msg.
cargo_id) {
280 RCLCPP_DEBUG_STREAM(
logger_->get_logger(),
"CMV completed pickup action. CMV is now carrying cargo ID " <<
cargo_id_);
283 RCLCPP_DEBUG_STREAM(
logger_->get_logger(),
"CMV has completed pickup, but there is no Cargo ID associated with the picked up cargo.");
287 RCLCPP_DEBUG_STREAM(
logger_->get_logger(),
"CMV completed dropoff action. CMV is no longer carrying cargo ID " <<
cargo_id_);
294 using boost::property_tree::ptree;
296 std::istringstream mobility_operation_strategy_params_ss(mobility_operation_strategy_params);
297 boost::property_tree::json_parser::read_json(mobility_operation_strategy_params_ss, pt);
305 RCLCPP_WARN_STREAM(
logger_->get_logger(),
"Received 'PICKUP' operation, but CMV is already carrying cargo.");
310 RCLCPP_WARN_STREAM(
logger_->get_logger(),
"Received 'DROPOFF' operation, but CMV isn't currently carrying cargo.");
314 if (pt.count(
"cargo_id") != 0){
320 RCLCPP_WARN_STREAM(
logger_->get_logger(),
"CMV commanded to dropoff an invalid Cargo ID. Currently carrying " <<
cargo_id_ <<
", commanded to dropoff " << pt.get<std::string>(
"cargo_id"));
326 RCLCPP_WARN_STREAM(
logger_->get_logger(),
"Received 'PICKUP' operation, but no cargo_id was included.");
329 RCLCPP_WARN_STREAM(
logger_->get_logger(),
"Received 'DROPOFF' operation, but no cargo_id was included.");
336 if (pt.count(
"action_id") != 0){
345 if (pt.count(
"location") != 0){
357 if (pt.count(
"destination") != 0) {
372 RCLCPP_DEBUG_STREAM(
logger_->get_logger(),
"CMV has been engaged for the first time. Processing DRAYAGE_START event.");
380 if (
latest_route_event_->event == carma_planning_msgs::msg::RouteEvent::ROUTE_COMPLETED && msg->event == carma_planning_msgs::msg::RouteEvent::ROUTE_LOADED) {
382 RCLCPP_DEBUG_STREAM(
logger_->get_logger(),
"CMV completed its previous route, and the previous route is no longer active.");
383 RCLCPP_DEBUG_STREAM(
logger_->get_logger(),
"Processing ARRIVED_AT_DESTINATION event.");
399 RCLCPP_DEBUG_STREAM(
logger_->get_logger(),
"Ignoring pose message as projection string has not been defined");
404 lanelet::GPSPoint coord =
map_projector_->reverse( { msg->pose.position.x, msg->pose.position.y, msg->pose.position.z } );
416 map_projector_ = std::make_shared<lanelet::projection::LocalFrameProjector>(msg->data.c_str());
Helper class containing an enum for valid port drayage MobilityOperation message operation IDs and a ...
OperationID::Operation getOperationID() const
Getter function to obtain the Operation enum associated with this object.
const Operation operation_enum_
Operation
Enum containing possible operation IDs used to define destinations for port drayage.
std::string operationToString() const
Function to convert this object's 'operation_enum_' to a human-readable string.
void processEvent(PortDrayageEvent event)
void setOnArrivedAtDestinationCallback(const std::function< void()> &cb)
Set the callback to be invoked upon transitioning into the AWAITING_DESTINATION state.
void setOnReceivedNewDestinationCallback(const std::function< void()> &cb)
Set the callback to be invoked upon transitioning into the EN_ROUTE state.
PortDrayageState getState() const
Get the current state of the state machine.
const std::string SET_GUIDANCE_ACTIVE_SERVICE_ID
void setVehicleID(const std::string &cmv_id)
Setter function to set this object's cmv_id_ string.
carma_msgs::msg::UIInstructions composeUIInstructions(const std::string ¤t_operation, const std::string &previous_operation)
Creates a UIInstructions message that can be used to create a pop-up on the Web UI to notify a user t...
const std::string PORT_DRAYAGE_STRATEGY_ID
PortDrayageWorker(rclcpp::node_interfaces::NodeLoggingInterface::SharedPtr logger, rclcpp::Clock::SharedPtr clock, std::function< void(carma_v2x_msgs::msg::MobilityOperation)> mobility_operations_publisher, std::function< void(carma_msgs::msg::UIInstructions)> ui_instructions_publisher, std::function< bool(std::shared_ptr< carma_planning_msgs::srv::SetActiveRoute::Request >)> call_set_active_route)
Standard constructor for the PortDrayageWorker.
LatLonCoordinate current_gps_position_
std::string previous_strategy_params_
void setStartingAtStagingAreaFlag(bool starting_at_staging_area)
Setter function to set this object's starting_at_staging_area flag.
PortDrayageStateMachine pdsm_
PortDrayageState getPortDrayageState()
Get the current state of the port drayage state machine.
void onRouteEvent(const carma_planning_msgs::msg::RouteEvent::UniquePtr msg)
Callback to process each Route Event.
PortDrayageMobilityOperationMsg latest_mobility_operation_msg_
void updateCargoInformationAfterActionCompletion(const PortDrayageMobilityOperationMsg &previous_port_drayage_msg)
Method to update worker's cargo-related data members depending on whether the previously completed ac...
std::string georeference_
void onArrivedAtDestination()
Callback for usage by the PortDrayageStateMachine when the vehicle has arrived at a destination.
void setEnablePortDrayageFlag(bool enable_port_drayage)
Setter function to set this object's enable_port_drayage flag.
bool enable_port_drayage_
std::function< void(carma_v2x_msgs::msg::MobilityOperation)> publish_mobility_operation_
void mobilityOperationMessageParser(std::string mobility_operation_strategy_params)
Function to help parse the text included in an inbound MobilityOperation message's strategy_params fi...
void onNewPose(geometry_msgs::msg::PoseStamped::UniquePtr msg)
Callback for the pose subscriber. The pose will be converted into lat/lon and stored locally.
void onReceivedNewDestination()
Callback for usage by the PortDrayageStateMachine when the vehicle has received a new destination.
std::shared_ptr< carma_planning_msgs::srv::SetActiveRoute::Request > composeSetActiveRouteRequest(boost::optional< double > dest_latitude, boost::optional< double > dest_longitude) const
Create a SetActiveRoute service request to set a new active route for the system based on the destina...
std::shared_ptr< lanelet::projection::LocalFrameProjector > map_projector_
std::function< void(carma_msgs::msg::UIInstructions)> publish_ui_instructions_
bool starting_at_staging_area_
rclcpp::node_interfaces::NodeLoggingInterface::SharedPtr logger_
void onGuidanceState(const carma_planning_msgs::msg::GuidanceState::UniquePtr msg)
Callback to process the current status of the guidance state machine.
void onInboundMobilityOperation(carma_v2x_msgs::msg::MobilityOperation::UniquePtr msg)
Callback to process a received MobilityOperation message.
void setCargoID(const std::string &cargo_id)
Setter function to set this object's cargo_id_ string.
std::shared_ptr< carma_planning_msgs::msg::RouteEvent > latest_route_event_
void onNewGeoreference(std_msgs::msg::String::UniquePtr msg)
Callback for map projection string to define lat/lon <--> map conversion.
std::function< bool(std::shared_ptr< carma_planning_msgs::srv::SetActiveRoute::Request >)> call_set_active_route_service_
rclcpp::Clock::SharedPtr clock_
carma_v2x_msgs::msg::MobilityOperation composeArrivalMessage() const
Assemble the current dataset into a MobilityOperations message with a JSON formatted body containing ...
std::string previously_completed_operation_
@ RECEIVED_NEW_DESTINATION
PortDrayageState
Enum containing the possible state values for the PortDrayagePlugin.
@ EN_ROUTE_TO_INITIAL_DESTINATION
@ EN_ROUTE_TO_RECEIVED_DESTINATION
Convenience struct for storing all data contained in a received MobilityOperation message's strategy_...
boost::optional< double > dest_longitude
boost::optional< std::string > current_action_id
boost::optional< double > start_longitude
boost::optional< double > dest_latitude
boost::optional< std::string > cargo_id
boost::optional< double > start_latitude