26 #include <arpa/inet.h>
32 #include <rcutils/logging.h>
38 #define ROS12_LOG(level, ...) NODELET_##level(__VA_ARGS__)
42 #define ROS12_LOG(level, ...) RCLCPP_##level(this->get_logger(), __VA_ARGS__)
43 #include <rclcpp_components/register_node_macro.hpp>
123 std::map<std::string, ros::console::levels::Level> loggers;
127 if (loggers.count(node_logger) > 0) {
128 if (loggers[node_logger] == ros::console::levels::Level::Debug)
return true;
131 if (loggers.count(nodelet_logger) > 0) {
132 if (loggers[nodelet_logger] == ros::console::levels::Level::Debug)
return true;
135 auto logger_level = rcutils_logging_get_logger_effective_level(this->get_logger().get_name());
136 return (logger_level == RCUTILS_LOG_SEVERITY_DEBUG);
144 void Converter::onInit() {
146 private_node_handle_ = this->getMTPrivateNodeHandle();
159 rcl_interfaces::msg::ParameterDescriptor param_desc;
166 param_desc = rcl_interfaces::msg::ParameterDescriptor();
167 param_desc.description =
"whether incoming/outgoing UDP messages include a 4-byte BTP header";
178 param_desc = rcl_interfaces::msg::ParameterDescriptor();
179 param_desc.description =
"number of bytes until actual message payload starts in incoming UDP message (optionally including BTP header)";
190 param_desc = rcl_interfaces::msg::ParameterDescriptor();
191 param_desc.description =
"number of bytes until actual message payload starts in incoming UDP message (optionally including BTP header)";
202 param_desc = rcl_interfaces::msg::ParameterDescriptor();
203 std::stringstream ss_ros2udp;
204 ss_ros2udp <<
"list of ETSI types to convert from ROS to UDP, one of ";
206 param_desc.description = ss_ros2udp.str();
227 param_desc = rcl_interfaces::msg::ParameterDescriptor();
228 std::stringstream ss_udp2ros;
229 ss_udp2ros <<
"list of ETSI types to convert from UDP to ROS, one of ";
231 param_desc.description = ss_udp2ros.str();
256 param_desc = rcl_interfaces::msg::ParameterDescriptor();
257 param_desc.description =
"queue size for incoming ROS messages";
268 param_desc = rcl_interfaces::msg::ParameterDescriptor();
269 param_desc.description =
"queue size for outgoing ROS messages";
290 ROS12_LOG(INFO,
"Converting UDP messages of type CAM on '%s' to native ROS messages on '%s'",
subscriber_udp_->getTopic().c_str(), publishers_[
"cam"]->getTopic().c_str());
293 boost::function<void(
const cam_msgs::CAM::ConstPtr)> callback =
300 ROS12_LOG(INFO,
"Converting UDP messages of type CAM (TS) on '%s' to native ROS messages on '%s'",
subscriber_udp_->getTopic().c_str(), publishers_[
"cam_ts"]->getTopic().c_str());
303 boost::function<void(
const cam_ts_msgs::CAM::ConstPtr)> callback =
310 ROS12_LOG(INFO,
"Converting UDP messages of type CPM (TS) on '%s' to native ROS messages on '%s'",
subscriber_udp_->getTopic().c_str(), publishers_[
"cpm_ts"]->getTopic().c_str());
313 boost::function<void(
const cpm_ts_msgs::CollectivePerceptionMessage::ConstPtr)> callback =
320 ROS12_LOG(INFO,
"Converting UDP messages of type DENM on '%s' to native ROS messages on '%s'",
subscriber_udp_->getTopic().c_str(), publishers_[
"denm"]->getTopic().c_str());
323 boost::function<void(
const denm_msgs::DENM::ConstPtr)> callback =
330 ROS12_LOG(INFO,
"Converting UDP messages of type DENM (TS) on '%s' to native ROS messages on '%s'",
subscriber_udp_->getTopic().c_str(), publishers_[
"denm_ts"]->getTopic().c_str());
333 boost::function<void(
const denm_ts_msgs::DENM::ConstPtr)> callback =
340 ROS12_LOG(INFO,
"Converting UDP messages of type MAPEM (TS) on '%s' to native ROS messages on '%s'",
subscriber_udp_->getTopic().c_str(), publishers_[
"mapem_ts"]->getTopic().c_str());
343 boost::function<void(
const mapem_ts_msgs::MAPEM::ConstPtr)> callback =
350 ROS12_LOG(INFO,
"Converting UDP messages of type MCM (UULM) on '%s' to native ROS messages on '%s'",
subscriber_udp_->getTopic().c_str(), publishers_[
"mcm_uulm"]->getTopic().c_str());
353 boost::function<void(
const mcm_uulm_msgs::MCM::ConstPtr)> callback =
360 ROS12_LOG(INFO,
"Converting UDP messages of type SPATEM (TS) on '%s' to native ROS messages on '%s'",
subscriber_udp_->getTopic().c_str(), publishers_[
"spatem_ts"]->getTopic().c_str());
363 boost::function<void(
const spatem_ts_msgs::SPATEM::ConstPtr)> callback =
370 ROS12_LOG(INFO,
"Converting UDP messages of type VAM (TS) on '%s' to native ROS messages on '%s'",
subscriber_udp_->getTopic().c_str(), publishers_[
"vam_ts"]->getTopic().c_str());
373 boost::function<void(
const vam_ts_msgs::VAM::ConstPtr)> callback =
390 std::function<void(
const cam_msgs::CAM::UniquePtr)> callback =
400 std::function<void(
const cam_ts_msgs::CAM::UniquePtr)> callback =
410 std::function<void(
const cpm_ts_msgs::CollectivePerceptionMessage::UniquePtr)> callback =
420 std::function<void(
const denm_msgs::DENM::UniquePtr)> callback =
430 std::function<void(
const denm_ts_msgs::DENM::UniquePtr)> callback =
440 std::function<void(
const mapem_ts_msgs::MAPEM::UniquePtr)> callback =
450 std::function<void(
const mcm_uulm_msgs::MCM::UniquePtr)> callback =
460 std::function<void(
const spatem_ts_msgs::SPATEM::UniquePtr)> callback =
470 std::function<void(
const vam_ts_msgs::VAM::UniquePtr)> callback =
479 template <
typename T_struct>
484 ROS12_LOG(ERROR,
"Failed to decode message");
493 template <
typename T_ros,
typename T_struct>
497 conversion_fn(asn1_struct, msg);
503 template <
typename T_ros,
typename T_struct>
506 T_struct asn1_struct{};
508 if (success) msg = this->
structToRosMessage(asn1_struct, type_descriptor, conversion_fn);
515 template <
typename T_ros,
typename T_struct>
518 T_struct asn1_struct{};
519 conversion_fn(msg, asn1_struct);
526 template <
typename T_struct>
529 char error_buffer[1024];
530 size_t error_length =
sizeof(error_buffer);
532 if (check_ret != 0) {
533 ROS12_LOG(ERROR,
"Check of struct failed: %s", error_buffer);
543 buffer =
static_cast<uint8_t*
>(ret.
buffer);
559 uint16_t destination_port = htons(btp_header_destination_port);
560 uint16_t destination_port_info = 0;
561 uint16_t* btp_header =
new uint16_t[2] {destination_port, destination_port_info};
562 uint8_t* btp_header_uint8 =
reinterpret_cast<uint8_t*
>(btp_header);
563 udp_msg.data.insert(udp_msg.data.end(), btp_header_uint8, btp_header_uint8 + 2 *
sizeof(uint16_t));
566 udp_msg.data.insert(udp_msg.data.end(), buffer, buffer + size);
572 template <
typename T_ros,
typename T_struct>
579 uint8_t* buffer =
nullptr;
581 bool successful = this->
encodeStructToBuffer(asn1_struct, type_descriptor, buffer, buffer_size);
582 if (!successful)
return false;
601 ROS12_LOG(DEBUG,
"Received bitstring (total payload size: %ld)", udp_msg->data.size());
607 uint16_t destination_port = ntohs(*btp_destination_port);
616 else detected_etsi_type =
"unknown";
622 ROS12_LOG(INFO,
"Received ETSI message of type '%s' (protocolVersion: %d) as bitstring (message size: %d | total payload size: %ld)", detected_etsi_type.c_str(), *protocol_version , msg_size, udp_msg->data.size());
624 if (detected_etsi_type ==
"cam" || detected_etsi_type ==
"cam_ts") {
629 if (!success)
return;
631 publishers_[
"cam"]->publish(msg);
637 cam_ts_msgs::CAM msg;
639 if (!success)
return;
641 publishers_[
"cam_ts"]->publish(msg);
647 }
else if (detected_etsi_type ==
"cpm_ts") {
650 cpm_ts_msgs::CollectivePerceptionMessage msg;
652 if (!success)
return;
656 publishers_[
"cpm_ts"]->publish(msg);
661 }
else if (detected_etsi_type ==
"denm" || detected_etsi_type ==
"denm_ts") {
666 if (!success)
return;
668 publishers_[
"denm"]->publish(msg);
674 denm_ts_msgs::DENM msg;
676 if (!success)
return;
678 publishers_[
"denm_ts"]->publish(msg);
684 }
else if (detected_etsi_type ==
"vam_ts") {
687 vam_ts_msgs::VAM msg;
689 if (!success)
return;
693 publishers_[
"vam_ts"]->publish(msg);
698 }
else if (detected_etsi_type ==
"mapem_ts") {
701 mapem_ts_msgs::MAPEM msg;
703 if (!success)
return;
707 publishers_[
"mapem_ts"]->publish(msg);
712 }
else if (detected_etsi_type ==
"mcm_uulm") {
715 mcm_uulm_msgs::MCM msg;
717 if (!success)
return;
721 publishers_[
"mcm_uulm"]->publish(msg);
726 }
else if (detected_etsi_type ==
"spatem_ts") {
729 spatem_ts_msgs::SPATEM msg;
731 if (!success)
return;
735 publishers_[
"spatem_ts"]->publish(msg);
741 ROS12_LOG(ERROR,
"Detected ETSI message type '%s' not yet supported, dropping message", detected_etsi_type.c_str());
745 ROS12_LOG(INFO,
"Published ETSI message of type '%s' as ROS message", detected_etsi_type.c_str());
749 template <
typename T_ros,
typename T_struct>
755 const std::string& type,
const asn_TYPE_descriptor_t* type_descriptor, std::function<
void(
const T_ros&, T_struct&)> conversion_fn) {
757 ROS12_LOG(INFO,
"Received ETSI message of type '%s' as ROS message", type.c_str());
759 int btp_header_destination_port = 0;
770 bool success = this->encodeRosMessageToUdpPacketMessage<T_ros, T_struct>(*msg, udp_msg, type_descriptor, conversion_fn, btp_header_destination_port);
771 if (!success)
return;
776 ROS12_LOG(INFO,
"Published ETSI message of type '%s' as bitstring (message size: %d | total payload size: %ld)", type.c_str(), msg_size, udp_msg.data.size());