dynamic_graph_manager
ros_queued_subscribe.hh
Go to the documentation of this file.
1 
10 #ifndef DYNAMIC_GRAPH_ROS_QUEUED_SUBSCRIBE_HH
11 #define DYNAMIC_GRAPH_ROS_QUEUED_SUBSCRIBE_HH
12 #include <iostream>
13 #include <map>
14 
15 #include <boost/shared_ptr.hpp>
16 #include <boost/thread/mutex.hpp>
17 
18 #include <dynamic-graph/command.h>
19 #include <dynamic-graph/entity.h>
20 #include <dynamic-graph/signal-ptr.h>
21 #include <dynamic-graph/signal-time-dependent.h>
22 
23 #include <ros/ros.h>
24 
28 
29 namespace dynamic_graph
30 {
31 class RosQueuedSubscribe;
32 
33 namespace command
34 {
35 namespace rosQueuedSubscribe
36 {
37 using ::dynamicgraph::command::Command;
38 using ::dynamicgraph::command::Value;
39 
40 #define ROS_QUEUED_SUBSCRIBE_MAKE_COMMAND(CMD) \
41  class CMD : public Command \
42  { \
43  public: \
44  CMD(RosQueuedSubscribe& entity, const std::string& docstring); \
45  virtual Value doExecute(); \
46  }
47 
48 ROS_QUEUED_SUBSCRIBE_MAKE_COMMAND(Add);
49 ROS_QUEUED_SUBSCRIBE_MAKE_COMMAND(Clear);
50 ROS_QUEUED_SUBSCRIBE_MAKE_COMMAND(List);
51 ROS_QUEUED_SUBSCRIBE_MAKE_COMMAND(Rm);
52 ROS_QUEUED_SUBSCRIBE_MAKE_COMMAND(ClearQueue);
53 ROS_QUEUED_SUBSCRIBE_MAKE_COMMAND(QueueSize);
54 ROS_QUEUED_SUBSCRIBE_MAKE_COMMAND(ReadQueue);
55 
56 #undef ROS_QUEUED_SUBSCRIBE_MAKE_COMMAND
57 
58 } // end of namespace rosQueuedSubscribe.
59 } // end of namespace command.
60 
61 class RosQueuedSubscribe;
62 
63 namespace internal
64 {
65 template <typename T>
66 struct Add;
67 
69 {
70  typedef boost::shared_ptr<ros::Subscriber> Subscriber_t;
71 
72  BindedSignalBase(RosQueuedSubscribe* e) : entity(e)
73  {
74  }
75  virtual ~BindedSignalBase()
76  {
77  }
78 
79  virtual void clear() = 0;
80  virtual std::size_t size() const = 0;
81 
82  Subscriber_t subscriber;
83  RosQueuedSubscribe* entity;
84 };
85 
86 template <typename T, int BufferSize>
88 {
89  typedef dynamicgraph::Signal<T, int> Signal_t;
90  typedef boost::shared_ptr<Signal_t> SignalPtr_t;
91  typedef std::vector<T> buffer_t;
92  typedef typename buffer_t::size_type size_type;
93 
95  : BindedSignalBase(e),
96  frontIdx(0),
97  backIdx(0),
98  buffer(BufferSize),
99  init(false)
100  {
101  }
102  ~BindedSignal()
103  {
104  std::cout << signal->getName() << ": Delete" << std::endl;
105  signal.reset();
106  clear();
107  }
108 
110  void clear()
111  {
112  // synchronize with method writer
113  wmutex.lock();
114  if (!empty())
115  {
116  if (backIdx == 0)
117  last = buffer[BufferSize - 1];
118  else
119  last = buffer[backIdx - 1];
120  }
121  // synchronize with method reader
122  rmutex.lock();
123  frontIdx = backIdx = 0;
124  rmutex.unlock();
125  wmutex.unlock();
126  }
127 
128  bool empty() const
129  {
130  return frontIdx == backIdx;
131  }
132 
133  bool full() const
134  {
135  return ((backIdx + 1) % BufferSize) == frontIdx;
136  }
137 
138  size_type size() const
139  {
140  if (frontIdx <= backIdx)
141  return backIdx - frontIdx;
142  else
143  return backIdx + BufferSize - frontIdx;
144  }
145 
146  SignalPtr_t signal;
148  size_type frontIdx;
151  size_type backIdx;
152  buffer_t buffer;
153  boost::mutex wmutex, rmutex;
154  T last;
155  bool init;
156 
157  template <typename R>
158  void writer(const R& data);
159  T& reader(T& val, int time);
160 };
161 } // namespace internal
162 
164 class RosQueuedSubscribe : public dynamicgraph::Entity
165 {
166  DYNAMIC_GRAPH_ENTITY_DECL();
167  typedef boost::posix_time::ptime ptime;
168 
169 public:
170  typedef boost::shared_ptr<internal::BindedSignalBase> bindedSignal_t;
171 
172  RosQueuedSubscribe(const std::string& n);
173  virtual ~RosQueuedSubscribe();
174 
175  virtual std::string getDocString() const;
176  void display(std::ostream& os) const;
177 
178  void rm(const std::string& signal);
179  std::string list();
180  void clear();
181  void clearQueue(const std::string& signal);
182  void readQueue(int beginReadingAt);
183  std::size_t queueSize(const std::string& signal) const;
184 
185  template <typename T>
186  void add(const std::string& type,
187  const std::string& signal,
188  const std::string& topic);
189 
190  std::map<std::string, bindedSignal_t>& bindedSignal()
191  {
192  return bindedSignal_;
193  }
194 
195  ros::NodeHandle& nh()
196  {
197  return nh_;
198  }
199 
200  template <typename R, typename S>
201  void callback(boost::shared_ptr<dynamicgraph::SignalPtr<S, int> > signal,
202  const R& data);
203 
204  template <typename R>
205  void callbackTimestamp(
206  boost::shared_ptr<dynamicgraph::SignalPtr<ptime, int> > signal,
207  const R& data);
208 
209  template <typename T>
210  friend class internal::Add;
211 
212  int readQueue()
213  {
214  return readQueue_;
215  }
216 
217 private:
218  static const std::string docstring_;
219  ros::NodeHandle& nh_;
220  std::map<std::string, bindedSignal_t> bindedSignal_;
221 
222  int readQueue_;
223  // Signal<bool, int> readQueue_;
224 
225  template <typename T, int BufferSize>
226  friend class internal::BindedSignal;
227 };
228 } // namespace dynamic_graph
229 
230 #include "ros_queued_subscribe.hxx"
231 #endif
size_type backIdx
Index of the slot where to write next value (does not contain valid data).
Definition: ros_queued_subscribe.hh:151
Definition: ros_queued_subscribe.hh:68
size_type frontIdx
Index of the next value to be read.
Definition: ros_queued_subscribe.hh:148
this is this package namespace in order to avoid naming conflict
Definition: device.hh:22
Definition: ros_queued_subscribe.hh:66
Definition: ros_queued_subscribe.hh:87
void clear()
See comments in reader and writer for details about synchronisation.
Definition: ros_queued_subscribe.hh:110
Publish ROS information in the dynamic-graph.
Definition: ros_queued_subscribe.hh:164