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 #ifndef _IRI_BASE_ALGORITHM_H
00020 #define _IRI_BASE_ALGORITHM_H
00021
00022 #include <ros/ros.h>
00023 #include <signal.h>
00024
00025
00026 #include <boost/thread.hpp>
00027 #include <boost/bind.hpp>
00028
00029
00030 #include <dynamic_reconfigure/server.h>
00031
00032
00033 #include <diagnostic_updater/diagnostic_updater.h>
00034
00035 namespace algorithm_base
00036 {
00037
00042 class AbstractAlgorithmNode
00043 {
00044 protected:
00045 static int ctrl_c_hit_count_;
00046
00047 static void hupCalled(int sig)
00048 {
00049 ROS_WARN("Unexpected SIGHUP caught. Ignoring it.");
00050 }
00051
00052 static void sigCalled(int sig)
00053 {
00054 ctrl_c_hit_count_++;
00055 }
00056 };
00057
00082 template <class Algorithm>
00083 class IriBaseAlgorithm : public AbstractAlgorithmNode
00084 {
00085 public:
00093 typedef typename Algorithm::Config Config;
00094
00095 protected:
00104 pthread_t thread;
00105
00113 Algorithm alg_;
00114
00122 ros::NodeHandle public_node_handle_;
00123
00131 ros::NodeHandle private_node_handle_;
00132
00141 ros::Rate loop_rate_;
00142
00149 static const unsigned int DEFAULT_RATE = 10;
00150
00157 diagnostic_updater::Updater diagnostic_;
00158
00159 public:
00167 IriBaseAlgorithm(void);
00168
00174 ~IriBaseAlgorithm(void);
00175
00183 int spin(void);
00184
00185 private:
00192 boost::shared_ptr<boost::thread> ros_thread_;
00193
00200 dynamic_reconfigure::Server<Config> dsrv_;
00201
00202 protected:
00215 void reconfigureCallback(Config &config, uint32_t level);
00216
00229 virtual void node_config_update(Config &config, uint32_t level) = 0;
00230
00237 void addDiagnostics(void);
00238
00245 virtual void addNodeDiagnostics(void) = 0;
00246
00247
00248
00249
00250
00251
00252
00253
00267 static void *mainThread(void *param);
00268
00275 virtual void mainNodeThread(void) = 0;
00276 };
00277
00278
00279 template <class Algorithm>
00280 IriBaseAlgorithm<Algorithm>::IriBaseAlgorithm() :
00281 public_node_handle_(ros::this_node::getName()),
00282 private_node_handle_("~"),
00283 loop_rate_(DEFAULT_RATE),
00284 diagnostic_(),
00285 dsrv_(private_node_handle_)
00286 {
00287 ROS_DEBUG("IriBaseAlgorithm::Constructor");
00288
00289
00290 pthread_create(&this->thread,NULL,this->mainThread,this);
00291
00292
00293
00294
00295 }
00296
00297 template <class Algorithm>
00298 IriBaseAlgorithm<Algorithm>::~IriBaseAlgorithm()
00299 {
00300 ROS_DEBUG("IriBaseAlgorithm::Destructor");
00301 pthread_cancel(this->thread);
00302 pthread_join(this->thread,NULL);
00303 }
00304
00305 template <class Algorithm>
00306 void IriBaseAlgorithm<Algorithm>::reconfigureCallback(Config &config, uint32_t level)
00307 {
00308 ROS_DEBUG("IriBaseAlgorithm::reconfigureCallback");
00309 this->node_config_update(config, level);
00310 this->alg_.config_update(config, level);
00311 }
00312
00313 template <class Algorithm>
00314 void IriBaseAlgorithm<Algorithm>::addDiagnostics(void)
00315 {
00316 ROS_DEBUG("IriBaseAlgorithm::addDiagnostics");
00317 addNodeDiagnostics();
00318 }
00319
00320 template <class Algorithm>
00321 void *IriBaseAlgorithm<Algorithm>::mainThread(void *param)
00322 {
00323 ROS_DEBUG("IriBaseAlgorithm::mainThread");
00324
00325
00326 IriBaseAlgorithm *iriNode = (IriBaseAlgorithm *)param;
00327
00328 while(ros::ok() && !ctrl_c_hit_count_)
00329 {
00330
00331 iriNode->mainNodeThread();
00332
00333
00334 iriNode->loop_rate_.sleep();
00335 }
00336
00337
00338 pthread_exit(NULL);
00339 }
00340
00341 template <class Algorithm>
00342 int IriBaseAlgorithm<Algorithm>::spin(void)
00343 {
00344 ROS_DEBUG("IriBaseAlgorithm::spin");
00345
00346
00347 this->diagnostic_.setHardwareID("none");
00348 this->addDiagnostics();
00349
00350
00351 this->ros_thread_.reset( new boost::thread(boost::bind(&ros::spin)) );
00352 assert(ros_thread_);
00353
00354
00355 this->dsrv_.setCallback(boost::bind(&IriBaseAlgorithm<Algorithm>::reconfigureCallback, this, _1, _2));
00356
00357 while(ros::ok() && !ctrl_c_hit_count_)
00358 {
00359
00360 this->diagnostic_.update();
00361
00362 ros::WallDuration(0.1).sleep();
00363 }
00364
00365
00366 ros::shutdown();
00367
00368
00369 this->ros_thread_.reset();
00370
00371 return 0;
00372 }
00373
00374
00375 int AbstractAlgorithmNode::ctrl_c_hit_count_ = 0;
00376
00391 template <class AlgImplTempl>
00392 int main(int argc, char **argv, std::string node_name)
00393 {
00394 ROS_DEBUG("IriBaseAlgorithm::%s Launched", node_name.c_str());
00395
00396
00397 ros::init(argc, argv, node_name);
00398
00399
00400 signal(SIGHUP, &AbstractAlgorithmNode::hupCalled);
00401
00402
00403 AlgImplTempl algImpl;
00404 algImpl.spin();
00405
00406 return 0;
00407 }
00408
00409 }
00410 #endif