CARLA
 
载入中...
搜索中...
未找到
CarlaIMUPublisher.cpp
浏览该文件的文档.
1#define _GLIBCXX_USE_CXX11_ABI 0
2
3#include "CarlaIMUPublisher.h"
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// 为了方便使用 eprosima::fastdds::dds 命名空间,使用别名 efd 来指代它
30 namespace efd = eprosima::fastdds::dds;
31// 使用别名 erc 来指代 eprosima::fastrtps::types::ReturnCode_t 类型,该类型通常用于表示操作的返回码
32 using erc = eprosima::fastrtps::types::ReturnCode_t;
33// 定义一个名为 CarlaIMUPublisherImpl 的结构体,用于封装与 Carla IMU 发布者相关的内部实现细节
34
36// 指向 DDS 领域参与者的指针,用于参与 DDS 网络通信,初始化为 nullptr
37 efd::DomainParticipant* _participant { nullptr };
38 // 指向 DDS 发布者的指针,用于发布数据,初始化为 nullptr
39 efd::Publisher* _publisher { nullptr };
40// 指向 DDS 主题的指针,用于定义发布的数据主题,初始化为 nullptr
41 efd::Topic* _topic { nullptr };
42// 指向 DDS 数据写入器的指针,用于实际将数据写入 DDS 网络,初始化为 nullptr
43 efd::DataWriter* _datawriter { nullptr };
44// 用于支持要发布的数据类型,这里实例化为 sensor_msgs::msg::ImuPubSubType 类型,用于 IMU 数据类型支持
45 efd::TypeSupport _type { new sensor_msgs::msg::ImuPubSubType() };
46// Carla 监听器对象,可能用于监听发布过程中的一些事件等情况
47 CarlaListener _listener {};
48// 用于存储 IMU 数据的消息对象,初始化为默认状态
50 };
51// CarlaIMUPublisher 类的初始化函数,用于初始化发布者相关的各种 DDS 对象等资源
53 if (_impl->_type == nullptr) {
54 std::cerr << "Invalid TypeSupport" << std::endl;
55 return false;// 检查类型支持对象是否为空,如果为空则说明类型支持设置不正确,输出错误信息并返回 false
56 }
57// 获取默认的 DDS 领域参与者 QoS 配置,并赋值给 pqos 对象,后续可基于此进行个性化配置
58 efd::DomainParticipantQos pqos = efd::PARTICIPANT_QOS_DEFAULT;// 获取默认的 DDS 领域参与者 QoS 配置,并赋值给 pqos 对象
59 pqos.name(_name);// 设置领域参与者的名称为类成员变量 _name 存储的值
60 // 获取 DDS 领域参与者工厂的单例实例,用于创建领域参与者对象
61 auto factory = efd::DomainParticipantFactory::get_instance();
62 // 使用工厂创建一个领域参与者对象,传入领域 ID(这里为 0)和配置好的 QoS 对象 pqos,若创建失败返回 nullptr
63 _impl->_participant = factory->create_participant(0, pqos);
64 if (_impl->_participant == nullptr) {
65 std::cerr << "Failed to create DomainParticipant" << std::endl;
66 return false;
67 }// // 使用创建好的领域参与者注册要发布的数据类型,确保 DDS 网络知道如何处理该类型的数据
68 _impl->_type.register_type(_impl->_participant);
69// 获取默认的 DDS 发布者 QoS 配置,并赋值给 pubqos 对象
70 efd::PublisherQos pubqos = efd::PUBLISHER_QOS_DEFAULT;
71 // 使用领域参与者创建一个 DDS 发布者,使用前面设置的 QoS 配置 pubqos,监听器为 nullptr
72 _impl->_publisher = _impl->_participant->create_publisher(pubqos, nullptr);
73 // 如果创建发布者失败(返回的指针为 nullptr),输出错误信息并返回 false
74 if (_impl->_publisher == nullptr) {
75 std::cerr << "Failed to create Publisher" << std::endl;
76 return false;
77 }
78 // 获取默认的 DDS 主题 QoS 配置,并赋值给 tqos 对象
79 efd::TopicQos tqos = efd::TOPIC_QOS_DEFAULT;
80 // 定义一个基础的主题名称字符串前缀
81 const std::string base { "rt/carla/" };
82 // 初始化主题名称字符串为基础前缀
83 std::string topic_name = base;
84 if (!_parent.empty())
85 topic_name += _parent + "/";
86 topic_name += _name;
87 _impl->_topic = _impl->_participant->create_topic(topic_name, _impl->_type->getName(), tqos); // 如果创建主题失败(返回的指针为 nullptr),输出错误信息并返回 false
88 if (_impl->_topic == nullptr) {
89 std::cerr << "Failed to create Topic" << std::endl;
90 return false;
91 }
92
93 efd::DataWriterQos wqos = efd::DATAWRITER_QOS_DEFAULT;
94 // 设置数据写入器的历史内存策略为预分配并可重新分配内存模式,用于管理数据写入的内存相关配置
95 wqos.endpoint().history_memory_policy = eprosima::fastrtps::rtps::PREALLOCATED_WITH_REALLOC_MEMORY_MODE;
96 // 获取 Carla 监听器内部实现对象的指针(进行了类型转换),用于传递给数据写入器
97 efd::DataWriterListener* listener = (efd::DataWriterListener*)_impl->_listener._impl.get();
98 _impl->_datawriter = _impl->_publisher->create_datawriter(_impl->_topic, wqos, listener);
99 // 如果创建数据写入器失败(返回的指针为 nullptr),输出错误信息并返回 false
100 if (_impl->_datawriter == nullptr) {
101 std::cerr << "Failed to create DataWriter" << std::endl;
102 return false;
103 }
105 return true;
106 }
107 // CarlaIMUPublisher 类的发布函数,用于将存储在内部的 IMU 数据发布出去
109 // 定义一个实例句柄对象,用于在 DDS 中标识要发布的数据实例(具体用法与 DDS 内部机制相关)
110 eprosima::fastrtps::rtps::InstanceHandle_t instance_handle;
111 // 调用数据写入器的 write 方法尝试将内部存储的 IMU 数据(_impl->_imu)写入到 DDS 网络中,返回操作结果码
112 eprosima::fastrtps::types::ReturnCode_t rcode = _impl->_datawriter->write(&_impl->_imu, instance_handle);
113 // 如果返回码表示操作成功(RETCODE_OK),则返回 true,表示发布成功
114 if (rcode == erc::ReturnCodeValue::RETCODE_OK) {
115 return true;
116 }
117 // 如果返回码表示发生错误(RETCODE_ERROR),输出错误信息并返回 false,表示发布失败
118 if (rcode == erc::ReturnCodeValue::RETCODE_ERROR) {
119 std::cerr << "RETCODE_ERROR" << std::endl;
120 return false;
121 }
122 // 如果返回码表示操作不被支持(RETCODE_UNSUPPORTED),输出错误信息并返回 false,表示发布失败
123 if (rcode == erc::ReturnCodeValue::RETCODE_UNSUPPORTED) {
124 std::cerr << "RETCODE_UNSUPPORTED" << std::endl;
125 return false;
126 }
127 // 如果返回码表示参数错误(RETCODE_BAD_PARAMETER),输出错误信息并返回 false,表示发布失败
128 if (rcode == erc::ReturnCodeValue::RETCODE_BAD_PARAMETER) {
129 std::cerr << "RETCODE_BAD_PARAMETER" << std::endl;
130 return false;
131 }
132 if (rcode == erc::ReturnCodeValue::RETCODE_PRECONDITION_NOT_MET) {
133 std::cerr << "RETCODE_PRECONDITION_NOT_MET" << std::endl;
134 return false;
135 }
136 if (rcode == erc::ReturnCodeValue::RETCODE_OUT_OF_RESOURCES) {
137 std::cerr << "RETCODE_OUT_OF_RESOURCES" << std::endl;
138 return false;
139 }
140 if (rcode == erc::ReturnCodeValue::RETCODE_NOT_ENABLED) {
141 std::cerr << "RETCODE_NOT_ENABLED" << std::endl;
142 return false;
143 }
144 if (rcode == erc::ReturnCodeValue::RETCODE_IMMUTABLE_POLICY) {
145 std::cerr << "RETCODE_IMMUTABLE_POLICY" << std::endl;
146 return false;
147 }
148 if (rcode == erc::ReturnCodeValue::RETCODE_INCONSISTENT_POLICY) {
149 std::cerr << "RETCODE_INCONSISTENT_POLICY" << std::endl;
150 return false;
151 }
152 if (rcode == erc::ReturnCodeValue::RETCODE_ALREADY_DELETED) {
153 std::cerr << "RETCODE_ALREADY_DELETED" << std::endl;
154 return false;
155 }
156 if (rcode == erc::ReturnCodeValue::RETCODE_TIMEOUT) {
157 std::cerr << "RETCODE_TIMEOUT" << std::endl;
158 return false;
159 }
160 if (rcode == erc::ReturnCodeValue::RETCODE_NO_DATA) {
161 std::cerr << "RETCODE_NO_DATA" << std::endl;
162 return false;
163 }
164 if (rcode == erc::ReturnCodeValue::RETCODE_ILLEGAL_OPERATION) {
165 std::cerr << "RETCODE_ILLEGAL_OPERATION" << std::endl;
166 return false;
167 }
168 if (rcode == erc::ReturnCodeValue::RETCODE_NOT_ALLOWED_BY_SECURITY) {
169 std::cerr << "RETCODE_NOT_ALLOWED_BY_SECURITY" << std::endl;
170 return false;
171 }
172 std::cerr << "UNKNOWN" << std::endl;
173 return false;
174 }
175 // 设置 IMU 数据的函数,根据传入的参数填充内部的 IMU 消息对象的各个字段
176 void CarlaIMUPublisher::SetData(int32_t seconds, uint32_t nanoseconds, float* pAccelerometer, float* pGyroscope, float compass) {
177 // 定义一个用于存储陀螺仪数据的向量对象
179 // 定义一个用于存储线性加速度数据的向量对象
180 geometry_msgs::msg::Vector3 linear_acceleration;
181 // 从传入的加速度计数据指针中依次取出 x、y、z 方向的加速度值,并设置到线性加速度向量对象中
182 const float ax = *pAccelerometer++;
183 const float ay = *pAccelerometer++;
184 const float az = *pAccelerometer++;
185 linear_acceleration.x(ax);
186 linear_acceleration.y(ay);
187 linear_acceleration.z(az);
188 // 从传入的陀螺仪数据指针中依次取出 x、y、z 方向的角速度值,并设置到陀螺仪向量对象中
189 const float gx = *pGyroscope++;
190 const float gy = *pGyroscope++;
191 const float gz = *pGyroscope++;
192 gyroscope.x(gx);
193 gyroscope.y(gy);
194 gyroscope.z(gz);
195// 创建一个时间消息对象,用于存储时间戳信息
197 time.sec(seconds);
198 time.nanosec(nanoseconds);
199 // 创建一个消息头对象,用于存储消息的一些通用元数据,如时间戳、帧 ID 等
200 std_msgs::msg::Header header;
201 header.stamp(std::move(time));
202 header.frame_id(_frame_id);
203// 定义一个用于存储姿态(四元数表示)的对象
205// 设置俯仰角(这里固定为 0.0f)
206 const float rx = 0.0f; // pitch
207 const float ry = (M_PIf32 / 2.0f) - compass; // yaw
208 const float rz = 0.0f; // roll
209
210 const float cr = cosf(rz * 0.5f);
211 const float sr = sinf(rz * 0.5f);
212 const float cp = cosf(rx * 0.5f);
213 const float sp = sinf(rx * 0.5f);
214 const float cy = cosf(ry * 0.5f);
215 const float sy = sinf(ry * 0.5f);
216
217 orientation.w(cr * cp * cy + sr * sp * sy);
218 orientation.x(sr * cp * cy - cr * sp * sy);
219 orientation.y(cr * sp * cy + sr * cp * sy);
220 orientation.z(cr * cp * sy - sr * sp * cy);
221
222 _impl->_imu.header(std::move(header));
223 _impl->_imu.orientation(orientation);
224 _impl->_imu.angular_velocity(gyroscope);
225 _impl->_imu.linear_acceleration(linear_acceleration);
226 }
227
228 CarlaIMUPublisher::CarlaIMUPublisher(const char* ros_name, const char* parent) :
229 _impl(std::make_shared<CarlaIMUPublisherImpl>()) {
230 _name = ros_name;
231 _parent = parent;
232 }
233
235 if (!_impl)
236 return;
237
238 if (_impl->_datawriter)
239 _impl->_publisher->delete_datawriter(_impl->_datawriter);
240
241 if (_impl->_publisher)
242 _impl->_participant->delete_publisher(_impl->_publisher);
243
244 if (_impl->_topic)
245 _impl->_participant->delete_topic(_impl->_topic);
246
247 if (_impl->_participant)
248 efd::DomainParticipantFactory::get_instance()->delete_participant(_impl->_participant);
249 }
250
252 _frame_id = other._frame_id;
253 _name = other._name;
254 _parent = other._parent;
255 _impl = other._impl;
256 }
257
259 _frame_id = other._frame_id;
260 _name = other._name;
261 _parent = other._parent;
262 _impl = other._impl;
263
264 return *this;
265 }
266
268 _frame_id = std::move(other._frame_id);
269 _name = std::move(other._name);
270 _parent = std::move(other._parent);
271 _impl = std::move(other._impl);
272 }
273
275 _frame_id = std::move(other._frame_id);
276 _name = std::move(other._name);
277 _parent = std::move(other._parent);
278 _impl = std::move(other._impl);
279
280 return *this;
281 }
282}
283}
此类表示用户在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
CarlaIMUPublisher(const char *ros_name="", const char *parent="")
std::shared_ptr< CarlaIMUPublisherImpl > _impl
void SetData(int32_t seconds, uint32_t nanoseconds, float *accelerometer, float *gyroscope, float compass)
CarlaIMUPublisher & operator=(const CarlaIMUPublisher &)
const std::string & parent() const
This class represents the structure Quaternion defined by the user in the IDL file.
Definition Quaternion.h:71
eProsima_user_DllExport void x(double _x)
This function sets a value in member x
eProsima_user_DllExport void y(double _y)
This function sets a value in member y
eProsima_user_DllExport void z(double _z)
This function sets a value in member z
eProsima_user_DllExport void w(double _w)
This function sets a value in member w
此类表示用户在 IDL 文件中定义的 Vector3 结构。 <>
Definition Vector3.h:72
eProsima_user_DllExport void x(double _x)
设置成员 x 的值
Definition Vector3.cpp:150
eProsima_user_DllExport void z(double _z)
设置成员 z 的值
Definition Vector3.cpp:189
eProsima_user_DllExport void y(double _y)
设置成员 y 的值
Definition Vector3.cpp:170
This class represents the TopicDataType of the type Imu defined by the user in the IDL file.
This class represents the structure Imu defined by the user in the IDL file.
Definition Imu.h:76
Carlaе·عܵռ
eprosima::fastrtps::types::ReturnCode_t erc
@using erc
CARLA模拟器的主命名空间。
Definition Carla.cpp:139
efd::DomainParticipant * _participant