CARLA
 
载入中...
搜索中...
未找到
CarlaSpeedometerSensor.cpp
浏览该文件的文档.
1#define _GLIBCXX_USE_CXX11_ABI 0
2/**
3 * @file
4 * 包含必要的头文件,实现CARLA车速传感器的ROS2和FastDDS通信。
5 */
6
7 /**
8 * @brief 包含CARLA车速传感器的头文件。
9 */
11 /**
12 * @brief 包含标准字符串库。
13 */
14#include <string>
15 /**
16 * @brief 包含CARLA ROS2类型的Float32发布和订阅类型定义。
17 */
19 /**
20 * @brief 包含CARLA ROS2监听器相关定义。
21 */
23 /**
24 * @brief 包含FastDDS DomainParticipant类的声明。
25 */
26#include <fastdds/dds/domain/DomainParticipant.hpp>
27 /**
28 * @brief 包含FastDDS Publisher类的声明。
29 */
30#include <fastdds/dds/publisher/Publisher.hpp>
31 /**
32 * @brief 包含FastDDS Topic类的声明。
33 */
34#include <fastdds/dds/topic/Topic.hpp>
35 /**
36 * @brief 包含FastDDS DataWriter类的声明。
37 */
38#include <fastdds/dds/publisher/DataWriter.hpp>
39 /**
40 * @brief 包含FastDDS TypeSupport类的声明,用于支持特定类型的数据传输。
41 */
42#include <fastdds/dds/topic/TypeSupport.hpp>
43 /**
44 * @brief 包含FastDDS DomainParticipantQos类的声明,用于配置DomainParticipant的QoS策略。
45 */
46#include <fastdds/dds/domain/qos/DomainParticipantQos.hpp>
47 /**
48 * @brief 包含FastDDS DomainParticipantFactory类的声明,用于创建DomainParticipant实例。
49 */
50#include <fastdds/dds/domain/DomainParticipantFactory.hpp>
51 /**
52 * @brief 包含FastDDS PublisherQos类的声明,用于配置Publisher的QoS策略。
53 */
54#include <fastdds/dds/publisher/qos/PublisherQos.hpp>
55 /**
56 * @brief 包含FastDDS TopicQos类的声明,用于配置Topic的QoS策略。
57 */
58#include <fastdds/dds/topic/qos/TopicQos.hpp>
59 /**
60 * @brief 包含FastRTPS的ParticipantAttributes类,用于配置RTPS参与者属性。
61 */
62#include <fastrtps/attributes/ParticipantAttributes.h>
63 /**
64 * @brief 包含FastRTPS的QosPolicies类,用于配置RTPS的QoS策略。
65 */
66#include <fastrtps/qos/QosPolicies.h>
67 /**
68 * @brief 包含FastDDS DataWriterQos类的声明,用于配置DataWriter的QoS策略。
69 */
70#include <fastdds/dds/publisher/qos/DataWriterQos.hpp>
71 /**
72 * @brief 包含FastDDS DataWriterListener类的声明,用于监听DataWriter的事件。
73 */
74#include <fastdds/dds/publisher/DataWriterListener.hpp>
75
76/**
77 * @namespace carla::ros2
78 * @brief 包含与ROS2集成相关的Carla模块的实现。
79 */
80namespace carla {
81/**
82 * @namespace carla::ros2::efd
83 * @brief eprosima::fastdds::dds命名空间的别名,用于简化代码中对FastDDS库的引用。
84 */
85namespace ros2 {
86 /**
87 * @typedef erc
88 * @brief eprosima::fastrtps::types::ReturnCode_t类型的别名,用于表示FastRTPS操作的结果代码。
89 */
90 namespace efd = eprosima::fastdds::dds;
91 using erc = eprosima::fastrtps::types::ReturnCode_t;
92 /**
93 * @struct CarlaSpeedometerSensorImpl
94 * @brief Carla车速传感器实现的内部结构体。
95 *
96 * 该结构体封装了与FastDDS相关的资源,包括DomainParticipant、Publisher、Topic和DataWriter,以及用于发布车速数据的TypeSupport和监听器。
97 */
99 /**
100 * @brief FastDDS的DomainParticipant指针,用于创建和管理FastDDS的通信实体。
101 */
102 efd::DomainParticipant* _participant { nullptr };
103 /**
104 * @brief FastDDS的Publisher指针,用于发布数据。
105 */
106 efd::Publisher* _publisher { nullptr };
107 /**
108 * @brief FastDDS的Topic指针,用于定义数据的主题。
109 */
110 efd::Topic* _topic { nullptr };
111 /**
112 * @brief FastDDS的DataWriter指针,用于写入数据到指定的Topic。
113 */
114 efd::DataWriter* _datawriter { nullptr };
115 /**
116 * @brief TypeSupport对象,用于注册和识别发布的消息类型。
117 */
118 efd::TypeSupport _type { new std_msgs::msg::Float32PubSubType() };
119 /**
120 * @brief CarlaListener对象,用于处理相关的回调事件。
121 */
122 CarlaListener _listener {};
123 /**
124 * @brief 用于发布的车速数据。
125 */
127 };
128 /**
129 * @brief 初始化Carla车速传感器。
130 *
131 * 该函数负责初始化Carla车速传感器的FastDDS相关资源,包括创建DomainParticipant、Publisher、Topic和DataWriter。
132 *
133 * @return 初始化成功返回true,否则返回false。
134 */
136 /**
137 * @brief 检查TypeSupport是否有效。
138 */
139 if (_impl->_type == nullptr) {
140 std::cerr << "Invalid TypeSupport" << std::endl;
141 return false;
142 }
143 /**
144 * @brief 设置DomainParticipant的QoS策略,并创建DomainParticipant。
145 */
146 efd::DomainParticipantQos pqos = efd::PARTICIPANT_QOS_DEFAULT;
147 pqos.name(_name);
148 auto factory = efd::DomainParticipantFactory::get_instance();
149 _impl->_participant = factory->create_participant(0, pqos);
150 if (_impl->_participant == nullptr) {
151 std::cerr << "Failed to create DomainParticipant" << std::endl;
152 return false;
153 }
154 /**
155 * @brief 注册TypeSupport。
156 */
157 _impl->_type.register_type(_impl->_participant);
158 /**
159 * @brief 设置Publisher的QoS策略,并创建Publisher。
160 */
161 efd::PublisherQos pubqos = efd::PUBLISHER_QOS_DEFAULT;
162 _impl->_publisher = _impl->_participant->create_publisher(pubqos, nullptr);
163 if (_impl->_publisher == nullptr) {
164 std::cerr << "Failed to create Publisher" << std::endl;
165 return false;
166 }
167 /**
168 * @brief 设置Topic的QoS策略,并创建Topic。
169 */
170 efd::TopicQos tqos = efd::TOPIC_QOS_DEFAULT;
171 const std::string base { "rt/carla/" };
172 std::string topic_name = base;
173 if (!_parent.empty())
174 topic_name += _parent + "/";
175 topic_name += _name;
176 _impl->_topic = _impl->_participant->create_topic(topic_name, _impl->_type->getName(), tqos);
177 if (_impl->_topic == nullptr) {
178 std::cerr << "Failed to create Topic" << std::endl;
179 return false;
180 }
181 /**
182 * @brief 设置DataWriter的QoS策略,并创建DataWriter。
183 */
184 efd::DataWriterQos wqos = efd::DATAWRITER_QOS_DEFAULT;
185 wqos.endpoint().history_memory_policy = eprosima::fastrtps::rtps::PREALLOCATED_WITH_REALLOC_MEMORY_MODE;
186 efd::DataWriterListener* listener = (efd::DataWriterListener*)_impl->_listener._impl.get();
187 _impl->_datawriter = _impl->_publisher->create_datawriter(_impl->_topic, wqos, listener);
188 if (_impl->_datawriter == nullptr) {
189 std::cerr << "Failed to create DataWriter" << std::endl;
190 return false;
191 }
192 /**
193 * @brief 设置帧ID为传感器名称。
194 */
196 return true;
197 }
198 /**
199 * @brief 发布速度计传感器的数据
200 *
201 * 该函数尝试通过RTPS(实时发布订阅)协议发布速度计传感器的数据。
202 * 如果发布成功,则返回true;否则,根据返回码输出相应的错误信息,并返回false。
203 *
204 * @return bool 如果数据成功发布,则返回true;否则返回false。
205 */
207 /// @brief RTPS实例句柄
208 eprosima::fastrtps::rtps::InstanceHandle_t instance_handle;
209 /// @brief 调用数据写入函数,并获取返回码
210 /// @param &_impl->_float 指向要写入数据的指针
211 /// @param instance_handle RTPS实例句柄
212 /// @return eprosima::fastrtps::types::ReturnCode_t 返回码,表示写入操作的结果
213 eprosima::fastrtps::types::ReturnCode_t rcode = _impl->_datawriter->write(&_impl->_float, instance_handle);
214 // 根据不同的返回码处理相应的逻辑
215 if (rcode == erc::ReturnCodeValue::RETCODE_OK) {
216 /// @brief 数据成功发布
217 return true;
218 }
219 if (rcode == erc::ReturnCodeValue::RETCODE_ERROR) {
220 /// @brief 发生了一般错误
221 std::cerr << "RETCODE_ERROR" << std::endl;
222 return false;
223 }
224 if (rcode == erc::ReturnCodeValue::RETCODE_UNSUPPORTED) {
225 /// @brief 操作不被支持
226 std::cerr << "RETCODE_UNSUPPORTED" << std::endl;
227 return false;
228 }
229 if (rcode == erc::ReturnCodeValue::RETCODE_BAD_PARAMETER) {
230 /// @brief 提供了错误的参数
231 std::cerr << "RETCODE_BAD_PARAMETER" << std::endl;
232 return false;
233 }
234 if (rcode == erc::ReturnCodeValue::RETCODE_PRECONDITION_NOT_MET) {
235 /// @brief 前置条件未满足
236 std::cerr << "RETCODE_PRECONDITION_NOT_MET" << std::endl;
237 return false;
238 }
239 if (rcode == erc::ReturnCodeValue::RETCODE_OUT_OF_RESOURCES) {
240 /// @brief 资源不足
241 std::cerr << "RETCODE_OUT_OF_RESOURCES" << std::endl;
242 return false;
243 }
244 if (rcode == erc::ReturnCodeValue::RETCODE_NOT_ENABLED) {
245 /// @brief 功能未启用
246 std::cerr << "RETCODE_NOT_ENABLED" << std::endl;
247 return false;
248 }
249 if (rcode == erc::ReturnCodeValue::RETCODE_IMMUTABLE_POLICY) {
250 /// @brief 策略不可变
251 std::cerr << "RETCODE_IMMUTABLE_POLICY" << std::endl;
252 return false;
253 }
254 if (rcode == erc::ReturnCodeValue::RETCODE_INCONSISTENT_POLICY) {
255 /// @brief 策略不一致
256 std::cerr << "RETCODE_INCONSISTENT_POLICY" << std::endl;
257 return false;
258 }
259 if (rcode == erc::ReturnCodeValue::RETCODE_ALREADY_DELETED) {
260 /// @brief 实体已被删除
261 std::cerr << "RETCODE_ALREADY_DELETED" << std::endl;
262 return false;
263 }
264 if (rcode == erc::ReturnCodeValue::RETCODE_TIMEOUT) {
265 /// @brief 操作超时
266 std::cerr << "RETCODE_TIMEOUT" << std::endl;
267 return false;
268 }
269 if (rcode == erc::ReturnCodeValue::RETCODE_NO_DATA) {
270 /// @brief 没有数据
271 std::cerr << "RETCODE_NO_DATA" << std::endl;
272 return false;
273 }
274 if (rcode == erc::ReturnCodeValue::RETCODE_ILLEGAL_OPERATION) {
275 /// @brief 非法操作
276 std::cerr << "RETCODE_ILLEGAL_OPERATION" << std::endl;
277 return false;
278 }
279 if (rcode == erc::ReturnCodeValue::RETCODE_NOT_ALLOWED_BY_SECURITY) {
280 /// @brief 安全策略不允许
281 std::cerr << "RETCODE_NOT_ALLOWED_BY_SECURITY" << std::endl;
282 return false;
283 }
284 /// @brief 未知错误
285 std::cerr << "UNKNOWN" << std::endl;
286 return false;
287 }
288 /**
289 * @brief 设置速度传感器的数据
290 *
291 * 该函数用于将速度数据设置到速度传感器的内部实现中。
292 *
293 * @param data 浮点数类型,表示速度数据
294 */
296 _impl->_float.data(data);
297 }
298 /**
299 * @brief CarlaSpeedometerSensor类的构造函数
300 *
301 * 构造函数初始化速度传感器的实例,并设置其名称和父节点。
302 *
303 * @param ros_name 字符指针,表示ROS节点的名称
304 * @param parent 字符指针,表示父节点的名称
305 */
306 CarlaSpeedometerSensor::CarlaSpeedometerSensor(const char* ros_name, const char* parent) :
307 _impl(std::make_shared<CarlaSpeedometerSensorImpl>()) {
308 _name = ros_name;
309 _parent = parent;
310 }
311 /**
312 * @brief CarlaSpeedometerSensor类的析构函数
313 *
314 * 析构函数释放速度传感器所使用的资源,包括数据写入器、发布者、主题和参与者。
315 */
317 if (!_impl)
318 return;
319
320 if (_impl->_datawriter)
321 _impl->_publisher->delete_datawriter(_impl->_datawriter);
322
323 if (_impl->_publisher)
324 _impl->_participant->delete_publisher(_impl->_publisher);
325
326 if (_impl->_topic)
327 _impl->_participant->delete_topic(_impl->_topic);
328
329 if (_impl->_participant)
330 efd::DomainParticipantFactory::get_instance()->delete_participant(_impl->_participant);
331 }
332 /**
333 * @brief CarlaSpeedometerSensor类的拷贝构造函数
334 *
335 * 拷贝构造函数通过复制另一个速度传感器的实例来初始化当前实例。
336 *
337 * @param other 另一个CarlaSpeedometerSensor实例,用于复制数据
338 */
340 _frame_id = other._frame_id;
341 _name = other._name;
342 _parent = other._parent;
343 _impl = other._impl;
344 }
345 /**
346 * @brief 拷贝赋值运算符
347 *
348 * 通过复制另一个速度传感器的实例来更新当前实例的数据。
349 *
350 * @param other 另一个CarlaSpeedometerSensor实例,用于复制数据
351 * @return CarlaSpeedometerSensor& 当前实例的引用
352 */
354 _frame_id = other._frame_id;
355 _name = other._name;
356 _parent = other._parent;
357 _impl = other._impl;
358
359 return *this;
360 }
361 /**
362 * @brief CarlaSpeedometerSensor类的移动构造函数
363 *
364 * 移动构造函数通过移动另一个速度传感器的实例来初始化当前实例,避免数据复制。
365 *
366 * @param other 另一个CarlaSpeedometerSensor实例,用于移动数据
367 */
369 _frame_id = std::move(other._frame_id);
370 _name = std::move(other._name);
371 _parent = std::move(other._parent);
372 _impl = std::move(other._impl);
373 }
374 /**
375 * @brief 移动赋值运算符
376 *
377 * 通过移动另一个速度传感器的实例来更新当前实例的数据,避免数据复制。
378 *
379 * @param other 另一个CarlaSpeedometerSensor实例,用于移动数据
380 * @return CarlaSpeedometerSensor& 当前实例的引用
381 */
383 _frame_id = std::move(other._frame_id);
384 _name = std::move(other._name);
385 _parent = std::move(other._parent);
386 _impl = std::move(other._impl);
387
388 return *this;
389 }
390}
391}
const std::string & parent() const
CarlaSpeedometerSensor & operator=(const CarlaSpeedometerSensor &)
拷贝赋值运算符
~CarlaSpeedometerSensor()
CarlaSpeedometerSensor类的析构函数
bool Publish()
发布速度计传感器的数据
std::shared_ptr< CarlaSpeedometerSensorImpl > _impl
void SetData(float data)
设置速度传感器的数据
bool Init()
初始化Carla车速传感器。
CarlaSpeedometerSensor(const char *ros_name="", const char *parent="")
CarlaSpeedometerSensor类的构造函数
此类表示由用户在 IDL 文件中定义的 Float32 类型的主题数据类型(TopicDataType)。它继承自 eprosima::fastdds::dds::TopicDataType,意味着需要...
这个类表示用户在IDL文件中定义的Float32结构。
Definition Float32.h:72
eprosima::fastrtps::types::ReturnCode_t erc
@using erc
CARLA模拟器的主命名空间。
Definition Carla.cpp:139
Carla车速传感器实现的内部结构体。
efd::DataWriter * _datawriter
FastDDS的DataWriter指针,用于写入数据到指定的Topic。
efd::TypeSupport _type
TypeSupport对象,用于注册和识别发布的消息类型。
efd::Topic * _topic
FastDDS的Topic指针,用于定义数据的主题。
CarlaListener _listener
CarlaListener对象,用于处理相关的回调事件。
efd::DomainParticipant * _participant
FastDDS的DomainParticipant指针,用于创建和管理FastDDS的通信实体。
efd::Publisher * _publisher
FastDDS的Publisher指针,用于发布数据。
std_msgs::msg::Float32 _float
用于发布的车速数据。