1 #define _GLIBCXX_USE_CXX11_ABI 0 12 #include <fastdds/dds/domain/DomainParticipant.hpp> 13 #include <fastdds/dds/publisher/Publisher.hpp> 14 #include <fastdds/dds/topic/Topic.hpp> 15 #include <fastdds/dds/publisher/DataWriter.hpp> 16 #include <fastdds/dds/topic/TypeSupport.hpp> 18 #include <fastdds/dds/domain/qos/DomainParticipantQos.hpp> 19 #include <fastdds/dds/domain/DomainParticipantFactory.hpp> 20 #include <fastdds/dds/publisher/qos/PublisherQos.hpp> 21 #include <fastdds/dds/topic/qos/TopicQos.hpp> 23 #include <fastrtps/attributes/ParticipantAttributes.h> 24 #include <fastrtps/qos/QosPolicies.h> 25 #include <fastdds/dds/publisher/qos/DataWriterQos.hpp> 26 #include <fastdds/dds/publisher/DataWriterListener.hpp> 28 template <
typename T> T
CLAMP(
const T& value,
const T& low,
const T& high)
30 return value < low ? low : (value > high ? high : value);
36 namespace efd = eprosima::fastdds::dds;
37 using erc = eprosima::fastrtps::types::ReturnCode_t;
51 efd::Topic*
_topic {
nullptr };
60 return _impl_info->_init;
65 SetInfoRegionOfInterest(x_offset, y_offset, height, width, do_rectify);
66 _impl_info->_init =
true;
70 return InitImage() && InitInfo();
74 if (_impl->_type ==
nullptr) {
75 std::cerr <<
"Invalid TypeSupport" << std::endl;
79 efd::DomainParticipantQos pqos = efd::PARTICIPANT_QOS_DEFAULT;
81 auto factory = efd::DomainParticipantFactory::get_instance();
82 _impl->_participant = factory->create_participant(0, pqos);
83 if (_impl->_participant ==
nullptr) {
84 std::cerr <<
"Failed to create DomainParticipant" << std::endl;
87 _impl->_type.register_type(_impl->_participant);
89 efd::PublisherQos pubqos = efd::PUBLISHER_QOS_DEFAULT;
90 _impl->_publisher = _impl->_participant->create_publisher(pubqos,
nullptr);
91 if (_impl->_publisher ==
nullptr) {
92 std::cerr <<
"Failed to create Publisher" << std::endl;
96 efd::TopicQos tqos = efd::TOPIC_QOS_DEFAULT;
97 const std::string publisher_type {
"/image"};
98 const std::string base {
"rt/carla/" };
99 std::string topic_name = base;
100 if (!_parent.empty())
101 topic_name += _parent +
"/";
103 topic_name += publisher_type;
104 _impl->_topic = _impl->_participant->create_topic(topic_name, _impl->_type->getName(), tqos);
105 if (_impl->_topic ==
nullptr) {
106 std::cerr <<
"Failed to create Topic" << std::endl;
110 efd::DataWriterQos wqos = efd::DATAWRITER_QOS_DEFAULT;
111 wqos.endpoint().history_memory_policy = eprosima::fastrtps::rtps::PREALLOCATED_WITH_REALLOC_MEMORY_MODE;
112 efd::DataWriterListener* listener = (efd::DataWriterListener*)_impl->_listener._impl.get();
113 _impl->_datawriter = _impl->_publisher->create_datawriter(_impl->_topic, wqos, listener);
114 if (_impl->_datawriter ==
nullptr) {
115 std::cerr <<
"Failed to create DataWriter" << std::endl;
123 if (_impl_info->_type ==
nullptr) {
124 std::cerr <<
"Invalid TypeSupport" << std::endl;
128 efd::DomainParticipantQos pqos = efd::PARTICIPANT_QOS_DEFAULT;
130 auto factory = efd::DomainParticipantFactory::get_instance();
131 _impl_info->_participant = factory->create_participant(0, pqos);
132 if (_impl_info->_participant ==
nullptr) {
133 std::cerr <<
"Failed to create DomainParticipant" << std::endl;
136 _impl_info->_type.register_type(_impl_info->_participant);
138 efd::PublisherQos pubqos = efd::PUBLISHER_QOS_DEFAULT;
139 _impl_info->_publisher = _impl_info->_participant->create_publisher(pubqos,
nullptr);
140 if (_impl_info->_publisher ==
nullptr) {
141 std::cerr <<
"Failed to create Publisher" << std::endl;
145 efd::TopicQos tqos = efd::TOPIC_QOS_DEFAULT;
146 const std::string publisher_type {
"/camera_info"};
147 const std::string base {
"rt/carla/" };
148 std::string topic_name = base;
149 if (!_parent.empty())
150 topic_name += _parent +
"/";
152 topic_name += publisher_type;
153 _impl_info->_topic = _impl_info->_participant->create_topic(topic_name, _impl_info->_type->getName(), tqos);
154 if (_impl_info->_topic ==
nullptr) {
155 std::cerr <<
"Failed to create Topic" << std::endl;
158 efd::DataWriterQos wqos = efd::DATAWRITER_QOS_DEFAULT;
159 efd::DataWriterListener* listener = (efd::DataWriterListener*)_impl_info->_listener._impl.get();
160 _impl_info->_datawriter = _impl_info->_publisher->create_datawriter(_impl_info->_topic, wqos, listener);
161 if (_impl_info->_datawriter ==
nullptr) {
162 std::cerr <<
"Failed to create DataWriter" << std::endl;
171 return PublishImage() && PublishInfo();
176 eprosima::fastrtps::types::ReturnCode_t rcode = _impl->_datawriter->write(&_impl->_image, instance_handle);
177 if (rcode == erc::ReturnCodeValue::RETCODE_OK) {
180 if (rcode == erc::ReturnCodeValue::RETCODE_ERROR) {
181 std::cerr <<
"RETCODE_ERROR" << std::endl;
184 if (rcode == erc::ReturnCodeValue::RETCODE_UNSUPPORTED) {
185 std::cerr <<
"RETCODE_UNSUPPORTED" << std::endl;
188 if (rcode == erc::ReturnCodeValue::RETCODE_BAD_PARAMETER) {
189 std::cerr <<
"RETCODE_BAD_PARAMETER" << std::endl;
192 if (rcode == erc::ReturnCodeValue::RETCODE_PRECONDITION_NOT_MET) {
193 std::cerr <<
"RETCODE_PRECONDITION_NOT_MET" << std::endl;
196 if (rcode == erc::ReturnCodeValue::RETCODE_OUT_OF_RESOURCES) {
197 std::cerr <<
"RETCODE_OUT_OF_RESOURCES" << std::endl;
200 if (rcode == erc::ReturnCodeValue::RETCODE_NOT_ENABLED) {
201 std::cerr <<
"RETCODE_NOT_ENABLED" << std::endl;
204 if (rcode == erc::ReturnCodeValue::RETCODE_IMMUTABLE_POLICY) {
205 std::cerr <<
"RETCODE_IMMUTABLE_POLICY" << std::endl;
208 if (rcode == erc::ReturnCodeValue::RETCODE_INCONSISTENT_POLICY) {
209 std::cerr <<
"RETCODE_INCONSISTENT_POLICY" << std::endl;
212 if (rcode == erc::ReturnCodeValue::RETCODE_ALREADY_DELETED) {
213 std::cerr <<
"RETCODE_ALREADY_DELETED" << std::endl;
216 if (rcode == erc::ReturnCodeValue::RETCODE_TIMEOUT) {
217 std::cerr <<
"RETCODE_TIMEOUT" << std::endl;
220 if (rcode == erc::ReturnCodeValue::RETCODE_NO_DATA) {
221 std::cerr <<
"RETCODE_NO_DATA" << std::endl;
224 if (rcode == erc::ReturnCodeValue::RETCODE_ILLEGAL_OPERATION) {
225 std::cerr <<
"RETCODE_ILLEGAL_OPERATION" << std::endl;
228 if (rcode == erc::ReturnCodeValue::RETCODE_NOT_ALLOWED_BY_SECURITY) {
229 std::cerr <<
"RETCODE_NOT_ALLOWED_BY_SECURITY" << std::endl;
232 std::cerr <<
"UNKNOWN" << std::endl;
238 eprosima::fastrtps::types::ReturnCode_t rcode = _impl_info->_datawriter->write(&_impl_info->_info, instance_handle);
239 if (rcode == erc::ReturnCodeValue::RETCODE_OK) {
242 if (rcode == erc::ReturnCodeValue::RETCODE_ERROR) {
243 std::cerr <<
"RETCODE_ERROR" << std::endl;
246 if (rcode == erc::ReturnCodeValue::RETCODE_UNSUPPORTED) {
247 std::cerr <<
"RETCODE_UNSUPPORTED" << std::endl;
250 if (rcode == erc::ReturnCodeValue::RETCODE_BAD_PARAMETER) {
251 std::cerr <<
"RETCODE_BAD_PARAMETER" << std::endl;
254 if (rcode == erc::ReturnCodeValue::RETCODE_PRECONDITION_NOT_MET) {
255 std::cerr <<
"RETCODE_PRECONDITION_NOT_MET" << std::endl;
258 if (rcode == erc::ReturnCodeValue::RETCODE_OUT_OF_RESOURCES) {
259 std::cerr <<
"RETCODE_OUT_OF_RESOURCES" << std::endl;
262 if (rcode == erc::ReturnCodeValue::RETCODE_NOT_ENABLED) {
263 std::cerr <<
"RETCODE_NOT_ENABLED" << std::endl;
266 if (rcode == erc::ReturnCodeValue::RETCODE_IMMUTABLE_POLICY) {
267 std::cerr <<
"RETCODE_IMMUTABLE_POLICY" << std::endl;
270 if (rcode == erc::ReturnCodeValue::RETCODE_INCONSISTENT_POLICY) {
271 std::cerr <<
"RETCODE_INCONSISTENT_POLICY" << std::endl;
274 if (rcode == erc::ReturnCodeValue::RETCODE_ALREADY_DELETED) {
275 std::cerr <<
"RETCODE_ALREADY_DELETED" << std::endl;
278 if (rcode == erc::ReturnCodeValue::RETCODE_TIMEOUT) {
279 std::cerr <<
"RETCODE_TIMEOUT" << std::endl;
282 if (rcode == erc::ReturnCodeValue::RETCODE_NO_DATA) {
283 std::cerr <<
"RETCODE_NO_DATA" << std::endl;
286 if (rcode == erc::ReturnCodeValue::RETCODE_ILLEGAL_OPERATION) {
287 std::cerr <<
"RETCODE_ILLEGAL_OPERATION" << std::endl;
290 if (rcode == erc::ReturnCodeValue::RETCODE_NOT_ALLOWED_BY_SECURITY) {
291 std::cerr <<
"RETCODE_NOT_ALLOWED_BY_SECURITY" << std::endl;
294 std::cerr <<
"UNKNOWN" << std::endl;
299 constexpr
float pi = 3.1415f;
300 constexpr
float rad2ang = 360.0f/(2.0f*pi);
301 const size_t max_index = width * height * 2;
302 std::vector<uint8_t> vector_data;
303 vector_data.resize(height * width * 4);
304 size_t data_index = 0;
305 for (
size_t index = 0; index < max_index; index += 2) {
306 const float vx = data[index];
307 const float vy = data[index + 1];
308 float angle = 180.0f + std::atan2(vy, vx) * rad2ang;
311 angle = 360.0f + angle;
313 angle = std::fmod(angle, 360.0f);
315 const float norm = std::sqrt(vx * vx + vy * vy);
316 const float shift = 0.999f;
317 const float a = 1.0f /
std::log(0.1f + shift);
318 const float intensity = CLAMP<float>(a *
std::log(norm + shift), 0.0f, 1.0f);
320 const float& H = angle;
321 const float S = 1.0f;
322 const float V = intensity;
323 const float H_60 = H * (1.0f / 60.0f);
325 const float C = V * S;
326 const float X = C * (1.0f - std::abs(std::fmod(H_60, 2.0f) - 1.0f));
327 const float m = V - C;
332 const unsigned int angle_case =
static_cast<const unsigned int>(H_60);
333 switch (angle_case) {
371 const uint8_t
R =
static_cast<uint8_t
>((r + m) * 255.0f);
372 const uint8_t G =
static_cast<uint8_t
>((g + m) * 255.0f);
373 const uint8_t B =
static_cast<uint8_t
>((b + m) * 255.0f);
375 vector_data[data_index++] = B;
376 vector_data[data_index++] = G;
377 vector_data[data_index++] =
R;
378 vector_data[data_index++] = 0;
380 SetData(seconds, nanoseconds, height, width, std::move(vector_data));
390 _impl_info->_info.roi(roi);
399 header.
stamp(std::move(time));
402 _impl->_image.header(std::move(header));
403 _impl->_image.width(width);
404 _impl->_image.height(height);
405 _impl->_image.encoding(
"bgra8");
406 _impl->_image.is_bigendian(0);
407 _impl->_image.step(_impl->_image.width() *
sizeof(uint8_t) * 4);
408 _impl->_image.data(std::move(data));
417 header.
stamp(std::move(time));
419 _impl_info->_info.header(header);
433 if (
_impl->_datawriter)
434 _impl->_publisher->delete_datawriter(
_impl->_datawriter);
436 if (
_impl->_publisher)
437 _impl->_participant->delete_publisher(
_impl->_publisher);
440 _impl->_participant->delete_topic(
_impl->_topic);
442 if (
_impl->_participant)
443 efd::DomainParticipantFactory::get_instance()->delete_participant(
_impl->_participant);
458 efd::DomainParticipantFactory::get_instance()->delete_participant(
_impl_info->_participant);
481 _name = std::move(other._name);
482 _parent = std::move(other._parent);
483 _impl = std::move(other._impl);
490 _name = std::move(other._name);
491 _parent = std::move(other._parent);
492 _impl = std::move(other._impl);
~CarlaOpticalFlowCameraPublisher()
static void log(Args &&... args)
efd::Publisher * _publisher
carla::rpc::Response< T > R
eprosima::fastrtps::rtps::InstanceHandle_t InstanceHandle_t
eprosima::fastrtps::types::ReturnCode_t erc
This file contains definitions of common data structures used in traffic manager. ...
efd::DomainParticipant * _participant
efd::DataWriter * _datawriter
This class represents the structure CameraInfo defined by the user in the IDL file.
void SetInfoRegionOfInterest(uint32_t x_offset, uint32_t y_offset, uint32_t height, uint32_t width, bool do_rectify)
This class represents the structure Image defined by the user in the IDL file.
void SetCameraInfoData(int32_t seconds, uint32_t nanoseconds)
sensor_msgs::msg::Image _image
CarlaOpticalFlowCameraPublisher(const char *ros_name="", const char *parent="")
eProsima_user_DllExport void width(uint32_t _width)
This function sets a value in member width.
This class represents the TopicDataType of the type Image defined by the user in the IDL file...
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)
eProsima_user_DllExport void x_offset(uint32_t _x_offset)
This function sets a value in member x_offset.
eProsima_user_DllExport void sec(int32_t _sec)
This function sets a value in member sec.
This class represents the TopicDataType of the type CameraInfo defined by the user in the IDL file...
eProsima_user_DllExport void nanosec(uint32_t _nanosec)
This function sets a value in member nanosec.
T CLAMP(const T &value, const T &low, const T &high)
bool HasBeenInitialized() const
This class represents the structure RegionOfInterest defined by the user in the IDL file...
const std::string & parent() const
std::shared_ptr< CarlaOpticalFlowCameraPublisherImpl > _impl
This class represents the structure Time defined by the user in the IDL file.
CarlaOpticalFlowCameraPublisher & operator=(const CarlaOpticalFlowCameraPublisher &)
void SetImageData(int32_t seconds, uint32_t nanoseconds, size_t height, size_t width, const float *data)
eProsima_user_DllExport void height(uint32_t _height)
This function sets a value in member height.
eProsima_user_DllExport void y_offset(uint32_t _y_offset)
This function sets a value in member y_offset.
std::shared_ptr< CarlaCameraInfoPublisherImpl > _impl_info
eProsima_user_DllExport void do_rectify(bool _do_rectify)
This function sets a value in member do_rectify.