Go to the documentation of this file.00001
00002
00003
00004 #include "../include/realsense_node_factory.h"
00005 #include "../include/base_realsense_node.h"
00006 #include "../include/t265_realsense_node.h"
00007 #include <iostream>
00008 #include <map>
00009 #include <mutex>
00010 #include <condition_variable>
00011 #include <signal.h>
00012 #include <thread>
00013 #include <sys/time.h>
00014
00015 using namespace realsense2_camera;
00016
00017 #define REALSENSE_ROS_EMBEDDED_VERSION_STR (VAR_ARG_STRING(VERSION: REALSENSE_ROS_MAJOR_VERSION.REALSENSE_ROS_MINOR_VERSION.REALSENSE_ROS_PATCH_VERSION))
00018 constexpr auto realsense_ros_camera_version = REALSENSE_ROS_EMBEDDED_VERSION_STR;
00019
00020 PLUGINLIB_EXPORT_CLASS(realsense2_camera::RealSenseNodeFactory, nodelet::Nodelet)
00021
00022 RealSenseNodeFactory::RealSenseNodeFactory()
00023 {
00024 ROS_INFO("RealSense ROS v%s", REALSENSE_ROS_VERSION_STR);
00025 ROS_INFO("Running with LibRealSense v%s", RS2_API_VERSION_STR);
00026
00027 auto severity = rs2_log_severity::RS2_LOG_SEVERITY_WARN;
00028 tryGetLogSeverity(severity);
00029 if (rs2_log_severity::RS2_LOG_SEVERITY_DEBUG == severity)
00030 ros::console::set_logger_level(ROSCONSOLE_DEFAULT_NAME, ros::console::levels::Debug);
00031
00032 rs2::log_to_console(severity);
00033 }
00034
00035 void RealSenseNodeFactory::closeDevice()
00036 {
00037 for(rs2::sensor sensor : _device.query_sensors())
00038 {
00039 sensor.stop();
00040 sensor.close();
00041 }
00042 }
00043
00044 RealSenseNodeFactory::~RealSenseNodeFactory()
00045 {
00046 closeDevice();
00047 }
00048
00049 void RealSenseNodeFactory::getDevice(rs2::device_list list)
00050 {
00051 if (!_device)
00052 {
00053 if (0 == list.size())
00054 {
00055 ROS_WARN("No RealSense devices were found!");
00056 }
00057 else
00058 {
00059 bool found = false;
00060 for (auto&& dev : list)
00061 {
00062 auto sn = dev.get_info(RS2_CAMERA_INFO_SERIAL_NUMBER);
00063 ROS_DEBUG_STREAM("Device with serial number " << sn << " was found.");
00064 if (_serial_no.empty() || sn == _serial_no)
00065 {
00066 _device = dev;
00067 _serial_no = sn;
00068 found = true;
00069 break;
00070 }
00071 }
00072 if (!found)
00073 {
00074
00075 ROS_ERROR_STREAM("The requested device with serial number " << _serial_no << " is NOT found. Will Try again.");
00076 }
00077 }
00078 }
00079
00080 bool remove_tm2_handle(_device && RS_T265_PID != std::stoi(_device.get_info(RS2_CAMERA_INFO_PRODUCT_ID), 0, 16));
00081 if (remove_tm2_handle)
00082 {
00083 _ctx.unload_tracking_module();
00084 }
00085
00086 if (_device && _initial_reset)
00087 {
00088 _initial_reset = false;
00089 try
00090 {
00091 ROS_INFO("Resetting device...");
00092 _device.hardware_reset();
00093 _device = rs2::device();
00094
00095 }
00096 catch(const std::exception& ex)
00097 {
00098 ROS_WARN_STREAM("An exception has been thrown: " << ex.what());
00099 }
00100 }
00101 }
00102
00103 void RealSenseNodeFactory::change_device_callback(rs2::event_information& info)
00104 {
00105 if (info.was_removed(_device))
00106 {
00107 ROS_ERROR("The device has been disconnected!");
00108 _realSenseNode.reset(nullptr);
00109 _device = rs2::device();
00110 }
00111 if (!_device)
00112 {
00113 rs2::device_list new_devices = info.get_new_devices();
00114 if (new_devices.size() > 0)
00115 {
00116 ROS_INFO("Checking new devices...");
00117 getDevice(new_devices);
00118 if (_device)
00119 {
00120 StartDevice();
00121 }
00122 }
00123 }
00124 }
00125
00126 void RealSenseNodeFactory::onInit()
00127 {
00128 try
00129 {
00130 #ifdef BPDEBUG
00131 std::cout << "Attach to Process: " << getpid() << std::endl;
00132 std::cout << "Press <ENTER> key to continue." << std::endl;
00133 std::cin.get();
00134 #endif
00135 ros::NodeHandle nh = getNodeHandle();
00136 auto privateNh = getPrivateNodeHandle();
00137 privateNh.param("serial_no", _serial_no, std::string(""));
00138
00139 std::string rosbag_filename("");
00140 privateNh.param("rosbag_filename", rosbag_filename, std::string(""));
00141 if (!rosbag_filename.empty())
00142 {
00143 {
00144 ROS_INFO_STREAM("publish topics from rosbag file: " << rosbag_filename.c_str());
00145 auto pipe = std::make_shared<rs2::pipeline>();
00146 rs2::config cfg;
00147 cfg.enable_device_from_file(rosbag_filename.c_str(), false);
00148 cfg.enable_all_streams();
00149 pipe->start(cfg);
00150 _device = pipe->get_active_profile().get_device();
00151 _realSenseNode = std::unique_ptr<BaseRealSenseNode>(new BaseRealSenseNode(nh, privateNh, _device, _serial_no));
00152 _realSenseNode->publishTopics();
00153 _realSenseNode->registerDynamicReconfigCb(nh);
00154 }
00155 if (_device)
00156 {
00157 StartDevice();
00158 }
00159 }
00160 else
00161 {
00162 privateNh.param("initial_reset", _initial_reset, false);
00163
00164 _query_thread = std::thread([=]()
00165 {
00166 std::chrono::milliseconds timespan(6000);
00167 while (!_device)
00168 {
00169
00170 getDevice(_ctx.query_devices());
00171 if (_device)
00172 {
00173 std::function<void(rs2::event_information&)> change_device_callback_function = [this](rs2::event_information& info){change_device_callback(info);};
00174 _ctx.set_devices_changed_callback(change_device_callback_function);
00175 StartDevice();
00176 }
00177 else
00178 {
00179 std::this_thread::sleep_for(timespan);
00180 }
00181 }
00182 });
00183 }
00184 }
00185 catch(const std::exception& ex)
00186 {
00187 ROS_ERROR_STREAM("An exception has been thrown: " << ex.what());
00188 exit(1);
00189 }
00190 catch(...)
00191 {
00192 ROS_ERROR_STREAM("Unknown exception has occured!");
00193 exit(1);
00194 }
00195 }
00196
00197 void RealSenseNodeFactory::StartDevice()
00198 {
00199 ros::NodeHandle nh = getNodeHandle();
00200 ros::NodeHandle privateNh = getPrivateNodeHandle();
00201
00202 std::string pid_str(_device.get_info(RS2_CAMERA_INFO_PRODUCT_ID));
00203 uint16_t pid = std::stoi(pid_str, 0, 16);
00204 switch(pid)
00205 {
00206 case SR300_PID:
00207 case RS400_PID:
00208 case RS405_PID:
00209 case RS410_PID:
00210 case RS460_PID:
00211 case RS415_PID:
00212 case RS420_PID:
00213 case RS420_MM_PID:
00214 case RS430_PID:
00215 case RS430_MM_PID:
00216 case RS430_MM_RGB_PID:
00217 case RS435_RGB_PID:
00218 case RS435i_RGB_PID:
00219 case RS_USB2_PID:
00220 _realSenseNode = std::unique_ptr<BaseRealSenseNode>(new BaseRealSenseNode(nh, privateNh, _device, _serial_no));
00221 break;
00222 case RS_T265_PID:
00223 _realSenseNode = std::unique_ptr<T265RealsenseNode>(new T265RealsenseNode(nh, privateNh, _device, _serial_no));
00224 break;
00225 default:
00226 ROS_FATAL_STREAM("Unsupported device!" << " Product ID: 0x" << pid_str);
00227 ros::shutdown();
00228 exit(1);
00229 }
00230 assert(_realSenseNode);
00231 _realSenseNode->publishTopics();
00232 _realSenseNode->registerDynamicReconfigCb(nh);
00233 }
00234
00235 void RealSenseNodeFactory::tryGetLogSeverity(rs2_log_severity& severity) const
00236 {
00237 static const char* severity_var_name = "LRS_LOG_LEVEL";
00238 auto content = getenv(severity_var_name);
00239
00240 if (content)
00241 {
00242 std::string content_str(content);
00243 std::transform(content_str.begin(), content_str.end(), content_str.begin(), ::toupper);
00244
00245 for (uint32_t i = 0; i < RS2_LOG_SEVERITY_COUNT; i++)
00246 {
00247 auto current = std::string(rs2_log_severity_to_string((rs2_log_severity)i));
00248 std::transform(current.begin(), current.end(), current.begin(), ::toupper);
00249 if (content_str == current)
00250 {
00251 severity = (rs2_log_severity)i;
00252 break;
00253 }
00254 }
00255 }
00256 }