Converter.cpp
Go to the documentation of this file.
1 
25 #include <algorithm>
26 #include <arpa/inet.h>
27 #include <sstream>
28 
29 #ifdef ROS1
30 #include <ros/console.h>
31 #else
32 #include <rcutils/logging.h>
33 #endif
34 
36 
37 #ifdef ROS1
38 #define ROS12_LOG(level, ...) NODELET_##level(__VA_ARGS__)
41 #else
42 #define ROS12_LOG(level, ...) RCLCPP_##level(this->get_logger(), __VA_ARGS__)
43 #include <rclcpp_components/register_node_macro.hpp>
44 RCLCPP_COMPONENTS_REGISTER_NODE(etsi_its_conversion::Converter)
45 #endif
46 
47 namespace etsi_its_conversion {
48 
57 
58 #ifdef ROS1
59 const std::string Converter::kInputTopicUdp{"udp/in"};
60 const std::string Converter::kOutputTopicUdp{"udp/out"};
61 const std::string Converter::kInputTopicCam{"cam/in"};
62 const std::string Converter::kOutputTopicCam{"cam/out"};
63 const std::string Converter::kInputTopicCamTs{"cam_ts/in"};
64 const std::string Converter::kOutputTopicCamTs{"cam_ts/out"};
65 const std::string Converter::kInputTopicCpmTs{"cpm_ts/in"};
66 const std::string Converter::kOutputTopicCpmTs{"cpm_ts/out"};
67 const std::string Converter::kInputTopicDenm{"denm/in"};
68 const std::string Converter::kOutputTopicDenm{"denm/out"};
69 const std::string Converter::kInputTopicDenmTs{"denm_ts/in"};
70 const std::string Converter::kOutputTopicDenmTs{"denm_ts/out"};
71 const std::string Converter::kInputTopicMapemTs{"mapem_ts/in"};
72 const std::string Converter::kOutputTopicMapemTs{"mapem_ts/out"};
73 const std::string Converter::kInputTopicMcmUulm{"mcm_uulm/in"};
74 const std::string Converter::kOutputTopicMcmUulm{"mcm_uulm/out"};
75 const std::string Converter::kInputTopicSpatemTs{"spatem_ts/in"};
76 const std::string Converter::kOutputTopicSpatemTs{"spatem_ts/out"};
77 const std::string Converter::kInputTopicVamTs{"vam_ts/in"};
78 const std::string Converter::kOutputTopicVamTs{"vam_ts/out"};
79 #else
80 const std::string Converter::kInputTopicUdp{"~/udp/in"};
81 const std::string Converter::kOutputTopicUdp{"~/udp/out"};
82 const std::string Converter::kInputTopicCam{"~/cam/in"};
83 const std::string Converter::kOutputTopicCam{"~/cam/out"};
84 const std::string Converter::kInputTopicCamTs{"~/cam_ts/in"};
85 const std::string Converter::kOutputTopicCamTs{"~/cam_ts/out"};
86 const std::string Converter::kInputTopicCpmTs{"~/cpm_ts/in"};
87 const std::string Converter::kOutputTopicCpmTs{"~/cpm_ts/out"};
88 const std::string Converter::kInputTopicDenm{"~/denm/in"};
89 const std::string Converter::kOutputTopicDenm{"~/denm/out"};
90 const std::string Converter::kInputTopicDenmTs{"~/denm_ts/in"};
91 const std::string Converter::kOutputTopicDenmTs{"~/denm_ts/out"};
92 const std::string Converter::kInputTopicMapemTs{"~/mapem_ts/in"};
93 const std::string Converter::kOutputTopicMapemTs{"~/mapem_ts/out"};
94 const std::string Converter::kInputTopicMcmUulm{"~/mcm_uulm/in"};
95 const std::string Converter::kOutputTopicMcmUulm{"~/mcm_uulm/out"};
96 const std::string Converter::kInputTopicSpatemTs{"~/spatem_ts/in"};
97 const std::string Converter::kOutputTopicSpatemTs{"~/spatem_ts/out"};
98 const std::string Converter::kInputTopicVamTs{"~/vam_ts/in"};
99 const std::string Converter::kOutputTopicVamTs{"~/vam_ts/out"};
100 #endif
101 
102 const std::string Converter::kHasBtpDestinationPortParam{"has_btp_destination_port"};
104 const std::string Converter::kBtpDestinationPortOffsetParam{"btp_destination_port_offset"};
106 const std::string Converter::kEtsiMessagePayloadOffsetParam{"etsi_message_payload_offset"};
108 const std::string Converter::kRos2UdpEtsiTypesParam{"ros2udp_etsi_types"};
109 const std::string Converter::kUdp2RosEtsiTypesParam{"udp2ros_etsi_types"};
110 const std::vector<std::string> Converter::kEtsiTypesParamSupportedOptions{"cam", "cam_ts", "cpm_ts", "denm", "denm_ts", "mapem_ts", "mcm_uulm", "spatem_ts", "vam_ts"};
112 const std::vector<std::string> Converter::kUdp2RosEtsiTypesParamDefault{"cam", "cpm_ts", "denm", "mapem_ts", "mcm_uulm", "spatem_ts", "vam_ts"};
113 const std::string Converter::kSubscriberQueueSizeParam{"subscriber_queue_size"};
115 const std::string Converter::kPublisherQueueSizeParam{"publisher_queue_size"};
118 
119 
121 
122 #ifdef ROS1
123  std::map<std::string, ros::console::levels::Level> loggers;
124  bool ret = ros::console::get_loggers(loggers);
125  std::string node_logger = ROSCONSOLE_DEFAULT_NAME;
126  node_logger += "." + ros::this_node::getName();
127  if (loggers.count(node_logger) > 0) {
128  if (loggers[node_logger] == ros::console::levels::Level::Debug) return true;
129  }
130  std::string nodelet_logger = "ros.nodelet." + ros::this_node::getName();
131  if (loggers.count(nodelet_logger) > 0) {
132  if (loggers[nodelet_logger] == ros::console::levels::Level::Debug) return true;
133  }
134 #else
135  auto logger_level = rcutils_logging_get_logger_effective_level(this->get_logger().get_name());
136  return (logger_level == RCUTILS_LOG_SEVERITY_DEBUG);
137 #endif
138 
139  return false;
140 }
141 
142 
143 #ifdef ROS1
144 void Converter::onInit() {
145 
146  private_node_handle_ = this->getMTPrivateNodeHandle();
147 #else
148 Converter::Converter(const rclcpp::NodeOptions& options) : Node("converter", options) {
149 #endif
150 
151  this->loadParameters();
152  this->setup();
153 }
154 
155 
157 
158 #ifndef ROS1
159  rcl_interfaces::msg::ParameterDescriptor param_desc;
160 #endif
161 
162  // load has_btp_destination_port
163 #ifdef ROS1
165 #else
166  param_desc = rcl_interfaces::msg::ParameterDescriptor();
167  param_desc.description = "whether incoming/outgoing UDP messages include a 4-byte BTP header";
168  this->declare_parameter(kHasBtpDestinationPortParam, kHasBtpDestinationPortParamDefault, param_desc);
169  if (!this->get_parameter(kHasBtpDestinationPortParam, has_btp_destination_port_)) {
170 #endif
171  ROS12_LOG(WARN, "Parameter '%s' is not set, defaulting to '%s'", kHasBtpDestinationPortParam.c_str(), kHasBtpDestinationPortParamDefault ? "true" : "false");
172  }
173 
174  // load btp_destination_port_offset
175 #ifdef ROS1
177 #else
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)";
180  this->declare_parameter(kBtpDestinationPortOffsetParam, kBtpDestinationPortOffsetParamDefault, param_desc);
182 #endif
183  ROS12_LOG(WARN, "Parameter '%s' is not set, defaulting to '%d'", kBtpDestinationPortOffsetParam.c_str(), kBtpDestinationPortOffsetParamDefault);
184  }
185 
186  // load etsi_message_payload_offset
187 #ifdef ROS1
189 #else
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)";
192  this->declare_parameter(kEtsiMessagePayloadOffsetParam, kEtsiMessagePayloadOffsetParamDefault, param_desc);
194 #endif
195  ROS12_LOG(WARN, "Parameter '%s' is not set, defaulting to '%d'", kEtsiMessagePayloadOffsetParam.c_str(), kEtsiMessagePayloadOffsetParamDefault);
196  }
197 
198  // load ros2udp_etsi_types_
199 #ifdef ROS1
200  if (!private_node_handle_.param<std::vector<std::string>>(kRos2UdpEtsiTypesParam, ros2udp_etsi_types_, kRos2UdpEtsiTypesParamDefault)) {
201 #else
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 ";
205  for (const auto& e : kRos2UdpEtsiTypesParamDefault) ss_ros2udp << e << ", ";
206  param_desc.description = ss_ros2udp.str();
207  this->declare_parameter(kRos2UdpEtsiTypesParam, kRos2UdpEtsiTypesParamDefault, param_desc);
208  if (!this->get_parameter(kRos2UdpEtsiTypesParam, ros2udp_etsi_types_)) {
209 #endif
210  ROS12_LOG(WARN, "Parameter '%s' is not set, defaulting to all", kRos2UdpEtsiTypesParam.c_str());
211  }
212 
213  // check ros2udp_etsi_types
214  for (auto it = ros2udp_etsi_types_.begin(); it != ros2udp_etsi_types_.end(); ) {
216  ROS12_LOG(WARN, "Invalid value '%s' for parameter '%s', removing", it->c_str(), kRos2UdpEtsiTypesParam.c_str());
217  it = ros2udp_etsi_types_.erase(it);
218  } else {
219  ++it;
220  }
221  }
222 
223  // load udp2ros_etsi_types_
224 #ifdef ROS1
225  if (!private_node_handle_.param<std::vector<std::string>>(kUdp2RosEtsiTypesParam, udp2ros_etsi_types_, kUdp2RosEtsiTypesParamDefault)) {
226 #else
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 ";
230  for (const auto& e : kUdp2RosEtsiTypesParamDefault) ss_udp2ros << e << ", ";
231  param_desc.description = ss_udp2ros.str();
232  this->declare_parameter(kUdp2RosEtsiTypesParam, kUdp2RosEtsiTypesParamDefault, param_desc);
233  if (!this->get_parameter(kUdp2RosEtsiTypesParam, udp2ros_etsi_types_)) {
234 #endif
235  ROS12_LOG(WARN, "Parameter '%s' is not set, defaulting to all", kUdp2RosEtsiTypesParam.c_str());
236  }
237 
238  // check udp2ros_etsi_types
239  for (auto it = udp2ros_etsi_types_.begin(); it != udp2ros_etsi_types_.end(); ) {
241  ROS12_LOG(WARN, "Invalid value '%s' for parameter '%s', removing", it->c_str(), kRos2UdpEtsiTypesParam.c_str());
242  it = udp2ros_etsi_types_.erase(it);
243  } else {
244  ++it;
245  }
246  }
247  if (!has_btp_destination_port_ && udp2ros_etsi_types_.size() > 1) {
248  ROS12_LOG(WARN, "Parameter '%s' is set to 'false', but multiple 'udp2ros_etsi_types' are configured, dropping all but the first", kHasBtpDestinationPortParam.c_str());
249  udp2ros_etsi_types_.resize(1);
250  }
251 
252  // load subscriber_queue_size
253 #ifdef ROS1
255 #else
256  param_desc = rcl_interfaces::msg::ParameterDescriptor();
257  param_desc.description = "queue size for incoming ROS messages";
258  this->declare_parameter(kSubscriberQueueSizeParam, kSubscriberQueueSizeParamDefault, param_desc);
259  if (!this->get_parameter(kSubscriberQueueSizeParam, subscriber_queue_size_)) {
260 #endif
261  ROS12_LOG(WARN, "Parameter '%s' is not set, defaulting to '%d'", kSubscriberQueueSizeParam.c_str(), kSubscriberQueueSizeParamDefault);
262  }
263 
264  // load publisher_queue_size
265 #ifdef ROS1
266  if (!private_node_handle_.param<int>(kPublisherQueueSizeParam, publisher_queue_size_, kPublisherQueueSizeParamDefault)) {
267 #else
268  param_desc = rcl_interfaces::msg::ParameterDescriptor();
269  param_desc.description = "queue size for outgoing ROS messages";
270  this->declare_parameter(kPublisherQueueSizeParam, kPublisherQueueSizeParamDefault, param_desc);
271  if (!this->get_parameter(kPublisherQueueSizeParam, publisher_queue_size_)) {
272 #endif
273  ROS12_LOG(WARN, "Parameter '%s' is not set, defaulting to '%d'", kPublisherQueueSizeParam.c_str(), kPublisherQueueSizeParamDefault);
274  }
275 }
276 
277 
279 
280  // create subscribers and publishers
281 #ifdef ROS1
282  if (!ros2udp_etsi_types_.empty()) {
283  publisher_udp_ = std::make_shared<ros::Publisher>(private_node_handle_.advertise<UdpPacket>(kOutputTopicUdp, publisher_queue_size_));
284  }
285  if (!udp2ros_etsi_types_.empty()) {
286  subscriber_udp_ = std::make_shared<ros::Subscriber>(private_node_handle_.subscribe(kInputTopicUdp, subscriber_queue_size_, &Converter::udpCallback, this));
287  }
288  if (std::find(udp2ros_etsi_types_.begin(), udp2ros_etsi_types_.end(), "cam") != udp2ros_etsi_types_.end()) {
289  publishers_["cam"] = std::make_shared<ros::Publisher>(private_node_handle_.advertise<cam_msgs::CAM>(kOutputTopicCam, publisher_queue_size_));
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());
291  }
292  if (std::find(ros2udp_etsi_types_.begin(), ros2udp_etsi_types_.end(), "cam") != ros2udp_etsi_types_.end()) {
293  boost::function<void(const cam_msgs::CAM::ConstPtr)> callback =
294  boost::bind(&Converter::rosCallback<cam_msgs::CAM, cam_CAM_t>, this, _1, "cam", &asn_DEF_cam_CAM, std::function<void(const cam_msgs::CAM&, cam_CAM_t&)>(etsi_its_cam_conversion::toStruct_CAM));
295  subscribers_["cam"] = std::make_shared<ros::Subscriber>(private_node_handle_.subscribe<cam_msgs::CAM>(kInputTopicCam, subscriber_queue_size_, callback));
296  ROS12_LOG(INFO, "Converting native ROS CAMs on '%s' to UDP messages on '%s'", subscribers_["cam"]->getTopic().c_str(), publisher_udp_->getTopic().c_str());
297  }
298  if (std::find(udp2ros_etsi_types_.begin(), udp2ros_etsi_types_.end(), "cam_ts") != udp2ros_etsi_types_.end()) {
299  publishers_["cam_ts"] = std::make_shared<ros::Publisher>(private_node_handle_.advertise<cam_ts_msgs::CAM>(kOutputTopicCamTs, publisher_queue_size_));
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());
301  }
302  if (std::find(ros2udp_etsi_types_.begin(), ros2udp_etsi_types_.end(), "cam_ts") != ros2udp_etsi_types_.end()) {
303  boost::function<void(const cam_ts_msgs::CAM::ConstPtr)> callback =
304  boost::bind(&Converter::rosCallback<cam_ts_msgs::CAM, cam_ts_CAM_t>, this, _1, "cam_ts", &asn_DEF_cam_ts_CAM, std::function<void(const cam_ts_msgs::CAM&, cam_ts_CAM_t&)>(etsi_its_cam_ts_conversion::toStruct_CAM));
305  subscribers_["cam_ts"] = std::make_shared<ros::Subscriber>(private_node_handle_.subscribe<cam_ts_msgs::CAM>(kInputTopicCamTs, subscriber_queue_size_, callback));
306  ROS12_LOG(INFO, "Converting native ROS CAM (TS) on '%s' to UDP messages on '%s'", subscribers_["cam_ts"]->getTopic().c_str(), publisher_udp_->getTopic().c_str());
307  }
308  if (std::find(udp2ros_etsi_types_.begin(), udp2ros_etsi_types_.end(), "cpm_ts") != udp2ros_etsi_types_.end()) {
309  publishers_["cpm_ts"] = std::make_shared<ros::Publisher>(private_node_handle_.advertise<cpm_ts_msgs::CollectivePerceptionMessage>(kOutputTopicCpmTs, publisher_queue_size_));
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());
311  }
312  if (std::find(ros2udp_etsi_types_.begin(), ros2udp_etsi_types_.end(), "cpm_ts") != ros2udp_etsi_types_.end()) {
313  boost::function<void(const cpm_ts_msgs::CollectivePerceptionMessage::ConstPtr)> callback =
314  boost::bind(&Converter::rosCallback<cpm_ts_msgs::CollectivePerceptionMessage, cpm_ts_CollectivePerceptionMessage_t>, this, _1, "cpm_ts", &asn_DEF_cpm_ts_CollectivePerceptionMessage, std::function<void(const cpm_ts_msgs::CollectivePerceptionMessage&, cpm_ts_CollectivePerceptionMessage_t&)>(etsi_its_cpm_ts_conversion::toStruct_CollectivePerceptionMessage));
315  subscribers_["cpm_ts"] = std::make_shared<ros::Subscriber>(private_node_handle_.subscribe<cpm_ts_msgs::CollectivePerceptionMessage>(kInputTopicCpmTs, subscriber_queue_size_, callback));
316  ROS12_LOG(INFO, "Converting native ROS CPM (TS) on '%s' to UDP messages on '%s'", subscribers_["cpm_ts"]->getTopic().c_str(), publisher_udp_->getTopic().c_str());
317  }
318  if (std::find(udp2ros_etsi_types_.begin(), udp2ros_etsi_types_.end(), "denm") != udp2ros_etsi_types_.end()) {
319  publishers_["denm"] = std::make_shared<ros::Publisher>(private_node_handle_.advertise<denm_msgs::DENM>(kOutputTopicDenm, publisher_queue_size_));
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());
321  }
322  if (std::find(ros2udp_etsi_types_.begin(), ros2udp_etsi_types_.end(), "denm") != ros2udp_etsi_types_.end()) {
323  boost::function<void(const denm_msgs::DENM::ConstPtr)> callback =
324  boost::bind(&Converter::rosCallback<denm_msgs::DENM, denm_DENM_t>, this, _1, "denm", &asn_DEF_denm_DENM, std::function<void(const denm_msgs::DENM&, denm_DENM_t&)>(etsi_its_denm_conversion::toStruct_DENM));
325  subscribers_["denm"] = std::make_shared<ros::Subscriber>(private_node_handle_.subscribe<denm_msgs::DENM>(kInputTopicDenm, subscriber_queue_size_, callback));
326  ROS12_LOG(INFO, "Converting native ROS DENMs on '%s' to UDP messages on '%s'", subscribers_["denm"]->getTopic().c_str(), publisher_udp_->getTopic().c_str());
327  }
328  if (std::find(udp2ros_etsi_types_.begin(), udp2ros_etsi_types_.end(), "denm_ts") != udp2ros_etsi_types_.end()) {
329  publishers_["denm_ts"] = std::make_shared<ros::Publisher>(private_node_handle_.advertise<denm_ts_msgs::DENM>(kOutputTopicDenmTs, publisher_queue_size_));
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());
331  }
332  if (std::find(ros2udp_etsi_types_.begin(), ros2udp_etsi_types_.end(), "denm_ts") != ros2udp_etsi_types_.end()) {
333  boost::function<void(const denm_ts_msgs::DENM::ConstPtr)> callback =
334  boost::bind(&Converter::rosCallback<denm_ts_msgs::DENM, denm_ts_DENM_t>, this, _1, "denm_ts", &asn_DEF_denm_ts_DENM, std::function<void(const denm_ts_msgs::DENM&, denm_ts_DENM_t&)>(etsi_its_denm_ts_conversion::toStruct_DENM));
335  subscribers_["denm_ts"] = std::make_shared<ros::Subscriber>(private_node_handle_.subscribe<denm_ts_msgs::DENM>(kInputTopicDenmTs, subscriber_queue_size_, callback));
336  ROS12_LOG(INFO, "Converting native ROS DENMs (TS) on '%s' to UDP messages on '%s'", subscribers_["denm_ts"]->getTopic().c_str(), publisher_udp_->getTopic().c_str());
337  }
338  if (std::find(udp2ros_etsi_types_.begin(), udp2ros_etsi_types_.end(), "mapem_ts") != udp2ros_etsi_types_.end()) {
339  publishers_["mapem_ts"] = std::make_shared<ros::Publisher>(private_node_handle_.advertise<mapem_ts_msgs::MAPEM>(kOutputTopicMapemTs, publisher_queue_size_));
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());
341  }
342  if (std::find(ros2udp_etsi_types_.begin(), ros2udp_etsi_types_.end(), "mapem_ts") != ros2udp_etsi_types_.end()) {
343  boost::function<void(const mapem_ts_msgs::MAPEM::ConstPtr)> callback =
344  boost::bind(&Converter::rosCallback<mapem_ts_msgs::MAPEM, mapem_ts_MAPEM_t>, this, _1, "mapem_ts", &asn_DEF_mapem_ts_MAPEM, std::function<void(const mapem_ts_msgs::MAPEM&, mapem_ts_MAPEM_t&)>(etsi_its_mapem_ts_conversion::toStruct_MAPEM));
345  subscribers_["mapem_ts"] = std::make_shared<ros::Subscriber>(private_node_handle_.subscribe<mapem_ts_msgs::MAPEM>(kInputTopicMapemTs, subscriber_queue_size_, callback));
346  ROS12_LOG(INFO, "Converting native ROS MAPEMs (TS) on '%s' to UDP messages on '%s'", subscribers_["mapem_ts"]->getTopic().c_str(), publisher_udp_->getTopic().c_str());
347  }
348  if (std::find(udp2ros_etsi_types_.begin(), udp2ros_etsi_types_.end(), "mcm_uulm") != udp2ros_etsi_types_.end()) {
349  publishers_["mcm_uulm"] = std::make_shared<ros::Publisher>(private_node_handle_.advertise<mcm_uulm_msgs::MCM>(kOutputTopicMcmUulm, publisher_queue_size_));
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());
351  }
352  if (std::find(ros2udp_etsi_types_.begin(), ros2udp_etsi_types_.end(), "mcm_uulm") != ros2udp_etsi_types_.end()) {
353  boost::function<void(const mcm_uulm_msgs::MCM::ConstPtr)> callback =
354  boost::bind(&Converter::rosCallback<mcm_uulm_msgs::MCM, mcm_uulm_MCM_t>, this, _1, "mcm_uulm", &asn_DEF_mcm_uulm_MCM, std::function<void(const mcm_uulm_msgs::MCM&, mcm_uulm_MCM_t&)>(etsi_its_mcm_uulm_conversion::toStruct_MCM));
355  subscribers_["mcm_uulm"] = std::make_shared<ros::Subscriber>(private_node_handle_.subscribe<mcm_uulm_msgs::MCM>(kInputTopicMcmUulm, subscriber_queue_size_, callback));
356  ROS12_LOG(INFO, "Converting native ROS MCM (UULM) on '%s' to UDP messages on '%s'", subscribers_["mcm_uulm"]->getTopic().c_str(), publisher_udp_->getTopic().c_str());
357  }
358  if (std::find(udp2ros_etsi_types_.begin(), udp2ros_etsi_types_.end(), "spatem_ts") != udp2ros_etsi_types_.end()) {
359  publishers_["spatem_ts"] = std::make_shared<ros::Publisher>(private_node_handle_.advertise<spatem_ts_msgs::SPATEM>(kOutputTopicSpatemTs, publisher_queue_size_));
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());
361  }
362  if (std::find(ros2udp_etsi_types_.begin(), ros2udp_etsi_types_.end(), "spatem_ts") != ros2udp_etsi_types_.end()) {
363  boost::function<void(const spatem_ts_msgs::SPATEM::ConstPtr)> callback =
364  boost::bind(&Converter::rosCallback<spatem_ts_msgs::SPATEM, spatem_ts_SPATEM_t>, this, _1, "spatem_ts", &asn_DEF_spatem_ts_SPATEM, std::function<void(const spatem_ts_msgs::SPATEM&, spatem_ts_SPATEM_t&)>(etsi_its_spatem_ts_conversion::toStruct_SPATEM));
365  subscribers_["spatem_ts"] = std::make_shared<ros::Subscriber>(private_node_handle_.subscribe<spatem_ts_msgs::SPATEM>(kInputTopicSpatemTs, subscriber_queue_size_, callback));
366  ROS12_LOG(INFO, "Converting native ROS SPATEMs (TS) on '%s' to UDP messages on '%s'", subscribers_["spatem_ts"]->getTopic().c_str(), publisher_udp_->getTopic().c_str());
367  }
368  if (std::find(udp2ros_etsi_types_.begin(), udp2ros_etsi_types_.end(), "vam_ts") != udp2ros_etsi_types_.end()) {
369  publishers_["vam_ts"] = std::make_shared<ros::Publisher>(private_node_handle_.advertise<vam_ts_msgs::VAM>(kOutputTopicVamTs, publisher_queue_size_));
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());
371  }
372  if (std::find(ros2udp_etsi_types_.begin(), ros2udp_etsi_types_.end(), "vam_ts") != ros2udp_etsi_types_.end()) {
373  boost::function<void(const vam_ts_msgs::VAM::ConstPtr)> callback =
374  boost::bind(&Converter::rosCallback<vam_ts_msgs::VAM, vam_ts_VAM_t>, this, _1, "vam_ts", &asn_DEF_vam_ts_VAM, std::function<void(const vam_ts_msgs::VAM&, vam_ts_VAM_t&)>(etsi_its_vam_ts_conversion::toStruct_VAM));
375  subscribers_["vam_ts"] = std::make_shared<ros::Subscriber>(private_node_handle_.subscribe<vam_ts_msgs::VAM>(kInputTopicVamTs, subscriber_queue_size_, callback));
376  ROS12_LOG(INFO, "Converting native ROS VAM (TS) on '%s' to UDP messages on '%s'", subscribers_["vam_ts"]->getTopic().c_str(), publisher_udp_->getTopic().c_str());
377  }
378 #else
379  if (!ros2udp_etsi_types_.empty()) {
380  publisher_udp_ = this->create_publisher<UdpPacket>(kOutputTopicUdp, publisher_queue_size_);
381  }
382  if (!udp2ros_etsi_types_.empty()) {
383  subscriber_udp_ = this->create_subscription<UdpPacket>(kInputTopicUdp, subscriber_queue_size_, std::bind(&Converter::udpCallback, this, std::placeholders::_1));
384  }
385  if (std::find(udp2ros_etsi_types_.begin(), udp2ros_etsi_types_.end(), "cam") != udp2ros_etsi_types_.end()) {
386  publisher_cam_ = this->create_publisher<cam_msgs::CAM>(kOutputTopicCam, publisher_queue_size_);
387  ROS12_LOG(INFO, "Converting UDP messages of type CAM on '%s' to native ROS messages on '%s'", subscriber_udp_->get_topic_name(), publisher_cam_->get_topic_name());
388  }
389  if (std::find(ros2udp_etsi_types_.begin(), ros2udp_etsi_types_.end(), "cam") != ros2udp_etsi_types_.end()) {
390  std::function<void(const cam_msgs::CAM::UniquePtr)> callback =
391  std::bind(&Converter::rosCallback<cam_msgs::CAM, cam_CAM_t>, this, std::placeholders::_1, "cam", &asn_DEF_cam_CAM, std::function<void(const cam_msgs::CAM&, cam_CAM_t&)>(etsi_its_cam_conversion::toStruct_CAM));
392  subscribers_["cam"] = this->create_subscription<cam_msgs::CAM>(kInputTopicCam, subscriber_queue_size_, callback);
393  ROS12_LOG(INFO, "Converting native ROS CAMs on '%s' to UDP messages on '%s'", subscribers_["cam"]->get_topic_name(), publisher_udp_->get_topic_name());
394  }
395  if (std::find(udp2ros_etsi_types_.begin(), udp2ros_etsi_types_.end(), "cam_ts") != udp2ros_etsi_types_.end()) {
396  publisher_cam_ts_ = this->create_publisher<cam_ts_msgs::CAM>(kOutputTopicCamTs, publisher_queue_size_);
397  ROS12_LOG(INFO, "Converting UDP messages of type CAM (TS) on '%s' to native ROS messages on '%s'", subscriber_udp_->get_topic_name(), publisher_cam_ts_->get_topic_name());
398  }
399  if (std::find(ros2udp_etsi_types_.begin(), ros2udp_etsi_types_.end(), "cam_ts") != ros2udp_etsi_types_.end()) {
400  std::function<void(const cam_ts_msgs::CAM::UniquePtr)> callback =
401  std::bind(&Converter::rosCallback<cam_ts_msgs::CAM, cam_ts_CAM_t>, this, std::placeholders::_1, "cam_ts", &asn_DEF_cam_ts_CAM, std::function<void(const cam_ts_msgs::CAM&, cam_ts_CAM_t&)>(etsi_its_cam_ts_conversion::toStruct_CAM));
402  subscribers_["cam_ts"] = this->create_subscription<cam_ts_msgs::CAM>(kInputTopicCamTs, subscriber_queue_size_, callback);
403  ROS12_LOG(INFO, "Converting native ROS CAM (TS) on '%s' to UDP messages on '%s'", subscribers_["cam_ts"]->get_topic_name(), publisher_udp_->get_topic_name());
404  }
405  if (std::find(udp2ros_etsi_types_.begin(), udp2ros_etsi_types_.end(), "cpm_ts") != udp2ros_etsi_types_.end()) {
406  publisher_cpm_ts_ = this->create_publisher<cpm_ts_msgs::CollectivePerceptionMessage>(kOutputTopicCpmTs, publisher_queue_size_);
407  ROS12_LOG(INFO, "Converting UDP messages of type CPM (TS) on '%s' to native ROS messages on '%s'", subscriber_udp_->get_topic_name(), publisher_cpm_ts_->get_topic_name());
408  }
409  if (std::find(ros2udp_etsi_types_.begin(), ros2udp_etsi_types_.end(), "cpm_ts") != ros2udp_etsi_types_.end()) {
410  std::function<void(const cpm_ts_msgs::CollectivePerceptionMessage::UniquePtr)> callback =
411  std::bind(&Converter::rosCallback<cpm_ts_msgs::CollectivePerceptionMessage, cpm_ts_CollectivePerceptionMessage_t>, this, std::placeholders::_1, "cpm_ts", &asn_DEF_cpm_ts_CollectivePerceptionMessage, std::function<void(const cpm_ts_msgs::CollectivePerceptionMessage&, cpm_ts_CollectivePerceptionMessage_t&)>(etsi_its_cpm_ts_conversion::toStruct_CollectivePerceptionMessage));
412  subscribers_["cpm_ts"] = this->create_subscription<cpm_ts_msgs::CollectivePerceptionMessage>(kInputTopicCpmTs, subscriber_queue_size_, callback);
413  ROS12_LOG(INFO, "Converting native ROS CPMs (TS) on '%s' to UDP messages on '%s'", subscribers_["cpm_ts"]->get_topic_name(), publisher_udp_->get_topic_name());
414  }
415  if (std::find(udp2ros_etsi_types_.begin(), udp2ros_etsi_types_.end(), "denm") != udp2ros_etsi_types_.end()) {
416  publisher_denm_ = this->create_publisher<denm_msgs::DENM>(kOutputTopicDenm, publisher_queue_size_);
417  ROS12_LOG(INFO, "Converting UDP messages of type DENM on '%s' to native ROS messages on '%s'", subscriber_udp_->get_topic_name(), publisher_denm_->get_topic_name());
418  }
419  if (std::find(ros2udp_etsi_types_.begin(), ros2udp_etsi_types_.end(), "denm") != ros2udp_etsi_types_.end()) {
420  std::function<void(const denm_msgs::DENM::UniquePtr)> callback =
421  std::bind(&Converter::rosCallback<denm_msgs::DENM, denm_DENM_t>, this, std::placeholders::_1, "denm", &asn_DEF_denm_DENM, std::function<void(const denm_msgs::DENM&, denm_DENM_t&)>(etsi_its_denm_conversion::toStruct_DENM));
422  subscribers_["denm"] = this->create_subscription<denm_msgs::DENM>(kInputTopicDenm, subscriber_queue_size_, callback);
423  ROS12_LOG(INFO, "Converting native ROS DENMs on '%s' to UDP messages on '%s'", subscribers_["denm"]->get_topic_name(), publisher_udp_->get_topic_name());
424  }
425  if (std::find(udp2ros_etsi_types_.begin(), udp2ros_etsi_types_.end(), "denm_ts") != udp2ros_etsi_types_.end()) {
426  publisher_denm_ts_ = this->create_publisher<denm_ts_msgs::DENM>(kOutputTopicDenmTs, publisher_queue_size_);
427  ROS12_LOG(INFO, "Converting UDP messages of type DENM (TS) on '%s' to native ROS messages on '%s'", subscriber_udp_->get_topic_name(), publisher_denm_ts_->get_topic_name());
428  }
429  if (std::find(ros2udp_etsi_types_.begin(), ros2udp_etsi_types_.end(), "denm_ts") != ros2udp_etsi_types_.end()) {
430  std::function<void(const denm_ts_msgs::DENM::UniquePtr)> callback =
431  std::bind(&Converter::rosCallback<denm_ts_msgs::DENM, denm_ts_DENM_t>, this, std::placeholders::_1, "denm_ts", &asn_DEF_denm_ts_DENM, std::function<void(const denm_ts_msgs::DENM&, denm_ts_DENM_t&)>(etsi_its_denm_ts_conversion::toStruct_DENM));
432  subscribers_["denm_ts"] = this->create_subscription<denm_ts_msgs::DENM>(kInputTopicDenmTs, subscriber_queue_size_, callback);
433  ROS12_LOG(INFO, "Converting native ROS DENMs (TS) on '%s' to UDP messages on '%s'", subscribers_["denm_ts"]->get_topic_name(), publisher_udp_->get_topic_name());
434  }
435  if (std::find(udp2ros_etsi_types_.begin(), udp2ros_etsi_types_.end(), "mapem_ts") != udp2ros_etsi_types_.end()) {
436  publisher_mapem_ts_ = this->create_publisher<mapem_ts_msgs::MAPEM>(kOutputTopicMapemTs, publisher_queue_size_);
437  ROS12_LOG(INFO, "Converting UDP messages of type MAPEM (TS) on '%s' to native ROS messages on '%s'", subscriber_udp_->get_topic_name(), publisher_mapem_ts_->get_topic_name());
438  }
439  if (std::find(ros2udp_etsi_types_.begin(), ros2udp_etsi_types_.end(), "mapem_ts") != ros2udp_etsi_types_.end()) {
440  std::function<void(const mapem_ts_msgs::MAPEM::UniquePtr)> callback =
441  std::bind(&Converter::rosCallback<mapem_ts_msgs::MAPEM, mapem_ts_MAPEM_t>, this, std::placeholders::_1, "mapem_ts", &asn_DEF_mapem_ts_MAPEM, std::function<void(const mapem_ts_msgs::MAPEM&, mapem_ts_MAPEM_t&)>(etsi_its_mapem_ts_conversion::toStruct_MAPEM));
442  subscribers_["mapem_ts"] = this->create_subscription<mapem_ts_msgs::MAPEM>(kInputTopicMapemTs, subscriber_queue_size_, callback);
443  ROS12_LOG(INFO, "Converting native ROS MAPEMs (TS) on '%s' to UDP messages on '%s'", subscribers_["mapem_ts"]->get_topic_name(), publisher_udp_->get_topic_name());
444  }
445  if (std::find(udp2ros_etsi_types_.begin(), udp2ros_etsi_types_.end(), "mcm_uulm") != udp2ros_etsi_types_.end()) {
446  publisher_mcm_uulm_ = this->create_publisher<mcm_uulm_msgs::MCM>(kOutputTopicMcmUulm, publisher_queue_size_);
447  ROS12_LOG(INFO, "Converting UDP messages of type MCM (UULM) on '%s' to native ROS messages on '%s'", subscriber_udp_->get_topic_name(), publisher_mcm_uulm_->get_topic_name());
448  }
449  if (std::find(ros2udp_etsi_types_.begin(), ros2udp_etsi_types_.end(), "mcm_uulm") != ros2udp_etsi_types_.end()) {
450  std::function<void(const mcm_uulm_msgs::MCM::UniquePtr)> callback =
451  std::bind(&Converter::rosCallback<mcm_uulm_msgs::MCM, mcm_uulm_MCM_t>, this, std::placeholders::_1, "mcm_uulm", &asn_DEF_mcm_uulm_MCM, std::function<void(const mcm_uulm_msgs::MCM&, mcm_uulm_MCM_t&)>(etsi_its_mcm_uulm_conversion::toStruct_MCM));
452  subscribers_["mcm_uulm"] = this->create_subscription<mcm_uulm_msgs::MCM>(kInputTopicMcmUulm, subscriber_queue_size_, callback);
453  ROS12_LOG(INFO, "Converting native ROS MCM (UULM) on '%s' to UDP messages on '%s'", subscribers_["mcm_uulm"]->get_topic_name(), publisher_udp_->get_topic_name());
454  }
455  if (std::find(udp2ros_etsi_types_.begin(), udp2ros_etsi_types_.end(), "spatem_ts") != udp2ros_etsi_types_.end()) {
456  publisher_spatem_ts_ = this->create_publisher<spatem_ts_msgs::SPATEM>(kOutputTopicSpatemTs, publisher_queue_size_);
457  ROS12_LOG(INFO, "Converting UDP messages of type SPATEM (TS) on '%s' to native ROS messages on '%s'", subscriber_udp_->get_topic_name(), publisher_spatem_ts_->get_topic_name());
458  }
459  if (std::find(ros2udp_etsi_types_.begin(), ros2udp_etsi_types_.end(), "spatem_ts") != ros2udp_etsi_types_.end()) {
460  std::function<void(const spatem_ts_msgs::SPATEM::UniquePtr)> callback =
461  std::bind(&Converter::rosCallback<spatem_ts_msgs::SPATEM, spatem_ts_SPATEM_t>, this, std::placeholders::_1, "spatem_ts", &asn_DEF_spatem_ts_SPATEM, std::function<void(const spatem_ts_msgs::SPATEM&, spatem_ts_SPATEM_t&)>(etsi_its_spatem_ts_conversion::toStruct_SPATEM));
462  subscribers_["spatem_ts"] = this->create_subscription<spatem_ts_msgs::SPATEM>(kInputTopicSpatemTs, subscriber_queue_size_, callback);
463  ROS12_LOG(INFO, "Converting native ROS SPATEMs (TS) on '%s' to UDP messages on '%s'", subscribers_["spatem_ts"]->get_topic_name(), publisher_udp_->get_topic_name());
464  }
465  if (std::find(udp2ros_etsi_types_.begin(), udp2ros_etsi_types_.end(), "vam_ts") != udp2ros_etsi_types_.end()) {
466  publisher_vam_ts_ = this->create_publisher<vam_ts_msgs::VAM>(kOutputTopicVamTs, publisher_queue_size_);
467  ROS12_LOG(INFO, "Converting UDP messages of type VAM (TS) on '%s' to native ROS messages on '%s'", subscriber_udp_->get_topic_name(), publisher_vam_ts_->get_topic_name());
468  }
469  if (std::find(ros2udp_etsi_types_.begin(), ros2udp_etsi_types_.end(), "vam_ts") != ros2udp_etsi_types_.end()) {
470  std::function<void(const vam_ts_msgs::VAM::UniquePtr)> callback =
471  std::bind(&Converter::rosCallback<vam_ts_msgs::VAM, vam_ts_VAM_t>, this, std::placeholders::_1, "vam_ts", &asn_DEF_vam_ts_VAM, std::function<void(const vam_ts_msgs::VAM&, vam_ts_VAM_t&)>(etsi_its_vam_ts_conversion::toStruct_VAM));
472  subscribers_["vam_ts"] = this->create_subscription<vam_ts_msgs::VAM>(kInputTopicVamTs, subscriber_queue_size_, callback);
473  ROS12_LOG(INFO, "Converting native ROS VAM (TS) on '%s' to UDP messages on '%s'", subscribers_["vam_ts"]->get_topic_name(), publisher_udp_->get_topic_name());
474  }
475 #endif
476 }
477 
478 
479 template <typename T_struct>
480 bool Converter::decodeBufferToStruct(const uint8_t* buffer, const int size, const asn_TYPE_descriptor_t* type_descriptor, T_struct* asn1_struct) {
481 
482  asn_dec_rval_t ret = asn_decode(0, ATS_UNALIGNED_BASIC_PER, type_descriptor, (void **)&asn1_struct, buffer, size);
483  if (ret.code != RC_OK) {
484  ROS12_LOG(ERROR, "Failed to decode message");
485  return false;
486  }
487  if (logLevelIsDebug()) asn_fprint(stdout, type_descriptor, asn1_struct);
488 
489  return true;
490 }
491 
492 
493 template <typename T_ros, typename T_struct>
494 T_ros Converter::structToRosMessage(const T_struct& asn1_struct, const asn_TYPE_descriptor_t* type_descriptor, std::function<void(const T_struct&, T_ros&)> conversion_fn) {
495 
496  T_ros msg;
497  conversion_fn(asn1_struct, msg);
498 
499  return msg;
500 }
501 
502 
503 template <typename T_ros, typename T_struct>
504 bool Converter::decodeBufferToRosMessage(const uint8_t* buffer, const int size, const asn_TYPE_descriptor_t* type_descriptor, std::function<void(const T_struct&, T_ros&)> conversion_fn, T_ros& msg) {
505 
506  T_struct asn1_struct{};
507  bool success = this->decodeBufferToStruct(buffer, size, type_descriptor, &asn1_struct);
508  if (success) msg = this->structToRosMessage(asn1_struct, type_descriptor, conversion_fn);
509  ASN_STRUCT_FREE_CONTENTS_ONLY(*type_descriptor, &asn1_struct);
510 
511  return success;
512 }
513 
514 
515 template <typename T_ros, typename T_struct>
516 T_struct Converter::rosMessageToStruct(const T_ros& msg, const asn_TYPE_descriptor_t* type_descriptor, std::function<void(const T_ros&, T_struct&)> conversion_fn) {
517 
518  T_struct asn1_struct{};
519  conversion_fn(msg, asn1_struct);
520  if (logLevelIsDebug()) asn_fprint(stdout, type_descriptor, &asn1_struct);
521 
522  return asn1_struct;
523 }
524 
525 
526 template <typename T_struct>
527 bool Converter::encodeStructToBuffer(const T_struct& asn1_struct, const asn_TYPE_descriptor_t* type_descriptor, uint8_t*& buffer, int& size) {
528 
529  char error_buffer[1024];
530  size_t error_length = sizeof(error_buffer);
531  int check_ret = asn_check_constraints(type_descriptor, &asn1_struct, error_buffer, &error_length);
532  if (check_ret != 0) {
533  ROS12_LOG(ERROR, "Check of struct failed: %s", error_buffer);
534  return false;
535  }
536 
538  if (ret.result.encoded == -1) {
539  ROS12_LOG(ERROR, "Failed to encode message: %s", ret.result.failed_type->xml_tag);
540  return false;
541  }
542 
543  buffer = static_cast<uint8_t*>(ret.buffer);
544  size = ret.result.encoded;
545 
546  return true;
547 }
548 
549 
550 UdpPacket Converter::bufferToUdpPacketMessage(const uint8_t* buffer, const int size, const int btp_header_destination_port) {
551 
552 #ifdef ROS1
553  UdpPacket udp_msg;
554 #else
555  UdpPacket udp_msg;
556 #endif
558  // add BTP destination port and destination port info
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));
564  delete[] btp_header;
565  }
566  udp_msg.data.insert(udp_msg.data.end(), buffer, buffer + size);
567 
568  return udp_msg;
569 }
570 
571 
572 template <typename T_ros, typename T_struct>
573 bool Converter::encodeRosMessageToUdpPacketMessage(const T_ros& msg, UdpPacket& udp_msg, const asn_TYPE_descriptor_t* type_descriptor, std::function<void(const T_ros&, T_struct&)> conversion_fn, const int btp_header_destination_port) {
574 
575  // convert ROS msg to struct
576  auto asn1_struct = this->rosMessageToStruct(msg, type_descriptor, conversion_fn);
577 
578  // encode struct to ASN1 bitstring
579  uint8_t* buffer = nullptr;
580  int buffer_size;
581  bool successful = this->encodeStructToBuffer(asn1_struct, type_descriptor, buffer, buffer_size);
582  if (!successful) return false;
583 
584  // copy bitstring to ROS UDP msg
585  udp_msg = this->bufferToUdpPacketMessage(buffer, buffer_size, btp_header_destination_port);
586 
587  // free memory
588  ASN_STRUCT_FREE_CONTENTS_ONLY(*type_descriptor, &asn1_struct);
589  free(buffer);
590 
591  return true;
592 }
593 
594 
595 #ifdef ROS1
596 void Converter::udpCallback(const UdpPacket::ConstPtr udp_msg) {
597 #else
598 void Converter::udpCallback(const UdpPacket::UniquePtr udp_msg) {
599 #endif
600 
601  ROS12_LOG(DEBUG, "Received bitstring (total payload size: %ld)", udp_msg->data.size());
602 
603  // auto-detect ETSI message type if BTP destination port is present
604  std::string detected_etsi_type = udp2ros_etsi_types_[0];
606  const uint16_t* btp_destination_port = reinterpret_cast<const uint16_t*>(&udp_msg->data[btp_destination_port_offset_]);
607  uint16_t destination_port = ntohs(*btp_destination_port);
608  if (destination_port == kBtpHeaderDestinationPortCam) detected_etsi_type = "cam";
609  else if (destination_port == kBtpHeaderDestinationPortCpmTs) detected_etsi_type = "cpm_ts";
610  else if (destination_port == kBtpHeaderDestinationPortDenm) detected_etsi_type = "denm";
611  else if (destination_port == kBtpHeaderDestinationPortIvi) detected_etsi_type = "ivi";
612  else if (destination_port == kBtpHeaderDestinationPortMapem) detected_etsi_type = "mapem_ts";
613  else if (destination_port == kBtpHeaderDestinationPortMcmUulm) detected_etsi_type = "mcm_uulm";
614  else if (destination_port == kBtpHeaderDestinationPortSpatem) detected_etsi_type = "spatem_ts";
615  else if (destination_port == kBtpHeaderDestinationPortVamTs) detected_etsi_type = "vam_ts";
616  else detected_etsi_type = "unknown";
617  }
618 
619  const uint8_t* protocol_version = reinterpret_cast<const uint8_t*>(&udp_msg->data[etsi_message_payload_offset_]);
620 
621  int msg_size = udp_msg->data.size() - etsi_message_payload_offset_;
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());
623 
624  if (detected_etsi_type == "cam" || detected_etsi_type == "cam_ts") {
625 
626  if (std::find(udp2ros_etsi_types_.begin(), udp2ros_etsi_types_.end(), "cam") != udp2ros_etsi_types_.end()) { // CAM EN v1.4.1
627  cam_msgs::CAM msg;
628  bool success = this->decodeBufferToRosMessage(&udp_msg->data[etsi_message_payload_offset_], msg_size, &asn_DEF_cam_CAM, std::function<void(const cam_CAM_t&, cam_msgs::CAM&)>(etsi_its_cam_conversion::toRos_CAM), msg);
629  if (!success) return;
630 #ifdef ROS1
631  publishers_["cam"]->publish(msg);
632 #else
633  publisher_cam_->publish(msg);
634 #endif
635  }
636  if (std::find(udp2ros_etsi_types_.begin(), udp2ros_etsi_types_.end(), "cam_ts") != udp2ros_etsi_types_.end()) { // CAM TS v2.1.1
637  cam_ts_msgs::CAM msg;
638  bool success = this->decodeBufferToRosMessage(&udp_msg->data[etsi_message_payload_offset_], msg_size, &asn_DEF_cam_ts_CAM, std::function<void(const cam_ts_CAM_t&, cam_ts_msgs::CAM&)>(etsi_its_cam_ts_conversion::toRos_CAM), msg);
639  if (!success) return;
640 #ifdef ROS1
641  publishers_["cam_ts"]->publish(msg);
642 #else
643  publisher_cam_ts_->publish(msg);
644 #endif
645  }
646 
647  } else if (detected_etsi_type == "cpm_ts") {
648 
649  // decode buffer to ROS msg
650  cpm_ts_msgs::CollectivePerceptionMessage msg;
651  bool success = this->decodeBufferToRosMessage(&udp_msg->data[etsi_message_payload_offset_], msg_size, &asn_DEF_cpm_ts_CollectivePerceptionMessage, std::function<void(const cpm_ts_CollectivePerceptionMessage_t&, cpm_ts_msgs::CollectivePerceptionMessage&)>(etsi_its_cpm_ts_conversion::toRos_CollectivePerceptionMessage), msg);
652  if (!success) return;
653 
654  // publish msg
655 #ifdef ROS1
656  publishers_["cpm_ts"]->publish(msg);
657 #else
658  publisher_cpm_ts_->publish(msg);
659 #endif
660 
661  } else if (detected_etsi_type == "denm" || detected_etsi_type == "denm_ts") {
662 
663  if (std::find(udp2ros_etsi_types_.begin(), udp2ros_etsi_types_.end(), "denm") != udp2ros_etsi_types_.end()) { // DENM EN v1.3.1
664  denm_msgs::DENM msg;
665  bool success = this->decodeBufferToRosMessage(&udp_msg->data[etsi_message_payload_offset_], msg_size, &asn_DEF_denm_DENM, std::function<void(const denm_DENM_t&, denm_msgs::DENM&)>(etsi_its_denm_conversion::toRos_DENM), msg);
666  if (!success) return;
667 #ifdef ROS1
668  publishers_["denm"]->publish(msg);
669 #else
670  publisher_denm_->publish(msg);
671 #endif
672  }
673  if (std::find(udp2ros_etsi_types_.begin(), udp2ros_etsi_types_.end(), "denm_ts") != udp2ros_etsi_types_.end()) { // DENM TS v2.2.1
674  denm_ts_msgs::DENM msg;
675  bool success = this->decodeBufferToRosMessage(&udp_msg->data[etsi_message_payload_offset_], msg_size, &asn_DEF_denm_ts_DENM, std::function<void(const denm_ts_DENM_t&, denm_ts_msgs::DENM&)>(etsi_its_denm_ts_conversion::toRos_DENM), msg);
676  if (!success) return;
677 #ifdef ROS1
678  publishers_["denm_ts"]->publish(msg);
679 #else
680  publisher_denm_ts_->publish(msg);
681 #endif
682  }
683 
684  } else if (detected_etsi_type == "vam_ts") {
685 
686  // decode buffer to ROS msg
687  vam_ts_msgs::VAM msg;
688  bool success = this->decodeBufferToRosMessage(&udp_msg->data[etsi_message_payload_offset_], msg_size, &asn_DEF_vam_ts_VAM, std::function<void(const vam_ts_VAM_t&, vam_ts_msgs::VAM&)>(etsi_its_vam_ts_conversion::toRos_VAM), msg);
689  if (!success) return;
690 
691  // publish msg
692 #ifdef ROS1
693  publishers_["vam_ts"]->publish(msg);
694 #else
695  publisher_vam_ts_->publish(msg);
696 #endif
697 
698  } else if (detected_etsi_type == "mapem_ts") {
699 
700  // decode buffer to ROS msg
701  mapem_ts_msgs::MAPEM msg;
702  bool success = this->decodeBufferToRosMessage(&udp_msg->data[etsi_message_payload_offset_], msg_size, &asn_DEF_mapem_ts_MAPEM, std::function<void(const mapem_ts_MAPEM_t&, mapem_ts_msgs::MAPEM&)>(etsi_its_mapem_ts_conversion::toRos_MAPEM), msg);
703  if (!success) return;
704 
705  // publish msg
706  #ifdef ROS1
707  publishers_["mapem_ts"]->publish(msg);
708  #else
709  publisher_mapem_ts_->publish(msg);
710  #endif
711 
712  } else if (detected_etsi_type == "mcm_uulm") {
713 
714  // decode buffer to ROS msg
715  mcm_uulm_msgs::MCM msg;
716  bool success = this->decodeBufferToRosMessage(&udp_msg->data[etsi_message_payload_offset_], msg_size, &asn_DEF_mcm_uulm_MCM, std::function<void(const mcm_uulm_MCM_t&, mcm_uulm_msgs::MCM&)>(etsi_its_mcm_uulm_conversion::toRos_MCM), msg);
717  if (!success) return;
718 
719  // publish msg
720  #ifdef ROS1
721  publishers_["mcm_uulm"]->publish(msg);
722  #else
723  publisher_mcm_uulm_->publish(msg);
724  #endif
725 
726  } else if (detected_etsi_type == "spatem_ts") {
727 
728  // decode buffer to ROS msg
729  spatem_ts_msgs::SPATEM msg;
730  bool success = this->decodeBufferToRosMessage(&udp_msg->data[etsi_message_payload_offset_], msg_size, &asn_DEF_spatem_ts_SPATEM, std::function<void(const spatem_ts_SPATEM_t&, spatem_ts_msgs::SPATEM&)>(etsi_its_spatem_ts_conversion::toRos_SPATEM), msg);
731  if (!success) return;
732 
733  // publish msg
734  #ifdef ROS1
735  publishers_["spatem_ts"]->publish(msg);
736  #else
737  publisher_spatem_ts_->publish(msg);
738  #endif
739 
740  } else {
741  ROS12_LOG(ERROR, "Detected ETSI message type '%s' not yet supported, dropping message", detected_etsi_type.c_str());
742  return;
743  }
744 
745  ROS12_LOG(INFO, "Published ETSI message of type '%s' as ROS message", detected_etsi_type.c_str());
746 }
747 
748 
749 template <typename T_ros, typename T_struct>
750 #ifdef ROS1
751 void Converter::rosCallback(const typename T_ros::ConstPtr msg,
752 #else
753 void Converter::rosCallback(const typename T_ros::UniquePtr msg,
754 #endif
755  const std::string& type, const asn_TYPE_descriptor_t* type_descriptor, std::function<void(const T_ros&, T_struct&)> conversion_fn) {
756 
757  ROS12_LOG(INFO, "Received ETSI message of type '%s' as ROS message", type.c_str());
758 
759  int btp_header_destination_port = 0;
760  if (type == "cam" || type == "cam_ts") btp_header_destination_port = kBtpHeaderDestinationPortCam;
761  else if (type == "cpm_ts") btp_header_destination_port = kBtpHeaderDestinationPortCpmTs;
762  else if (type == "denm" || type == "denm_ts") btp_header_destination_port = kBtpHeaderDestinationPortDenm;
763  else if (type == "mapem_ts") btp_header_destination_port = kBtpHeaderDestinationPortMapem;
764  else if (type == "mcm_uulm") btp_header_destination_port = kBtpHeaderDestinationPortMcmUulm;
765  else if (type == "spatem_ts") btp_header_destination_port = kBtpHeaderDestinationPortSpatem;
766  else if (type == "vam_ts") btp_header_destination_port = kBtpHeaderDestinationPortVamTs;
767 
768  // encode ROS msg to UDP msg
769  UdpPacket udp_msg;
770  bool success = this->encodeRosMessageToUdpPacketMessage<T_ros, T_struct>(*msg, udp_msg, type_descriptor, conversion_fn, btp_header_destination_port);
771  if (!success) return;
772 
773  // publish UDP msg
774  publisher_udp_->publish(udp_msg);
775  int msg_size = has_btp_destination_port_ ? udp_msg.data.size() - 4 : udp_msg.data.size();
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());
777 }
778 
779 
780 } // end of namespace
denm_ts_DENM
asn_DEF_denm_ts_DENM
asn_TYPE_descriptor_t asn_DEF_denm_ts_DENM
etsi_its_conversion::Converter::kInputTopicCpmTs
static const std::string kInputTopicCpmTs
Definition: Converter.hpp:160
etsi_its_conversion::kBtpHeaderDestinationPortCpmTs
const int kBtpHeaderDestinationPortCpmTs
Definition: Converter.cpp:54
etsi_its_conversion::Converter::subscribers_
std::unordered_map< std::string, rclcpp::SubscriptionBase::SharedPtr > subscribers_
Definition: Converter.hpp:209
etsi_its_conversion::kBtpHeaderDestinationPortIvi
const int kBtpHeaderDestinationPortIvi
Definition: Converter.cpp:53
etsi_its_conversion::Converter::kOutputTopicMcmUulm
static const std::string kOutputTopicMcmUulm
Definition: Converter.hpp:169
etsi_its_conversion::Converter::has_btp_destination_port_
bool has_btp_destination_port_
Definition: Converter.hpp:193
cam_CAM
etsi_its_conversion::Converter::setup
void setup()
Definition: Converter.cpp:278
etsi_its_conversion::Converter::decodeBufferToStruct
bool decodeBufferToStruct(const uint8_t *buffer, const int size, const asn_TYPE_descriptor_t *type_descriptor, T_struct *asn1_struct)
Definition: Converter.cpp:480
etsi_its_conversion::kBtpHeaderDestinationPortDenm
const int kBtpHeaderDestinationPortDenm
Definition: Converter.cpp:50
etsi_its_conversion::Converter::kOutputTopicCamTs
static const std::string kOutputTopicCamTs
Definition: Converter.hpp:159
etsi_its_denm_ts_conversion::toStruct_DENM
void toStruct_DENM(const denm_ts_msgs::DENM &in, denm_ts_DENM_t &out)
asn_DEF_cam_CAM
asn_TYPE_descriptor_t asn_DEF_cam_CAM
etsi_its_conversion::Converter::kEtsiMessagePayloadOffsetParamDefault
static const int kEtsiMessagePayloadOffsetParamDefault
Definition: Converter.hpp:180
etsi_its_conversion::Converter::kBtpDestinationPortOffsetParamDefault
static const int kBtpDestinationPortOffsetParamDefault
Definition: Converter.hpp:178
etsi_its_cpm_ts_conversion::toStruct_CollectivePerceptionMessage
void toStruct_CollectivePerceptionMessage(const cpm_ts_msgs::CollectivePerceptionMessage &in, cpm_ts_CollectivePerceptionMessage_t &out)
etsi_its_vam_ts_conversion::toRos_VAM
void toRos_VAM(const vam_ts_VAM_t &in, vam_ts_msgs::VAM &out)
asn_check_constraints
int asn_check_constraints(const asn_TYPE_descriptor_t *type_descriptor, const void *struct_ptr, char *errbuf, size_t *errlen)
etsi_its_conversion::Converter::kEtsiTypesParamSupportedOptions
static const std::vector< std::string > kEtsiTypesParamSupportedOptions
Definition: Converter.hpp:183
etsi_its_conversion::Converter::kBtpDestinationPortOffsetParam
static const std::string kBtpDestinationPortOffsetParam
Definition: Converter.hpp:177
asn_DEF_vam_ts_VAM
asn_TYPE_descriptor_t asn_DEF_vam_ts_VAM
etsi_its_spatem_ts_conversion::toStruct_SPATEM
void toStruct_SPATEM(const spatem_ts_msgs::SPATEM &in, spatem_ts_SPATEM_t &out)
mcm_uulm_MCM
etsi_its_vam_ts_conversion::toStruct_VAM
void toStruct_VAM(const vam_ts_msgs::VAM &in, vam_ts_VAM_t &out)
asn_fprint
int asn_fprint(FILE *stream, const asn_TYPE_descriptor_t *td, const void *struct_ptr)
spatem_ts_SPATEM
etsi_its_conversion::Converter::kRos2UdpEtsiTypesParamDefault
static const std::vector< std::string > kRos2UdpEtsiTypesParamDefault
Definition: Converter.hpp:184
etsi_its_conversion::Converter::publisher_cam_
rclcpp::Publisher< cam_msgs::CAM >::SharedPtr publisher_cam_
Definition: Converter.hpp:210
etsi_its_conversion::Converter::kOutputTopicDenmTs
static const std::string kOutputTopicDenmTs
Definition: Converter.hpp:165
vam_ts_VAM
etsi_its_conversion::Converter::publisher_spatem_ts_
rclcpp::Publisher< spatem_ts_msgs::SPATEM >::SharedPtr publisher_spatem_ts_
Definition: Converter.hpp:217
etsi_its_mapem_ts_conversion::toRos_MAPEM
void toRos_MAPEM(const mapem_ts_MAPEM_t &in, mapem_ts_msgs::MAPEM &out)
etsi_its_spatem_ts_conversion::toRos_SPATEM
void toRos_SPATEM(const spatem_ts_SPATEM_t &in, spatem_ts_msgs::SPATEM &out)
etsi_its_conversion::Converter
Definition: Converter.hpp:99
etsi_its_conversion::Converter::publisher_udp_
rclcpp::Publisher< UdpPacket >::SharedPtr publisher_udp_
Definition: Converter.hpp:219
etsi_its_conversion::Converter::kPublisherQueueSizeParamDefault
static const int kPublisherQueueSizeParamDefault
Definition: Converter.hpp:189
etsi_its_conversion::Converter::publisher_denm_ts_
rclcpp::Publisher< denm_ts_msgs::DENM >::SharedPtr publisher_denm_ts_
Definition: Converter.hpp:214
etsi_its_conversion::Converter::Converter
Converter(const rclcpp::NodeOptions &options)
Definition: Converter.cpp:148
etsi_its_conversion::Converter::kInputTopicMcmUulm
static const std::string kInputTopicMcmUulm
Definition: Converter.hpp:168
etsi_its_conversion::Converter::etsi_message_payload_offset_
int etsi_message_payload_offset_
Definition: Converter.hpp:195
asn_TYPE_descriptor_s::xml_tag
const char * xml_tag
class_list_macros.h
etsi_its_conversion::Converter::kRos2UdpEtsiTypesParam
static const std::string kRos2UdpEtsiTypesParam
Definition: Converter.hpp:181
console.h
etsi_its_conversion::Converter::publisher_cam_ts_
rclcpp::Publisher< cam_ts_msgs::CAM >::SharedPtr publisher_cam_ts_
Definition: Converter.hpp:211
asn_DEF_cpm_ts_CollectivePerceptionMessage
asn_TYPE_descriptor_t asn_DEF_cpm_ts_CollectivePerceptionMessage
asn_TYPE_descriptor_s
etsi_its_conversion::Converter::kOutputTopicUdp
static const std::string kOutputTopicUdp
Definition: Converter.hpp:155
PLUGINLIB_EXPORT_CLASS
#define PLUGINLIB_EXPORT_CLASS(class_type, base_class_type)
asn_enc_rval_s::failed_type
const struct asn_TYPE_descriptor_s * failed_type
asn_encode_to_new_buffer_result_s
etsi_its_denm_conversion::toStruct_DENM
void toStruct_DENM(const denm_msgs::DENM &in, denm_DENM_t &out)
etsi_its_conversion::Converter::subscriber_udp_
rclcpp::Subscription< UdpPacket >::SharedPtr subscriber_udp_
Definition: Converter.hpp:208
etsi_its_conversion::Converter::rosCallback
void rosCallback(const typename T_ros::UniquePtr msg, const std::string &type, const asn_TYPE_descriptor_t *type_descriptor, std::function< void(const T_ros &, T_struct &)> conversion_fn)
Definition: Converter.cpp:753
cpm_ts_CollectivePerceptionMessage
Converter.hpp
etsi_its_conversion::Converter::bufferToUdpPacketMessage
UdpPacket bufferToUdpPacketMessage(const uint8_t *buffer, const int size, const int btp_header_destination_port)
Definition: Converter.cpp:550
asn_encode_to_new_buffer_result_s::result
asn_enc_rval_t result
etsi_its_conversion::Converter::kSubscriberQueueSizeParam
static const std::string kSubscriberQueueSizeParam
Definition: Converter.hpp:186
etsi_its_conversion::kBtpHeaderDestinationPortMcmUulm
const int kBtpHeaderDestinationPortMcmUulm
Definition: Converter.cpp:56
etsi_its_conversion::kBtpHeaderDestinationPortMapem
const int kBtpHeaderDestinationPortMapem
Definition: Converter.cpp:51
etsi_its_mcm_uulm_conversion::toRos_MCM
void toRos_MCM(const mcm_uulm_MCM_t &in, mcm_uulm_msgs::MCM &out)
etsi_its_conversion::Converter::kInputTopicUdp
static const std::string kInputTopicUdp
Definition: Converter.hpp:154
etsi_its_conversion::kBtpHeaderDestinationPortCam
const int kBtpHeaderDestinationPortCam
Definition: Converter.cpp:49
RC_OK
RC_OK
etsi_its_conversion::Converter::kPublisherQueueSizeParam
static const std::string kPublisherQueueSizeParam
Definition: Converter.hpp:188
etsi_its_conversion::kBtpHeaderDestinationPortSpatem
const int kBtpHeaderDestinationPortSpatem
Definition: Converter.cpp:52
asn_DEF_denm_DENM
asn_TYPE_descriptor_t asn_DEF_denm_DENM
cam_ts_CAM
asn_DEF_spatem_ts_SPATEM
asn_TYPE_descriptor_t asn_DEF_spatem_ts_SPATEM
etsi_its_conversion::Converter::loadParameters
void loadParameters()
Definition: Converter.cpp:156
etsi_its_cpm_ts_conversion::toRos_CollectivePerceptionMessage
void toRos_CollectivePerceptionMessage(const cpm_ts_CollectivePerceptionMessage_t &in, cpm_ts_msgs::CollectivePerceptionMessage &out)
etsi_its_conversion::Converter::btp_destination_port_offset_
int btp_destination_port_offset_
Definition: Converter.hpp:194
etsi_its_cam_ts_conversion::toStruct_CAM
void toStruct_CAM(const cam_ts_msgs::CAM &in, cam_ts_CAM_t &out)
etsi_its_conversion::Converter::kUdp2RosEtsiTypesParamDefault
static const std::vector< std::string > kUdp2RosEtsiTypesParamDefault
Definition: Converter.hpp:185
etsi_its_conversion::Converter::kOutputTopicCpmTs
static const std::string kOutputTopicCpmTs
Definition: Converter.hpp:161
denm_DENM
asn_DEF_mapem_ts_MAPEM
asn_TYPE_descriptor_t asn_DEF_mapem_ts_MAPEM
etsi_its_conversion::Converter::decodeBufferToRosMessage
bool decodeBufferToRosMessage(const uint8_t *buffer, const int size, const asn_TYPE_descriptor_t *type_descriptor, std::function< void(const T_struct &, T_ros &)> conversion_fn, T_ros &msg)
Definition: Converter.cpp:504
etsi_its_conversion::Converter::kEtsiMessagePayloadOffsetParam
static const std::string kEtsiMessagePayloadOffsetParam
Definition: Converter.hpp:179
etsi_its_conversion::Converter::kOutputTopicSpatemTs
static const std::string kOutputTopicSpatemTs
Definition: Converter.hpp:171
asn_decode
asn_dec_rval_t asn_decode(const asn_codec_ctx_t *opt_codec_ctx, enum asn_transfer_syntax syntax, const asn_TYPE_descriptor_t *td, void **sptr, const void *buffer, size_t size)
etsi_its_conversion::Converter::ros2udp_etsi_types_
std::vector< std::string > ros2udp_etsi_types_
Definition: Converter.hpp:196
etsi_its_conversion::Converter::publisher_cpm_ts_
rclcpp::Publisher< cpm_ts_msgs::CollectivePerceptionMessage >::SharedPtr publisher_cpm_ts_
Definition: Converter.hpp:212
etsi_its_conversion::Converter::kHasBtpDestinationPortParam
static const std::string kHasBtpDestinationPortParam
Definition: Converter.hpp:175
etsi_its_conversion::Converter::structToRosMessage
T_ros structToRosMessage(const T_struct &asn1_struct, const asn_TYPE_descriptor_t *type_descriptor, std::function< void(const T_struct &, T_ros &)> conversion_fn)
Definition: Converter.cpp:494
etsi_its_conversion::Converter::kCheckConstraintsBeforeEncodingParamDefault
static const bool kCheckConstraintsBeforeEncodingParamDefault
Definition: Converter.hpp:191
ros::this_node::getName
const ROSCPP_DECL std::string & getName()
etsi_its_denm_conversion::toRos_DENM
void toRos_DENM(const denm_DENM_t &in, denm_msgs::DENM &out)
etsi_its_conversion
Definition: Converter.hpp:68
asn_encode_to_new_buffer
asn_encode_to_new_buffer_result_t asn_encode_to_new_buffer(const asn_codec_ctx_t *opt_codec_ctx, enum asn_transfer_syntax syntax, const asn_TYPE_descriptor_t *td, const void *sptr)
etsi_its_mcm_uulm_conversion::toStruct_MCM
void toStruct_MCM(const mcm_uulm_msgs::MCM &in, mcm_uulm_MCM_t &out)
etsi_its_conversion::Converter::publisher_mapem_ts_
rclcpp::Publisher< mapem_ts_msgs::MAPEM >::SharedPtr publisher_mapem_ts_
Definition: Converter.hpp:215
etsi_its_mapem_ts_conversion::toStruct_MAPEM
void toStruct_MAPEM(const mapem_ts_msgs::MAPEM &in, mapem_ts_MAPEM_t &out)
nodelet::Nodelet
etsi_its_conversion::Converter::kOutputTopicCam
static const std::string kOutputTopicCam
Definition: Converter.hpp:157
etsi_its_cam_conversion::toStruct_CAM
void toStruct_CAM(const cam_msgs::CAM &in, cam_CAM_t &out)
etsi_its_conversion::Converter::publisher_queue_size_
int publisher_queue_size_
Definition: Converter.hpp:199
etsi_its_conversion::Converter::kOutputTopicVamTs
static const std::string kOutputTopicVamTs
Definition: Converter.hpp:173
etsi_its_conversion::Converter::encodeRosMessageToUdpPacketMessage
bool encodeRosMessageToUdpPacketMessage(const T_ros &msg, UdpPacket &udp_msg, const asn_TYPE_descriptor_t *type_descriptor, std::function< void(const T_ros &, T_struct &)> conversion_fn, const int btp_header_destination_port)
Definition: Converter.cpp:573
etsi_its_conversion::Converter::publisher_denm_
rclcpp::Publisher< denm_msgs::DENM >::SharedPtr publisher_denm_
Definition: Converter.hpp:213
asn_dec_rval_s
etsi_its_conversion::Converter::subscriber_queue_size_
int subscriber_queue_size_
Definition: Converter.hpp:198
etsi_its_conversion::Converter::kInputTopicDenm
static const std::string kInputTopicDenm
Definition: Converter.hpp:162
etsi_its_conversion::Converter::kInputTopicMapemTs
static const std::string kInputTopicMapemTs
Definition: Converter.hpp:166
ATS_UNALIGNED_BASIC_PER
ATS_UNALIGNED_BASIC_PER
etsi_its_conversion::Converter::publisher_mcm_uulm_
rclcpp::Publisher< mcm_uulm_msgs::MCM >::SharedPtr publisher_mcm_uulm_
Definition: Converter.hpp:216
etsi_its_denm_ts_conversion::toRos_DENM
void toRos_DENM(const denm_ts_DENM_t &in, denm_ts_msgs::DENM &out)
asn_enc_rval_s::encoded
ssize_t encoded
asn_encode_to_new_buffer_result_s::buffer
void * buffer
etsi_its_conversion::Converter::kHasBtpDestinationPortParamDefault
static const bool kHasBtpDestinationPortParamDefault
Definition: Converter.hpp:176
asn_DEF_cam_ts_CAM
asn_TYPE_descriptor_t asn_DEF_cam_ts_CAM
ROSCONSOLE_DEFAULT_NAME
#define ROSCONSOLE_DEFAULT_NAME
etsi_its_cam_ts_conversion::toRos_CAM
void toRos_CAM(const cam_ts_CAM_t &in, cam_ts_msgs::CAM &out)
asn_DEF_mcm_uulm_MCM
asn_TYPE_descriptor_t asn_DEF_mcm_uulm_MCM
etsi_its_conversion::Converter::kInputTopicCamTs
static const std::string kInputTopicCamTs
Definition: Converter.hpp:158
ROS12_LOG
#define ROS12_LOG(level,...)
Definition: Converter.cpp:42
etsi_its_conversion::kBtpHeaderDestinationPortVamTs
const int kBtpHeaderDestinationPortVamTs
Definition: Converter.cpp:55
etsi_its_conversion::Converter::kInputTopicVamTs
static const std::string kInputTopicVamTs
Definition: Converter.hpp:172
etsi_its_conversion::Converter::kSubscriberQueueSizeParamDefault
static const int kSubscriberQueueSizeParamDefault
Definition: Converter.hpp:187
ASN_STRUCT_FREE_CONTENTS_ONLY
#define ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF, ptr)
ros::console::get_loggers
ROSCONSOLE_DECL bool get_loggers(std::map< std::string, levels::Level > &loggers)
etsi_its_cam_conversion::toRos_CAM
void toRos_CAM(const cam_CAM_t &in, cam_msgs::CAM &out)
etsi_its_conversion::Converter::udp2ros_etsi_types_
std::vector< std::string > udp2ros_etsi_types_
Definition: Converter.hpp:197
etsi_its_conversion::Converter::rosMessageToStruct
T_struct rosMessageToStruct(const T_ros &msg, const asn_TYPE_descriptor_t *type_descriptor, std::function< void(const T_ros &, T_struct &)> conversion_fn)
Definition: Converter.cpp:516
etsi_its_conversion::Converter::kInputTopicCam
static const std::string kInputTopicCam
Definition: Converter.hpp:156
etsi_its_conversion::Converter::publisher_vam_ts_
rclcpp::Publisher< vam_ts_msgs::VAM >::SharedPtr publisher_vam_ts_
Definition: Converter.hpp:218
etsi_its_conversion::Converter::kOutputTopicDenm
static const std::string kOutputTopicDenm
Definition: Converter.hpp:163
etsi_its_conversion::Converter::kUdp2RosEtsiTypesParam
static const std::string kUdp2RosEtsiTypesParam
Definition: Converter.hpp:182
etsi_its_conversion::Converter::encodeStructToBuffer
bool encodeStructToBuffer(const T_struct &asn1_struct, const asn_TYPE_descriptor_t *type_descriptor, uint8_t *&buffer, int &size)
Definition: Converter.cpp:527
asn_dec_rval_s::code
enum asn_dec_rval_code_e code
etsi_its_conversion::Converter::kOutputTopicMapemTs
static const std::string kOutputTopicMapemTs
Definition: Converter.hpp:167
etsi_its_conversion::Converter::kInputTopicDenmTs
static const std::string kInputTopicDenmTs
Definition: Converter.hpp:164
etsi_its_conversion::Converter::udpCallback
void udpCallback(const UdpPacket::UniquePtr udp_msg)
Definition: Converter.cpp:598
etsi_its_conversion::Converter::logLevelIsDebug
bool logLevelIsDebug()
Definition: Converter.cpp:120
etsi_its_conversion::Converter::kInputTopicSpatemTs
static const std::string kInputTopicSpatemTs
Definition: Converter.hpp:170
mapem_ts_MAPEM


etsi_its_conversion
Author(s): Jean-Pierre Busch , Guido Küppers , Lennart Reiher
autogenerated on Sun May 18 2025 02:32:28