CARLA
 
载入中...
搜索中...
未找到
CarlaSSCameraPublisher.cpp
浏览该文件的文档.
1#define _GLIBCXX_USE_CXX11_ABI 0
2
3#include "CarlaSSCameraPublisher.h"// 引入CarlaSSCameraPublisher类的声明
4
5#include <string>// 引入标准字符串库
6// 引入CARLA ROS2桥接器中定义的图像和相机信息类型的PubSubTypes
9#include "carla/ros2/listeners/CarlaListener.h"// 引入CARLA ROS2监听器基类
10// 引入Fast-DDS(eProsima Fast RTPS的C++ API封装)相关的头文件
11#include <fastdds/dds/domain/DomainParticipant.hpp> // DomainParticipant类,用于创建、删除和管理RTPS实体
12#include <fastdds/dds/publisher/Publisher.hpp>// Publisher类,用于发布数据
13#include <fastdds/dds/topic/Topic.hpp>// Topic类,用于定义数据的主题
14#include <fastdds/dds/publisher/DataWriter.hpp>// DataWriter类,用于写入数据到指定的主题
15#include <fastdds/dds/topic/TypeSupport.hpp> // TypeSupport类,用于支持特定类型的数据
16// 引入Fast-DDS中与质量服务(QoS)相关的头文件
17#include <fastdds/dds/domain/qos/DomainParticipantQos.hpp>// DomainParticipantQos类,用于配置DomainParticipant的QoS策略
18#include <fastdds/dds/domain/DomainParticipantFactory.hpp>// DomainParticipantFactory类,用于创建DomainParticipant实例
19#include <fastdds/dds/publisher/qos/PublisherQos.hpp>// PublisherQos类,用于配置Publisher的QoS策略
20#include <fastdds/dds/topic/qos/TopicQos.hpp>// TopicQos类,用于配置Topic的QoS策略
21// 引入Fast-RTPS(eProsima Fast RTPS库)中的头文件,用于配置参与者属性和QoS策略
22#include <fastrtps/attributes/ParticipantAttributes.h>
23#include <fastrtps/qos/QosPolicies.h>
24// 引入Fast-DDS中DataWriter的QoS配置和数据写入监听器
25#include <fastdds/dds/publisher/qos/DataWriterQos.hpp>// DataWriterQos类,用于配置DataWriter的QoS策略
26#include <fastdds/dds/publisher/DataWriterListener.hpp>// DataWriterListener类,用于监听DataWriter的事件
27/**
28 * @namespace carla::ros2
29 * @brief 此命名空间包含了CARLA与ROS2集成相关的类和函数。
30 */
31namespace carla {
32namespace ros2 {
33 /**
34 * @brief 命名空间别名,简化eprosima::fastdds::dds的引用。
35 */
36 namespace efd = eprosima::fastdds::dds;
37 /**
38 * @brief 类型别名,简化eprosima::fastrtps::types::ReturnCode_t的引用。
39 */
40 using erc = eprosima::fastrtps::types::ReturnCode_t;
41 /**
42 * @struct CarlaSSCameraPublisherImpl
43 * @brief CarlaSSCameraPublisher的内部实现结构体,包含Fast-DDS相关的资源和配置。
44 */
46 /**
47 * @brief Fast-DDS的DomainParticipant指针,用于管理RTPS实体。
48 */
49 efd::DomainParticipant* _participant { nullptr };
50 /**
51 * @brief Fast-DDS的Publisher指针,用于发布数据。
52 */
53 efd::Publisher* _publisher { nullptr };
54 /**
55 * @brief Fast-DDS的Topic指针,定义了数据的主题。
56 */
57 efd::Topic* _topic { nullptr };
58 /**
59 * @brief Fast-DDS的DataWriter指针,用于写入数据到指定的主题。
60 */
61 efd::DataWriter* _datawriter { nullptr };
62 /**
63 * @brief Fast-DDS的TypeSupport对象,支持特定类型的数据(这里是sensor_msgs::msg::Image)。
64 */
65 efd::TypeSupport _type { new sensor_msgs::msg::ImagePubSubType() };
66 /**
67 * @brief CarlaListener对象,用于监听CARLA的事件。
68 */
69 CarlaListener _listener {};
70 /**
71 * @brief 存储的图像数据。
72 */
74 };
75 /**
76 * @struct CarlaCameraInfoPublisherImpl
77 * @brief CarlaCameraInfoPublisher的内部实现结构体,包含Fast-DDS相关的资源和配置。
78 */
79 struct CarlaCameraInfoPublisherImpl {
80 /**
81 * @brief Fast-DDS的DomainParticipant指针,用于管理RTPS实体。
82 */
83 efd::DomainParticipant* _participant { nullptr };
84 /**
85 * @brief Fast-DDS的Publisher指针,用于发布数据。
86 */
87 efd::Publisher* _publisher { nullptr };
88 /**
89 * @brief Fast-DDS的Topic指针,定义了数据的主题。
90 */
91 efd::Topic* _topic { nullptr };
92 /**
93 * @brief Fast-DDS的DataWriter指针,用于写入数据到指定的主题。
94 */
95 efd::DataWriter* _datawriter { nullptr };
96 /**
97 * @brief Fast-DDS的TypeSupport对象,支持特定类型的数据(这里是sensor_msgs::msg::CameraInfo)。
98 */
99 efd::TypeSupport _type { new sensor_msgs::msg::CameraInfoPubSubType() };
100 /**
101 * @brief CarlaListener对象,用于监听CARLA的事件。
102 */
103 CarlaListener _listener {};
104 /**
105 * @brief 标记是否已初始化。
106 */
107 bool _init {false};
108 /**
109 * @brief 存储的相机信息数据。
110 */
112 };
113 /**
114 * @brief 检查CarlaSSCameraPublisher是否已初始化。
115 *
116 * @return 如果已初始化,则返回true;否则返回false。
117 */
119 return _impl_info->_init;
120 }
121 /**
122 * @brief 初始化相机信息数据
123 *
124 * 该函数用于初始化相机的信息数据,包括高度、宽度、视场角(FOV),并设置感兴趣区域(ROI)。
125 *
126 * @param x_offset 感兴趣区域的X轴偏移量
127 * @param y_offset 感兴趣区域的Y轴偏移量
128 * @param height 相机图像的高度
129 * @param width 相机图像的宽度
130 * @param fov 相机的视场角(FOV)
131 * @param do_rectify 是否对图像进行校正
132 */
133 void CarlaSSCameraPublisher::InitInfoData(uint32_t x_offset, uint32_t y_offset, uint32_t height, uint32_t width, float fov, bool do_rectify) {
134 _impl_info->_info = std::move(sensor_msgs::msg::CameraInfo(height, width, fov));
135 SetInfoRegionOfInterest(x_offset, y_offset, height, width, do_rectify);
136 _impl_info->_init = true;
137 }
138 /**
139 * @brief 初始化相机发布者
140 *
141 * 该函数用于初始化相机发布者,包括图像和信息的初始化。
142 *
143 * @return 初始化是否成功,成功返回true,失败返回false
144 */
146 return InitImage() && InitInfo();
147 }
148 /**
149 * @brief 初始化相机图像
150 *
151 * 该函数用于初始化相机图像的发布,包括创建DomainParticipant、Publisher、Topic和DataWriter。
152 *
153 * @return 初始化是否成功,成功返回true,失败返回false
154 */
156 if (_impl->_type == nullptr) {
157 std::cerr << "Invalid TypeSupport" << std::endl;
158 return false;
159 }
160 efd::DomainParticipantQos pqos = efd::PARTICIPANT_QOS_DEFAULT;
161 pqos.name(_name);
162 auto factory = efd::DomainParticipantFactory::get_instance();
163 _impl->_participant = factory->create_participant(0, pqos);
164 if (_impl->_participant == nullptr) {
165 std::cerr << "Failed to create DomainParticipant" << std::endl;
166 return false;
167 }
168 _impl->_type.register_type(_impl->_participant);
169
170 efd::PublisherQos pubqos = efd::PUBLISHER_QOS_DEFAULT;
171 _impl->_publisher = _impl->_participant->create_publisher(pubqos, nullptr);
172 if (_impl->_publisher == nullptr) {
173 std::cerr << "Failed to create Publisher" << std::endl;
174 return false;
175 }
176
177 efd::TopicQos tqos = efd::TOPIC_QOS_DEFAULT;
178 const std::string publisher_type {"/image"};
179 const std::string base { "rt/carla/" };
180 std::string topic_name = base;
181 if (!_parent.empty())
182 topic_name += _parent + "/";
183 topic_name += _name;
184 topic_name += publisher_type;
185 _impl->_topic = _impl->_participant->create_topic(topic_name, _impl->_type->getName(), tqos);
186 if (_impl->_topic == nullptr) {
187 std::cerr << "Failed to create Topic" << std::endl;
188 return false;
189 }
190
191 efd::DataWriterQos wqos = efd::DATAWRITER_QOS_DEFAULT;
192 wqos.endpoint().history_memory_policy = eprosima::fastrtps::rtps::PREALLOCATED_WITH_REALLOC_MEMORY_MODE;
193 efd::DataWriterListener* listener = (efd::DataWriterListener*)_impl->_listener._impl.get();
194 _impl->_datawriter = _impl->_publisher->create_datawriter(_impl->_topic, wqos, listener);
195 if (_impl->_datawriter == nullptr) {
196 std::cerr << "Failed to create DataWriter" << std::endl;
197 return false;
198 }
200 return true;
201 }
202 /**
203 * @brief 初始化CarlaSSCameraPublisher的信息
204 *
205 * 此函数负责初始化CarlaSSCameraPublisher所需的各种组件,包括DomainParticipant, Publisher, Topic和DataWriter。
206 * 如果任何步骤失败,函数将输出错误信息并返回false。
207 *
208 * @return bool 如果初始化成功返回true,否则返回false。
209 */
211 /**
212 * 检查_impl_info->_type是否为nullptr,如果是,则输出错误信息并返回false。
213 */
214 if (_impl_info->_type == nullptr) {
215 std::cerr << "Invalid TypeSupport" << std::endl;
216 return false;
217 }
218 /**
219 * 设置DomainParticipant的QoS参数为默认值,并设置其名称。
220 */
221 efd::DomainParticipantQos pqos = efd::PARTICIPANT_QOS_DEFAULT;
222 pqos.name(_name);
223 /**
224 * 获取DomainParticipantFactory的实例,并创建一个DomainParticipant。
225 */
226 auto factory = efd::DomainParticipantFactory::get_instance();
227 _impl_info->_participant = factory->create_participant(0, pqos);
228 /**
229 * 如果DomainParticipant创建失败,输出错误信息并返回false。
230 */
231 if (_impl_info->_participant == nullptr) {
232 std::cerr << "Failed to create DomainParticipant" << std::endl;
233 return false;
234 }
235 /**
236 * 注册类型到DomainParticipant。
237 */
238 _impl_info->_type.register_type(_impl_info->_participant);
239 /**
240 * 设置Publisher的QoS参数为默认值,并创建一个Publisher。
241 */
242 efd::PublisherQos pubqos = efd::PUBLISHER_QOS_DEFAULT;
243 _impl_info->_publisher = _impl_info->_participant->create_publisher(pubqos, nullptr);
244 /**
245 * 如果Publisher创建失败,输出错误信息并返回false。
246 */
247 if (_impl_info->_publisher == nullptr) {
248 std::cerr << "Failed to create Publisher" << std::endl;
249 return false;
250 }
251 /**
252 * 设置Topic的QoS参数为默认值,并构造Topic名称。
253 */
254 efd::TopicQos tqos = efd::TOPIC_QOS_DEFAULT;
255 const std::string publisher_type {"/camera_info"};
256 const std::string base { "rt/carla/" };
257 std::string topic_name = base;
258 if (!_parent.empty())
259 topic_name += _parent + "/";
260 topic_name += _name;
261 topic_name += publisher_type;
262 /**
263 * 创建一个Topic。
264 */
265 _impl_info->_topic = _impl_info->_participant->create_topic(topic_name, _impl_info->_type->getName(), tqos);
266 /**
267 * 如果Topic创建失败,输出错误信息并返回false。
268 */
269 if (_impl_info->_topic == nullptr) {
270 std::cerr << "Failed to create Topic" << std::endl;
271 return false;
272 }
273 /**
274 * 设置DataWriter的QoS参数为默认值,并创建一个DataWriter。
275 */
276 efd::DataWriterQos wqos = efd::DATAWRITER_QOS_DEFAULT;
277 efd::DataWriterListener* listener = (efd::DataWriterListener*)_impl_info->_listener._impl.get();
278 _impl_info->_datawriter = _impl_info->_publisher->create_datawriter(_impl_info->_topic, wqos, listener);
279 /**
280 * 如果DataWriter创建失败,输出错误信息并返回false。
281 */
282 if (_impl_info->_datawriter == nullptr) {
283 std::cerr << "Failed to create DataWriter" << std::endl;
284 return false;
285 }
286 /**
287 * 设置_frame_id为_name。
288 */
290 /**
291 * 初始化成功,返回true。
292 */
293 return true;
294 }
295 /**
296 * @brief 发布图像和信息
297 *
298 * 此函数调用PublishImage和PublishInfo函数来发布图像和相关信息。
299 * 如果两个函数都成功返回true,则此函数也返回true;否则返回false。
300 *
301 * @return bool 如果发布成功返回true,否则返回false。
302 */
306 /**
307 * @brief 发布图像数据
308 *
309 * 此函数尝试通过Fast RTPS发布图像数据。根据返回码(ReturnCode_t),函数会输出相应的错误信息并返回发布是否成功。
310 *
311 * @return true 如果图像数据成功发布,否则返回false。
312 */
314 eprosima::fastrtps::rtps::InstanceHandle_t instance_handle;
315 eprosima::fastrtps::types::ReturnCode_t rcode = _impl->_datawriter->write(&_impl->_image, instance_handle);
316 // 根据不同的返回码处理不同的错误情况
317 if (rcode == erc::ReturnCodeValue::RETCODE_OK) {
318 return true;
319 }
320 if (rcode == erc::ReturnCodeValue::RETCODE_ERROR) {
321 std::cerr << "RETCODE_ERROR" << std::endl;
322 return false;
323 }
324 if (rcode == erc::ReturnCodeValue::RETCODE_UNSUPPORTED) {
325 std::cerr << "RETCODE_UNSUPPORTED" << std::endl;
326 return false;
327 }
328 if (rcode == erc::ReturnCodeValue::RETCODE_BAD_PARAMETER) {
329 std::cerr << "RETCODE_BAD_PARAMETER" << std::endl;
330 return false;
331 }
332 if (rcode == erc::ReturnCodeValue::RETCODE_PRECONDITION_NOT_MET) {
333 std::cerr << "RETCODE_PRECONDITION_NOT_MET" << std::endl;
334 return false;
335 }
336 if (rcode == erc::ReturnCodeValue::RETCODE_OUT_OF_RESOURCES) {
337 std::cerr << "RETCODE_OUT_OF_RESOURCES" << std::endl;
338 return false;
339 }
340 if (rcode == erc::ReturnCodeValue::RETCODE_NOT_ENABLED) {
341 std::cerr << "RETCODE_NOT_ENABLED" << std::endl;
342 return false;
343 }
344 if (rcode == erc::ReturnCodeValue::RETCODE_IMMUTABLE_POLICY) {
345 std::cerr << "RETCODE_IMMUTABLE_POLICY" << std::endl;
346 return false;
347 }
348 if (rcode == erc::ReturnCodeValue::RETCODE_INCONSISTENT_POLICY) {
349 std::cerr << "RETCODE_INCONSISTENT_POLICY" << std::endl;
350 return false;
351 }
352 if (rcode == erc::ReturnCodeValue::RETCODE_ALREADY_DELETED) {
353 std::cerr << "RETCODE_ALREADY_DELETED" << std::endl;
354 return false;
355 }
356 if (rcode == erc::ReturnCodeValue::RETCODE_TIMEOUT) {
357 std::cerr << "RETCODE_TIMEOUT" << std::endl;
358 return false;
359 }
360 if (rcode == erc::ReturnCodeValue::RETCODE_NO_DATA) {
361 std::cerr << "RETCODE_NO_DATA" << std::endl;
362 return false;
363 }
364 if (rcode == erc::ReturnCodeValue::RETCODE_ILLEGAL_OPERATION) {
365 std::cerr << "RETCODE_ILLEGAL_OPERATION" << std::endl;
366 return false;
367 }
368 if (rcode == erc::ReturnCodeValue::RETCODE_NOT_ALLOWED_BY_SECURITY) {
369 std::cerr << "RETCODE_NOT_ALLOWED_BY_SECURITY" << std::endl;
370 return false;
371 }
372 std::cerr << "UNKNOWN" << std::endl;
373 return false;
374 }
375 /**
376 * @brief 发布信息数据
377 *
378 * 此函数尝试通过Fast RTPS发布信息数据。根据返回码(ReturnCode_t),函数会输出相应的错误信息并返回发布是否成功。
379 *
380 * @return true 如果信息数据成功发布,否则返回false。
381 */
383 eprosima::fastrtps::rtps::InstanceHandle_t instance_handle;
384 eprosima::fastrtps::types::ReturnCode_t rcode = _impl_info->_datawriter->write(&_impl_info->_info, instance_handle);
385 // 根据不同的返回码处理不同的错误情况
386 if (rcode == erc::ReturnCodeValue::RETCODE_OK) {
387 return true;
388 }
389 if (rcode == erc::ReturnCodeValue::RETCODE_ERROR) {
390 std::cerr << "RETCODE_ERROR" << std::endl;
391 return false;
392 }
393 if (rcode == erc::ReturnCodeValue::RETCODE_UNSUPPORTED) {
394 std::cerr << "RETCODE_UNSUPPORTED" << std::endl;
395 return false;
396 }
397 if (rcode == erc::ReturnCodeValue::RETCODE_BAD_PARAMETER) {
398 std::cerr << "RETCODE_BAD_PARAMETER" << std::endl;
399 return false;
400 }
401 if (rcode == erc::ReturnCodeValue::RETCODE_PRECONDITION_NOT_MET) {
402 std::cerr << "RETCODE_PRECONDITION_NOT_MET" << std::endl;
403 return false;
404 }
405 if (rcode == erc::ReturnCodeValue::RETCODE_OUT_OF_RESOURCES) {
406 std::cerr << "RETCODE_OUT_OF_RESOURCES" << std::endl;
407 return false;
408 }
409 if (rcode == erc::ReturnCodeValue::RETCODE_NOT_ENABLED) {
410 std::cerr << "RETCODE_NOT_ENABLED" << std::endl;
411 return false;
412 }
413 if (rcode == erc::ReturnCodeValue::RETCODE_IMMUTABLE_POLICY) {
414 std::cerr << "RETCODE_IMMUTABLE_POLICY" << std::endl;
415 return false;
416 }
417 if (rcode == erc::ReturnCodeValue::RETCODE_INCONSISTENT_POLICY) {
418 std::cerr << "RETCODE_INCONSISTENT_POLICY" << std::endl;
419 return false;
420 }
421 if (rcode == erc::ReturnCodeValue::RETCODE_ALREADY_DELETED) {
422 std::cerr << "RETCODE_ALREADY_DELETED" << std::endl;
423 return false;
424 }
425 if (rcode == erc::ReturnCodeValue::RETCODE_TIMEOUT) {
426 std::cerr << "RETCODE_TIMEOUT" << std::endl;
427 return false;
428 }
429 if (rcode == erc::ReturnCodeValue::RETCODE_NO_DATA) {
430 std::cerr << "RETCODE_NO_DATA" << std::endl;
431 return false;
432 }
433 if (rcode == erc::ReturnCodeValue::RETCODE_ILLEGAL_OPERATION) {
434 std::cerr << "RETCODE_ILLEGAL_OPERATION" << std::endl;
435 return false;
436 }
437 if (rcode == erc::ReturnCodeValue::RETCODE_NOT_ALLOWED_BY_SECURITY) {
438 std::cerr << "RETCODE_NOT_ALLOWED_BY_SECURITY" << std::endl;
439 return false;
440 }
441 std::cerr << "UNKNOWN" << std::endl;
442 return false;
443 }
444 /**
445 * @brief 设置图像数据
446 *
447 * 该函数接收时间戳、图像高度、图像宽度和图像数据,然后将这些数据复制到一个新的vector中,
448 * 并调用SetData函数设置图像数据。
449 *
450 * @param seconds 时间戳的秒部分
451 * @param nanoseconds 时间戳的纳秒部分
452 * @param height 图像的高度
453 * @param width 图像的宽度
454 * @param data 图像数据的指针,假设为BGRA格式
455 */
456 void CarlaSSCameraPublisher::SetImageData(int32_t seconds, uint32_t nanoseconds, size_t height, size_t width, const uint8_t* data) {
457 std::vector<uint8_t> vector_data;
458 const size_t size = height * width * 4;
459 vector_data.resize(size);
460 std::memcpy(&vector_data[0], &data[0], size);
461 SetData(seconds, nanoseconds, height, width, std::move(vector_data));
462 }
463 /**
464 * @brief 设置感兴趣区域的信息
465 *
466 * 该函数用于设置图像的感兴趣区域(Region Of Interest, ROI),包括偏移量、高度、宽度和是否需要校正。
467 *
468 * @param x_offset ROI的X轴偏移量
469 * @param y_offset ROI的Y轴偏移量
470 * @param height ROI的高度
471 * @param width ROI的宽度
472 * @param do_rectify 是否需要校正ROI
473 */
474 void CarlaSSCameraPublisher::SetInfoRegionOfInterest( uint32_t x_offset, uint32_t y_offset, uint32_t height, uint32_t width, bool do_rectify) {
476 roi.x_offset(x_offset);
477 roi.y_offset(y_offset);
478 roi.height(height);
479 roi.width(width);
480 roi.do_rectify(do_rectify);
481 _impl_info->_info.roi(roi);
482 }
483 /**
484 * @brief 设置图像数据
485 *
486 * 该函数接收时间戳、图像高度、图像宽度和图像数据(以vector形式),然后设置图像的元数据和数据。
487 *
488 * @param seconds 时间戳的秒部分
489 * @param nanoseconds 时间戳的纳秒部分
490 * @param height 图像的高度
491 * @param width 图像的宽度
492 * @param data 图像数据的vector,假设为BGRA格式,使用右值引用进行移动语义优化
493 */
494 void CarlaSSCameraPublisher::SetData(int32_t seconds, uint32_t nanoseconds, size_t height, size_t width, std::vector<uint8_t>&& data) {
496 time.sec(seconds);
497 time.nanosec(nanoseconds);
498
499 std_msgs::msg::Header header;
500 header.stamp(std::move(time));
501 header.frame_id(_frame_id);
502
503 _impl->_image.header(std::move(header));
504 _impl->_image.width(width);
505 _impl->_image.height(height);
506 _impl->_image.encoding("bgra8"); //taken from the list of strings in include/sensor_msgs/image_encodings.h
507 _impl->_image.is_bigendian(0);
508 _impl->_image.step(_impl->_image.width() * sizeof(uint8_t) * 4);
509 _impl->_image.data(std::move(data)); //https://github.com/eProsima/Fast-DDS/issues/2330
510 }
511 /**
512 * @brief 设置相机信息数据的时间戳
513 *
514 * 该函数接收时间戳,并设置相机信息的头部时间戳和帧ID。
515 *
516 * @param seconds 时间戳的秒部分
517 * @param nanoseconds 时间戳的纳秒部分
518 */
519 void CarlaSSCameraPublisher::SetCameraInfoData(int32_t seconds, uint32_t nanoseconds) {
521 time.sec(seconds);
522 time.nanosec(nanoseconds);
523
524 std_msgs::msg::Header header;
525 header.stamp(std::move(time));
526 header.frame_id(_frame_id);
527 _impl_info->_info.header(header);
528 }
529 /**
530 * @brief CarlaSSCameraPublisher类的构造函数
531 *
532 * 初始化CarlaSSCameraPublisher对象,并创建内部实现对象和相机信息发布者对象。
533 *
534 * @param ros_name ROS节点名称
535 * @param parent 父节点或组件的名称
536 */
537 CarlaSSCameraPublisher::CarlaSSCameraPublisher(const char* ros_name, const char* parent) :
538 _impl(std::make_shared<CarlaSSCameraPublisherImpl>()),
539 _impl_info(std::make_shared<CarlaCameraInfoPublisherImpl>()) {
540 _name = ros_name;
541 _parent = parent;
542 }
543 /**
544 * @brief CarlaSSCameraPublisher类的析构函数
545 *
546 * 清理资源,包括删除数据写入器、发布者、主题和参与者。
547 */
549 if (!_impl)
550 return;
551 // 清理_impl相关的资源
552 if (_impl->_datawriter)
553 _impl->_publisher->delete_datawriter(_impl->_datawriter);
554
555 if (_impl->_publisher)
556 _impl->_participant->delete_publisher(_impl->_publisher);
557
558 if (_impl->_topic)
559 _impl->_participant->delete_topic(_impl->_topic);
560
561 if (_impl->_participant)
562 efd::DomainParticipantFactory::get_instance()->delete_participant(_impl->_participant);
563
564 if (!_impl_info)
565 return;
566 // 清理_impl_info相关的资源
567 if (_impl_info->_datawriter)
568 _impl_info->_publisher->delete_datawriter(_impl_info->_datawriter);
569
570 if (_impl_info->_publisher)
571 _impl_info->_participant->delete_publisher(_impl_info->_publisher);
572
573 if (_impl_info->_topic)
574 _impl_info->_participant->delete_topic(_impl_info->_topic);
575
576 if (_impl_info->_participant)
577 efd::DomainParticipantFactory::get_instance()->delete_participant(_impl_info->_participant);
578 }
579 /**
580 * @brief CarlaSSCameraPublisher类的拷贝构造函数
581 *
582 * 创建当前对象的深拷贝。注意:这里的实现可能存在问题,因为_impl和_impl_info是智能指针,直接赋值可能导致多个对象共享相同的内部实现,这通常不是期望的行为。
583 * 在实际实现中,应该考虑使用深拷贝或者避免在拷贝构造函数中直接赋值智能指针。
584 *
585 * @param other 要拷贝的对象
586 */
588 _frame_id = other._frame_id;
589 _name = other._name;
590 _parent = other._parent;
591 _impl = other._impl;
592 _impl_info = other._impl_info;
593 }
594 /**
595 * @brief 赋值运算符重载
596 *
597 * 将当前对象设置为另一个CarlaSSCameraPublisher对象的拷贝。与拷贝构造函数类似,这里的实现也可能存在问题。
598 *
599 * @param other 要赋值的对象
600 * @return 对当前对象的引用
601 */
603 _frame_id = other._frame_id;
604 _name = other._name;
605 _parent = other._parent;
606 _impl = other._impl;
607 _impl_info = other._impl_info;
608
609 return *this;
610 }
611 /**
612 * @brief CarlaSSCameraPublisher类的移动构造函数
613 *
614 * 使用另一个CarlaSSCameraPublisher对象的资源初始化当前对象,并清空源对象的资源。
615 *
616 * @param other 要移动的对象
617 */
619 _frame_id = std::move(other._frame_id);
620 _name = std::move(other._name);
621 _parent = std::move(other._parent);
622 _impl = std::move(other._impl);
623 _impl_info = std::move(other._impl_info);
624 }
625 /**
626 * @brief 移动赋值运算符重载
627 *
628 * 将当前对象设置为另一个CarlaSSCameraPublisher对象的移动拷贝,并清空源对象的资源。
629 *
630 * @param other 要移动赋值的对象
631 * @return 对当前对象的引用
632 */
634 _frame_id = std::move(other._frame_id);
635 _name = std::move(other._name);
636 _parent = std::move(other._parent);
637 _impl = std::move(other._impl);
638 _impl_info = std::move(other._impl_info);
639
640 return *this;
641 }
642}
643}
此类表示用户在IDL文件中定义的Time结构。
eProsima_user_DllExport void nanosec(uint32_t _nanosec)
此函数设置成员nanosec的值。
Definition Time.cpp:183
eProsima_user_DllExport void sec(int32_t _sec)
此函数设置成员sec的值。
Definition Time.cpp:152
const std::string & parent() const
bool HasBeenInitialized() const
检查CarlaSSCameraPublisher是否已初始化。
std::shared_ptr< CarlaSSCameraPublisherImpl > _impl
CarlaSSCameraPublisher & operator=(const CarlaSSCameraPublisher &)
赋值运算符重载
CarlaSSCameraPublisher(const char *ros_name="", const char *parent="")
CarlaSSCameraPublisher类的构造函数
void SetCameraInfoData(int32_t seconds, uint32_t nanoseconds)
设置相机信息数据的时间戳
void SetInfoRegionOfInterest(uint32_t x_offset, uint32_t y_offset, uint32_t height, uint32_t width, bool do_rectify)
设置感兴趣区域的信息
void SetImageData(int32_t seconds, uint32_t nanoseconds, size_t height, size_t width, const uint8_t *data)
设置图像数据
std::shared_ptr< CarlaCameraInfoPublisherImpl > _impl_info
bool InitInfo()
初始化CarlaSSCameraPublisher的信息
void InitInfoData(uint32_t x_offset, uint32_t y_offset, uint32_t height, uint32_t width, float fov, bool do_rectify)
初始化相机信息数据
void SetData(int32_t seconds, uint32_t nanoseconds, size_t height, size_t width, std::vector< uint8_t > &&data)
设置图像数据
~CarlaSSCameraPublisher()
CarlaSSCameraPublisher类的析构函数
此类表示用户在 IDL 文件中定义的 CameraInfo 类型的 TopicDataType。 <>
This class represents the structure CameraInfo defined by the user in the IDL file....
Definition CameraInfo.h:75
此类表示用户在IDL文件中定义的Image类型的主题数据类型。
This class represents the structure Image defined by the user in the IDL file.这个类表示在 IDL(接口定义语言)文件中由用...
This class represents the structure RegionOfInterest defined by the user in the IDL file.
eProsima_user_DllExport void y_offset(uint32_t _y_offset)
This function sets a value in member y_offset
eProsima_user_DllExport void width(uint32_t _width)
This function sets a value in member width
eProsima_user_DllExport void height(uint32_t _height)
This function sets a value in member height
eProsima_user_DllExport void x_offset(uint32_t _x_offset)
This function sets a value in member x_offset
eProsima_user_DllExport void do_rectify(bool _do_rectify)
This function sets a value in member do_rectify
eprosima::fastrtps::types::ReturnCode_t erc
@using erc
CARLA模拟器的主命名空间。
Definition Carla.cpp:139
Carla相机信息发布者内部实现的结构体。
sensor_msgs::msg::CameraInfo _info
相机信息消息实例。
efd::DomainParticipant * _participant
DDS域参与者指针。
efd::TypeSupport _type
DDS类型支持,用于相机信息消息。
efd::DataWriter * _datawriter
DDS数据写入器指针。
efd::Publisher * _publisher
DDS发布者指针。
CarlaListener _listener
CARLA监听器实例。
CarlaSSCameraPublisher的内部实现结构体,包含Fast-DDS相关的资源和配置。
efd::Topic * _topic
Fast-DDS的Topic指针,定义了数据的主题。
efd::DomainParticipant * _participant
Fast-DDS的DomainParticipant指针,用于管理RTPS实体。
efd::DataWriter * _datawriter
Fast-DDS的DataWriter指针,用于写入数据到指定的主题。
sensor_msgs::msg::Image _image
存储的图像数据。
efd::Publisher * _publisher
Fast-DDS的Publisher指针,用于发布数据。
CarlaListener _listener
CarlaListener对象,用于监听CARLA的事件。
efd::TypeSupport _type
Fast-DDS的TypeSupport对象,支持特定类型的数据(这里是sensor_msgs::msg::Image)。