factory.hpp
Go to the documentation of this file.
1 // Copyright 2018 Open Source Robotics Foundation, Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef ROS_IGN_BRIDGE__FACTORY_HPP_
16 #define ROS_IGN_BRIDGE__FACTORY_HPP_
17 
18 #include <functional>
19 #include <memory>
20 #include <string>
21 
22 #include <ignition/transport/Node.hh>
23 
24 // include ROS message event
25 #include <ros/console.h>
26 #include <ros/message.h>
27 #include <ros/ros.h>
28 
29 #include "factory_interface.hpp"
30 
31 namespace ros_ign_bridge
32 {
33 
34 template<typename ROS_T, typename IGN_T>
35 class Factory : public FactoryInterface
36 {
37 public:
39  const std::string & ros_type_name, const std::string & ign_type_name)
40  : ros_type_name_(ros_type_name),
41  ign_type_name_(ign_type_name)
42  {}
43 
46  ros::NodeHandle node,
47  const std::string & topic_name,
48  size_t queue_size)
49  {
50  return node.advertise<ROS_T>(topic_name, queue_size);
51  }
52 
53  ignition::transport::Node::Publisher
55  std::shared_ptr<ignition::transport::Node> ign_node,
56  const std::string & topic_name,
57  size_t /*queue_size*/)
58  {
59  return ign_node->Advertise<IGN_T>(topic_name);
60  }
61 
64  ros::NodeHandle node,
65  const std::string & topic_name,
66  size_t queue_size,
67  ignition::transport::Node::Publisher & ign_pub)
68  {
69  // workaround for https://github.com/ros/roscpp_core/issues/22 to get the
70  // connection header
72  ops.topic = topic_name;
73  ops.queue_size = queue_size;
74  ops.md5sum = ros::message_traits::md5sum<ROS_T>();
75  ops.datatype = ros::message_traits::datatype<ROS_T>();
79  boost::bind(
81  _1, ign_pub, ros_type_name_, ign_type_name_)));
82  return node.subscribe(ops);
83  }
84 
85  void
87  std::shared_ptr<ignition::transport::Node> node,
88  const std::string & topic_name,
89  size_t /*queue_size*/,
90  ros::Publisher ros_pub)
91  {
92 
93  std::function<void(const IGN_T&,
94  const ignition::transport::MessageInfo &)> subCb =
95  [this, ros_pub](const IGN_T &_msg,
96  const ignition::transport::MessageInfo &_info)
97  {
98  // Ignore messages that are published from this bridge.
99  if (!_info.IntraProcess())
100  this->ign_callback(_msg, ros_pub);
101  };
102 
103  node->Subscribe(topic_name, subCb);
104  }
105 
106 protected:
107 
108  static
110  const ros::MessageEvent<ROS_T const> & ros_msg_event,
111  ignition::transport::Node::Publisher & ign_pub,
112  const std::string &ros_type_name,
113  const std::string &ign_type_name)
114  {
115  const boost::shared_ptr<ros::M_string> & connection_header =
116  ros_msg_event.getConnectionHeaderPtr();
117  if (!connection_header) {
118  ROS_ERROR("Dropping message %s without connection header",
119  ros_type_name.c_str());
120  return;
121  }
122 
123  std::string key = "callerid";
124  if (connection_header->find(key) != connection_header->end()) {
125  if (connection_header->at(key) == ros::this_node::getName()) {
126  return;
127  }
128  }
129 
130  const boost::shared_ptr<ROS_T const> & ros_msg =
131  ros_msg_event.getConstMessage();
132 
133  IGN_T ign_msg;
134  convert_ros_to_ign(*ros_msg, ign_msg);
135  ign_pub.Publish(ign_msg);
136  ROS_INFO_ONCE("Passing message from ROS %s to Ignition %s (showing msg"\
137  " only once per type)", ros_type_name.c_str(), ign_type_name.c_str());
138  }
139 
140  static
142  const IGN_T & ign_msg,
143  ros::Publisher ros_pub)
144  {
145  ROS_T ros_msg;
146  convert_ign_to_ros(ign_msg, ros_msg);
147  ros_pub.publish(ros_msg);
148  }
149 
150 public:
151  // since convert functions call each other for sub messages they must be
152  // public defined outside of the class
153  static
154  void
156  const ROS_T & ros_msg,
157  IGN_T & ign_msg);
158  static
159  void
161  const IGN_T & ign_msg,
162  ROS_T & ros_msg);
163 
164  std::string ros_type_name_;
165  std::string ign_type_name_;
166 };
167 
168 } // namespace ros_ign_bridge
169 
170 #endif // ROS_BRIDGE__FACTORY_HPP_
ros_ign_bridge::Factory::create_ign_subscriber
void create_ign_subscriber(std::shared_ptr< ignition::transport::Node > node, const std::string &topic_name, size_t, ros::Publisher ros_pub)
Definition: factory.hpp:86
ros::SubscriptionCallbackHelperPtr
boost::shared_ptr< SubscriptionCallbackHelper > SubscriptionCallbackHelperPtr
message.h
ros::Publisher
boost::shared_ptr
factory_interface.hpp
ros.h
ros::SubscribeOptions::topic
std::string topic
ros::SubscriptionCallbackHelperT
ros::MessageEvent::getConstMessage
const boost::shared_ptr< ConstMessage > & getConstMessage() const
ros_ign_bridge::Factory::create_ign_publisher
ignition::transport::Node::Publisher create_ign_publisher(std::shared_ptr< ignition::transport::Node > ign_node, const std::string &topic_name, size_t)
Definition: factory.hpp:54
ros::Publisher::publish
void publish(const boost::shared_ptr< M > &message) const
ros::NodeHandle::advertise
Publisher advertise(AdvertiseOptions &ops)
console.h
ros::SubscribeOptions::md5sum
std::string md5sum
ros_ign_bridge::Factory
Definition: factory.hpp:35
ROS_INFO_ONCE
#define ROS_INFO_ONCE(...)
ros_ign_bridge::Factory::ros_callback
static void ros_callback(const ros::MessageEvent< ROS_T const > &ros_msg_event, ignition::transport::Node::Publisher &ign_pub, const std::string &ros_type_name, const std::string &ign_type_name)
Definition: factory.hpp:109
ros_ign_bridge::FactoryInterface
Definition: factory_interface.hpp:30
ros::NodeHandle::subscribe
Subscriber subscribe(const std::string &topic, uint32_t queue_size, const boost::function< void(C)> &callback, const VoidConstPtr &tracked_object=VoidConstPtr(), const TransportHints &transport_hints=TransportHints())
ros_ign_bridge::Factory::Factory
Factory(const std::string &ros_type_name, const std::string &ign_type_name)
Definition: factory.hpp:38
ros_ign_bridge::Factory::convert_ign_to_ros
static void convert_ign_to_ros(const IGN_T &ign_msg, ROS_T &ros_msg)
ros_ign_bridge::Factory::ign_type_name_
std::string ign_type_name_
Definition: factory.hpp:165
ros::this_node::getName
const ROSCPP_DECL std::string & getName()
ros_ign_bridge::Factory::create_ros_publisher
ros::Publisher create_ros_publisher(ros::NodeHandle node, const std::string &topic_name, size_t queue_size)
Definition: factory.hpp:45
ros::SubscribeOptions
ros::SubscribeOptions::queue_size
uint32_t queue_size
ros_ign_bridge::Factory::ign_callback
static void ign_callback(const IGN_T &ign_msg, ros::Publisher ros_pub)
Definition: factory.hpp:141
ROS_ERROR
#define ROS_ERROR(...)
ros_ign_bridge::Factory::convert_ros_to_ign
static void convert_ros_to_ign(const ROS_T &ros_msg, IGN_T &ign_msg)
ros_ign_bridge::Factory::ros_type_name_
std::string ros_type_name_
Definition: factory.hpp:164
ros_ign_bridge
Definition: convert.hpp:59
ros_ign_bridge::Factory::create_ros_subscriber
ros::Subscriber create_ros_subscriber(ros::NodeHandle node, const std::string &topic_name, size_t queue_size, ignition::transport::Node::Publisher &ign_pub)
Definition: factory.hpp:63
ros::MessageEvent::getConnectionHeaderPtr
const boost::shared_ptr< M_string > & getConnectionHeaderPtr() const
ros::SubscribeOptions::datatype
std::string datatype
ros::SubscribeOptions::helper
SubscriptionCallbackHelperPtr helper
ros::NodeHandle
ros::MessageEvent
ros::Subscriber


ros_ign_bridge
Author(s):
autogenerated on Sat Mar 11 2023 04:02:16