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 #ifndef RVIZ_RPC_SERVER_H
00031 #define RVIZ_RPC_SERVER_H
00032
00033 #include "exceptions.h"
00034 #include "serializable_message.h"
00035 #include "request_wrapper.h"
00036 #include "response_wrapper.h"
00037 #include "call_handle.h"
00038
00039 #include <rve_common/uuid.h>
00040
00041 #include <string>
00042 #include <boost/shared_ptr.hpp>
00043 #include <boost/make_shared.hpp>
00044 #include <boost/function.hpp>
00045
00046 #include <boost/type_traits/remove_const.hpp>
00047 #include <boost/type_traits/is_const.hpp>
00048
00049 #include <ros/serialization.h>
00050 #include <ros/message_event.h>
00051
00052 namespace ros
00053 {
00054 class NodeHandle;
00055 class Publisher;
00056 }
00057
00058 namespace rve_rpc
00059 {
00060
00061 class CallbackHelper
00062 {
00063 public:
00064 virtual ~CallbackHelper() {}
00065 virtual void call(const ros::MessageEvent<RequestWrapper const>& incoming_event, const RespondFn& respond) = 0;
00066
00067 virtual const char* getRequestMD5Sum() = 0;
00068 virtual const char* getRequestDataType() = 0;
00069 virtual const char* getRequestDefinition() = 0;
00070 virtual const char* getResponseMD5Sum() = 0;
00071 virtual const char* getResponseDataType() = 0;
00072 virtual const char* getResponseDefinition() = 0;
00073 };
00074 typedef boost::shared_ptr<CallbackHelper> CallbackHelperPtr;
00075
00076 template<typename Req, typename Res>
00077 class CallbackHelperT : public CallbackHelper
00078 {
00079 public:
00080 typedef boost::shared_ptr<Req> ReqPtr;
00081 typedef boost::shared_ptr<Req const> ReqConstPtr;
00082 typedef ros::MessageEvent<Req const> ReqEvent;
00083 typedef boost::shared_ptr<Res> ResPtr;
00084 typedef boost::shared_ptr<Res const> ResConstPtr;
00085 typedef CallHandle<Req, Res> Handle;
00086 typedef boost::function<void(Handle&)> Callback;
00087
00088 CallbackHelperT(const Callback& cb)
00089 : cb_(cb)
00090 {}
00091
00092 virtual void call(const ros::MessageEvent<RequestWrapper const>& incoming_event, const RespondFn& respond_fn)
00093 {
00094 namespace ser = ros::serialization;
00095
00096 ros::MessageEvent<Req const> evt(incoming_event.getMessage()->instantiate<Req>(), incoming_event.getConnectionHeaderPtr(),
00097 incoming_event.getReceiptTime(), incoming_event.getMessageWillCopy(),
00098 typename ros::MessageEvent<Req const>::CreateFunction());
00099
00100 rve_common::UUID request_id = incoming_event.getMessage()->request_id;
00101 Handle handle(incoming_event.getMessage()->request_id, evt, respond_fn);
00102
00103 try
00104 {
00105 cb_(handle);
00106 }
00107 catch (std::exception& e)
00108 {
00109 handle.except(e.what());
00110
00111 ROS_ERROR("%s", e.what());
00112 }
00113 }
00114
00115 virtual const char* getRequestMD5Sum() { return ros::message_traits::md5sum<Req>(); }
00116 virtual const char* getRequestDataType() { return ros::message_traits::datatype<Req>(); }
00117 virtual const char* getRequestDefinition() { return ros::message_traits::definition<Req>(); }
00118 virtual const char* getResponseMD5Sum() { return ros::message_traits::md5sum<Res>(); }
00119 virtual const char* getResponseDataType() { return ros::message_traits::md5sum<Res>(); }
00120 virtual const char* getResponseDefinition() { return ros::message_traits::md5sum<Res>(); }
00121
00122 private:
00123 Callback cb_;
00124 };
00125
00126 class Server
00127 {
00128 public:
00129 Server(const std::string& name, const ros::NodeHandle& nh);
00130
00131 template<typename Req, typename Res>
00132 void addMethod(const std::string& name, const boost::function<void(CallHandle<Req, Res>&)>& callback)
00133 {
00134 CallbackHelperPtr helper(new CallbackHelperT<Req, Res>(callback));
00135 addMethod(name, helper);
00136 }
00137
00138 void addMethod(const std::string& name, const CallbackHelperPtr& helper);
00139
00140 void ready();
00141
00142 private:
00143 struct Impl;
00144 typedef boost::shared_ptr<Impl> ImplPtr;
00145 ImplPtr impl_;
00146 };
00147 typedef boost::shared_ptr<Server> ServerPtr;
00148
00149 }
00150
00151 #endif // RVIZ_RPC_SERVER_H