$search
00001 00002 // relay just passes messages on. it can be useful if you're trying to ensure 00003 // that a message doesn't get sent twice over a wireless link, by having the 00004 // relay catch the message and then do the fanout on the far side of the 00005 // wireless link. 00006 // 00007 // Copyright (C) 2009, Morgan Quigley 00008 // 00009 // Redistribution and use in source and binary forms, with or without 00010 // modification, are permitted provided that the following conditions are met: 00011 // * Redistributions of source code must retain the above copyright notice, 00012 // this list of conditions and the following disclaimer. 00013 // * Redistributions in binary form must reproduce the above copyright 00014 // notice, this list of conditions and the following disclaimer in the 00015 // documentation and/or other materials provided with the distribution. 00016 // * Neither the name of Stanford University nor the names of its 00017 // contributors may be used to endorse or promote products derived from 00018 // this software without specific prior written permission. 00019 // 00020 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00021 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00022 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00023 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 00024 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00025 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00026 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00027 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00028 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00029 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00030 // POSSIBILITY OF SUCH DAMAGE. 00032 00033 00034 #include <cstdio> 00035 #include "topic_tools/shape_shifter.h" 00036 #include "topic_tools/parse.h" 00037 #include "XmlRpc.h" 00038 #include "ros/xmlrpc_manager.h" 00039 #include "ros/network.h" 00040 00041 using std::string; 00042 using std::vector; 00043 using namespace topic_tools; 00044 00045 ros::NodeHandle *g_node = NULL; 00046 static bool g_advertised = false; 00047 static string g_output_topic; 00048 static ros::Publisher g_pub; 00049 static string g_host; 00050 uint32_t g_port = 0; 00051 bool g_error = false; 00052 00053 ros::XMLRPCManagerPtr g_xmlrpc_manager = ros::XMLRPCManager::instance(); 00054 00055 void foreign_advertise(const std::string &type) 00056 { 00057 XmlRpc::XmlRpcClient *client = g_xmlrpc_manager->getXMLRPCClient(g_host, g_port, "/"); 00058 XmlRpc::XmlRpcValue args, result; 00059 args[0] = ros::this_node::getName(); 00060 args[1] = g_output_topic; 00061 args[2] = type; 00062 args[3] = g_xmlrpc_manager->getServerURI(); 00063 if (!client->execute("registerPublisher", args, result)) 00064 { 00065 ROS_FATAL("Failed to contact foreign master at [%s:%d] to register [%s].", g_host.c_str(), g_port, g_output_topic.c_str()); 00066 g_error = true; 00067 ros::shutdown(); 00068 } 00069 ros::XMLRPCManager::instance()->releaseXMLRPCClient(client); 00070 } 00071 00072 void foreign_unadvertise() 00073 { 00074 XmlRpc::XmlRpcClient *client = g_xmlrpc_manager->getXMLRPCClient(g_host, g_port, "/"); 00075 XmlRpc::XmlRpcValue args, result; 00076 args[0] = ros::this_node::getName(); 00077 args[1] = g_output_topic; 00078 args[2] = g_xmlrpc_manager->getServerURI(); 00079 if (!client->execute("unregisterPublisher", args, result)) 00080 { 00081 ROS_ERROR("Failed to contact foreign master at [%s:%d] to unregister [%s].", g_host.c_str(), g_port, g_output_topic.c_str()); 00082 g_error = true; 00083 } 00084 ros::XMLRPCManager::instance()->releaseXMLRPCClient(client); 00085 } 00086 00087 void in_cb(const boost::shared_ptr<ShapeShifter const>& msg) 00088 { 00089 if (!g_advertised) 00090 { 00091 g_pub = msg->advertise(*g_node, g_output_topic, 10, true); 00092 foreign_advertise((*(msg->__connection_header))["type"]); 00093 g_advertised = true; 00094 printf("advertised as %s\n", g_output_topic.c_str()); 00095 } 00096 g_pub.publish(msg); 00097 } 00098 00099 int main(int argc, char **argv) 00100 { 00101 if (argc < 3) 00102 { 00103 printf("\nusage: unreliable_relay FOREIGN_MASTER_URI IN_TOPIC [OUT_TOPIC]\n\n"); 00104 return 1; 00105 } 00106 std::string topic_name; 00107 if(!getBaseName(string(argv[2]), topic_name)) 00108 return 1; 00109 ros::init(argc, argv, topic_name + string("_foreign_relay"), 00110 ros::init_options::AnonymousName); 00111 if (!ros::network::splitURI(string(argv[1]), g_host, g_port)) 00112 { 00113 ROS_FATAL("Couldn't parse the foreign master URI [%s] into a host:port pair.", argv[1]); 00114 return 1; 00115 } 00116 if (argc == 3) 00117 g_output_topic = string(argv[2])+string("_foreign_relay"); 00118 else // argc == 3 00119 g_output_topic = string(argv[3]); 00120 ros::NodeHandle n; 00121 ros::NodeHandle pnh("~"); 00122 g_node = &pnh; 00123 ros::Subscriber sub = n.subscribe<ShapeShifter>(string(argv[2]), 10, &in_cb); 00124 ros::spin(); 00125 foreign_unadvertise(); 00126 return g_error; 00127 } 00128