standalone_complexed_nodelet.cpp
Go to the documentation of this file.
00001 // -*- mode: c++ -*-
00002 /*********************************************************************
00003  * Software License Agreement (BSD License)
00004  *
00005  *  Copyright (c) 2015, JSK Lab
00006  *  All rights reserved.
00007  *
00008  *  Redistribution and use in source and binary forms, with or without
00009  *  modification, are permitted provided that the following conditions
00010  *  are met:
00011  *
00012  *   * Redistributions of source code must retain the above copyright
00013  *     notice, this list of conditions and the following disclaimer.
00014  *   * Redistributions in binary form must reproduce the above
00015  *     copyright notice, this list of conditions and the following
00016  *     disclaimer in the documentation and/o2r other materials provided
00017  *     with the distribution.
00018  *   * Neither the name of the JSK Lab nor the names of its
00019  *     contributors may be used to endorse or promote products derived
00020  *     from this software without specific prior written permission.
00021  *
00022  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00023  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00024  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00025  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00026  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00027  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00028  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00029  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00030  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00031  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00032  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00033  *  POSSIBILITY OF SUCH DAMAGE.
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 // Parameter structure is
00042 // nodelets:
00043 //   -  name: node_name
00044 //      type: nodelet_type
00045 //      remappings:
00046 //        - from: from_topic
00047 //        - to: to_topic
00048 //        - from: from_topic
00049 //        - to: to_topic
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); // Don't bring up the manager ROS API
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             // Done reading parmaeter for one nodelet
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 }


jsk_topic_tools
Author(s): Kei Okada , Yusuke Furuta
autogenerated on Fri Sep 8 2017 03:38:56