CARLA
 
载入中...
搜索中...
未找到
CarlaISCameraPublisher.cpp
浏览该文件的文档.
1#define _GLIBCXX_USE_CXX11_ABI 0
2
3#include "CarlaISCameraPublisher.h"// 引入自定义的相机发布器头文件
4
5#include <string>// 引入字符串库
6
7#include "carla/ros2/types/ImagePubSubTypes.h"// 引入图像类型的发布/订阅类型
8#include "carla/ros2/types/CameraInfoPubSubTypes.h"// 引入相机信息类型的发布/订阅类型
9#include "carla/ros2/listeners/CarlaListener.h"// 引入Carla监听器
10
11#include <fastdds/dds/domain/DomainParticipant.hpp>// 引入Fast DDS的DomainParticipant类
12#include <fastdds/dds/publisher/Publisher.hpp>// 引入Fast DDS的Publisher类
13#include <fastdds/dds/topic/Topic.hpp>// 引入Fast DDS的Topic类
14#include <fastdds/dds/publisher/DataWriter.hpp> // 引入Fast DDS的DataWriter类
15#include <fastdds/dds/topic/TypeSupport.hpp> // 引入Fast DDS的TypeSupport类
16
17#include <fastdds/dds/domain/qos/DomainParticipantQos.hpp>// 引入DomainParticipant的QOS设置
18#include <fastdds/dds/domain/DomainParticipantFactory.hpp>// 引入DomainParticipant工厂类
19#include <fastdds/dds/publisher/qos/PublisherQos.hpp>// 引入Publisher的QOS设置
20#include <fastdds/dds/topic/qos/TopicQos.hpp> // 引入Topic的QOS设置
21
22#include <fastrtps/attributes/ParticipantAttributes.h>// 引入Participant属性
23#include <fastrtps/qos/QosPolicies.h>// 引入QOS策略
24#include <fastdds/dds/publisher/qos/DataWriterQos.hpp>// 引入DataWriter的QOS设置
25#include <fastdds/dds/publisher/DataWriterListener.hpp>// 引入DataWriter监听器
26
27namespace carla {
28namespace ros2 {
29// 使用Fast DDS命名空间
30 namespace efd = eprosima::fastdds::dds;
31 using erc = eprosima::fastrtps::types::ReturnCode_t;// 定义返回码类型
32// CarlaISCameraPublisher的实现结构体
34 efd::DomainParticipant* _participant { nullptr };// DomainParticipant指针
35 efd::Publisher* _publisher { nullptr };// Publisher指针
36 efd::Topic* _topic { nullptr };// Topic指针
37 efd::DataWriter* _datawriter { nullptr };// DataWriter指针
38 efd::TypeSupport _type { new sensor_msgs::msg::ImagePubSubType() }; // 图像类型支持
39 CarlaListener _listener {};// Carla监听器实例
40 sensor_msgs::msg::Image _image {};// 存储图像数据
41 };
42// CarlaCameraInfoPublisher的实现结构体
43 struct CarlaCameraInfoPublisherImpl {
44 efd::DomainParticipant* _participant { nullptr };// DomainParticipant指针
45 efd::Publisher* _publisher { nullptr };// Publisher指针
46 efd::Topic* _topic { nullptr }; // Topic指针
47 efd::DataWriter* _datawriter { nullptr };// DataWriter指针
48 efd::TypeSupport _type { new sensor_msgs::msg::CameraInfoPubSubType() }; // 图像类型支持
49 CarlaListener _listener {};// Carla监听器实例
50 bool _init {false};// 初始化标志
51 sensor_msgs::msg::CameraInfo _info {};// 存储相机信息
52 };
53// 检查相机发布器是否已初始化
55 return _impl_info->_init;// 返回初始化状态
56 }
57
58 void CarlaISCameraPublisher::InitInfoData(uint32_t x_offset, uint32_t y_offset, uint32_t height, uint32_t width, float fov, bool do_rectify) {
59 _impl_info->_info = std::move(sensor_msgs::msg::CameraInfo(height, width, fov));// 移动构造相机信息
60 SetInfoRegionOfInterest(x_offset, y_offset, height, width, do_rectify);// 设置感兴趣区域
61 _impl_info->_init = true;// 标记为已初始化
62 }
63// 初始化相机发布器
65 return InitImage() && InitInfo();// 初始化图像和相机信息
66 }
67// 初始化图像发布器
69 if (_impl->_type == nullptr) {
70 std::cerr << "Invalid TypeSupport" << std::endl; // 检查类型支持
71 return false;// 返回失败
72 }
73 efd::DomainParticipantQos pqos = efd::PARTICIPANT_QOS_DEFAULT; // 默认QOS设置
74 pqos.name(_name);// 设置参与者名称
75 auto factory = efd::DomainParticipantFactory::get_instance(); // 获取参与者工厂实例
76 _impl->_participant = factory->create_participant(0, pqos);// 创建DomainParticipant
77 if (_impl->_participant == nullptr) {
78 std::cerr << "Failed to create DomainParticipant" << std::endl;// 创建失败
79 return false;// 返回失败
80 }
81 _impl->_type.register_type(_impl->_participant);// 注册类型
82
83 efd::PublisherQos pubqos = efd::PUBLISHER_QOS_DEFAULT;// 默认Publisher QOS设置
84 _impl->_publisher = _impl->_participant->create_publisher(pubqos, nullptr);// 创建Publisher
85 if (_impl->_publisher == nullptr) {
86 std::cerr << "Failed to create Publisher" << std::endl;// 创建失败
87 return false;// 返回失败
88 }
89
90 efd::TopicQos tqos = efd::TOPIC_QOS_DEFAULT;// 默认Topic QOS设置
91 const std::string publisher_type {"/image"};// 图像主题类型
92 const std::string base { "rt/carla/" };// 基本主题名称
93 std::string topic_name = base;// 主题名称
94 if (!_parent.empty())
95 topic_name += _parent + "/";// 添加父主题
96 topic_name += _name;// 添加当前名称
97 topic_name += publisher_type; // 添加图像主题类型
98 _impl->_topic = _impl->_participant->create_topic(topic_name, _impl->_type->getName(), tqos);
99 if (_impl->_topic == nullptr) {
100 std::cerr << "Failed to create Topic" << std::endl;//创建失败
101 return false;//返回失败
102 }
103
104 efd::DataWriterQos wqos = efd::DATAWRITER_QOS_DEFAULT;// 默认DataWriter QOS设置
105 wqos.endpoint().history_memory_policy = eprosima::fastrtps::rtps::PREALLOCATED_WITH_REALLOC_MEMORY_MODE; // 设置内存策略
106 efd::DataWriterListener* listener = (efd::DataWriterListener*)_impl->_listener._impl.get();// 获取监听器
107 _impl->_datawriter = _impl->_publisher->create_datawriter(_impl->_topic, wqos, listener);// 创建DataWriter
108 if (_impl->_datawriter == nullptr) {
109 std::cerr << "Failed to create DataWriter" << std::endl;// 创建失败
110 return false;// 返回失败
111 }
112 _frame_id = _name;// 设置帧ID
113 return true;// 返回成功
114 }
115// 初始化相机信息发布器
117 if (_impl_info->_type == nullptr) {
118 std::cerr << "Invalid TypeSupport" << std::endl; // 检查类型支持
119 return false;// 返回失败
120 }
121
122 efd::DomainParticipantQos pqos = efd::PARTICIPANT_QOS_DEFAULT;// 默认QOS设置
123 pqos.name(_name);// 设置参与者名称
124 auto factory = efd::DomainParticipantFactory::get_instance();// 获取参与者工厂实例
125 _impl_info->_participant = factory->create_participant(0, pqos);// 创建DomainParticipant
126 if (_impl_info->_participant == nullptr) {
127 std::cerr << "Failed to create DomainParticipant" << std::endl;// 创建失败
128 return false; // 返回失败
129 }
130 _impl_info->_type.register_type(_impl_info->_participant);// 注册类型
131
132 efd::PublisherQos pubqos = efd::PUBLISHER_QOS_DEFAULT;// 默认Publisher QOS设置
133 _impl_info->_publisher = _impl_info->_participant->create_publisher(pubqos, nullptr);// 创建Publisher
134 if (_impl_info->_publisher == nullptr) {
135 std::cerr << "Failed to create Publisher" << std::endl;// 创建失败
136 return false;// 返回失败
137 }
138
139 efd::TopicQos tqos = efd::TOPIC_QOS_DEFAULT; // 默认Topic QOS设置
140 const std::string publisher_type {"/camera_info"};// 相机信息主题类型
141 const std::string base { "rt/carla/" };// 基本主题名称
142 std::string topic_name = base;// 主题名称
143 if (!_parent.empty())
144 topic_name += _parent + "/";// 添加父主题
145 topic_name += _name;// 添加当前名称
146 topic_name += publisher_type; // 添加相机信息主题类型
147 _impl_info->_topic = _impl_info->_participant->create_topic(topic_name, _impl_info->_type->getName(), tqos);
148 if (_impl_info->_topic == nullptr) {
149 std::cerr << "Failed to create Topic" << std::endl;//创建失败
150 return false;//返回失败
151 }
152 efd::DataWriterQos wqos = efd::DATAWRITER_QOS_DEFAULT;// 默认DataWriter QOS设置
153 efd::DataWriterListener* listener = (efd::DataWriterListener*)_impl_info->_listener._impl.get();// 获取监听器
154 _impl_info->_datawriter = _impl_info->_publisher->create_datawriter(_impl_info->_topic, wqos, listener);// 创建DataWriter
155 if (_impl_info->_datawriter == nullptr) {
156 std::cerr << "Failed to create DataWriter" << std::endl; // 创建失败
157 return false;// 返回失败
158 }
159
160 _frame_id = _name;// 设置帧ID
161 return true; // 返回成功
162 }
163// 发布图像和相机信息
165 return PublishImage() && PublishInfo();// 发布图像和信息
166 }
167// 发布图像
169 eprosima::fastrtps::rtps::InstanceHandle_t instance_handle;
170 eprosima::fastrtps::types::ReturnCode_t rcode = _impl->_datawriter->write(&_impl->_image, instance_handle);
171 if (rcode == erc::ReturnCodeValue::RETCODE_OK) {
172 return true;
173 }
174 // 处理各种返回码并输出错误信息
175 if (rcode == erc::ReturnCodeValue::RETCODE_ERROR) {
176 std::cerr << "RETCODE_ERROR" << std::endl;
177 return false;
178 }
179 if (rcode == erc::ReturnCodeValue::RETCODE_UNSUPPORTED) {
180 std::cerr << "RETCODE_UNSUPPORTED" << std::endl;
181 return false;
182 }
183 if (rcode == erc::ReturnCodeValue::RETCODE_BAD_PARAMETER) {
184 std::cerr << "RETCODE_BAD_PARAMETER" << std::endl;
185 return false;
186 }
187 if (rcode == erc::ReturnCodeValue::RETCODE_PRECONDITION_NOT_MET) {
188 std::cerr << "RETCODE_PRECONDITION_NOT_MET" << std::endl;
189 return false;
190 }
191 if (rcode == erc::ReturnCodeValue::RETCODE_OUT_OF_RESOURCES) {
192 std::cerr << "RETCODE_OUT_OF_RESOURCES" << std::endl;
193 return false;
194 }
195 if (rcode == erc::ReturnCodeValue::RETCODE_NOT_ENABLED) {
196 std::cerr << "RETCODE_NOT_ENABLED" << std::endl;
197 return false;
198 }
199 if (rcode == erc::ReturnCodeValue::RETCODE_IMMUTABLE_POLICY) {
200 std::cerr << "RETCODE_IMMUTABLE_POLICY" << std::endl;
201 return false;
202 }
203 if (rcode == erc::ReturnCodeValue::RETCODE_INCONSISTENT_POLICY) {
204 std::cerr << "RETCODE_INCONSISTENT_POLICY" << std::endl;
205 return false;
206 }
207 if (rcode == erc::ReturnCodeValue::RETCODE_ALREADY_DELETED) {
208 std::cerr << "RETCODE_ALREADY_DELETED" << std::endl;
209 return false;
210 }
211 if (rcode == erc::ReturnCodeValue::RETCODE_TIMEOUT) {
212 std::cerr << "RETCODE_TIMEOUT" << std::endl;
213 return false;
214 }
215 if (rcode == erc::ReturnCodeValue::RETCODE_NO_DATA) {
216 std::cerr << "RETCODE_NO_DATA" << std::endl;
217 return false;
218 }
219 if (rcode == erc::ReturnCodeValue::RETCODE_ILLEGAL_OPERATION) {
220 std::cerr << "RETCODE_ILLEGAL_OPERATION" << std::endl;
221 return false;
222 }
223 if (rcode == erc::ReturnCodeValue::RETCODE_NOT_ALLOWED_BY_SECURITY) {
224 std::cerr << "RETCODE_NOT_ALLOWED_BY_SECURITY" << std::endl;
225 return false;
226 }
227 std::cerr << "UNKNOWN" << std::endl;
228 return false;
229 }
230// 发布相机信息
232 eprosima::fastrtps::rtps::InstanceHandle_t instance_handle;
233 eprosima::fastrtps::types::ReturnCode_t rcode = _impl_info->_datawriter->write(&_impl_info->_info, instance_handle);
234 if (rcode == erc::ReturnCodeValue::RETCODE_OK) {
235 return true;
236 }
237 // 处理各种返回码并输出错误信息
238 if (rcode == erc::ReturnCodeValue::RETCODE_ERROR) {
239 std::cerr << "RETCODE_ERROR" << std::endl;
240 return false;
241 }
242 if (rcode == erc::ReturnCodeValue::RETCODE_UNSUPPORTED) {
243 std::cerr << "RETCODE_UNSUPPORTED" << std::endl;
244 return false;
245 }
246 if (rcode == erc::ReturnCodeValue::RETCODE_BAD_PARAMETER) {
247 std::cerr << "RETCODE_BAD_PARAMETER" << std::endl;
248 return false;
249 }
250 if (rcode == erc::ReturnCodeValue::RETCODE_PRECONDITION_NOT_MET) {
251 std::cerr << "RETCODE_PRECONDITION_NOT_MET" << std::endl;
252 return false;
253 }
254 if (rcode == erc::ReturnCodeValue::RETCODE_OUT_OF_RESOURCES) {
255 std::cerr << "RETCODE_OUT_OF_RESOURCES" << std::endl;
256 return false;
257 }
258 if (rcode == erc::ReturnCodeValue::RETCODE_NOT_ENABLED) {
259 std::cerr << "RETCODE_NOT_ENABLED" << std::endl;
260 return false;
261 }
262 if (rcode == erc::ReturnCodeValue::RETCODE_IMMUTABLE_POLICY) {
263 std::cerr << "RETCODE_IMMUTABLE_POLICY" << std::endl;
264 return false;
265 }
266 if (rcode == erc::ReturnCodeValue::RETCODE_INCONSISTENT_POLICY) {
267 std::cerr << "RETCODE_INCONSISTENT_POLICY" << std::endl;
268 return false;
269 }
270 if (rcode == erc::ReturnCodeValue::RETCODE_ALREADY_DELETED) {
271 std::cerr << "RETCODE_ALREADY_DELETED" << std::endl;
272 return false;
273 }
274 if (rcode == erc::ReturnCodeValue::RETCODE_TIMEOUT) {
275 std::cerr << "RETCODE_TIMEOUT" << std::endl;
276 return false;
277 }
278 if (rcode == erc::ReturnCodeValue::RETCODE_NO_DATA) {
279 std::cerr << "RETCODE_NO_DATA" << std::endl;
280 return false;
281 }
282 if (rcode == erc::ReturnCodeValue::RETCODE_ILLEGAL_OPERATION) {
283 std::cerr << "RETCODE_ILLEGAL_OPERATION" << std::endl;
284 return false;
285 }
286 if (rcode == erc::ReturnCodeValue::RETCODE_NOT_ALLOWED_BY_SECURITY) {
287 std::cerr << "RETCODE_NOT_ALLOWED_BY_SECURITY" << std::endl;
288 return false;
289 }
290 std::cerr << "UNKNOWN" << std::endl;
291 return false;
292 }
293// 设置图像数据
294 void CarlaISCameraPublisher::SetImageData(int32_t seconds, uint32_t nanoseconds, size_t height, size_t width, const uint8_t* data) {
295 std::vector<uint8_t> vector_data;// 创建数据向量
296 const size_t size = height * width * 4;// 计算数据大小(假设为BGRA格式)
297 vector_data.resize(size);// 调整向量大小
298 std::memcpy(&vector_data[0], &data[0], size); // 复制数据
299 SetData(seconds, nanoseconds, height, width, std::move(vector_data));// 设置数据
300 }
301// 设置相机信息的感兴趣区域
302 void CarlaISCameraPublisher::SetInfoRegionOfInterest( uint32_t x_offset, uint32_t y_offset, uint32_t height, uint32_t width, bool do_rectify) {
303 sensor_msgs::msg::RegionOfInterest roi;// 创建感兴趣区域对象
304 roi.x_offset(x_offset);// 设置x偏移
305 roi.y_offset(y_offset);// 设置y偏移
306 roi.height(height);// 设置高度
307 roi.width(width);// 设置宽度
308 roi.do_rectify(do_rectify);// 设置是否进行矫正
309 _impl_info->_info.roi(roi);// 设置相机信息中的感兴趣区域
310 }
311
312 void CarlaISCameraPublisher::SetData(int32_t seconds, uint32_t nanoseconds, size_t height, size_t width, std::vector<uint8_t>&& data) {
314 time.sec(seconds);
315 time.nanosec(nanoseconds);
316
317 std_msgs::msg::Header header;
318 header.stamp(std::move(time));
319 header.frame_id(_frame_id);
320
321 _impl->_image.header(std::move(header));
322 _impl->_image.width(width);
323 _impl->_image.height(height);
324 _impl->_image.encoding("bgra8"); //taken from the list of strings in include/sensor_msgs/image_encodings.h
325 _impl->_image.is_bigendian(0);
326 _impl->_image.step(_impl->_image.width() * sizeof(uint8_t) * 4);
327 _impl->_image.data(std::move(data)); //https://github.com/eProsima/Fast-DDS/issues/2330
328 }
329
330 void CarlaISCameraPublisher::SetCameraInfoData(int32_t seconds, uint32_t nanoseconds) {
332 time.sec(seconds);
333 time.nanosec(nanoseconds);
334
335 std_msgs::msg::Header header;
336 header.stamp(std::move(time));
337 header.frame_id(_frame_id);
338 _impl_info->_info.header(header);
339 }
340
341 CarlaISCameraPublisher::CarlaISCameraPublisher(const char* ros_name, const char* parent) :
342 _impl(std::make_shared<CarlaISCameraPublisherImpl>()),
343 _impl_info(std::make_shared<CarlaCameraInfoPublisherImpl>()) {
344 _name = ros_name;
345 _parent = parent;
346 }
347
349 if (!_impl)
350 return;
351
352 if (_impl->_datawriter)
353 _impl->_publisher->delete_datawriter(_impl->_datawriter);
354
355 if (_impl->_publisher)
356 _impl->_participant->delete_publisher(_impl->_publisher);
357
358 if (_impl->_topic)
359 _impl->_participant->delete_topic(_impl->_topic);
360
361 if (_impl->_participant)
362 efd::DomainParticipantFactory::get_instance()->delete_participant(_impl->_participant);
363
364 if (!_impl_info)
365 return;
366
367 if (_impl_info->_datawriter)
368 _impl_info->_publisher->delete_datawriter(_impl_info->_datawriter);
369
370 if (_impl_info->_publisher)
371 _impl_info->_participant->delete_publisher(_impl_info->_publisher);
372
373 if (_impl_info->_topic)
374 _impl_info->_participant->delete_topic(_impl_info->_topic);
375
376 if (_impl_info->_participant)
377 efd::DomainParticipantFactory::get_instance()->delete_participant(_impl_info->_participant);
378 }
379// 拷贝构造函数
381 _frame_id = other._frame_id;// 拷贝帧ID
382 _name = other._name; // 拷贝ROS名称
383 _parent = other._parent;// 拷贝父主题
384 _impl = other._impl; // 拷贝实现结构体
385 _impl_info = other._impl_info;// 拷贝相机信息实现结构体
386 }
387// 拷贝赋值运算符
389 _frame_id = other._frame_id;// 拷贝帧ID
390 _name = other._name;// 拷贝ROS名称
391 _parent = other._parent;// 拷贝父主题
392 _impl = other._impl;// 拷贝实现结构体
393 _impl_info = other._impl_info;// 拷贝相机信息实现结构体
394
395 return *this;// 返回自身
396 }
397// 移动构造函数
399 _frame_id = std::move(other._frame_id);// 移动帧ID
400 _name = std::move(other._name); // 移动ROS名称
401 _parent = std::move(other._parent); // 移动父主题
402 _impl = std::move(other._impl);// 移动实现结构体
403 _impl_info = std::move(other._impl_info); // 移动相机信息实现结构体
404 }
405// 移动赋值运算符
407 _frame_id = std::move(other._frame_id);// 移动帧ID
408 _name = std::move(other._name);// 移动ROS名称
409 _parent = std::move(other._parent);// 移动父主题
410 _impl = std::move(other._impl);// 移动实现结构体
411 _impl_info = std::move(other._impl_info);// 移动相机信息实现结构体
412
413 return *this;// 返回自身
414 }
415}
416}
此类表示用户在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
CarlaISCameraPublisher & operator=(const CarlaISCameraPublisher &)
void SetData(int32_t seconds, uint32_t nanoseconds, size_t height, size_t width, std::vector< uint8_t > &&data)
void SetInfoRegionOfInterest(uint32_t x_offset, uint32_t y_offset, uint32_t height, uint32_t width, bool do_rectify)
std::shared_ptr< CarlaCameraInfoPublisherImpl > _impl_info
void InitInfoData(uint32_t x_offset, uint32_t y_offset, uint32_t height, uint32_t width, float fov, bool do_rectify)
std::shared_ptr< CarlaISCameraPublisherImpl > _impl
void SetImageData(int32_t seconds, uint32_t nanoseconds, size_t height, size_t width, const uint8_t *data)
CarlaISCameraPublisher(const char *ros_name="", const char *parent="")
void SetCameraInfoData(int32_t seconds, uint32_t nanoseconds)
const std::string & parent() const
此类表示用户在 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监听器实例。