29 #ifndef SWRI_ROSCPP_NODE_HANDLE_H_
30 #define SWRI_ROSCPP_NODE_HANDLE_H_
41 #include <marti_introspection_msgs/NodeInfo.h>
44 #define SWRI_NODE_HANDLE(nh, pnh, description) swri::NodeHandle(nh, pnh, description, __FILE__)
50 class DynamicParameters;
84 if (ns.length() && ns[0] ==
'/')
95 if (!
nh_->enable_docs_)
100 for (
size_t i = 0; i <
nh_->info_msg_.parameters.size(); i++)
102 if (
nh_->info_msg_.parameters[i].name ==
name)
118 const std::string description,
119 const char* source_file =
"")
135 inh->
info_pub_ = pnh.
advertise<marti_introspection_msgs::NodeInfo>(
"documentation", 1,
true);
138 inh->
info_msg_.description = description;
149 operator void*()
const {
return nh_ ? (
void*)1 : (
void*)0; }
156 return nh_->enable_docs_;
165 inline marti_introspection_msgs::NodeInfo
getDocMsg()
const
169 return nh_->info_msg_;
173 return marti_introspection_msgs::NodeInfo();
179 const std::string& group =
"")
185 if (ns.length() > 1 && ns[0] ==
'~')
205 const std::string description)
207 return param(
name, value, value, description);
211 const std::string description)
214 bool set =
nh_->pnh_.getParam(real_name, value);
219 marti_introspection_msgs::ParamInfo info;
220 info.name = real_name;
221 info.description = description;
223 info.resolved_name =
nh_->pnh_.resolveName(real_name);
224 info.type = marti_introspection_msgs::ParamInfo::TYPE_XMLRPC;
225 info.dynamic =
false;
226 nh_->info_msg_.parameters.push_back(info);
227 nh_->info_pub_.publish(
nh_->info_msg_);
232 inline bool getParam(
const std::string&
name, std::vector<std::string>& value,
233 const std::string description)
236 bool set =
nh_->pnh_.getParam(real_name, value);
241 marti_introspection_msgs::ParamInfo info;
242 info.name = real_name;
243 info.description = description;
245 info.resolved_name =
nh_->pnh_.resolveName(real_name);
246 info.type = marti_introspection_msgs::ParamInfo::TYPE_STRING;
247 info.dynamic =
false;
248 nh_->info_msg_.parameters.push_back(info);
249 nh_->info_pub_.publish(
nh_->info_msg_);
257 nh_->pnh_.setParam(
name, value);
264 const double default_value,
265 const std::string description,
266 const bool dynamic =
false)
272 ROS_INFO(
"Read parameter %s = %lf", real_name.c_str(), variable);
277 marti_introspection_msgs::ParamInfo info;
278 info.name = real_name;
279 info.description = description;
281 info.resolved_name =
nh_->pnh_.resolveName(real_name);
282 info.type = marti_introspection_msgs::ParamInfo::TYPE_DOUBLE;
284 info.dynamic = dynamic;
285 nh_->info_msg_.parameters.push_back(info);
286 nh_->info_pub_.publish(
nh_->info_msg_);
296 const double default_value,
297 const std::string description,
298 const double min_value = 0.0,
299 const double max_value = 0.0,
300 const bool dynamic =
false)
306 ROS_INFO(
"Read parameter %s = %lf", real_name.c_str(), variable);
309 if (variable < min_value)
311 ROS_ERROR(
"Parameter '%s' is out of range. Clamping to %f.", real_name.c_str(), min_value);
312 variable = min_value;
314 else if (variable > max_value)
316 ROS_ERROR(
"Parameter '%s' is out of range. Clamping to %f.", real_name.c_str(), max_value);
317 variable = max_value;
322 marti_introspection_msgs::ParamInfo info;
323 info.name = real_name;
324 info.description = description;
326 info.resolved_name =
nh_->pnh_.resolveName(real_name);
327 info.type = marti_introspection_msgs::ParamInfo::TYPE_DOUBLE;
329 info.dynamic = dynamic;
330 info.max_value = max_value;
331 info.min_value = min_value;
332 nh_->info_msg_.parameters.push_back(info);
333 nh_->info_pub_.publish(
nh_->info_msg_);
341 const int default_value,
342 const std::string description,
343 const int min_value = 0.0,
344 const int max_value = 0.0,
345 const bool dynamic =
false)
351 ROS_INFO(
"Read parameter %s = %i", real_name.c_str(), variable);
354 if (variable < min_value)
356 ROS_ERROR(
"Parameter '%s' is out of range. Clamping to %i.", real_name.c_str(), min_value);
357 variable = min_value;
359 else if (variable > max_value)
361 ROS_ERROR(
"Parameter '%s' is out of range. Clamping to %i.", real_name.c_str(), max_value);
362 variable = max_value;
367 marti_introspection_msgs::ParamInfo info;
368 info.name = real_name;
369 info.description = description;
371 info.resolved_name =
nh_->pnh_.resolveName(real_name);
372 info.type = marti_introspection_msgs::ParamInfo::TYPE_INT;
374 info.dynamic = dynamic;
375 info.max_value = max_value;
376 info.min_value = min_value;
377 nh_->info_msg_.parameters.push_back(info);
378 nh_->info_pub_.publish(
nh_->info_msg_);
386 const float default_value,
387 const std::string description,
388 const float min_value = 0.0,
389 const float max_value = 0.0,
390 const bool dynamic =
false)
396 ROS_INFO(
"Read parameter %s = %lf", real_name.c_str(), variable);
399 if (variable < min_value)
401 ROS_ERROR(
"Parameter '%s' is out of range. Clamping to %f.", real_name.c_str(), min_value);
402 variable = min_value;
404 else if (variable > max_value)
406 ROS_ERROR(
"Parameter '%s' is out of range. Clamping to %f.", real_name.c_str(), max_value);
407 variable = max_value;
412 marti_introspection_msgs::ParamInfo info;
413 info.name = real_name;
414 info.description = description;
416 info.resolved_name =
nh_->pnh_.resolveName(real_name);
417 info.type = marti_introspection_msgs::ParamInfo::TYPE_FLOAT;
419 info.dynamic = dynamic;
420 info.max_value = max_value;
421 info.min_value = min_value;
422 nh_->info_msg_.parameters.push_back(info);
423 nh_->info_pub_.publish(
nh_->info_msg_);
431 const float default_value,
432 const std::string description,
433 const bool dynamic =
false)
439 ROS_INFO(
"Read parameter %s = %lf", real_name.c_str(), variable);
444 marti_introspection_msgs::ParamInfo info;
445 info.name = real_name;
446 info.description = description;
448 info.resolved_name =
nh_->pnh_.resolveName(real_name);
449 info.type = marti_introspection_msgs::ParamInfo::TYPE_DOUBLE;
451 info.dynamic = dynamic;
452 nh_->info_msg_.parameters.push_back(info);
453 nh_->info_pub_.publish(
nh_->info_msg_);
462 const int default_value,
463 const std::string description,
464 const bool dynamic =
false)
470 ROS_INFO(
"Read parameter %s = %i", real_name.c_str(), variable);
475 marti_introspection_msgs::ParamInfo info;
476 info.name = real_name;
477 info.description = description;
479 info.resolved_name =
nh_->pnh_.resolveName(real_name);
480 info.type = marti_introspection_msgs::ParamInfo::TYPE_INT;
482 info.dynamic = dynamic;
483 nh_->info_msg_.parameters.push_back(info);
484 nh_->info_pub_.publish(
nh_->info_msg_);
492 std::string &variable,
493 const std::string default_value,
494 const std::string description,
495 const bool dynamic =
false)
501 ROS_INFO(
"Read parameter %s = %s", real_name.c_str(), variable.c_str());
506 marti_introspection_msgs::ParamInfo info;
507 info.name = real_name;
508 info.description = description;
510 info.resolved_name =
nh_->pnh_.resolveName(real_name);
511 info.type = marti_introspection_msgs::ParamInfo::TYPE_STRING;
513 info.dynamic = dynamic;
514 nh_->info_msg_.parameters.push_back(info);
515 nh_->info_pub_.publish(
nh_->info_msg_);
524 const bool default_value,
525 const std::string description,
526 const bool dynamic =
false)
532 ROS_INFO(
"Read parameter %s = %s", real_name.c_str(), variable ?
"true" :
"false");
537 marti_introspection_msgs::ParamInfo info;
538 info.name = real_name;
539 info.description = description;
541 info.resolved_name =
nh_->pnh_.resolveName(real_name);
542 info.type = marti_introspection_msgs::ParamInfo::TYPE_BOOL;
544 info.dynamic = dynamic;
545 nh_->info_msg_.parameters.push_back(info);
546 nh_->info_pub_.publish(
nh_->info_msg_);
552 template<
class M ,
class T >
557 const std::string description,
562 if (
nh_->enable_docs_)
564 const std::string resolved_name =
nh_->nh_.resolveName(real_name);
565 marti_introspection_msgs::TopicInfo info;
566 info.name = real_name;
567 info.resolved_name = resolved_name;
570 info.advertised =
false;
571 info.description = description;
572 nh_->info_msg_.topics.push_back(info);
573 nh_->info_pub_.publish(
nh_->info_msg_);
584 const std::string description,
589 if (
nh_->enable_docs_)
591 const std::string resolved_name =
nh_->nh_.resolveName(real_name);
592 marti_introspection_msgs::TopicInfo info;
593 info.name = real_name;
594 info.resolved_name = resolved_name;
597 info.advertised =
false;
598 info.description = description;
599 nh_->info_msg_.topics.push_back(info);
600 nh_->info_pub_.publish(
nh_->info_msg_);
607 template<
class M ,
class T >
612 const std::string description,
616 if (
nh_->enable_docs_)
618 const std::string resolved_name =
nh_->nh_.resolveName(real_name);
619 marti_introspection_msgs::TopicInfo info;
620 info.name = real_name;
621 info.resolved_name = resolved_name;
624 info.advertised =
false;
625 info.description = description;
626 nh_->info_msg_.topics.push_back(info);
627 nh_->info_pub_.publish(
nh_->info_msg_);
630 return nh_->nh_.subscribe(real_name, queue_size, fp, obj, transport_hints);
634 template<
class M ,
class T >
639 const std::string description,
643 if (
nh_->enable_docs_)
645 const std::string resolved_name =
nh_->nh_.resolveName(real_name);
646 marti_introspection_msgs::TopicInfo info;
647 info.name = real_name;
648 info.resolved_name = resolved_name;
651 info.advertised =
false;
652 info.description = description;
653 nh_->info_msg_.topics.push_back(info);
654 nh_->info_pub_.publish(
nh_->info_msg_);
657 return nh_->nh_.subscribe(real_name, queue_size, fp, obj, transport_hints);
665 const std::string description,
669 if (
nh_->enable_docs_)
671 const std::string resolved_name =
nh_->nh_.resolveName(real_name);
672 marti_introspection_msgs::TopicInfo info;
673 info.name = real_name;
674 info.resolved_name = resolved_name;
677 info.advertised =
false;
678 info.description = description;
679 nh_->info_msg_.topics.push_back(info);
680 nh_->info_pub_.publish(
nh_->info_msg_);
683 return nh_->nh_.subscribe<M>(real_name, queue_size, callback,
ros::VoidConstPtr(), transport_hints);
687 template<
class M ,
class T >
692 const std::string description,
696 if (
nh_->enable_docs_)
698 const std::string resolved_name =
nh_->nh_.resolveName(real_name);
699 marti_introspection_msgs::TopicInfo info;
700 info.name = real_name;
701 info.resolved_name = resolved_name;
704 info.advertised =
false;
705 info.description = description;
706 nh_->info_msg_.topics.push_back(info);
707 nh_->info_pub_.publish(
nh_->info_msg_);
710 return nh_->nh_.subscribe(real_name, queue_size, fp, obj, transport_hints);
714 template<
class M ,
class T >
719 const std::string description,
723 if (
nh_->enable_docs_)
725 const std::string resolved_name =
nh_->nh_.resolveName(real_name);
726 marti_introspection_msgs::TopicInfo info;
727 info.name = real_name;
728 info.resolved_name = resolved_name;
731 info.advertised =
false;
732 info.description = description;
733 nh_->info_msg_.topics.push_back(info);
734 nh_->info_pub_.publish(
nh_->info_msg_);
737 return nh_->nh_.subscribe(real_name, queue_size, fp, obj, transport_hints);
742 const std::string &
name,
744 const std::string description,
748 if (
nh_->enable_docs_)
750 const std::string resolved_name =
nh_->nh_.resolveName(real_name);
751 marti_introspection_msgs::TopicInfo info;
752 info.name = real_name;
753 info.resolved_name = resolved_name;
756 info.advertised =
false;
757 info.description = description;
758 nh_->info_msg_.topics.push_back(info);
759 nh_->info_pub_.publish(
nh_->info_msg_);
769 const std::string description)
772 if (
nh_->enable_docs_)
774 const std::string resolved_name =
nh_->nh_.resolveName(real_name);
775 marti_introspection_msgs::TopicInfo info;
776 info.name = real_name;
777 info.resolved_name = resolved_name;
780 info.advertised =
false;
781 info.description = description;
782 nh_->info_msg_.topics.push_back(info);
783 nh_->info_pub_.publish(
nh_->info_msg_);
791 const std::string description)
794 if (
nh_->enable_docs_)
796 const std::string resolved_name =
nh_->nh_.resolveName(real_name);
797 marti_introspection_msgs::TopicInfo info;
798 info.name = real_name;
799 info.resolved_name = resolved_name;
802 info.advertised =
true;
803 info.description = description;
804 nh_->info_msg_.topics.push_back(info);
805 nh_->info_pub_.publish(
nh_->info_msg_);
810 template<
class M ,
class T >
815 const std::string description,
819 if (
nh_->enable_docs_)
821 const std::string resolved_name =
nh_->nh_.resolveName(real_name);
822 marti_introspection_msgs::TopicInfo info;
823 info.name = real_name;
824 info.resolved_name = resolved_name;
827 info.advertised =
false;
828 info.description = description;
829 nh_->info_msg_.topics.push_back(info);
830 nh_->info_pub_.publish(
nh_->info_msg_);
839 const std::string description)
842 if (
nh_->enable_docs_)
844 const std::string resolved_name =
nh_->nh_.resolveName(real_name);
845 marti_introspection_msgs::ServiceInfo info;
846 info.name = real_name;
847 info.resolved_name = resolved_name;
850 info.topic_service =
true;
852 info.description = description;
853 nh_->info_msg_.services.push_back(info);
854 nh_->info_pub_.publish(
nh_->info_msg_);
863 template<
class MReq,
class MRes,
class T>
865 bool(T::*srv_func)(
const MReq &, MRes &),
867 const std::string description)
870 if (
nh_->enable_docs_)
872 const std::string resolved_name =
nh_->nh_.resolveName(real_name);
873 marti_introspection_msgs::ServiceInfo info;
874 info.name = real_name;
875 info.resolved_name = resolved_name;
878 info.topic_service =
true;
880 info.description = description;
881 nh_->info_msg_.services.push_back(info);
882 nh_->info_pub_.publish(
nh_->info_msg_);
892 const std::string& description)
895 if (
nh_->enable_docs_)
897 const std::string resolved_name =
nh_->nh_.resolveName(real_name);
898 marti_introspection_msgs::ServiceInfo info;
899 info.name = real_name;
900 info.resolved_name = resolved_name;
903 info.topic_service =
false;
905 info.description = description;
906 nh_->info_msg_.services.push_back(info);
907 nh_->info_pub_.publish(
nh_->info_msg_);
910 return nh_->nh_.serviceClient<T>(
name);
914 template<
class MReq,
class MRes,
class T>
916 bool(T::*srv_func)(MReq &, MRes &),
918 const std::string description)
921 if (
nh_->enable_docs_)
923 const std::string resolved_name =
nh_->nh_.resolveName(real_name);
924 marti_introspection_msgs::ServiceInfo info;
925 info.name = real_name;
926 info.resolved_name = resolved_name;
929 info.topic_service =
false;
931 info.description = description;
932 nh_->info_msg_.services.push_back(info);
933 nh_->info_pub_.publish(
nh_->info_msg_);
936 return nh_->nh_.advertiseService(real_name, srv_func, obj);
939 template<
class MReq,
class MRes,
class T>
941 bool(T::*srv_func)(MReq &, MRes &),
943 const std::string description)
946 if (
nh_->enable_docs_)
948 const std::string resolved_name =
nh_->nh_.resolveName(real_name);
949 marti_introspection_msgs::ServiceInfo info;
950 info.name = real_name;
951 info.resolved_name = resolved_name;
954 info.topic_service =
false;
956 info.description = description;
957 nh_->info_msg_.services.push_back(info);
958 nh_->info_pub_.publish(
nh_->info_msg_);
964 template<
class MReq,
class MRes,
class T>
968 const std::string description)
971 if (
nh_->enable_docs_)
973 const std::string resolved_name =
nh_->nh_.resolveName(real_name);
974 marti_introspection_msgs::ServiceInfo info;
975 info.name = real_name;
976 info.resolved_name = resolved_name;
979 info.topic_service =
false;
981 info.description = description;
982 nh_->info_msg_.services.push_back(info);
983 nh_->info_pub_.publish(
nh_->info_msg_);
989 template<
class MReq,
class MRes,
class T>
991 bool(T::*srv_func)(
const std::string &,
const MReq &, MRes &),
993 const std::string description)
996 if (
nh_->enable_docs_)
998 const std::string resolved_name =
nh_->nh_.resolveName(real_name);
999 marti_introspection_msgs::ServiceInfo info;
1000 info.name = real_name;
1001 info.resolved_name = resolved_name;
1004 info.topic_service =
false;
1006 info.description = description;
1007 nh_->info_msg_.services.push_back(info);
1008 nh_->info_pub_.publish(
nh_->info_msg_);
1015 template<
typename M>
1017 const std::string
name,
1018 uint32_t queue_size,
1020 const std::string description)
1023 const std::string resolved_name =
nh_->nh_.resolveName(real_name);
1024 ROS_INFO(
"Publishing [%s] to '%s' from node %s.",
1026 resolved_name.c_str(),
1027 nh_->node_name_.c_str());
1029 if (
nh_->enable_docs_)
1031 marti_introspection_msgs::TopicInfo info;
1032 info.name = real_name;
1033 info.resolved_name = resolved_name;
1036 info.advertised =
true;
1037 info.description = description;
1038 nh_->info_msg_.topics.push_back(info);
1039 nh_->info_pub_.publish(
nh_->info_msg_);
1042 return nh_->nh_.advertise<M>(real_name, queue_size, latched);
1046 template<
typename M>
1048 const std::string
name,
1049 uint32_t queue_size,
1050 const char* description)
1053 const std::string resolved_name =
nh_->nh_.resolveName(real_name);
1054 ROS_INFO(
"Publishing [%s] to '%s' from node %s.",
1056 resolved_name.c_str(),
1057 nh_->node_name_.c_str());
1059 if (
nh_->enable_docs_)
1061 marti_introspection_msgs::TopicInfo info;
1062 info.name = real_name;
1063 info.resolved_name = resolved_name;
1066 info.advertised =
true;
1067 info.description = description;
1068 nh_->info_msg_.topics.push_back(info);
1069 nh_->info_pub_.publish(
nh_->info_msg_);
1072 return nh_->nh_.advertise<M>(real_name, queue_size,
false);
1076 template<
typename M>
1078 const std::string &topic,
1079 uint32_t queue_size,
1084 const std::string &description =
"")
1087 const std::string resolved_name =
nh_->nh_.resolveName(real_topic_name);
1088 ROS_INFO(
"Publishing [%s] to '%s' from node %s.",
1089 real_topic_name.c_str(),
1090 resolved_name.c_str(),
1091 nh_->node_name_.c_str());
1092 if (
nh_->enable_docs_)
1094 marti_introspection_msgs::TopicInfo info;
1095 info.name = real_topic_name;
1096 info.resolved_name = resolved_name;
1099 info.advertised =
true;
1100 info.description = description;
1101 nh_->info_msg_.topics.push_back(info);
1102 nh_->info_pub_.publish(
nh_->info_msg_);
1105 ops.
init<M>(real_topic_name, queue_size, connect_cb, disconnect_cb);
1108 return nh_->nh_.advertise(ops);
1113 const std::string &description =
"")
1116 const std::string resolved_name =
nh_->nh_.resolveName(real_topic_name);
1117 ROS_INFO(
"Publishing [%s] to '%s' from node %s.",
1118 real_topic_name.c_str(),
1119 resolved_name.c_str(),
1120 nh_->node_name_.c_str());
1121 if (
nh_->enable_docs_)
1123 marti_introspection_msgs::TopicInfo info;
1124 info.name = real_topic_name;
1125 info.resolved_name = resolved_name;
1128 info.advertised =
true;
1129 info.description = description;
1130 nh_->info_msg_.topics.push_back(info);
1131 nh_->info_pub_.publish(
nh_->info_msg_);
1133 return nh_->nh_.advertise(ops);
1141 const bool oneshot =
false,
1142 const bool autostart =
true)
1144 return nh_->nh_.createTimer(duration, fp, obj, oneshot, autostart);
1152 const bool oneshot =
false,
1153 const bool autostart =
true)
1155 return nh_->nh_.createWallTimer(duration, fp, obj, oneshot, autostart);
1160 const std::string
name,
1162 const std::string def,
1163 const std::string description)
1165 nh.
param(
name, value, def, description);
1169 const std::string
name,
1172 const std::string description =
"",
1173 const double min = -std::numeric_limits<double>::infinity(),
1174 const double max = std::numeric_limits<double>::infinity())
1179 template<
typename T>
1181 const std::string
name,
1188 template<
typename T>
1190 const std::string
name,
1193 const std::string description)
1195 nh.
param(
name, value, def, description);
1199 template<
typename T>
1201 const std::string
name,
1203 const std::string description)
1208 ROS_ERROR(
"Required parameter %s does not exist",
name.c_str());
1213 template<
typename T>
1215 const std::string&
name,
1222 template<
typename M>
1224 const std::string
name,
1225 uint32_t queue_size,
1227 const std::string description)
1229 return nh.
advertise<M>(
name, queue_size, latched, description);
1232 template<
typename M>
1234 const std::string
name,
1235 uint32_t queue_size,
1236 const char* description)
1238 return nh.
advertise<M>(
name, queue_size,
false, description);
1242 template<
class M ,
class T >
1244 const std::string &
name,
1245 uint32_t queue_size,
1248 const std::string description,
1256 const std::string &
name,
1258 const std::string description,
1264 template<
class MReq,
class MRes,
class T>
1266 const std::string &service,
1267 bool(T::*srv_func)(MReq &, MRes &),
1269 const std::string description)
1274 template<
class MReq,
class MRes,
class T>
1276 const std::string &service,
1279 const std::string description)
1284 template<
class MReq,
class MRes,
class T>
1286 const std::string &service,
1287 bool(T::*srv_func)(
const std::string &,
const MReq &, MRes &),
1289 const std::string description)
1296 const std::string
name,
1297 const double timeout,
1298 const std::string desc)
1300 double to = timeout;
1306 #endif // SWRI_ROSCPP_NODE_HANDLE_H_