base_realsense_node.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365
  1. // Copyright 2023 Intel Corporation. All Rights Reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. #pragma once
  15. #include <librealsense2/rs.hpp>
  16. #include <librealsense2/rsutil.h>
  17. #include "constants.h"
  18. // cv_bridge.h last supported version is humble
  19. #if defined(CV_BRDIGE_HAS_HPP)
  20. #include <cv_bridge/cv_bridge.hpp>
  21. #else
  22. #include <cv_bridge/cv_bridge.h>
  23. #endif
  24. #include <diagnostic_updater/diagnostic_updater.hpp>
  25. #include <diagnostic_updater/publisher.hpp>
  26. #include "realsense2_camera_msgs/msg/imu_info.hpp"
  27. #include "realsense2_camera_msgs/msg/extrinsics.hpp"
  28. #include "realsense2_camera_msgs/msg/metadata.hpp"
  29. #include "realsense2_camera_msgs/msg/rgbd.hpp"
  30. #include "realsense2_camera_msgs/srv/device_info.hpp"
  31. #include <librealsense2/hpp/rs_processing.hpp>
  32. #include <librealsense2/rs_advanced_mode.hpp>
  33. #include <sensor_msgs/image_encodings.hpp>
  34. #include <sensor_msgs/msg/camera_info.hpp>
  35. #include <sensor_msgs/msg/image.hpp>
  36. #include <sensor_msgs/msg/imu.hpp>
  37. #include <tf2/LinearMath/Quaternion.h>
  38. #include <tf2_ros/transform_broadcaster.h>
  39. #include <tf2_ros/static_transform_broadcaster.h>
  40. #include <eigen3/Eigen/Geometry>
  41. #include <condition_variable>
  42. #include <ros_sensor.h>
  43. #include <named_filter.h>
  44. #if defined (ACCELERATE_GPU_WITH_GLSL)
  45. #include <gl_window.h>
  46. #endif
  47. #include <queue>
  48. #include <mutex>
  49. #include <atomic>
  50. #include <thread>
  51. using realsense2_camera_msgs::msg::Extrinsics;
  52. using realsense2_camera_msgs::msg::IMUInfo;
  53. using realsense2_camera_msgs::msg::RGBD;
  54. #define FRAME_ID(sip) (static_cast<std::ostringstream&&>(std::ostringstream() << _camera_name << "_" << STREAM_NAME(sip) << "_frame")).str()
  55. #define IMU_FRAME_ID (static_cast<std::ostringstream&&>(std::ostringstream() << _camera_name << "_imu_frame")).str()
  56. #define IMU_OPTICAL_FRAME_ID (static_cast<std::ostringstream&&>(std::ostringstream() << _camera_name << "_imu_optical_frame")).str()
  57. #define OPTICAL_FRAME_ID(sip) (static_cast<std::ostringstream&&>(std::ostringstream() << _camera_name << "_" << STREAM_NAME(sip) << "_optical_frame")).str()
  58. #define ALIGNED_DEPTH_TO_FRAME_ID(sip) (static_cast<std::ostringstream&&>(std::ostringstream() << _camera_name << "_" << "aligned_depth_to_" << STREAM_NAME(sip) << "_frame")).str()
  59. namespace realsense2_camera
  60. {
  61. typedef std::pair<rs2_stream, int> stream_index_pair;
  62. class image_publisher; // forward declaration
  63. class PipelineSyncer : public rs2::asynchronous_syncer
  64. {
  65. public:
  66. void operator()(rs2::frame f) const
  67. {
  68. invoke(std::move(f));
  69. }
  70. };
  71. class SyncedImuPublisher
  72. {
  73. public:
  74. SyncedImuPublisher(rclcpp::Publisher<sensor_msgs::msg::Imu>::SharedPtr imu_publisher,
  75. std::size_t waiting_list_size=1000);
  76. ~SyncedImuPublisher();
  77. void Pause(); // Pause sending messages. All messages from now on are saved in queue.
  78. void Resume(); // Send all pending messages and allow sending future messages.
  79. void Publish(sensor_msgs::msg::Imu msg); //either send or hold message.
  80. size_t getNumSubscribers();
  81. void Enable(bool is_enabled) {_is_enabled=is_enabled;};
  82. private:
  83. void PublishPendingMessages();
  84. private:
  85. std::mutex _mutex;
  86. rclcpp::Publisher<sensor_msgs::msg::Imu>::SharedPtr _publisher;
  87. bool _pause_mode;
  88. std::queue<sensor_msgs::msg::Imu> _pending_messages;
  89. std::size_t _waiting_list_size;
  90. bool _is_enabled;
  91. };
  92. class BaseRealSenseNode
  93. {
  94. public:
  95. BaseRealSenseNode(rclcpp::Node& node,
  96. rs2::device dev,
  97. std::shared_ptr<Parameters> parameters,
  98. bool use_intra_process = false);
  99. ~BaseRealSenseNode();
  100. void publishTopics();
  101. public:
  102. enum class imu_sync_method{NONE, COPY, LINEAR_INTERPOLATION};
  103. protected:
  104. class float3
  105. {
  106. public:
  107. float x, y, z;
  108. public:
  109. float3& operator*=(const float& factor)
  110. {
  111. x*=factor;
  112. y*=factor;
  113. z*=factor;
  114. return (*this);
  115. }
  116. float3& operator+=(const float3& other)
  117. {
  118. x+=other.x;
  119. y+=other.y;
  120. z+=other.z;
  121. return (*this);
  122. }
  123. };
  124. std::string _base_frame_id;
  125. bool _is_running;
  126. rclcpp::Node& _node;
  127. std::string _camera_name;
  128. std::vector<rs2_option> _monitor_options;
  129. rclcpp::Logger _logger;
  130. rclcpp::Service<realsense2_camera_msgs::srv::DeviceInfo>::SharedPtr _device_info_srv;
  131. std::shared_ptr<Parameters> _parameters;
  132. std::list<std::string> _parameters_names;
  133. void restartStaticTransformBroadcaster();
  134. void publishExtrinsicsTopic(const stream_index_pair& sip, const rs2_extrinsics& ex);
  135. void calcAndAppendTransformMsgs(const rs2::stream_profile& profile, const rs2::stream_profile& base_profile);
  136. void getDeviceInfo(const realsense2_camera_msgs::srv::DeviceInfo::Request::SharedPtr req,
  137. realsense2_camera_msgs::srv::DeviceInfo::Response::SharedPtr res);
  138. tf2::Quaternion rotationMatrixToQuaternion(const float rotation[9]) const;
  139. void append_static_tf_msg(const rclcpp::Time& t,
  140. const float3& trans,
  141. const tf2::Quaternion& q,
  142. const std::string& from,
  143. const std::string& to);
  144. void erase_static_tf_msg(const std::string& frame_id,
  145. const std::string& child_frame_id);
  146. void eraseTransformMsgs(const stream_index_pair& sip, const rs2::stream_profile& profile);
  147. void setup();
  148. private:
  149. class CimuData
  150. {
  151. public:
  152. CimuData() : m_time_ns(-1) {};
  153. CimuData(const stream_index_pair type, Eigen::Vector3d data, double time):
  154. m_type(type),
  155. m_data(data),
  156. m_time_ns(time){};
  157. bool is_set() {return m_time_ns > 0;};
  158. public:
  159. stream_index_pair m_type;
  160. Eigen::Vector3d m_data;
  161. double m_time_ns;
  162. };
  163. void getParameters();
  164. void setDynamicParams();
  165. void clearParameters();
  166. void setupDevice();
  167. void hardwareResetRequest();
  168. void setupPublishers();
  169. void enable_devices();
  170. void setupFilters();
  171. bool setBaseTime(double frame_time, rs2_timestamp_domain time_domain);
  172. uint64_t millisecondsToNanoseconds(double timestamp_ms);
  173. rclcpp::Time frameSystemTimeSec(rs2::frame frame);
  174. cv::Mat& fix_depth_scale(const cv::Mat& from_image, cv::Mat& to_image);
  175. void clip_depth(rs2::depth_frame depth_frame, float clipping_dist);
  176. void updateProfilesStreamCalibData(const std::vector<rs2::stream_profile>& profiles);
  177. void updateExtrinsicsCalibData(const rs2::video_stream_profile& left_video_profile, const rs2::video_stream_profile& right_video_profile);
  178. void updateStreamCalibData(const rs2::video_stream_profile& video_profile);
  179. void SetBaseStream();
  180. void publishStaticTransforms();
  181. void startDynamicTf();
  182. void publishDynamicTransforms();
  183. void publishPointCloud(rs2::points f, const rclcpp::Time& t, const rs2::frameset& frameset);
  184. Extrinsics rsExtrinsicsToMsg(const rs2_extrinsics& extrinsics) const;
  185. IMUInfo getImuInfo(const rs2::stream_profile& profile);
  186. void initializeFormatsMaps();
  187. bool fillROSImageMsgAndReturnStatus(
  188. const cv::Mat& cv_matrix_image,
  189. const stream_index_pair& stream,
  190. unsigned int width,
  191. unsigned int height,
  192. const rs2_format& stream_format,
  193. const rclcpp::Time& t,
  194. sensor_msgs::msg::Image* img_msg_ptr);
  195. bool fillCVMatImageAndReturnStatus(
  196. rs2::frame& frame,
  197. std::map<stream_index_pair, cv::Mat>& images,
  198. unsigned int width,
  199. unsigned int height,
  200. const stream_index_pair& stream);
  201. void publishFrame(
  202. rs2::frame f,
  203. const rclcpp::Time& t,
  204. const stream_index_pair& stream,
  205. std::map<stream_index_pair, cv::Mat>& images,
  206. const std::map<stream_index_pair, rclcpp::Publisher<sensor_msgs::msg::CameraInfo>::SharedPtr>& info_publishers,
  207. const std::map<stream_index_pair, std::shared_ptr<image_publisher>>& image_publishers,
  208. const bool is_publishMetadata = true);
  209. void publishRGBD(
  210. const cv::Mat& rgb_cv_matrix,
  211. const rs2_format& color_format,
  212. const cv::Mat& depth_cv_matrix,
  213. const rs2_format& depth_format,
  214. const rclcpp::Time& t);
  215. void publishMetadata(rs2::frame f, const rclcpp::Time& header_time, const std::string& frame_id);
  216. sensor_msgs::msg::Imu CreateUnitedMessage(const CimuData accel_data, const CimuData gyro_data);
  217. void FillImuData_Copy(const CimuData imu_data, std::deque<sensor_msgs::msg::Imu>& imu_msgs);
  218. void ImuMessage_AddDefaultValues(sensor_msgs::msg::Imu& imu_msg);
  219. void FillImuData_LinearInterpolation(const CimuData imu_data, std::deque<sensor_msgs::msg::Imu>& imu_msgs);
  220. void imu_callback(rs2::frame frame);
  221. void imu_callback_sync(rs2::frame frame, imu_sync_method sync_method=imu_sync_method::COPY);
  222. void multiple_message_callback(rs2::frame frame, imu_sync_method sync_method);
  223. void frame_callback(rs2::frame frame);
  224. void startDiagnosticsUpdater();
  225. void monitoringProfileChanges();
  226. void publish_temperature();
  227. void setAvailableSensors();
  228. void setCallbackFunctions();
  229. void updateSensors();
  230. void startUpdatedSensors();
  231. void stopRequiredSensors();
  232. void publishServices();
  233. void startPublishers(const std::vector<rs2::stream_profile>& profiles, const RosSensor& sensor);
  234. void startRGBDPublisherIfNeeded();
  235. void stopPublishers(const std::vector<rs2::stream_profile>& profiles);
  236. #if defined (ACCELERATE_GPU_WITH_GLSL)
  237. void initOpenGLProcessing(bool use_gpu_processing);
  238. void shutdownOpenGLProcessing();
  239. void glfwPollEventCallback();
  240. #endif
  241. rs2::device _dev;
  242. std::map<stream_index_pair, rs2::sensor> _sensors;
  243. std::map<std::string, std::function<void(rs2::frame)>> _sensors_callback;
  244. std::string _json_file_path;
  245. float _depth_scale_meters;
  246. float _clipping_distance;
  247. double _linear_accel_cov;
  248. double _angular_velocity_cov;
  249. bool _hold_back_imu_for_frames;
  250. std::map<stream_index_pair, bool> _enable;
  251. bool _publish_tf;
  252. double _tf_publish_rate, _diagnostics_period;
  253. std::mutex _publish_tf_mutex;
  254. std::mutex _update_sensor_mutex;
  255. std::mutex _profile_changes_mutex;
  256. std::mutex _publish_dynamic_tf_mutex;
  257. std::shared_ptr<tf2_ros::StaticTransformBroadcaster> _static_tf_broadcaster;
  258. std::shared_ptr<tf2_ros::TransformBroadcaster> _dynamic_tf_broadcaster;
  259. std::vector<geometry_msgs::msg::TransformStamped> _static_tf_msgs;
  260. std::shared_ptr<std::thread> _tf_t;
  261. bool _use_intra_process;
  262. std::map<stream_index_pair, std::shared_ptr<image_publisher>> _image_publishers;
  263. std::map<stream_index_pair, rclcpp::Publisher<sensor_msgs::msg::Imu>::SharedPtr> _imu_publishers;
  264. std::shared_ptr<SyncedImuPublisher> _synced_imu_publisher;
  265. std::map<stream_index_pair, rclcpp::Publisher<sensor_msgs::msg::CameraInfo>::SharedPtr> _info_publishers;
  266. std::map<stream_index_pair, rclcpp::Publisher<realsense2_camera_msgs::msg::Metadata>::SharedPtr> _metadata_publishers;
  267. std::map<stream_index_pair, rclcpp::Publisher<IMUInfo>::SharedPtr> _imu_info_publishers;
  268. std::map<stream_index_pair, rclcpp::Publisher<Extrinsics>::SharedPtr> _extrinsics_publishers;
  269. rclcpp::Publisher<realsense2_camera_msgs::msg::RGBD>::SharedPtr _rgbd_publisher;
  270. std::map<stream_index_pair, cv::Mat> _images;
  271. std::map<rs2_format, std::string> _rs_format_to_ros_format;
  272. std::map<rs2_format, int> _rs_format_to_cv_format;
  273. std::map<stream_index_pair, sensor_msgs::msg::CameraInfo> _camera_info;
  274. std::atomic_bool _is_initialized_time_base;
  275. double _camera_time_base;
  276. rclcpp::Time _ros_time_base;
  277. bool _sync_frames;
  278. bool _enable_rgbd;
  279. bool _is_color_enabled;
  280. bool _is_depth_enabled;
  281. bool _is_accel_enabled;
  282. bool _is_gyro_enabled;
  283. bool _pointcloud;
  284. imu_sync_method _imu_sync_method;
  285. stream_index_pair _pointcloud_texture;
  286. PipelineSyncer _syncer;
  287. rs2::asynchronous_syncer _asyncer;
  288. std::shared_ptr<NamedFilter> _colorizer_filter;
  289. std::shared_ptr<AlignDepthFilter> _align_depth_filter;
  290. std::shared_ptr<PointcloudFilter> _pc_filter;
  291. std::vector<std::shared_ptr<NamedFilter>> _filters;
  292. std::vector<rs2::sensor> _dev_sensors;
  293. std::vector<std::unique_ptr<RosSensor>> _available_ros_sensors;
  294. std::map<rs2_stream, std::shared_ptr<rs2::align>> _align;
  295. std::map<stream_index_pair, cv::Mat> _depth_aligned_image;
  296. std::map<stream_index_pair, cv::Mat> _depth_scaled_image;
  297. std::map<stream_index_pair, rclcpp::Publisher<sensor_msgs::msg::CameraInfo>::SharedPtr> _depth_aligned_info_publisher;
  298. std::map<stream_index_pair, std::shared_ptr<image_publisher>> _depth_aligned_image_publishers;
  299. std::map<std::string, rs2::region_of_interest> _auto_exposure_roi;
  300. std::map<rs2_stream, bool> _is_first_frame;
  301. std::shared_ptr<std::thread> _monitoring_t;
  302. std::shared_ptr<std::thread> _monitoring_pc; //pc = profile changes
  303. mutable std::condition_variable _cv_temp, _cv_mpc, _cv_tf;
  304. bool _is_profile_changed;
  305. bool _is_align_depth_changed;
  306. std::shared_ptr<diagnostic_updater::Updater> _diagnostics_updater;
  307. rs2::stream_profile _base_profile;
  308. #if defined (ACCELERATE_GPU_WITH_GLSL)
  309. GLwindow _app;
  310. rclcpp::TimerBase::SharedPtr _timer;
  311. bool _accelerate_gpu_with_glsl;
  312. bool _is_accelerate_gpu_with_glsl_changed;
  313. #endif
  314. };//end class
  315. }