Nodewrap.hpp
Go to the documentation of this file.
1 
7 #pragma once
8 
9 #include <ros/ros.h>
10 #include <atomic>
11 #include <chrono>
12 #include <condition_variable>
13 #include <memory>
14 #include <mutex>
15 
18 
19 namespace bota_node
20 {
21 template <class NodeImpl>
22 class Nodewrap
23 {
24 public:
25  Nodewrap() = delete;
35  Nodewrap(int argc, char** argv, const std::string& nodeName, int numSpinners = -1,
36  const bool installSignalHandler = true)
37  : nh_(nullptr)
38  , spinner_(nullptr)
39  , impl_(nullptr)
40  , signalHandlerInstalled_(installSignalHandler)
41  , running_(false)
42  , cvRunning_()
43  , mutexRunning_()
44  {
46  {
47  ros::init(argc, argv, nodeName, ros::init_options::NoSigintHandler);
48  }
49  else
50  {
51  ros::init(argc, argv, nodeName);
52  }
53 
54  nh_ = std::make_shared<ros::NodeHandle>("~");
55 
56  if (numSpinners == -1)
57  {
58  if (!nh_->param("num_spinners", numSpinners, 2))
59  {
60  ROS_WARN_STREAM("Could not acquire parameter '" << ros::this_node::getNamespace() << "/num_spinners"
61  << "' from server. Parameter still contains '" << numSpinners
62  << "'.");
63  }
64  }
65 
66  spinner_.reset(new ros::AsyncSpinner(numSpinners));
67  impl_.reset(new NodeImpl(nh_));
68 
70  }
71 
72  // not necessary to call ros::shutdown in the destructor, this is done as soon as the last nodeHandle
73  // is destructed
74  virtual ~Nodewrap() = default;
75 
79  bool execute()
80  {
81  bool init_success = init();
82  if (init_success)
83  {
84  run();
85  }
86  cleanup();
87  return init_success;
88  }
89 
93  bool init()
94  {
96  {
98  }
99 
100  spinner_->start();
101  if (!impl_->init())
102  {
103  ROS_ERROR("Failed to init Node %s!", ros::this_node::getName().c_str());
104  return false;
105  }
106 
107  running_ = true;
108  return true;
109  }
110 
114  void run()
115  {
116  // returns if running_ is false
117  std::unique_lock<std::mutex> lk(mutexRunning_);
118  cvRunning_.wait(lk, [this] { return !running_; });
119  }
120 
124  void cleanup()
125  {
127  {
129  }
130 
131  impl_->preCleanup();
132  impl_->stopAllWorkers();
133  spinner_->stop();
134  impl_->cleanup();
135  }
136 
140  void stop()
141  {
142  std::lock_guard<std::mutex> lk(mutexRunning_);
143  running_ = false;
144  cvRunning_.notify_all();
145  }
146 
147 public:
148  void signalHandler(const int signum)
149  {
150  ROS_DEBUG_STREAM("Signal: " << signum);
151  stop();
152 
153  if (signum == SIGSEGV)
154  {
155  signal(signum, SIG_DFL);
156  kill(getpid(), signum);
157  }
158  }
159 
160  static void checkSteadyClock()
161  {
162  if (std::chrono::steady_clock::period::num != 1 || std::chrono::steady_clock::period::den != 1000000000)
163  {
164  ROS_ERROR("std::chrono::steady_clock does not have a nanosecond resolution!");
165  }
166  if (std::chrono::system_clock::period::num != 1 || std::chrono::system_clock::period::den != 1000000000)
167  {
168  ROS_ERROR("std::chrono::system_clock does not have a nanosecond resolution!");
169  }
170  }
171 
172  NodeImpl* getImplPtr()
173  {
174  return impl_.get();
175  }
176 
177 protected:
178  std::shared_ptr<ros::NodeHandle> nh_;
179  std::unique_ptr<ros::AsyncSpinner> spinner_;
180  std::unique_ptr<NodeImpl> impl_;
181 
183 
184  std::atomic<bool> running_;
185  std::condition_variable cvRunning_;
186  std::mutex mutexRunning_;
187 };
188 
189 } // namespace bota_node
std::unique_ptr< NodeImpl > impl_
Definition: Nodewrap.hpp:180
static void checkSteadyClock()
Definition: Nodewrap.hpp:160
std::shared_ptr< ros::NodeHandle > nh_
Definition: Nodewrap.hpp:178
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
Nodewrap(int argc, char **argv, const std::string &nodeName, int numSpinners=-1, const bool installSignalHandler=true)
Definition: Nodewrap.hpp:35
std::condition_variable cvRunning_
Definition: Nodewrap.hpp:185
ROSCPP_DECL const std::string & getName()
ROSCPP_DECL const std::string & getNamespace()
NodeImpl * getImplPtr()
Definition: Nodewrap.hpp:172
static void unbindAll(void(T::*fp)(int), T *object)
#define ROS_WARN_STREAM(args)
#define ROS_DEBUG_STREAM(args)
std::atomic< bool > running_
Definition: Nodewrap.hpp:184
std::unique_ptr< ros::AsyncSpinner > spinner_
Definition: Nodewrap.hpp:179
static void bindAll(void(T::*fp)(int), T *object)
#define ROS_ERROR(...)
void signalHandler(const int signum)
INTERNAL FUNCTIONS.
Definition: Nodewrap.hpp:148
bool signalHandlerInstalled_
Definition: Nodewrap.hpp:182
virtual ~Nodewrap()=default
std::mutex mutexRunning_
Definition: Nodewrap.hpp:186


bota_node
Author(s):
autogenerated on Wed Mar 3 2021 03:09:11