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>
28template <
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;
48 struct CarlaCameraInfoPublisherImpl {
51 efd::Topic*
_topic {
nullptr };
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;
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;
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;
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);
133 std::cerr <<
"Failed to create DomainParticipant" << std::endl;
138 efd::PublisherQos pubqos = efd::PUBLISHER_QOS_DEFAULT;
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;
152 topic_name += publisher_type;
155 std::cerr <<
"Failed to create Topic" << std::endl;
158 efd::DataWriterQos wqos = efd::DATAWRITER_QOS_DEFAULT;
162 std::cerr <<
"Failed to create DataWriter" << std::endl;
175 eprosima::fastrtps::rtps::InstanceHandle_t instance_handle;
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;
237 eprosima::fastrtps::rtps::InstanceHandle_t instance_handle;
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));
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));
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);
T CLAMP(const T &value, const T &low, const T &high)
carla::rpc::Response< T > R
This class represents the structure Time defined by the user in the IDL file.
eProsima_user_DllExport void nanosec(uint32_t _nanosec)
This function sets a value in member nanosec
eProsima_user_DllExport void sec(int32_t _sec)
This function sets a value in member sec
void InitInfoData(uint32_t x_offset, uint32_t y_offset, uint32_t height, uint32_t width, float fov, bool do_rectify)
CarlaOpticalFlowCameraPublisher & operator=(const CarlaOpticalFlowCameraPublisher &)
void SetImageData(int32_t seconds, uint32_t nanoseconds, size_t height, size_t width, const float *data)
void SetInfoRegionOfInterest(uint32_t x_offset, uint32_t y_offset, uint32_t height, uint32_t width, bool do_rectify)
bool HasBeenInitialized() const
void SetCameraInfoData(int32_t seconds, uint32_t nanoseconds)
CarlaOpticalFlowCameraPublisher(const char *ros_name="", const char *parent="")
void SetData(int32_t seconds, uint32_t nanoseconds, size_t height, size_t width, std::vector< uint8_t > &&data)
std::shared_ptr< CarlaOpticalFlowCameraPublisherImpl > _impl
~CarlaOpticalFlowCameraPublisher()
std::shared_ptr< CarlaCameraInfoPublisherImpl > _impl_info
const std::string & parent() const
This class represents the TopicDataType of the type CameraInfo defined by the user in the IDL file.
This class represents the structure CameraInfo defined by the user in the IDL file.
This class represents the TopicDataType of the type Image defined by the user in the IDL file.
This class represents the structure Image defined by the user in the IDL file.
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
This file contains definitions of common data structures used in traffic manager.
sensor_msgs::msg::CameraInfo _info
efd::DomainParticipant * _participant
efd::DataWriter * _datawriter
efd::Publisher * _publisher
sensor_msgs::msg::Image _image
efd::DomainParticipant * _participant
efd::Publisher * _publisher
efd::DataWriter * _datawriter