Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008 #include <telekyb_base/ROS/ROSOptionController.hpp>
00009
00010 #include <telekyb_base/ROS/ROSModule.hpp>
00011
00012 #include <telekyb_base/Options/OptionContainer.hpp>
00013
00014 #include <boost/foreach.hpp>
00015
00016 namespace TELEKYB_NAMESPACE
00017 {
00018
00019
00020 class ROSOptionControllerOptions : public OptionContainer
00021 {
00022 public:
00023 Option<double> *tRosOptionUpdatePeriod;
00024 Option<std::string> *tRosOptionHandleSuffix;
00025 Option<bool>* tRosOptionMirroring;
00026 ROSOptionControllerOptions()
00027 : OptionContainer("ROSOptionController")
00028 {
00029 tRosOptionMirroring = addOption<bool>("tRosOptionMirroring", "Enabled/Disable Option Mirroring to ROS Parameter Server.",
00030 false, false, true);
00031 tRosOptionUpdatePeriod = addBoundsOption<double>("tRosOptionUpdatePeriod",
00032 "The update period (in s between updates) to the ROS Parameter Server", 1.0, 0.1, 10.0);
00033 tRosOptionHandleSuffix = addOption<std::string>("tRosOptionHandleSuffix",
00034 "Specify an alternative NodeHandle Suffix", TELEKYB_OPTION_NODESUFFIX, false, true);
00035 }
00036 };
00037
00038
00039 ROSOptionController::ROSOptionController()
00040 {
00041 options = new ROSOptionControllerOptions();
00042 optionHandle = ros::NodeHandle( ROSModule::Instance().getMainNodeHandle(), options->tRosOptionHandleSuffix->getValue() );
00043 }
00044
00045 void ROSOptionController::initialize()
00046 {
00047
00048 if (options->tRosOptionMirroring->getValue()) {
00049 optionUpdateTimer = optionHandle.createTimer(ros::Duration(options->tRosOptionUpdatePeriod->getValue()),
00050 &ROSOptionController::optionUpdateTimerCB, this);
00051 }
00052
00053
00054 setAllToParameterServer();
00055
00056
00057 createAllGetSetServices();
00058
00059
00060 options->tRosOptionUpdatePeriod->registerOptionListener(this);
00061
00062
00063 ros::NodeHandle mainNodeHandle(ROSModule::Instance().getMainNodeHandle());
00064 getOptionNodeHandleSrv = mainNodeHandle.advertiseService(
00065 "GetOptionNodeHandle", &ROSOptionController::getOptionNodeHandleSrvCB, this);
00066
00067 }
00068
00069 ROSOptionController::~ROSOptionController()
00070 {
00071
00072 options->tRosOptionUpdatePeriod->unRegisterOptionListener(this);
00073
00074 delete options;
00075 }
00076
00077 void ROSOptionController::optionUpdateTimerCB(const ros::TimerEvent& event)
00078 {
00079
00080 updateAllFromParameterServer();
00081 }
00082
00083 const ros::NodeHandle& ROSOptionController::getOptionNodeHandle() const
00084 {
00085 return optionHandle;
00086 }
00087
00088 std::string ROSOptionController::getOptionNodeHandleNamespace() const
00089 {
00090 return optionHandle.getNamespace();
00091 }
00092
00093 void ROSOptionController::createAllGetSetServices()
00094 {
00095
00096 BOOST_FOREACH(ROSBaseOption* rosOption, rosOptions) {
00097 rosOption->createGetService();
00098 rosOption->createSetService();
00099 }
00100
00101
00102 BOOST_FOREACH(ROSOptionContainer* rosOptionContainer, rosOptionContainers) {
00103 rosOptionContainer->createGetService();
00104 rosOptionContainer->createSetService();
00105 }
00106 }
00107
00108 void ROSOptionController::setAllToParameterServer()
00109 {
00110
00111 BOOST_FOREACH(ROSBaseOption* rosOption, rosOptions) {
00112 rosOption->setToParameterServer();
00113 }
00114 }
00115
00116 void ROSOptionController::updateAllFromParameterServer()
00117 {
00118
00119 BOOST_FOREACH(ROSBaseOption* rosOption, rosOptions) {
00120 rosOption->updateFromParameterServer();
00121 }
00122 }
00123
00124
00125 void ROSOptionController::deleteAllFromParameterServer()
00126 {
00127
00128 BOOST_FOREACH(ROSBaseOption* rosOption, rosOptions) {
00129 rosOption->deleteFromParameterServer();
00130 }
00131 }
00132
00133 void ROSOptionController::optionDidChange(const Option<double>* option_)
00134 {
00135
00136
00137 if (option_ == options->tRosOptionUpdatePeriod) {
00138
00139 optionUpdateTimer.setPeriod(ros::Duration(option_->getValue()));
00140 }
00141 }
00142
00143
00144 std::set<ROSBaseOption*> ROSOptionController::rosOptions;
00145 std::set<ROSOptionContainer*> ROSOptionController::rosOptionContainers;
00146
00147 bool ROSOptionController::addROSOption(ROSBaseOption* rosOption)
00148 {
00149
00150
00151 if (instance) {
00152 rosOption->setToParameterServer();
00153 rosOption->createGetService();
00154 rosOption->createSetService();
00155 }
00156 return rosOptions.insert(rosOption).second;
00157 }
00158
00159 bool ROSOptionController::removeROSOption(ROSBaseOption* rosOption)
00160 {
00161
00162
00163 if (instance) {
00164 if(!rosOption->deleteFromParameterServer()) {
00165 ROS_WARN_STREAM("Unable to remove ROSOption " << rosOption->getNSName() << " from Parameter Server!");
00166 }
00167 rosOption->shutdownGetService();
00168 rosOption->shutdownSetService();
00169 }
00170 return rosOptions.erase(rosOption);
00171 }
00172
00173
00174 bool ROSOptionController::addROSOptionContainer(ROSOptionContainer* rosOptionContainer)
00175 {
00176
00177
00178 if (instance) {
00179 rosOptionContainer->createGetService();
00180 rosOptionContainer->createSetService();
00181 }
00182 return rosOptionContainers.insert(rosOptionContainer).second;
00183 }
00184 bool ROSOptionController::removeROSOptionContainer(ROSOptionContainer* rosOptionContainer)
00185 {
00186
00187 if (instance) {
00188 rosOptionContainer->shutdownGetService();
00189 rosOptionContainer->shutdownSetService();
00190 }
00191 return rosOptionContainers.erase(rosOptionContainer);
00192 }
00193
00194 bool ROSOptionController::getOptionNodeHandleSrvCB(
00195 telekyb_srvs::StringOutput::Request& request,
00196 telekyb_srvs::StringOutput::Response& response)
00197 {
00198 response.output = getOptionNodeHandle().getNamespace();
00199 return true;
00200 }
00201
00202
00203 ROSOptionController* ROSOptionController::instance = NULL;
00204
00205 ROSOptionController& ROSOptionController::Instance()
00206 {
00207 if (!instance) {
00208
00209 instance = new ROSOptionController();
00210 instance->initialize();
00211 }
00212
00213 return *instance;
00214 }
00215
00216 const ROSOptionController* ROSOptionController::InstancePtr()
00217 {
00218 if (!instance) {
00219
00220 instance = new ROSOptionController();
00221 instance->initialize();
00222 }
00223
00224 return instance;
00225 }
00226
00227 void ROSOptionController::ShutDownInstance()
00228 {
00229 if (instance) {
00230 delete instance;
00231 }
00232
00233 instance = NULL;
00234 }
00235
00236 bool ROSOptionController::hasInstance()
00237 {
00238 return instance != NULL;
00239 }
00240
00241
00242 }