CARLA
 
载入中...
搜索中...
未找到
CarlaGNSSPublisher.cpp
浏览该文件的文档.
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
27namespace carla {
28namespace ros2 {
29 // 为了方便使用Fast DDS的相关命名空间,进行别名定义
30 namespace efd = eprosima::fastdds::dds;
31 // 为了方便使用Fast RTPS的返回码类型,进行别名定义
32 using erc = eprosima::fastrtps::types::ReturnCode_t;
33// CarlaGNSSPublisher的实现类结构体,用于封装相关的内部实现细节
35 // 域参与者指针,用于参与DDS通信域,管理实体等,初始化为nullptr
36 efd::DomainParticipant* _participant { nullptr };
37 efd::Publisher* _publisher { nullptr };
38 efd::Topic* _topic { nullptr };
39 efd::DataWriter* _datawriter { nullptr };
40 efd::TypeSupport _type { new sensor_msgs::msg::NavSatFixPubSubType() };
41 // Carla监听器对象,用于监听相关事件等
42 CarlaListener _listener {};
43 // 存储导航卫星定位消息的数据结构实例,用于后续设置和发布数据
45 };
46// CarlaGNSSPublisher类的初始化函数,用于初始化相关的DDS实体等操作
48 // 检查类型支持是否有效,如果为nullptr则输出错误信息并返回false
49 if (_impl->_type == nullptr) {
50 std::cerr << "Invalid TypeSupport" << std::endl;
51 return false;
52 }
53// 获取默认的域参与者QoS配置,并设置其名称为传入的_name
54 efd::DomainParticipantQos pqos = efd::PARTICIPANT_QOS_DEFAULT;
55 pqos.name(_name);
56 // 获取域参与者工厂的单例实例
57 auto factory = efd::DomainParticipantFactory::get_instance();
58 // 通过工厂创建域参与者,指定域ID为0,并传入QoS配置,如果创建失败则输出错误信息并返回false
59 _impl->_participant = factory->create_participant(0, pqos);
60 if (_impl->_participant == nullptr) {
61 std::cerr << "Failed to create DomainParticipant" << std::endl;
62 return false;
63 }
64 // 使用创建好的域参与者注册消息类型
65 _impl->_type.register_type(_impl->_participant);
66// 获取默认的发布者QoS配置
67 efd::PublisherQos pubqos = efd::PUBLISHER_QOS_DEFAULT;
68 // 通过域参与者创建发布者,传入QoS配置和nullptr(表示不使用特定的监听器),如果创建失败则输出错误信息并返回false
69 _impl->_publisher = _impl->_participant->create_publisher(pubqos, nullptr);
70 if (_impl->_publisher == nullptr) {
71 std::cerr << "Failed to create Publisher" << std::endl;
72 return false;
73 }
74// 获取默认的主题QoS配置
75 efd::TopicQos tqos = efd::TOPIC_QOS_DEFAULT;
76 // 构建主题名称的基础部分
77 const std::string base { "rt/carla/" };
78 std::string topic_name = base;
79 // 如果父名称不为空,则将父名称添加到主题名称中
80 if (!_parent.empty())
81 topic_name += _parent + "/";
82 // 再添加当前的名称到主题名称中
83 topic_name += _name;
84 // 通过域参与者创建主题,指定主题名称、消息类型名称以及QoS配置,如果创建失败则输出错误信息并返回false
85 _impl->_topic = _impl->_participant->create_topic(topic_name, _impl->_type->getName(), tqos);
86 if (_impl->_topic == nullptr) {
87 std::cerr << "Failed to create Topic" << std::endl;
88 return false;
89 }
90// 获取默认的数据写入器QoS配置
91 efd::DataWriterQos wqos = efd::DATAWRITER_QOS_DEFAULT;
92 // 设置数据写入器的历史内存策略为预分配可重分配模式
93 wqos.endpoint().history_memory_policy = eprosima::fastrtps::rtps::PREALLOCATED_WITH_REALLOC_MEMORY_MODE;
94 // 获取数据写入器监听器对象(从Carla监听器中获取其内部实现指针并进行类型转换)
95 efd::DataWriterListener* listener = (efd::DataWriterListener*)_impl->_listener._impl.get();
96 // 通过发布者创建数据写入器,指定主题、QoS配置以及监听器,如果创建失败则输出错误信息并返回false
97 _impl->_datawriter = _impl->_publisher->create_datawriter(_impl->_topic, wqos, listener);
98 if (_impl->_datawriter == nullptr) {
99 std::cerr << "Failed to create DataWriter" << std::endl;
100 return false;
101 }
102 // 设置帧ID为当前名称,通常用于标识消息所属的帧等情况
104 return true;
105 }
106// CarlaGNSSPublisher类的发布函数,用于将设置好的数据通过数据写入器发布出去
108 // 实例句柄,用于在发布数据时标识实例等情况(具体根据Fast DDS内部机制使用)
109 eprosima::fastrtps::rtps::InstanceHandle_t instance_handle;
110 // 调用数据写入器的write函数将导航卫星定位消息数据写入,获取返回码
111 eprosima::fastrtps::types::ReturnCode_t rcode = _impl->_datawriter->write(&_impl->_nav, instance_handle);
112 // 如果返回码表示操作成功,则返回true
113 if (rcode == erc::ReturnCodeValue::RETCODE_OK) {
114 return true;
115 }
116 // 以下是针对各种可能的错误返回码情况,分别输出相应的错误信息并返回false
117 if (rcode == erc::ReturnCodeValue::RETCODE_ERROR) {
118 std::cerr << "RETCODE_ERROR" << std::endl;
119 return false;
120 }
121 if (rcode == erc::ReturnCodeValue::RETCODE_UNSUPPORTED) {
122 std::cerr << "RETCODE_UNSUPPORTED" << std::endl;
123 return false;
124 }
125 if (rcode == erc::ReturnCodeValue::RETCODE_BAD_PARAMETER) {
126 std::cerr << "RETCODE_BAD_PARAMETER" << std::endl;
127 return false;
128 }
129 if (rcode == erc::ReturnCodeValue::RETCODE_PRECONDITION_NOT_MET) {
130 std::cerr << "RETCODE_PRECONDITION_NOT_MET" << std::endl;
131 return false;
132 }
133 if (rcode == erc::ReturnCodeValue::RETCODE_OUT_OF_RESOURCES) {
134 std::cerr << "RETCODE_OUT_OF_RESOURCES" << std::endl;
135 return false;
136 }
137 if (rcode == erc::ReturnCodeValue::RETCODE_NOT_ENABLED) {
138 std::cerr << "RETCODE_NOT_ENABLED" << std::endl;
139 return false;
140 }
141 if (rcode == erc::ReturnCodeValue::RETCODE_IMMUTABLE_POLICY) {
142 std::cerr << "RETCODE_IMMUTABLE_POLICY" << std::endl;
143 return false;
144 }
145 if (rcode == erc::ReturnCodeValue::RETCODE_INCONSISTENT_POLICY) {
146 std::cerr << "RETCODE_INCONSISTENT_POLICY" << std::endl;
147 return false;
148 }
149 if (rcode == erc::ReturnCodeValue::RETCODE_ALREADY_DELETED) {
150 std::cerr << "RETCODE_ALREADY_DELETED" << std::endl;
151 return false;
152 }
153 if (rcode == erc::ReturnCodeValue::RETCODE_TIMEOUT) {
154 std::cerr << "RETCODE_TIMEOUT" << std::endl;
155 return false;
156 }
157 if (rcode == erc::ReturnCodeValue::RETCODE_NO_DATA) {
158 std::cerr << "RETCODE_NO_DATA" << std::endl;
159 return false;
160 }
161 if (rcode == erc::ReturnCodeValue::RETCODE_ILLEGAL_OPERATION) {
162 std::cerr << "RETCODE_ILLEGAL_OPERATION" << std::endl;
163 return false;
164 }
165 if (rcode == erc::ReturnCodeValue::RETCODE_NOT_ALLOWED_BY_SECURITY) {
166 std::cerr << "RETCODE_NOT_ALLOWED_BY_SECURITY" << std::endl;
167 return false;
168 }
169 // 如果返回码不属于上述已知的情况,则输出未知返回码的错误信息并返回false
170 std::cerr << "UNKNOWN return code: " << rcode() << std::endl;
171 return false;
172 }
173// 设置要发布的导航卫星定位消息的数据函数
174 void CarlaGNSSPublisher::SetData(int32_t seconds, uint32_t nanoseconds, const double* data) {
175 // 创建一个时间结构体实例,用于设置消息的时间戳
177 // 设置时间的秒数部分
178 time.sec(seconds);
179 // 设置时间的纳秒部分
180 time.nanosec(nanoseconds);
181// 创建一个消息头结构体实例,用于设置消息的头部信息
182 std_msgs::msg::Header header;
183 header.stamp(std::move(time));
184 header.frame_id(_frame_id);
185// 设置导航卫星定位消息的头部信息为上面构建好的消息头结构体实例(通过移动语义传递)
186 _impl->_nav.header(std::move(header));
187 _impl->_nav.latitude(*data++);
188 _impl->_nav.longitude(*data++);
189 _impl->_nav.altitude(*data++);
190 }
191// CarlaGNSSPublisher类的构造函数,用于初始化对象,传入ROS名称和父名称
192 CarlaGNSSPublisher::CarlaGNSSPublisher(const char* ros_name, const char* parent) :
193 _impl(std::make_shared<CarlaGNSSPublisherImpl>()) {
194 _name = ros_name;
195 _parent = parent;
196 }
197// CarlaGNSSPublisher类的析构函数,用于释放相关的DDS资源
199// 如果内部实现指针为空,则直接返回,不进行资源释放操作
200 if (!_impl)
201 return;
202// 如果数据写入器存在,则通过发布者删除数据写入器
203 if (_impl->_datawriter)
204 _impl->_publisher->delete_datawriter(_impl->_datawriter);
205 // 如果发布者存在,则通过域参与者删除发布者
206 if (_impl->_publisher)
207 _impl->_participant->delete_publisher(_impl->_publisher);
208// 如果主题存在,则通过域参与者删除主题
209 if (_impl->_topic)
210 _impl->_participant->delete_topic(_impl->_topic);
211// 如果域参与者存在,则通过域参与者工厂删除域参与者
212 if (_impl->_participant)
213 efd::DomainParticipantFactory::get_instance()->delete_participant(_impl->_participant);
214 }
215// CarlaGNSSPublisher类的拷贝构造函数
217 _frame_id = other._frame_id;
218 _name = other._name;
219 _parent = other._parent;
220 _impl = other._impl;
221 }
222// CarlaGNSSPublisher类的拷贝赋值运算符重载函数
224 _frame_id = other._frame_id;
225 _name = other._name;
226 _parent = other._parent;
227 _impl = other._impl;
228
229 return *this;
230 }
231// CarlaGNSSPublisher类的移动构造函数
233 _frame_id = std::move(other._frame_id);
234 _name = std::move(other._name);
235 _parent = std::move(other._parent);
236 _impl = std::move(other._impl);
237 }
238// CarlaGNSSPublisher类的移动赋值运算符重载函数
240 _frame_id = std::move(other._frame_id);
241 _name = std::move(other._name);
242 _parent = std::move(other._parent);
243 _impl = std::move(other._impl);
244
245 return *this;
246 }
247}
248}
此类表示用户在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
用于在ROS 2中发布CARLA的GNSS(全球导航卫星系统)数据的类。 继承自CarlaPublisher类,专门用于初始化、设置和发布GNSS数据。
bool Init()
初始化函数,用于设置ROS节点和发布者。
~CarlaGNSSPublisher()
析构函数,用于销毁CarlaGNSSPublisher对象。
void SetData(int32_t seconds, uint32_t nanoseconds, const double *data)
设置GNSS数据。
std::shared_ptr< CarlaGNSSPublisherImpl > _impl
指向CarlaGNSSPublisherImpl的智能指针,用于隐藏实现细节。
CarlaGNSSPublisher(const char *ros_name="", const char *parent="")
构造函数,用于创建CarlaGNSSPublisher对象。
CarlaGNSSPublisher & operator=(const CarlaGNSSPublisher &)
拷贝赋值运算符,用于将当前对象的状态复制到另一个同类型的对象中。
bool Publish()
发布GNSS数据。
const std::string & parent() const
This class represents the TopicDataType of the type NavSatFix defined by the user in the IDL file.
This class represents the structure NavSatFix defined by the user in the IDL file.
Definition NavSatFix.h:79
eprosima::fastrtps::types::ReturnCode_t erc
@using erc
CARLA模拟器的主命名空间。
Definition Carla.cpp:139