CARLA
CarlaSemanticLidarPublisher.cpp
Go to the documentation of this file.
1 #define _GLIBCXX_USE_CXX11_ABI 0
2 
4 
5 #include <string>
6 
9 
10 #include <fastdds/dds/domain/DomainParticipant.hpp>
11 #include <fastdds/dds/publisher/Publisher.hpp>
12 #include <fastdds/dds/topic/Topic.hpp>
13 #include <fastdds/dds/publisher/DataWriter.hpp>
14 #include <fastdds/dds/topic/TypeSupport.hpp>
15 
16 #include <fastdds/dds/domain/qos/DomainParticipantQos.hpp>
17 #include <fastdds/dds/domain/DomainParticipantFactory.hpp>
18 #include <fastdds/dds/publisher/qos/PublisherQos.hpp>
19 #include <fastdds/dds/topic/qos/TopicQos.hpp>
20 
21 #include <fastrtps/attributes/ParticipantAttributes.h>
22 #include <fastrtps/qos/QosPolicies.h>
23 #include <fastdds/dds/publisher/qos/DataWriterQos.hpp>
24 #include <fastdds/dds/publisher/DataWriterListener.hpp>
25 
26 
27 namespace carla {
28 namespace ros2 {
29 
30  namespace efd = eprosima::fastdds::dds;
31  using erc = eprosima::fastrtps::types::ReturnCode_t;
32 
34  efd::DomainParticipant* _participant { nullptr };
35  efd::Publisher* _publisher { nullptr };
36  efd::Topic* _topic { nullptr };
37  efd::DataWriter* _datawriter { nullptr };
38  efd::TypeSupport _type { new sensor_msgs::msg::PointCloud2PubSubType() };
41  };
42 
44  if (_impl->_type == nullptr) {
45  std::cerr << "Invalid TypeSupport" << std::endl;
46  return false;
47  }
48  efd::DomainParticipantQos pqos = efd::PARTICIPANT_QOS_DEFAULT;
49  pqos.name(_name);
50  auto factory = efd::DomainParticipantFactory::get_instance();
51  _impl->_participant = factory->create_participant(0, pqos);
52  if (_impl->_participant == nullptr) {
53  std::cerr << "Failed to create DomainParticipant" << std::endl;
54  return false;
55  }
56  _impl->_type.register_type(_impl->_participant);
57 
58  efd::PublisherQos pubqos = efd::PUBLISHER_QOS_DEFAULT;
59  _impl->_publisher = _impl->_participant->create_publisher(pubqos, nullptr);
60  if (_impl->_publisher == nullptr) {
61  std::cerr << "Failed to create Publisher" << std::endl;
62  return false;
63  }
64 
65  efd::TopicQos tqos = efd::TOPIC_QOS_DEFAULT;
66  const std::string base { "rt/carla/" };
67  std::string topic_name = base;
68  if (!_parent.empty())
69  topic_name += _parent + "/";
70  topic_name += _name;
71  _impl->_topic = _impl->_participant->create_topic(topic_name, _impl->_type->getName(), tqos);
72  if (_impl->_topic == nullptr) {
73  std::cerr << "Failed to create Topic" << std::endl;
74  return false;
75  }
76 
77  efd::DataWriterQos wqos = efd::DATAWRITER_QOS_DEFAULT;
78  wqos.endpoint().history_memory_policy = eprosima::fastrtps::rtps::PREALLOCATED_WITH_REALLOC_MEMORY_MODE;
79  efd::DataWriterListener* listener = (efd::DataWriterListener*)_impl->_listener._impl.get();
80  _impl->_datawriter = _impl->_publisher->create_datawriter(_impl->_topic, wqos, listener);
81  if (_impl->_datawriter == nullptr) {
82  std::cerr << "Failed to create DataWriter" << std::endl;
83  return false;
84  }
85  _frame_id = _name;
86  return true;
87  }
88 
91  eprosima::fastrtps::types::ReturnCode_t rcode = _impl->_datawriter->write(&_impl->_lidar, instance_handle);
92  if (rcode == erc::ReturnCodeValue::RETCODE_OK) {
93  return true;
94  }
95  if (rcode == erc::ReturnCodeValue::RETCODE_ERROR) {
96  std::cerr << "RETCODE_ERROR" << std::endl;
97  return false;
98  }
99  if (rcode == erc::ReturnCodeValue::RETCODE_UNSUPPORTED) {
100  std::cerr << "RETCODE_UNSUPPORTED" << std::endl;
101  return false;
102  }
103  if (rcode == erc::ReturnCodeValue::RETCODE_BAD_PARAMETER) {
104  std::cerr << "RETCODE_BAD_PARAMETER" << std::endl;
105  return false;
106  }
107  if (rcode == erc::ReturnCodeValue::RETCODE_PRECONDITION_NOT_MET) {
108  std::cerr << "RETCODE_PRECONDITION_NOT_MET" << std::endl;
109  return false;
110  }
111  if (rcode == erc::ReturnCodeValue::RETCODE_OUT_OF_RESOURCES) {
112  std::cerr << "RETCODE_OUT_OF_RESOURCES" << std::endl;
113  return false;
114  }
115  if (rcode == erc::ReturnCodeValue::RETCODE_NOT_ENABLED) {
116  std::cerr << "RETCODE_NOT_ENABLED" << std::endl;
117  return false;
118  }
119  if (rcode == erc::ReturnCodeValue::RETCODE_IMMUTABLE_POLICY) {
120  std::cerr << "RETCODE_IMMUTABLE_POLICY" << std::endl;
121  return false;
122  }
123  if (rcode == erc::ReturnCodeValue::RETCODE_INCONSISTENT_POLICY) {
124  std::cerr << "RETCODE_INCONSISTENT_POLICY" << std::endl;
125  return false;
126  }
127  if (rcode == erc::ReturnCodeValue::RETCODE_ALREADY_DELETED) {
128  std::cerr << "RETCODE_ALREADY_DELETED" << std::endl;
129  return false;
130  }
131  if (rcode == erc::ReturnCodeValue::RETCODE_TIMEOUT) {
132  std::cerr << "RETCODE_TIMEOUT" << std::endl;
133  return false;
134  }
135  if (rcode == erc::ReturnCodeValue::RETCODE_NO_DATA) {
136  std::cerr << "RETCODE_NO_DATA" << std::endl;
137  return false;
138  }
139  if (rcode == erc::ReturnCodeValue::RETCODE_ILLEGAL_OPERATION) {
140  std::cerr << "RETCODE_ILLEGAL_OPERATION" << std::endl;
141  return false;
142  }
143  if (rcode == erc::ReturnCodeValue::RETCODE_NOT_ALLOWED_BY_SECURITY) {
144  std::cerr << "RETCODE_NOT_ALLOWED_BY_SECURITY" << std::endl;
145  return false;
146  }
147  std::cerr << "UNKNOWN" << std::endl;
148  return false;
149  }
150 
151 void CarlaSemanticLidarPublisher::SetData(int32_t seconds, uint32_t nanoseconds, size_t elements, size_t height, size_t width, float* data) {
152  float* it = data;
153  float* end = &data[height * width * elements];
154  for (++it; it < end; it += elements) {
155  *it *= -1.0f;
156  }
157 
158  std::vector<uint8_t> vector_data;
159  const size_t size = height * width * sizeof(float) * elements;
160  vector_data.resize(size);
161  std::memcpy(&vector_data[0], &data[0], size);
162  SetData(seconds, nanoseconds, height, width, std::move(vector_data));
163 }
164 
165 void CarlaSemanticLidarPublisher::SetData(int32_t seconds, uint32_t nanoseconds, size_t height, size_t width, std::vector<uint8_t>&& data) {
167  time.sec(seconds);
168  time.nanosec(nanoseconds);
169 
170  std_msgs::msg::Header header;
171  header.stamp(std::move(time));
172  header.frame_id(_frame_id);
173 
174  sensor_msgs::msg::PointField descriptor1;
175  descriptor1.name("x");
176  descriptor1.offset(0);
178  descriptor1.count(1);
179  sensor_msgs::msg::PointField descriptor2;
180  descriptor2.name("y");
181  descriptor2.offset(4);
183  descriptor2.count(1);
184  sensor_msgs::msg::PointField descriptor3;
185  descriptor3.name("z");
186  descriptor3.offset(8);
188  descriptor3.count(1);
189  sensor_msgs::msg::PointField descriptor4;
190  descriptor4.name("cos_inc_angle");
191  descriptor4.offset(12);
193  descriptor4.count(1);
194  sensor_msgs::msg::PointField descriptor5;
195  descriptor5.name("object_idx");
196  descriptor5.offset(16);
198  descriptor5.count(1);
199  sensor_msgs::msg::PointField descriptor6;
200  descriptor6.name("object_tag");
201  descriptor6.offset(20);
203  descriptor6.count(1);
204 
205  const size_t point_size = 6 * sizeof(float);
206  _impl->_lidar.header(std::move(header));
207  _impl->_lidar.width(width);
208  _impl->_lidar.height(height);
209  _impl->_lidar.is_bigendian(false);
210  _impl->_lidar.fields({descriptor1, descriptor2, descriptor3, descriptor4, descriptor5, descriptor6});
211  _impl->_lidar.point_step(point_size);
212  _impl->_lidar.row_step(width * point_size);
213  _impl->_lidar.is_dense(false); //True if there are not invalid points
214  _impl->_lidar.data(std::move(data));
215  }
216 
217  CarlaSemanticLidarPublisher::CarlaSemanticLidarPublisher(const char* ros_name, const char* parent) :
218  _impl(std::make_shared<CarlaSemanticLidarPublisherImpl>()) {
219  _name = ros_name;
220  _parent = parent;
221  }
222 
224  if (!_impl)
225  return;
226 
227  if (_impl->_datawriter)
228  _impl->_publisher->delete_datawriter(_impl->_datawriter);
229 
230  if (_impl->_publisher)
231  _impl->_participant->delete_publisher(_impl->_publisher);
232 
233  if (_impl->_topic)
234  _impl->_participant->delete_topic(_impl->_topic);
235 
236  if (_impl->_participant)
237  efd::DomainParticipantFactory::get_instance()->delete_participant(_impl->_participant);
238  }
239 
241  _frame_id = other._frame_id;
242  _name = other._name;
243  _parent = other._parent;
244  _impl = other._impl;
245  }
246 
248  _frame_id = other._frame_id;
249  _name = other._name;
250  _parent = other._parent;
251  _impl = other._impl;
252 
253  return *this;
254  }
255 
257  _frame_id = std::move(other._frame_id);
258  _name = std::move(other._name);
259  _parent = std::move(other._parent);
260  _impl = std::move(other._impl);
261  }
262 
264  _frame_id = std::move(other._frame_id);
265  _name = std::move(other._name);
266  _parent = std::move(other._parent);
267  _impl = std::move(other._impl);
268 
269  return *this;
270  }
271 }
272 }
This class represents the structure PointCloud2 defined by the user in the IDL file.
Definition: PointCloud2.h:73
std::shared_ptr< CarlaSemanticLidarPublisherImpl > _impl
This class represents the structure PointField defined by the user in the IDL file.
Definition: PointField.h:79
const uint8_t PointField__FLOAT32
Definition: PointField.h:72
eProsima_user_DllExport void name(const std::string &_name)
This function copies the value in member name.
Definition: PointField.cpp:150
CarlaSemanticLidarPublisher(const char *ros_name="", const char *parent="")
eprosima::fastrtps::rtps::InstanceHandle_t InstanceHandle_t
eprosima::fastrtps::types::ReturnCode_t erc
This file contains definitions of common data structures used in traffic manager. ...
Definition: Carla.cpp:133
This class represents the structure Header defined by the user in the IDL file.
Definition: Header.h:72
const uint8_t PointField__UINT32
Definition: PointField.h:71
CarlaSemanticLidarPublisher & operator=(const CarlaSemanticLidarPublisher &)
eProsima_user_DllExport void stamp(const builtin_interfaces::msg::Time &_stamp)
This function copies the value in member stamp.
Definition: Header.cpp:131
eProsima_user_DllExport void offset(uint32_t _offset)
This function sets a value in member offset.
Definition: PointField.cpp:188
eProsima_user_DllExport void datatype(uint8_t _datatype)
This function sets a value in member datatype.
Definition: PointField.cpp:216
This class represents the TopicDataType of the type PointCloud2 defined by the user in the IDL file...
eProsima_user_DllExport void sec(int32_t _sec)
This function sets a value in member sec.
Definition: Time.cpp:133
eProsima_user_DllExport void count(uint32_t _count)
This function sets a value in member count.
Definition: PointField.cpp:244
eProsima_user_DllExport void nanosec(uint32_t _nanosec)
This function sets a value in member nanosec.
Definition: Time.cpp:161
const std::string & parent() const
This class represents the structure Time defined by the user in the IDL file.
void SetData(int32_t seconds, uint32_t nanoseconds, size_t elements, size_t height, size_t width, float *data)
eProsima_user_DllExport void frame_id(const std::string &_frame_id)
This function copies the value in member frame_id.
Definition: Header.cpp:168