51 #include <rc_genicam_api/config.h> 63 #include <geometry_msgs/PoseWithCovarianceStamped.h> 65 #include <rc_common_msgs/ReturnCodeConstants.h> 66 #include <rc_common_msgs/CameraParam.h> 71 bool isRcVisardDevice(
const std::string& vendor,
const std::string& model)
73 bool isKuka3DPerception = vendor.find(
"KUKA") != std::string::npos && model.find(
"3d_perception") != std::string::npos;
74 bool isRcVisard = model.find(
"rc_visard") != std::string::npos;
75 return isKuka3DPerception || isRcVisard;
79 std::vector<std::string> discoverRcVisardDevices()
81 std::vector<std::string> device_ids;
85 for (
auto interf : system->getInterfaces())
88 for (
auto dev : interf->getDevices())
90 if (isRcVisardDevice(dev->getVendor(), dev->getModel()))
92 device_ids.push_back(dev->getID());
105 namespace rcd = dynamics;
106 using rc_common_msgs::ReturnCodeConstants;
110 const std::string& frame_id_prefix,
bool tfEnabled,
111 bool staticImu2CamTf)
113 if (stream ==
"pose")
117 if (stream ==
"pose_ins" || stream ==
"pose_rt" || stream ==
"pose_rt_ins" || stream ==
"imu")
121 if (stream ==
"dynamics" || stream ==
"dynamics_ins")
126 throw std::runtime_error(std::string(
"Not yet implemented! Stream type: ") + stream);
158 std::cout <<
"rc_visard_driver: Shutting down" << std::endl;
195 std::string device =
"";
196 std::string access =
"control";
202 tfPrefix = (ns !=
"") ? ns +
"_" :
"";
204 pnh.
param(
"device", device, device);
205 pnh.
param(
"gev_access", access, access);
214 if (access ==
"exclusive")
218 else if (access ==
"control")
222 else if (access ==
"off")
228 ROS_FATAL_STREAM(
"rc_visard_driver: Access must be 'control', 'exclusive' or 'off': " << access);
271 ROS_INFO(
"rc_visard_driver: Device successfully recovered from previous fail(s)!");
298 bool successfullyOpened =
false;
308 ROS_ERROR_STREAM(
"rc_visard_driver: Failed or lost connection. Trying to recover" 309 " rc_visard_driver from failed state (" 323 if (device.size() == 0)
325 ROS_INFO(
"No device ID given in the private parameter 'device'! Trying to auto-detect a single rc_visard device in the network...");
326 auto device_ids = discoverRcVisardDevices();
327 if (device_ids.size() != 1)
330 throw std::runtime_error(
"Auto-connection with rc_visard device failed because none or multiple devices were found!");
341 throw std::invalid_argument(
"Unknown or non-unique device '" + device +
"'");
354 ROS_INFO_STREAM(
"rc_visard_driver: rc_visard device not yet ready (GEV). Trying again...");
357 }
catch (std::invalid_argument& e)
380 ROS_INFO_STREAM(
"rc_visard_driver: rc_visard device not yet ready (REST). Trying again...");
383 }
catch (std::exception& e)
385 ROS_ERROR_STREAM(
"rc_visard_driver: checking system ready failed: " << e.what());
394 rc_common_msgs::Trigger::Request dummyreq;
395 rc_common_msgs::Trigger::Response dummyresp;
397 bool autostart_failed =
false;
400 autostart_failed |= dummyresp.return_code.value < ReturnCodeConstants::SUCCESS;
402 if (autostart_failed)
404 ROS_WARN_STREAM(
"rc_visard_driver: Could not auto-start dynamics module! " << dummyresp.return_code.message);
412 bool staticImu2CamTf =
false;
417 pbFrame.set_name(
tfPrefix + pbFrame.name());
418 pbFrame.set_parent(
tfPrefix + pbFrame.parent());
424 pbFrame.name(), pbFrame.parent());
426 geometry_msgs::TransformStamped
msg;
429 staticImu2CamTf =
true;
431 }
catch (rcd::RemoteInterface::NotAvailable& e)
433 ROS_WARN_STREAM(
"rc_visard_driver: Could not get and publish static transformation between camera and IMU " 434 <<
"because feature is not avilable in that rc_visard firmware version. Please update the firmware image " 435 <<
"or subscribe to the dynamics topic to have that transformation available in tf.");
442 for (
const auto& streamName : availStreams)
450 catch (
const std::exception& e)
452 ROS_WARN_STREAM(
"rc_visard_driver: Unable to create dynamics stream of type " << streamName <<
": " 457 successfullyOpened =
true;
460 catch (std::exception& ex)
488 rc_common_msgs::Trigger::Request dummyreq;
489 rc_common_msgs::Trigger::Response dummyresp;
490 ROS_INFO(
"rc_visard_driver: Autostop dynamics ...");
493 ROS_WARN(
"rc_visard_driver: Could not auto-stop dynamics module!");
496 std::cout <<
"rc_visard_driver: stopped." << std::endl;
506 cfg.camera_fps =
rcg::getFloat(nodemap,
"AcquisitionFrameRate", 0, 0,
true);
508 std::string v =
rcg::getEnum(nodemap,
"ExposureAuto",
true);
509 cfg.camera_exp_auto = (v !=
"Off");
511 if (cfg.camera_exp_auto)
513 if (v ==
"Continuous")
515 cfg.camera_exp_auto_mode =
"Normal";
519 cfg.camera_exp_auto_mode = v;
523 cfg.camera_exp_value =
rcg::getFloat(nodemap,
"ExposureTime", 0, 0,
true) / 1000000;
524 cfg.camera_exp_max =
rcg::getFloat(nodemap,
"ExposureTimeAutoMax", 0, 0,
true) / 1000000;
527 cfg.camera_exp_width =
rcg::getInteger(nodemap,
"ExposureRegionWidth", 0, 0,
false);
528 cfg.camera_exp_height =
rcg::getInteger(nodemap,
"ExposureRegionHeight", 0, 0,
false);
529 cfg.camera_exp_offset_x =
rcg::getInteger(nodemap,
"ExposureRegionOffsetX", 0, 0,
false);
530 cfg.camera_exp_offset_y =
rcg::getInteger(nodemap,
"ExposureRegionOffsetY", 0, 0,
false);
546 cfg.camera_gain_value =
rcg::getFloat(nodemap,
"Gain", 0, 0,
true);
551 ROS_WARN(
"rc_visard_driver: Device does not support setting gain. gain_value is without function.");
554 cfg.camera_gain_value = 0;
559 std::vector<std::string> formats;
562 for (
auto&& format : formats)
564 if (format ==
"YCbCr411_8")
577 cfg.camera_wb_auto = (v !=
"Off");
578 rcg::setEnum(nodemap,
"BalanceRatioSelector",
"Red",
true);
579 cfg.camera_wb_ratio_red =
rcg::getFloat(nodemap,
"BalanceRatio", 0, 0,
true);
580 rcg::setEnum(nodemap,
"BalanceRatioSelector",
"Blue",
true);
581 cfg.camera_wb_ratio_blue =
rcg::getFloat(nodemap,
"BalanceRatio", 0, 0,
true);
585 ROS_WARN(
"rc_visard_driver: Not a color camera. wb_auto, wb_ratio_red and wb_ratio_blue are without function.");
588 cfg.camera_wb_auto =
true;
589 cfg.camera_wb_ratio_red = 1;
590 cfg.camera_wb_ratio_blue = 1;
595 v =
rcg::getEnum(nodemap,
"DepthAcquisitionMode",
false);
599 cfg.depth_acquisition_mode = v;
603 ROS_WARN(
"rc_visard_driver: Device does not support triggering depth images. depth_acquisition_mode is without function.");
606 cfg.depth_acquisition_mode =
"Continuous";
610 cfg.depth_quality = v;
612 cfg.depth_static_scene =
rcg::getBoolean(nodemap,
"DepthStaticScene",
false);
615 cfg.depth_minconf =
rcg::getFloat(nodemap,
"DepthMinConf", 0, 0,
true);
616 cfg.depth_mindepth =
rcg::getFloat(nodemap,
"DepthMinDepth", 0, 0,
true);
617 cfg.depth_maxdepth =
rcg::getFloat(nodemap,
"DepthMaxDepth", 0, 0,
true);
618 cfg.depth_maxdeptherr =
rcg::getFloat(nodemap,
"DepthMaxDepthErr", 0, 0,
true);
624 if (cfg.depth_quality[0] ==
'S')
626 cfg.depth_quality =
"High";
627 cfg.depth_static_scene =
true;
639 ROS_INFO(
"rc_visard_driver: License for stereo_plus not available, disabling depth_quality=Full and depth_smooth.");
642 catch (
const std::exception&)
644 ROS_WARN(
"rc_visard_driver: rc_visard has an older firmware, disabling depth_quality=Full and depth_smooth.");
650 cfg.depth_double_shot =
rcg::getBoolean(nodemap,
"DepthDoubleShot",
true);
653 catch (
const std::exception&)
656 ROS_WARN(
"rc_visard_driver: rc_visard has an older firmware, depth_double_shot is not available.");
665 rcg::setEnum(nodemap,
"AcquisitionAlternateFilter",
"Off",
false);
681 ROS_INFO(
"rc_visard_driver: License for iocontrol module not available, disabling out1_mode and out2_mode.");
684 catch (
const std::exception&)
686 ROS_WARN(
"rc_visard_driver: rc_visard has an older firmware, IO control functions are not available.");
688 cfg.out1_mode =
"ExposureActive";
689 cfg.out2_mode =
"Low";
700 ROS_WARN(
"rc_visard_driver: rc_visard has an older firmware that does not support chunk data.");
706 pnh.
param(
"camera_fps", cfg.camera_fps, cfg.camera_fps);
707 pnh.
param(
"camera_exp_auto", cfg.camera_exp_auto, cfg.camera_exp_auto);
708 pnh.
param(
"camera_exp_auto_mode", cfg.camera_exp_auto_mode, cfg.camera_exp_auto_mode);
709 pnh.
param(
"camera_exp_value", cfg.camera_exp_value, cfg.camera_exp_value);
710 pnh.
param(
"camera_gain_value", cfg.camera_gain_value, cfg.camera_gain_value);
711 pnh.
param(
"camera_exp_max", cfg.camera_exp_max, cfg.camera_exp_max);
712 pnh.
param(
"camera_exp_width", cfg.camera_exp_width, cfg.camera_exp_width);
713 pnh.
param(
"camera_exp_height", cfg.camera_exp_height, cfg.camera_exp_height);
714 pnh.
param(
"camera_exp_offset_x", cfg.camera_exp_offset_x, cfg.camera_exp_offset_x);
715 pnh.
param(
"camera_exp_offset_y", cfg.camera_exp_offset_y, cfg.camera_exp_offset_y);
716 pnh.
param(
"camera_wb_auto", cfg.camera_wb_auto, cfg.camera_wb_auto);
717 pnh.
param(
"camera_wb_ratio_red", cfg.camera_wb_ratio_red, cfg.camera_wb_ratio_red);
718 pnh.
param(
"camera_wb_ratio_blue", cfg.camera_wb_ratio_blue, cfg.camera_wb_ratio_blue);
719 pnh.
param(
"depth_acquisition_mode", cfg.depth_acquisition_mode, cfg.depth_acquisition_mode);
720 pnh.
param(
"depth_quality", cfg.depth_quality, cfg.depth_quality);
721 pnh.
param(
"depth_static_scene", cfg.depth_static_scene, cfg.depth_static_scene);
722 pnh.
param(
"depth_double_shot", cfg.depth_double_shot, cfg.depth_double_shot);
723 pnh.
param(
"depth_seg", cfg.depth_seg, cfg.depth_seg);
724 pnh.
param(
"depth_smooth", cfg.depth_smooth, cfg.depth_smooth);
725 pnh.
param(
"depth_fill", cfg.depth_fill, cfg.depth_fill);
726 pnh.
param(
"depth_minconf", cfg.depth_minconf, cfg.depth_minconf);
727 pnh.
param(
"depth_mindepth", cfg.depth_mindepth, cfg.depth_mindepth);
728 pnh.
param(
"depth_maxdepth", cfg.depth_maxdepth, cfg.depth_maxdepth);
729 pnh.
param(
"depth_maxdeptherr", cfg.depth_maxdeptherr, cfg.depth_maxdeptherr);
730 pnh.
param(
"ptp_enabled", cfg.ptp_enabled, cfg.ptp_enabled);
731 pnh.
param(
"out1_mode", cfg.out1_mode, cfg.out1_mode);
732 pnh.
param(
"out2_mode", cfg.out2_mode, cfg.out2_mode);
736 pnh.
setParam(
"camera_fps", cfg.camera_fps);
737 pnh.
setParam(
"camera_exp_auto", cfg.camera_exp_auto);
738 pnh.
setParam(
"camera_exp_auto_mode", cfg.camera_exp_auto_mode);
739 pnh.
setParam(
"camera_exp_value", cfg.camera_exp_value);
740 pnh.
setParam(
"camera_gain_value", cfg.camera_gain_value);
741 pnh.
setParam(
"camera_exp_max", cfg.camera_exp_max);
742 pnh.
setParam(
"camera_exp_width", cfg.camera_exp_width);
743 pnh.
setParam(
"camera_exp_height", cfg.camera_exp_height);
744 pnh.
setParam(
"camera_exp_offset_x", cfg.camera_exp_offset_x);
745 pnh.
setParam(
"camera_exp_offset_y", cfg.camera_exp_offset_y);
746 pnh.
setParam(
"camera_wb_auto", cfg.camera_wb_auto);
747 pnh.
setParam(
"camera_wb_ratio_red", cfg.camera_wb_ratio_red);
748 pnh.
setParam(
"camera_wb_ratio_blue", cfg.camera_wb_ratio_blue);
749 pnh.
setParam(
"depth_acquisition_mode", cfg.depth_acquisition_mode);
750 pnh.
setParam(
"depth_quality", cfg.depth_quality);
751 pnh.
setParam(
"depth_static_scene", cfg.depth_static_scene);
752 pnh.
setParam(
"depth_double_shot", cfg.depth_double_shot);
753 pnh.
setParam(
"depth_seg", cfg.depth_seg);
754 pnh.
setParam(
"depth_smooth", cfg.depth_smooth);
755 pnh.
setParam(
"depth_fill", cfg.depth_fill);
756 pnh.
setParam(
"depth_minconf", cfg.depth_minconf);
757 pnh.
setParam(
"depth_mindepth", cfg.depth_mindepth);
758 pnh.
setParam(
"depth_maxdepth", cfg.depth_maxdepth);
759 pnh.
setParam(
"depth_maxdeptherr", cfg.depth_maxdeptherr);
760 pnh.
setParam(
"ptp_enabled", cfg.ptp_enabled);
761 pnh.
setParam(
"out1_mode", cfg.out1_mode);
762 pnh.
setParam(
"out2_mode", cfg.out2_mode);
767 reconfig =
new dynamic_reconfigure::Server<rc_visard_driver::rc_visard_driverConfig>(
mtx, pnh);
770 dynamic_reconfigure::Server<rc_visard_driver::rc_visard_driverConfig>::CallbackType cb;
777 boost::recursive_mutex::scoped_lock lock(
mtx);
783 c.camera_gain_value = 0;
789 c.depth_double_shot =
false;
793 c.camera_gain_value =
round(c.camera_gain_value / 6) * 6;
797 c.camera_wb_auto =
true;
798 c.camera_wb_ratio_red = 1;
799 c.camera_wb_ratio_blue = 1;
800 l &= ~(16384 | 32768 | 65536);
805 c.depth_acquisition_mode =
"Continuous";
809 if (c.depth_quality[0] ==
'L')
811 c.depth_quality =
"Low";
813 else if (c.depth_quality[0] ==
'M')
815 c.depth_quality =
"Medium";
819 c.depth_quality =
"Full";
823 c.depth_quality =
"High";
828 c.depth_smooth=
false;
834 if (c.out1_mode !=
"Low" && c.out1_mode !=
"High" && c.out1_mode !=
"ExposureActive" &&
835 c.out1_mode !=
"ExposureAlternateActive")
840 if (c.out2_mode !=
"Low" && c.out2_mode !=
"High" && c.out2_mode !=
"ExposureActive" &&
841 c.out2_mode !=
"ExposureAlternateActive")
888 if (c.camera_exp_auto)
890 std::string mode = c.camera_exp_auto_mode;
891 if (mode ==
"Normal") mode =
"Continuous";
895 c.camera_exp_auto_mode =
"Normal";
905 if (!c.camera_exp_auto)
928 void setConfiguration(
const std::shared_ptr<GenApi::CNodeMapRef>& nodemap,
929 const rc_visard_driver::rc_visard_driverConfig& cfg, uint32_t lvl,
bool iocontrol_avail)
931 uint32_t prev_lvl = 0;
933 while (lvl != 0 && prev_lvl != lvl)
946 rcg::setFloat(nodemap,
"AcquisitionFrameRate", cfg.camera_fps,
true);
955 rcg::setFloat(nodemap,
"ExposureTime", 1000000 * cfg.camera_exp_value,
true);
969 rcg::setFloat(nodemap,
"ExposureTimeAutoMax", 1000000 * cfg.camera_exp_max,
true);
976 rcg::setInteger(nodemap,
"ExposureRegionWidth", cfg.camera_exp_width,
false);
983 rcg::setInteger(nodemap,
"ExposureRegionHeight", cfg.camera_exp_height,
false);
990 rcg::setInteger(nodemap,
"ExposureRegionOffsetX", cfg.camera_exp_offset_x,
false);
991 ROS_DEBUG_STREAM(
"Set ExposureRegionOffsetX to " << cfg.camera_exp_offset_x);
997 rcg::setInteger(nodemap,
"ExposureRegionOffsetY", cfg.camera_exp_offset_y,
false);
998 ROS_DEBUG_STREAM(
"Set ExposureRegionOffsetY to " << cfg.camera_exp_offset_y);
1005 if (cfg.camera_wb_auto)
1007 rcg::setEnum(nodemap,
"BalanceWhiteAuto",
"Continuous",
false);
1012 rcg::setEnum(nodemap,
"BalanceWhiteAuto",
"Off",
false);
1021 rcg::setEnum(nodemap,
"BalanceRatioSelector",
"Red",
false);
1022 rcg::setFloat(nodemap,
"BalanceRatio", cfg.camera_wb_ratio_red,
false);
1030 rcg::setEnum(nodemap,
"BalanceRatioSelector",
"Blue",
false);
1031 rcg::setFloat(nodemap,
"BalanceRatio", cfg.camera_wb_ratio_blue,
false);
1039 std::vector<std::string> list;
1040 rcg::getEnum(nodemap,
"DepthAcquisitionMode", list,
true);
1043 for (
size_t i = 0; i < list.size(); i++)
1045 if (list[i].compare(cfg.depth_acquisition_mode) == 0)
1053 rcg::setEnum(nodemap,
"DepthAcquisitionMode", val.c_str(),
true);
1058 ROS_WARN_STREAM(
"DepthAcquisitionMode " << cfg.depth_acquisition_mode <<
" not supported by rc_visard");
1067 std::vector<std::string> list;
1072 if (cfg.depth_quality ==
"High" && cfg.depth_static_scene)
1076 for (
size_t i = 0; i < list.size() && val.size() == 0; i++)
1078 if (list[i].compare(0, 1,
"StaticHigh", 0, 1) == 0)
1085 for (
size_t i = 0; i < list.size() && val.size() == 0; i++)
1087 if (list[i].compare(0, 1, cfg.depth_quality, 0, 1) == 0)
1095 rcg::setEnum(nodemap,
"DepthQuality", val.c_str(),
true);
1103 rcg::setBoolean(nodemap,
"DepthDoubleShot", cfg.depth_double_shot,
false);
1111 if (!
rcg::setBoolean(nodemap,
"DepthStaticScene", cfg.depth_static_scene,
false))
1115 std::string quality = cfg.depth_quality;
1117 if (cfg.depth_static_scene && quality ==
"High")
1119 quality =
"StaticHigh";
1122 std::vector<std::string> list;
1126 for (
size_t i = 0; i < list.size() && val.size() == 0; i++)
1128 if (list[i].compare(0, 1, quality, 0, 1) == 0)
1136 rcg::setEnum(nodemap,
"DepthQuality", val.c_str(),
true);
1166 rcg::setFloat(nodemap,
"DepthMinConf", cfg.depth_minconf,
true);
1173 rcg::setFloat(nodemap,
"DepthMinDepth", cfg.depth_mindepth,
true);
1180 rcg::setFloat(nodemap,
"DepthMaxDepth", cfg.depth_maxdepth,
true);
1187 rcg::setFloat(nodemap,
"DepthMaxDepthErr", cfg.depth_maxdeptherr,
true);
1202 catch (
const std::exception& ex)
1215 void disableAll(
const std::shared_ptr<GenApi::CNodeMapRef>& nodemap)
1217 std::vector<std::string> component;
1219 rcg::getEnum(nodemap,
"ComponentSelector", component,
true);
1221 for (
size_t i = 0; i < component.size(); i++)
1223 rcg::setEnum(nodemap,
"ComponentSelector", component[i].c_str(),
true);
1227 rcg::setEnum(nodemap,
"ComponentSelector",
"Intensity");
1231 rcg::setEnum(nodemap,
"AcquisitionMultiPartMode",
"SingleComponent");
1243 int enable(
const std::shared_ptr<GenApi::CNodeMapRef>& nodemap,
const char* component,
bool& en_curr,
bool en_new)
1245 if (en_new != en_curr)
1248 ROS_INFO_STREAM(
"rc_visard_driver: Enabled image stream: " << component);
1250 ROS_INFO_STREAM(
"rc_visard_driver: Disabled image stream: " << component);
1252 rcg::setEnum(nodemap,
"ComponentSelector", component,
true);
1262 rc_common_msgs::CameraParam extractChunkData(
const std::shared_ptr<GenApi::CNodeMapRef>&
rcgnodemap)
1264 rc_common_msgs::CameraParam cam_param;
1267 std::vector<std::string> lines;
1268 rcg::getEnum(rcgnodemap,
"ChunkLineSelector", lines,
false);
1269 for (
auto&& line : lines)
1271 rc_common_msgs::KeyValue line_source;
1272 line_source.key = line;
1273 rcg::setEnum(rcgnodemap,
"ChunkLineSelector", line.c_str(),
false);
1274 line_source.value =
rcg::getEnum(rcgnodemap,
"ChunkLineSource",
false);
1275 cam_param.line_source.push_back(line_source);
1279 cam_param.line_status_all =
rcg::getInteger(rcgnodemap,
"ChunkLineStatusAll", 0, 0,
false);
1282 cam_param.gain =
rcg::getFloat(rcgnodemap,
"ChunkGain", 0, 0,
false);
1283 cam_param.exposure_time =
rcg::getFloat(rcgnodemap,
"ChunkExposureTime", 0, 0,
false) / 1000000l;
1286 cam_param.extra_data.clear();
1289 rc_common_msgs::KeyValue kv;
1291 kv.value = std::to_string(
rcg::getFloat(rcgnodemap,
"ChunkRcNoise", 0, 0,
true));
1292 cam_param.extra_data.push_back(kv);
1294 catch (std::invalid_argument& e)
1297 static float NOISE_BASE = 2.0;
1298 rc_common_msgs::KeyValue kv;
1300 kv.value = std::to_string(static_cast<float>(NOISE_BASE * std::exp(cam_param.gain * std::log(10)/20)));
1301 cam_param.extra_data.push_back(kv);
1306 rc_common_msgs::KeyValue kv;
1308 kv.value = std::to_string(
rcg::getBoolean(rcgnodemap,
"ChunkRcTest",
true));
1309 cam_param.extra_data.push_back(kv);
1311 catch (std::invalid_argument& e)
1317 std::string out1_reduction;
1320 out1_reduction = std::to_string(
rcg::getFloat(rcgnodemap,
"ChunkRcOut1Reduction", 0, 0,
true));
1322 catch (
const std::exception& e)
1325 out1_reduction = std::to_string(
rcg::getFloat(rcgnodemap,
"ChunkRcAdaptiveOut1Reduction", 0, 0,
true));
1328 rc_common_msgs::KeyValue kv;
1329 kv.key =
"out1_reduction";
1330 kv.value = out1_reduction;
1331 cam_param.extra_data.push_back(kv);
1333 catch (std::invalid_argument& e)
1339 rc_common_msgs::KeyValue kv;
1340 kv.key =
"brightness";
1341 kv.value = std::to_string(
rcg::getFloat(rcgnodemap,
"ChunkRcBrightness", 0, 0,
true));
1342 cam_param.extra_data.push_back(kv);
1344 catch (std::invalid_argument& e)
1355 unsigned int maxNumConsecutiveFails = 5;
1364 unsigned int cntConsecutiveFails = 0;
1365 while (!
stopImageThread && cntConsecutiveFails < maxNumConsecutiveFails)
1378 bool ccolor =
false;
1379 bool cintensity =
false;
1380 bool cintensitycombined =
false;
1381 bool cdisparity =
false;
1382 bool cconfidence =
false;
1383 bool cerror =
false;
1385 bool firstTime =
true;
1395 throw std::runtime_error(
"Focal length not found: Neither 'FocalLength' nor 'FocalLengthFactor'!");
1405 throw std::invalid_argument(
"Feature not found or not readable: Baseline");
1410 throw std::invalid_argument(
"Feature not float: Baseline");
1412 if (val->GetUnit() ==
"mm")
1432 float mindepth =
config.depth_mindepth;
1433 float maxdepth =
config.depth_maxdepth;
1434 bool is_depth_acquisition_continuous = (
config.depth_acquisition_mode[0] ==
'C');
1438 std::shared_ptr<GenApi::CChunkAdapter> chunkadapter;
1467 std::shared_ptr<ImagePublisher> limage_color;
1468 std::shared_ptr<ImagePublisher> rimage_color;
1471 limage_color = std::make_shared<ImagePublisher>(it,
tfPrefix,
true,
true,
true);
1472 rimage_color = std::make_shared<ImagePublisher>(it,
tfPrefix,
false,
true,
true);
1477 std::shared_ptr<CameraParamPublisher> lcamparams;
1478 std::shared_ptr<CameraParamPublisher> rcamparams;
1481 lcamparams = std::make_shared<CameraParamPublisher>(nh,
tfPrefix,
true);
1482 rcamparams = std::make_shared<CameraParamPublisher>(nh,
tfPrefix,
false);
1487 std::vector<std::shared_ptr<rcg::Stream> > stream =
rcgdev->getStreams();
1491 if (stream.size() > 0)
1494 stream[0]->startStreaming();
1498 std::string out1_mode_on_sensor;
1520 chunkadapter->AttachBuffer(reinterpret_cast<std::uint8_t*>(buffer->
getGlobalBase()),
1529 out1_mode_on_sensor = v;
1536 bool out1_alternate = (out1_mode_on_sensor ==
"ExposureAlternateActive");
1539 rc_common_msgs::CameraParam cam_param = extractChunkData(
rcgnodemap);
1541 out1 = (cam_param.line_status_all & 0x1);
1544 for (uint32_t part=0; part<npart; part++)
1550 cntConsecutiveFails = 0;
1560 lcaminfo.
publish(buffer, part, pixelformat);
1561 rcaminfo.
publish(buffer, part, pixelformat);
1563 if (lcamparams && rcamparams)
1565 lcamparams->publish(buffer, cam_param, pixelformat);
1566 rcamparams->publish(buffer, cam_param, pixelformat);
1569 limage.
publish(buffer, part, pixelformat, out1);
1570 rimage.
publish(buffer, part, pixelformat, out1);
1572 if (limage_color && rimage_color)
1574 limage_color->publish(buffer, part, pixelformat, out1);
1575 rimage_color->publish(buffer, part, pixelformat, out1);
1578 disp.
publish(buffer, part, pixelformat);
1579 cdisp.
publish(buffer, part, pixelformat);
1580 depth.
publish(buffer, part, pixelformat);
1582 confidence.
publish(buffer, part, pixelformat);
1583 error_disp.
publish(buffer, part, pixelformat);
1584 error_depth.
publish(buffer, part, pixelformat);
1586 points2.
publish(buffer, part, pixelformat, out1);
1593 out1_mode_on_sensor =
"";
1600 if (chunkadapter) chunkadapter->DetachBuffer();
1606 ROS_WARN(
"rc_visard_driver: Received incomplete image buffer");
1608 else if (buffer == 0)
1613 if (cintensity || cintensitycombined ||
1614 (is_depth_acquisition_continuous && (cdisparity || cconfidence || cerror)))
1622 out <<
"No images received for " << t <<
" seconds!";
1623 throw std::underflow_error(out.
str());
1647 ROS_INFO(
"rc_visard_driver: Depth image acquisition triggered");
1655 if (limage_color && rimage_color && (limage_color->used() || rimage_color->used() || points2.
used()))
1676 int changed = enable(
rcgnodemap,
"IntensityCombined", cintensitycombined,
1677 rimage.
used() || (rimage_color && rimage_color->used()));
1679 changed += enable(
rcgnodemap,
"Intensity", cintensity,
1680 !cintensitycombined && (lcaminfo.
used() || rcaminfo.
used() ||
1681 (lcamparams && lcamparams->used()) ||
1682 (rcamparams && rcamparams->used()) ||
1684 (limage_color && limage_color->used()) || points2.
used()));
1686 changed += enable(
rcgnodemap,
"Disparity", cdisparity,
1689 changed += enable(
rcgnodemap,
"Confidence", cconfidence, confidence.
used());
1691 changed += enable(
rcgnodemap,
"Error", cerror, error_disp.
used() || error_depth.
used());
1696 if (changed > 0 || firstTime)
1698 if (cintensity || cintensitycombined || cdisparity || cconfidence || cerror)
1712 rc_visard_driver::rc_visard_driverConfig cfg =
config;
1713 uint32_t lvl =
level;
1719 mindepth = cfg.depth_mindepth;
1720 maxdepth = cfg.depth_maxdepth;
1726 is_depth_acquisition_continuous = (cfg.depth_acquisition_mode[0] ==
'C');
1730 if (is_depth_acquisition_continuous)
1742 if (out1_mode_on_sensor.size() == 0)
1745 out1_mode_on_sensor =
config.out1_mode;
1748 if (out1_mode_on_sensor !=
config.out1_mode)
1750 config.out1_mode = out1_mode_on_sensor;
1756 stream[0]->stopStreaming();
1761 ROS_ERROR(
"rc_visard_driver: No stream");
1762 cntConsecutiveFails++;
1765 catch (
const std::exception& ex)
1768 cntConsecutiveFails++;
1774 if (cntConsecutiveFails > 0)
1776 ROS_ERROR_STREAM(
"rc_visard_driver: Number of consecutive failures: " << cntConsecutiveFails);
1778 if (cntConsecutiveFails >= maxNumConsecutiveFails)
1787 rc_common_msgs::Trigger::Response& resp)
1791 resp.return_code.value = ReturnCodeConstants::SUCCESS;
1792 resp.return_code.message =
"";
1809 stat.
summary(diagnostic_msgs::DiagnosticStatus::ERROR,
"Disconnected");
1821 stat.
summary(diagnostic_msgs::DiagnosticStatus::OK,
"Streaming");
1824 stat.
summary(diagnostic_msgs::DiagnosticStatus::WARN,
"No data");
1828 stat.
summary(diagnostic_msgs::DiagnosticStatus::OK,
"Idle");
1835 stat.
summary(diagnostic_msgs::DiagnosticStatus::ERROR,
"Unknown");
1837 stat.
summary(diagnostic_msgs::DiagnosticStatus::OK,
"Info");
bool dynamicsStart(rc_common_msgs::Trigger::Request &req, rc_common_msgs::Trigger::Response &resp)
Start Stereo INS.
bool getBoolean(const std::shared_ptr< GenApi::CNodeMapRef > &nodemap, const char *name, bool exception=false, bool igncache=false)
ThreadedStream::Manager::Ptr dynamicsStreams
void publish(const rcg::Buffer *buffer, uint32_t part, uint64_t pixelformat) override
Offers a buffer for publication.
std::shared_ptr< Device > getDevice(const char *devid)
bool dev_supports_chunk_data
bool used() override
Returns true if there are subscribers to the topic.
bool autopublishTrajectory
bool used() override
Returns true if there are subscribers to the topic.
tf::Transform toRosTfTransform(const roboception::msgs::Pose &pose)
size_t getSizeFilled() const
Specific implementation for roboception::msgs::Frame messages that publishes received messages not on...
unsigned int totalIncompleteBuffers
bool dynamicsStopSlam(rc_common_msgs::Trigger::Request &req, rc_common_msgs::Trigger::Response &resp)
Stop SLAM (keep Stereo INS running)
void summary(unsigned char lvl, const std::string s)
void reconfigure(rc_visard_driver::rc_visard_driverConfig &config, uint32_t level)
bool used() override
Returns true if there are subscribers to the topic.
std::shared_ptr< GenApi::CChunkAdapter > getChunkAdapter(const std::shared_ptr< GenApi::CNodeMapRef > &nodemap, const std::string &tltype)
bool used() override
Returns true if there are subscribers to the topic.
void publish(const rcg::Buffer *buffer, uint32_t part, uint64_t pixelformat) override
Offers a buffer for publication.
void produce_connection_diagnostics(diagnostic_updater::DiagnosticStatusWrapper &stat)
void publish(const rcg::Buffer *buffer, uint32_t part, uint64_t pixelformat) override
Offers a buffer for publication.
void setHardwareID(const std::string &hwid)
static std::vector< std::shared_ptr< System > > getSystems()
bool used() override
Returns true if there are subscribers to the topic.
std::shared_ptr< ThreadedStream > Ptr
diagnostic_updater::Updater updater
diagnostics publishing
void add(const std::string &name, TaskFunction f)
bool used() override
Returns true if there are subscribers to the topic.
bool getSlamTrajectory(rc_visard_driver::GetTrajectory::Request &req, rc_visard_driver::GetTrajectory::Response &resp)
Get the Slam trajectory.
int64_t getInteger(const std::shared_ptr< GenApi::CNodeMapRef > &nodemap, const char *name, int64_t *vmin=0, int64_t *vmax=0, bool exception=false, bool igncache=false)
ros::ServiceServer slamLoadMapService
bool dynamicsStartSlam(rc_common_msgs::Trigger::Request &req, rc_common_msgs::Trigger::Response &resp)
Start Stereo INS+SLAM.
void grab(std::string device, rcg::Device::ACCESS access)
void publish(const rcg::Buffer *buffer, uint32_t part, uint64_t pixelformat) override
Offers a buffer for publication.
ServiceServer advertiseService(const std::string &service, bool(T::*srv_func)(MReq &, MRes &), T *obj)
void publish(const rcg::Buffer *buffer, uint32_t part, uint64_t pixelformat) override
Offers a buffer for publication.
void produce_device_diagnostics(diagnostic_updater::DiagnosticStatusWrapper &stat)
Implementation of a ThreadedStream that receives rc_visard's dynamics protobuf messages and re-publis...
bool setFloat(const std::shared_ptr< GenApi::CNodeMapRef > &nodemap, const char *name, double value, bool exception=false)
ros::ServiceServer depthAcquisitionTriggerService
wrapper for REST-API calls relating to rc_visard's dynamics interface
bool setEnum(const std::shared_ptr< GenApi::CNodeMapRef > &nodemap, const char *name, const char *value, bool exception=false)
ros::ServiceServer dynamicsStartSlamService
bool dynamicsRestart(rc_common_msgs::Trigger::Request &req, rc_common_msgs::Trigger::Response &resp)
Restart Stereo INS.
ros::NodeHandle & getPrivateNodeHandle() const
bool removeSlamMap(rc_common_msgs::Trigger::Request &req, rc_common_msgs::Trigger::Response &resp)
Remove the onboard SLAM map.
ros::ServiceServer getSlamTrajectoryService
interface GENAPI_DECL_ABSTRACT IFloat
static void clearSystems()
bool perform_depth_acquisition_trigger
bool tfEnabled
should poses published also via tf?
void publish(const rcg::Buffer *buffer, uint32_t part, uint64_t pixelformat) override
Offers a buffer for publication.
bool dev_supports_depth_acquisition_trigger
void initConfiguration(const std::shared_ptr< GenApi::CNodeMapRef > &nodemap, rc_visard_driver::rc_visard_driverConfig &cfg, rcg::Device::ACCESS access)
tf2_ros::StaticTransformBroadcaster tfStaticBroadcaster
std::atomic_bool imageSuccess
bool used() override
Returns true if there are subscribers to the topic.
void * getGlobalBase() const
ROSCPP_DECL const std::string & getNamespace()
unsigned int totalCompleteBuffers
ros::ServiceServer dynamicsStopSlamService
void checkFeature(const std::shared_ptr< GenApi::CNodeMapRef > &nodemap, const char *name, const char *value, bool igncache=false)
unsigned int totalImageReceiveTimeouts
#define ROS_FATAL_STREAM(args)
std::string getEnum(const std::shared_ptr< GenApi::CNodeMapRef > &nodemap, const char *name, bool exception=false)
ros::ServiceServer dynamicsRestartSlamService
uint64_t getPixelFormat(std::uint32_t part) const
static ThreadedStream::Ptr CreateDynamicsStreamOfType(rc::dynamics::RemoteInterface::Ptr rcdIface, const std::string &stream, ros::NodeHandle &nh, const std::string &frame_id_prefix, bool tfEnabled, bool staticImu2CamTf)
bool param(const std::string ¶m_name, T ¶m_val, const T &default_val) const
std::atomic_uint_least32_t level
TFSIMD_FORCE_INLINE Quaternion inverse(const Quaternion &q)
rc_visard_driver::rc_visard_driverConfig config
void keepAliveAndRecoverFromFails()
int cntConsecutiveRecoveryFails
bool used() override
Returns true if there are subscribers to the topic.
ros::ServiceServer slamSaveMapService
bool IsReadable(const CPointer< T, B > &ptr)
ros::ServiceServer dynamicsStopService
void setOut1Alternate(bool alternate)
std::atomic_bool imageRequested
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
std::string gev_packet_size
ros::NodeHandle & getNodeHandle() const
#define ROS_WARN_STREAM(args)
ros::Publisher trajPublisher
#define ROS_DEBUG_STREAM(args)
void publish(const rcg::Buffer *buffer, uint32_t part, uint64_t pixelformat) override
Offers a buffer for publication.
bool setBoolean(const std::shared_ptr< GenApi::CNodeMapRef > &nodemap, const char *name, bool value, bool exception=false)
std::shared_ptr< rcg::Device > rcgdev
bool atLeastOnceSuccessfullyStarted
ros::ServiceServer dynamicsStartService
std::string strip_leading_slash(const std::string &frame_name)
bool dynamicsResetSlam(rc_common_msgs::Trigger::Request &req, rc_common_msgs::Trigger::Response &resp)
Reset SLAM (keep Stereo INS running)
std::atomic_bool stopImageThread
ros::ServiceServer dynamicsRestartService
bool dynamicsStop(rc_common_msgs::Trigger::Request &req, rc_common_msgs::Trigger::Response &resp)
Stop Stereo INS(+SLAM if running)
dynamic_reconfigure::Server< rc_visard_driver::rc_visard_driverConfig > * reconfig
bool getContainsChunkdata() const
double getFloat(const std::shared_ptr< GenApi::CNodeMapRef > &nodemap, const char *name, double *vmin=0, double *vmax=0, bool exception=false, bool igncache=false)
bool dynamicsRestartSlam(rc_common_msgs::Trigger::Request &req, rc_common_msgs::Trigger::Response &resp)
Restart Stereo INS+SLAM.
bool dev_supports_double_shot
bool depthAcquisitionTrigger(rc_common_msgs::Trigger::Request &req, rc_common_msgs::Trigger::Response &resp)
Trigger stereo matching in mode 'SingleFrame'.
#define ROS_INFO_STREAM(args)
std::atomic_bool stopRecoverThread
rc::dynamics::RemoteInterface::Ptr dynamicsInterface
void publish(const rcg::Buffer *buffer, uint32_t part, uint64_t pixelformat) override
Offers a buffer for publication.
bool callCommand(const std::shared_ptr< GenApi::CNodeMapRef > &nodemap, const char *name, bool exception=false)
bool getImagePresent(std::uint32_t part) const
bool getIsIncomplete() const
Specific implementation for roboception::msgs::Dynamics messages.
static void transformStampedTFToMsg(const StampedTransform &bt, geometry_msgs::TransformStamped &msg)
bool setInteger(const std::shared_ptr< GenApi::CNodeMapRef > &nodemap, const char *name, int64_t value, bool exception=false)
std::thread recoverThread
void setDepthRange(double _mindepth, double _maxdepth)
Set the depth range of the disparity images.
void add(const std::string &key, const T &val)
#define ROS_ERROR_STREAM(args)
bool saveSlamMap(rc_common_msgs::Trigger::Request &req, rc_common_msgs::Trigger::Response &resp)
Save the onboard SLAM map.
unsigned int totalConnectionLosses
interface GENAPI_DECL_ABSTRACT INode
std::shared_ptr< GenApi::CNodeMapRef > rcgnodemap
ros::Time toRosTime(const roboception::msgs::Time &time)
ros::ServiceServer dynamicsResetSlamService
#define PLUGINLIB_EXPORT_CLASS(class_type, base_class_type)
boost::recursive_mutex mtx
void setParam(const std::string &key, const XmlRpc::XmlRpcValue &v) const
bool used() override
Returns true if there are subscribers to the topic.
std::string getString(const std::shared_ptr< GenApi::CNodeMapRef > &nodemap, const char *name, bool exception=false, bool igncache=false)
void publish(const rcg::Buffer *buffer, uint32_t part, uint64_t pixelformat) override
Offers a buffer for publication.
std::string tfPrefix
all frame names must be prefixed when using more than one rc_visard
void setDepthRange(double _mindepth, double _maxdepth)
Set the depth range of the disparity images.
bool loadSlamMap(rc_common_msgs::Trigger::Request &req, rc_common_msgs::Trigger::Response &resp)
Load the onboard SLAM map.
ros::ServiceServer slamRemoveMapService
std::uint32_t getNumberOfParts() const