standalone_complexed_nodelet.cpp
Go to the documentation of this file.
1 // -*- mode: c++ -*-
2 /*********************************************************************
3  * Software License Agreement (BSD License)
4  *
5  * Copyright (c) 2015, JSK Lab
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * * Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  * * Redistributions in binary form must reproduce the above
15  * copyright notice, this list of conditions and the following
16  * disclaimer in the documentation and/o2r other materials provided
17  * with the distribution.
18  * * Neither the name of the JSK Lab nor the names of its
19  * contributors may be used to endorse or promote products derived
20  * from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
30  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33  * POSSIBILITY OF SUCH DAMAGE.
34  *********************************************************************/
35 
36 #include <nodelet/loader.h>
39 #include <boost/algorithm/string.hpp>
40 #include <list>
41 // Parameter structure is
42 // nodelets:
43 // - name: node_name
44 // type: nodelet_type
45 // remappings:
46 // - from: from_topic
47 // - to: to_topic
48 // - from: from_topic
49 // - to: to_topic
50 
51 std::string parentName(const std::string& name)
52 {
53  std::list<std::string> list_string;
54  std::string delim("/");
55  boost::split(list_string, name, boost::is_any_of(delim));
56 
57  if (list_string.size() > 0) {
58  list_string.pop_back();
59  }
60  return boost::algorithm::join(list_string, "/");
61 }
62 
63 int main(int argc, char** argv)
64 {
65  ros::init(argc, argv, "standalone_complexed_nodelet");
66  ros::NodeHandle private_nh("~");
67  ros::NodeHandle nh;
68  nodelet::Loader manager(false); // Don't bring up the manager ROS API
69  nodelet::V_string my_argv;
70  std::vector<std::string> candidate_root;
71  candidate_root.push_back("nodelets");
72  int candidate_num;
73  private_nh.param("candidate_num", candidate_num, 100);
74  for (size_t i = 0; i < candidate_num; i++) {
75  candidate_root.push_back((boost::format("nodelets_%lu") % i).str());
76  }
77  for (size_t i_candidate = 0; i_candidate < candidate_root.size(); i_candidate++) {
78  std::string root_name = candidate_root[i_candidate];
79  if (private_nh.hasParam(root_name)) {
80  XmlRpc::XmlRpcValue nodelets_values;
81  private_nh.param(root_name, nodelets_values, nodelets_values);
82  if (nodelets_values.getType() == XmlRpc::XmlRpcValue::TypeArray) {
83  for (size_t i_nodelet = 0; i_nodelet < nodelets_values.size(); i_nodelet++) {
84  ROS_INFO("i_nodelet %lu", i_nodelet);
85  XmlRpc::XmlRpcValue onenodelet_param = nodelets_values[i_nodelet];
86  if (onenodelet_param.getType() == XmlRpc::XmlRpcValue::TypeStruct) {
87  std::string name, type;
88  nodelet::M_string remappings;
89  if (onenodelet_param.hasMember("if") && !(bool)onenodelet_param["if"]) {
90  continue;
91  }
92  if (onenodelet_param.hasMember("unless") && (bool)onenodelet_param["unless"]) {
93  continue;
94  }
95  if (onenodelet_param.hasMember("name")) {
96  name = nh.resolveName((std::string)onenodelet_param["name"]);
97  }
98  else {
99  ROS_FATAL("element ~nodelets should have name field");
100  return 1;
101  }
102  if (onenodelet_param.hasMember("type")) {
103  type = (std::string)onenodelet_param["type"];
104  }
105  else {
106  ROS_FATAL("element ~nodelets should have type field");
107  return 1;
108  }
109  if (onenodelet_param.hasMember("remappings")) {
110  XmlRpc::XmlRpcValue remappings_params
111  = onenodelet_param["remappings"];
112  if (remappings_params.getType() == XmlRpc::XmlRpcValue::TypeArray) {
113  for (size_t remappings_i = 0; remappings_i < remappings_params.size(); remappings_i++) {
114  XmlRpc::XmlRpcValue remapping_element_param = remappings_params[remappings_i];
115  if (remapping_element_param.getType() == XmlRpc::XmlRpcValue::TypeStruct) {
116  if (remapping_element_param.hasMember("from") && remapping_element_param.hasMember("to")) {
117  std::string from = (std::string)remapping_element_param["from"];
118  std::string to = (std::string)remapping_element_param["to"];
119  if (from.size() > 0 && from[0] == '~') {
120  ros::NodeHandle nodelet_private_nh = ros::NodeHandle(name);
121  from = nodelet_private_nh.resolveName(from.substr(1, from.size() - 1));
122  }
123  else {
124  ros::NodeHandle nodelet_nh = ros::NodeHandle(parentName(name));
125  from = nodelet_nh.resolveName(from);
126  }
127  if (to.size() > 0 && to[0] == '~') {
128  ros::NodeHandle nodelet_private_nh = ros::NodeHandle(name);
129  to = nodelet_private_nh.resolveName(to.substr(1, to.size() - 1));
130  }
131  else {
132  ros::NodeHandle nodelet_nh = ros::NodeHandle(parentName(name));
133  to = nodelet_nh.resolveName(to);
134  }
135  ROS_INFO("remapping: %s => %s", from.c_str(), to.c_str());
136  remappings[from] = to;
137  }
138  else {
139  ROS_FATAL("remappings parameter requires from and to fields");
140  return 1;
141  }
142  }
143  else {
144  ROS_FATAL("remappings should be an array");
145  return 1;
146  }
147  }
148  }
149  else {
150  ROS_FATAL("remappings should be an array");
151  return 1;
152  }
153  }
154  // Done reading parmaeter for one nodelet
155 
156  if (!manager.load(name, type, remappings, my_argv)) {
157  ROS_ERROR("Failed to load nodelet [%s -- %s]", name.c_str(), type.c_str());
158  }
159  else {
160  ROS_INFO("Succeeded to load nodelet [%s -- %s]", name.c_str(), type.c_str());
161  }
162  }
163  else {
164  ROS_FATAL("element ~nodelets should be a dictionay");
165  return 1;
166  }
167  }
168  }
169  else {
170  ROS_FATAL("~nodelets should be a list");
171  return 1;
172  }
173  }
174  }
175  ROS_INFO("done reading parmaeters");
176  std::vector<std::string> loaded_nodelets = manager.listLoadedNodelets();
177  ROS_INFO("loaded nodelets: %lu", loaded_nodelets.size());
178  for (size_t i = 0; i < loaded_nodelets.size(); i++) {
179  ROS_INFO("loaded nodelet: %s", loaded_nodelets[i].c_str());
180  }
181  ros::spin();
182  return 0;
183 }
#define ROS_FATAL(...)
bool load(const std::string &name, const std::string &type, const M_string &remappings, const V_string &my_argv)
int size() const
std::string resolveName(const std::string &name, bool remap=true) const
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
std::vector< std::string > listLoadedNodelets()
Type const & getType() const
ROSCPP_DECL void spin(Spinner &spinner)
#define ROS_INFO(...)
bool param(const std::string &param_name, T &param_val, const T &default_val) const
string str
bool hasMember(const std::string &name) const
bool hasParam(const std::string &key) const
int main(int argc, char **argv)
#define ROS_ERROR(...)
std::vector< std::string > V_string
std::map< std::string, std::string > M_string
std::string parentName(const std::string &name)


jsk_topic_tools
Author(s): Kei Okada , Yusuke Furuta
autogenerated on Tue Feb 6 2018 03:45:19