Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include <nodelet/loader.h>
00037 #include "jsk_topic_tools/rosparam_utils.h"
00038 #include "jsk_topic_tools/log_utils.h"
00039 #include <boost/algorithm/string.hpp>
00040 #include <list>
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051 std::string parentName(const std::string& name)
00052 {
00053 std::list<std::string> list_string;
00054 std::string delim("/");
00055 boost::split(list_string, name, boost::is_any_of(delim));
00056
00057 if (list_string.size() > 0) {
00058 list_string.pop_back();
00059 }
00060 return boost::algorithm::join(list_string, "/");
00061 }
00062
00063 int main(int argc, char** argv)
00064 {
00065 ros::init(argc, argv, "standalone_complexed_nodelet");
00066 ros::NodeHandle private_nh("~");
00067 ros::NodeHandle nh;
00068 nodelet::Loader manager(false);
00069 nodelet::V_string my_argv;
00070 std::vector<std::string> candidate_root;
00071 candidate_root.push_back("nodelets");
00072 int candidate_num;
00073 private_nh.param("candidate_num", candidate_num, 100);
00074 for (size_t i = 0; i < candidate_num; i++) {
00075 candidate_root.push_back((boost::format("nodelets_%lu") % i).str());
00076 }
00077 for (size_t i_candidate = 0; i_candidate < candidate_root.size(); i_candidate++) {
00078 std::string root_name = candidate_root[i_candidate];
00079 if (private_nh.hasParam(root_name)) {
00080 XmlRpc::XmlRpcValue nodelets_values;
00081 private_nh.param(root_name, nodelets_values, nodelets_values);
00082 if (nodelets_values.getType() == XmlRpc::XmlRpcValue::TypeArray) {
00083 for (size_t i_nodelet = 0; i_nodelet < nodelets_values.size(); i_nodelet++) {
00084 ROS_INFO("i_nodelet %lu", i_nodelet);
00085 XmlRpc::XmlRpcValue onenodelet_param = nodelets_values[i_nodelet];
00086 if (onenodelet_param.getType() == XmlRpc::XmlRpcValue::TypeStruct) {
00087 std::string name, type;
00088 nodelet::M_string remappings;
00089 if (onenodelet_param.hasMember("if") && !(bool)onenodelet_param["if"]) {
00090 continue;
00091 }
00092 if (onenodelet_param.hasMember("unless") && (bool)onenodelet_param["unless"]) {
00093 continue;
00094 }
00095 if (onenodelet_param.hasMember("name")) {
00096 name = nh.resolveName((std::string)onenodelet_param["name"]);
00097 }
00098 else {
00099 ROS_FATAL("element ~nodelets should have name field");
00100 return 1;
00101 }
00102 if (onenodelet_param.hasMember("type")) {
00103 type = (std::string)onenodelet_param["type"];
00104 }
00105 else {
00106 ROS_FATAL("element ~nodelets should have type field");
00107 return 1;
00108 }
00109 if (onenodelet_param.hasMember("remappings")) {
00110 XmlRpc::XmlRpcValue remappings_params
00111 = onenodelet_param["remappings"];
00112 if (remappings_params.getType() == XmlRpc::XmlRpcValue::TypeArray) {
00113 for (size_t remappings_i = 0; remappings_i < remappings_params.size(); remappings_i++) {
00114 XmlRpc::XmlRpcValue remapping_element_param = remappings_params[remappings_i];
00115 if (remapping_element_param.getType() == XmlRpc::XmlRpcValue::TypeStruct) {
00116 if (remapping_element_param.hasMember("from") && remapping_element_param.hasMember("to")) {
00117 std::string from = (std::string)remapping_element_param["from"];
00118 std::string to = (std::string)remapping_element_param["to"];
00119 if (from.size() > 0 && from[0] == '~') {
00120 ros::NodeHandle nodelet_private_nh = ros::NodeHandle(name);
00121 from = nodelet_private_nh.resolveName(from.substr(1, from.size() - 1));
00122 }
00123 else {
00124 ros::NodeHandle nodelet_nh = ros::NodeHandle(parentName(name));
00125 from = nodelet_nh.resolveName(from);
00126 }
00127 if (to.size() > 0 && to[0] == '~') {
00128 ros::NodeHandle nodelet_private_nh = ros::NodeHandle(name);
00129 to = nodelet_private_nh.resolveName(to.substr(1, to.size() - 1));
00130 }
00131 else {
00132 ros::NodeHandle nodelet_nh = ros::NodeHandle(parentName(name));
00133 to = nodelet_nh.resolveName(to);
00134 }
00135 ROS_INFO("remapping: %s => %s", from.c_str(), to.c_str());
00136 remappings[from] = to;
00137 }
00138 else {
00139 ROS_FATAL("remappings parameter requires from and to fields");
00140 return 1;
00141 }
00142 }
00143 else {
00144 ROS_FATAL("remappings should be an array");
00145 return 1;
00146 }
00147 }
00148 }
00149 else {
00150 ROS_FATAL("remappings should be an array");
00151 return 1;
00152 }
00153 }
00154
00155
00156 if (!manager.load(name, type, remappings, my_argv)) {
00157 ROS_ERROR("Failed to load nodelet [%s -- %s]", name.c_str(), type.c_str());
00158 }
00159 else {
00160 ROS_INFO("Succeeded to load nodelet [%s -- %s]", name.c_str(), type.c_str());
00161 }
00162 }
00163 else {
00164 ROS_FATAL("element ~nodelets should be a dictionay");
00165 return 1;
00166 }
00167 }
00168 }
00169 else {
00170 ROS_FATAL("~nodelets should be a list");
00171 return 1;
00172 }
00173 }
00174 }
00175 ROS_INFO("done reading parmaeters");
00176 std::vector<std::string> loaded_nodelets = manager.listLoadedNodelets();
00177 ROS_INFO("loaded nodelets: %lu", loaded_nodelets.size());
00178 for (size_t i = 0; i < loaded_nodelets.size(); i++) {
00179 ROS_INFO("loaded nodelet: %s", loaded_nodelets[i].c_str());
00180 }
00181 ros::spin();
00182 return 0;
00183 }