Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008 #ifndef ROSOPTION_HPP_
00009 #define ROSOPTION_HPP_
00010
00011 #include <telekyb_defines/telekyb_defines.hpp>
00012 #include <telekyb_base/ROS/ROSOptionController.hpp>
00013 #include <telekyb_base/Tools/XmlRpcConversion.hpp>
00014
00015
00016 #include <telekyb_base/Tools/YamlHelper.hpp>
00017
00018
00019 #include <telekyb_base/Tools/OperatorOverload.hpp>
00020
00021
00022 #include <telekyb_srvs/StringInput.h>
00023 #include <telekyb_srvs/StringOutput.h>
00024
00025 namespace TELEKYB_NAMESPACE
00026 {
00027
00028 template < class _T >
00029 class ROSOption : public ROSBaseOption, public OptionListener<_T>
00030 {
00031 protected:
00032
00033 Option<_T>* option;
00034 _T valueOnRos;
00035
00036
00037
00038 ros::ServiceServer getService;
00039 ros::ServiceServer setService;
00040
00041 bool getServiceCallBack(
00042 telekyb_srvs::StringOutput::Request& request,
00043 telekyb_srvs::StringOutput::Response& response) {
00044 ROS_INFO_STREAM("SYNC: Option " << option->getNSName() << " received getSerivce . Answered: " << YamlHelper::parseValueToString(option->getValue()));
00045
00046 return YamlHelper::parseValueToString(option->getValue(), response.output);
00047 }
00048
00049 bool setServiceCallBack(
00050 telekyb_srvs::StringInput::Request& request,
00051 telekyb_srvs::StringInput::Response& response) {
00052
00053
00054
00055 YAML::Node node;
00056 if ( ! YamlHelper::parseStringToNode(request.input, node)) {
00057 ROS_INFO_STREAM("SYNC: Option " << option->getNSName() << " unable to convert from Yaml." );
00058 return false;
00059 }
00060
00061 return option->set(node);
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087 }
00088
00089
00090 virtual void createGetService() {
00091
00092 if (!ROSOptionController::hasInstance()) {
00093 ROS_ERROR_STREAM("createSetService() called on ROSOption " << option->getNSName() << ", ROSOptionController is not initialized yet.");
00094 return;
00095 }
00096 ros::NodeHandle serviceHandle(ROSOptionController::Instance().getOptionNodeHandle(), getNSName());
00097 getService = serviceHandle.advertiseService(OPTION_GETSERVICE_NAME, &ROSOption::getServiceCallBack, this);
00098 }
00099
00100
00101 virtual void createSetService() {
00102
00103 if (!ROSOptionController::hasInstance()) {
00104 ROS_ERROR_STREAM("createSetService() called on ROSOption " << option->getNSName() << ", ROSOptionController is not initialized yet.");
00105 return;
00106 }
00107 ros::NodeHandle serviceHandle(ROSOptionController::Instance().getOptionNodeHandle(), getNSName());
00108 setService = serviceHandle.advertiseService(OPTION_SETSERVICE_NAME, &ROSOption::setServiceCallBack, this);
00109 }
00110
00111 virtual void shutdownGetService() {
00112 getService.shutdown();
00113 }
00114
00115 virtual void shutdownSetService() {
00116 setService.shutdown();
00117 }
00118
00119
00120
00121
00122 virtual void setToParameterServer() {
00123 if (!ROSOptionController::hasInstance()) {
00124 ROS_ERROR_STREAM("setToParameterServer() called on ROSOption " << option->getNSName() << ", ROSOptionController is not initialized yet.");
00125 return;
00126 }
00127 XmlRpc::XmlRpcValue value;
00128
00129
00130
00131 try {
00132 option->getValue() >> value;
00133 ros::NodeHandle optionHandle = ROSOptionController::Instance().getOptionNodeHandle();
00134 optionHandle.setParam(option->getNSName(), value);
00135 valueOnRos = option->getValue();
00136 } catch (XmlRpc::XmlRpcException &e) {
00137 ROS_ERROR_STREAM("Could not convert Option " << option->getNSName() << " to XmlRpcValue! " << e.getMessage());
00138 }
00139 }
00140
00141 virtual bool updateFromParameterServer() {
00142 if (!ROSOptionController::hasInstance()) {
00143 ROS_ERROR_STREAM("updateFromParameterServer() called on ROSOption " << option->getNSName() << ", ROSOptionController is not initialized yet.");
00144 return false;
00145 }
00146
00147 ros::NodeHandle optionHandle = ROSOptionController::Instance().getOptionNodeHandle();
00148
00149 XmlRpc::XmlRpcValue value;
00150 optionHandle.getParam(option->getNSName(), value);
00151
00152
00153
00154
00155
00156
00157
00158
00159 try {
00160 value >> valueOnRos;
00161 } catch (XmlRpc::XmlRpcException &e) {
00162
00163 ROS_ERROR_STREAM("Could not convert Option " << option->getNSName() << " FROM XmlRpcValue! " << e.getMessage() << " Reverting..");
00164 setToParameterServer();
00165 return false;
00166 }
00167
00168
00169 if (valueOnRos == option->getValue()) {
00170
00171 return true;
00172 }
00173
00174
00175 if (option->isReadOnly()) {
00176
00177 ROS_WARN_STREAM("ASYNC: Read-only Option " << option->getNSName() << " was changed on ROS Parameter server. Reverting...");
00178 setToParameterServer();
00179 return false;
00180 }
00181
00182
00183
00184 if (option->hasBounds() && !option->isWithinBounds(valueOnRos)) {
00185 ROS_WARN_STREAM("ASYNC: Option " << option->getNSName() << " was changed on ROS Parameter server, but is out of bounds! Reverting...");
00186 setToParameterServer();
00187 return false;
00188 }
00189
00190
00191
00192 ROS_INFO_STREAM("ASYNC: Updating Option " << option->getNSName() << " to " << YamlHelper::parseValueToString(valueOnRos));
00193 option->setValue(valueOnRos);
00194
00195 return true;
00196 }
00197
00198 virtual bool deleteFromParameterServer() {
00199 if (!ROSOptionController::hasInstance()) {
00200 ROS_ERROR_STREAM("deleteFromParameterServer() called on ROSOption " << option->getNSName() << ", ROSOptionController is not initialized yet.");
00201
00202
00203 return false;
00204 }
00205
00206
00207
00208 ros::NodeHandle optionHandle = ROSOptionController::Instance().getOptionNodeHandle();
00209
00210 return optionHandle.deleteParam(option->getNSName());
00211 }
00212
00213 friend class ROSOptionController;
00214
00215 public:
00216 ROSOption(Option<_T>* option_) {
00217 option = option_;
00218 }
00219 virtual ~ROSOption() {
00220
00221 }
00222
00223 virtual void optionDidChange(const Option<_T>* option_) {
00224
00225 if(option_->getValue() != valueOnRos) {
00226 setToParameterServer();
00227 }
00228 }
00229 virtual void optionShouldDelete(const Option<_T>* option_) {
00230
00231
00232 }
00233
00234
00235
00236 virtual std::string getName() const {
00237 return option->getName();
00238 }
00239 virtual std::string getDescription() const {
00240 return option->getDescription();
00241 }
00242 virtual std::string getNamespace() const {
00243 return option->getNamespace();
00244 }
00245 virtual std::string getNSName() const {
00246 return option->getNSName();
00247 }
00248
00249
00250
00251
00252
00253 };
00254
00255 }
00256
00257 #endif