callback.h
Go to the documentation of this file.
1 //==============================================================================
2 // Copyright (c) 2012, Johannes Meyer, TU Darmstadt
3 // All rights reserved.
4 
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are met:
7 // * Redistributions of source code must retain the above copyright
8 // notice, this list of conditions and the following disclaimer.
9 // * Redistributions in binary form must reproduce the above copyright
10 // notice, this list of conditions and the following disclaimer in the
11 // documentation and/or other materials provided with the distribution.
12 // * Neither the name of the Flight Systems and Automatic Control group,
13 // TU Darmstadt, nor the names of its contributors may be used to
14 // endorse or promote products derived from this software without
15 // specific prior written permission.
16 
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
21 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 //==============================================================================
28 
29 #ifndef UBLOX_GPS_CALLBACK_H
30 #define UBLOX_GPS_CALLBACK_H
31 
32 #include <ros/console.h>
33 #include <ublox/serialization/ublox_msgs.h>
34 #include <boost/format.hpp>
35 #include <boost/function.hpp>
36 #include <boost/thread.hpp>
37 
38 namespace ublox_gps {
39 
44  public:
48  virtual void handle(ublox::Reader& reader) = 0;
49 
53  bool wait(const boost::posix_time::time_duration& timeout) {
54  boost::mutex::scoped_lock lock(mutex_);
55  return condition_.timed_wait(lock, timeout);
56  }
57 
58  protected:
59  boost::mutex mutex_;
60  boost::condition_variable condition_;
61 };
62 
67 template <typename T>
69  public:
70  typedef boost::function<void(const T&)> Callback;
71 
76  CallbackHandler_(const Callback& func = Callback()) : func_(func) {}
77 
81  virtual const T& get() { return message_; }
82 
87  void handle(ublox::Reader& reader) {
88  boost::mutex::scoped_lock lock(mutex_);
89  try {
90  if (!reader.read<T>(message_)) {
91  ROS_DEBUG_COND(debug >= 2,
92  "U-Blox Decoder error for 0x%02x / 0x%02x (%d bytes)",
93  static_cast<unsigned int>(reader.classId()),
94  static_cast<unsigned int>(reader.messageId()),
95  reader.length());
96  condition_.notify_all();
97  return;
98  }
99  } catch (std::runtime_error& e) {
100  ROS_DEBUG_COND(debug >= 2,
101  "U-Blox Decoder error for 0x%02x / 0x%02x (%d bytes)",
102  static_cast<unsigned int>(reader.classId()),
103  static_cast<unsigned int>(reader.messageId()),
104  reader.length());
105  condition_.notify_all();
106  return;
107  }
108 
109  if (func_) func_(message_);
110  condition_.notify_all();
111  }
112 
113  private:
116 };
117 
122  public:
128  template <typename T>
129  void insert(typename CallbackHandler_<T>::Callback callback) {
130  boost::mutex::scoped_lock lock(callback_mutex_);
131  CallbackHandler_<T>* handler = new CallbackHandler_<T>(callback);
132  callbacks_.insert(
133  std::make_pair(std::make_pair(T::CLASS_ID, T::MESSAGE_ID),
135  }
136 
145  template <typename T>
146  void insert(
147  typename CallbackHandler_<T>::Callback callback,
148  unsigned int message_id) {
149  boost::mutex::scoped_lock lock(callback_mutex_);
150  CallbackHandler_<T>* handler = new CallbackHandler_<T>(callback);
151  callbacks_.insert(
152  std::make_pair(std::make_pair(T::CLASS_ID, message_id),
154  }
155 
160  void set_nmea_callback(boost::function<void(const std::string&)> callback) {
161  boost::mutex::scoped_lock lock(callback_mutex_);
162  callback_nmea_ = callback;
163  }
164 
169  void handle(ublox::Reader& reader) {
170  // Find the callback handlers for the message & decode it
171  boost::mutex::scoped_lock lock(callback_mutex_);
172  Callbacks::key_type key =
173  std::make_pair(reader.classId(), reader.messageId());
174  for (Callbacks::iterator callback = callbacks_.lower_bound(key);
175  callback != callbacks_.upper_bound(key); ++callback)
176  callback->second->handle(reader);
177  }
178 
183  void handle_nmea(ublox::Reader& reader) {
184  boost::mutex::scoped_lock lock(callback_mutex_);
185  if(callback_nmea_.empty())
186  return;
187 
188  const std::string& buffer = reader.getUnusedData();
189  size_t nmea_start = buffer.find('$', 0);
190  size_t nmea_end = buffer.find('\n', nmea_start);
191  while(nmea_start != std::string::npos && nmea_end != std::string::npos) {
192  std::string sentence = buffer.substr(nmea_start, nmea_end - nmea_start + 1);
193  callback_nmea_(sentence);
194 
195  nmea_start = buffer.find('$', nmea_end+1);
196  nmea_end = buffer.find('\n', nmea_start);
197  }
198  }
199 
205  template <typename T>
206  bool read(T& message, const boost::posix_time::time_duration& timeout) {
207  bool result = false;
208  // Create a callback handler for this message
209  callback_mutex_.lock();
210  CallbackHandler_<T>* handler = new CallbackHandler_<T>();
211  Callbacks::iterator callback = callbacks_.insert(
212  (std::make_pair(std::make_pair(T::CLASS_ID, T::MESSAGE_ID),
214  callback_mutex_.unlock();
215 
216  // Wait for the message
217  if (handler->wait(timeout)) {
218  message = handler->get();
219  result = true;
220  }
221 
222  // Remove the callback handler
223  callback_mutex_.lock();
224  callbacks_.erase(callback);
225  callback_mutex_.unlock();
226  return result;
227  }
228 
235  void readCallback(unsigned char* data, std::size_t& size) {
236  ublox::Reader reader(data, size);
237  // Read all U-Blox messages in buffer
238  while (reader.search() != reader.end() && reader.found()) {
239  if (debug >= 3) {
240  // Print the received bytes
241  std::ostringstream oss;
242  for (ublox::Reader::iterator it = reader.pos();
243  it != reader.pos() + reader.length() + 8; ++it)
244  oss << boost::format("%02x") % static_cast<unsigned int>(*it) << " ";
245  ROS_DEBUG("U-blox: reading %d bytes\n%s", reader.length() + 8,
246  oss.str().c_str());
247  }
248 
249  handle(reader);
250  }
251  handle_nmea(reader);
252 
253  // delete read bytes from ASIO input buffer
254  std::copy(reader.pos(), reader.end(), data);
255  size -= reader.pos() - data;
256  }
257 
258  private:
259  typedef std::multimap<std::pair<uint8_t, uint8_t>,
261 
262  // Call back handlers for u-blox messages
264  boost::mutex callback_mutex_;
265 
267  boost::function<void(const std::string&)> callback_nmea_;
268 };
269 
270 } // namespace ublox_gps
271 
272 #endif // UBLOX_GPS_CALLBACK_H
ublox::Reader::end
iterator end()
ublox_gps::CallbackHandler_::CallbackHandler_
CallbackHandler_(const Callback &func=Callback())
Initialize the Callback Handler with a callback function.
Definition: callback.h:76
ublox_gps::CallbackHandlers
Callback handlers for incoming u-blox messages.
Definition: callback.h:121
ublox_gps::CallbackHandler_::get
virtual const T & get()
Get the last received message.
Definition: callback.h:81
boost::shared_ptr
ublox_gps::CallbackHandler_::message_
T message_
The last received message.
Definition: callback.h:115
ublox::Reader::length
uint32_t length()
ublox_gps::CallbackHandlers::handle
void handle(ublox::Reader &reader)
Calls the callback handler for the message in the reader.
Definition: callback.h:169
ublox_gps::CallbackHandler_::handle
void handle(ublox::Reader &reader)
Decode the U-Blox message & call the callback function if it exists.
Definition: callback.h:87
ublox_gps::CallbackHandler::wait
bool wait(const boost::posix_time::time_duration &timeout)
Wait for on the condition.
Definition: callback.h:53
ublox_gps::CallbackHandler_
Definition: callback.h:68
ublox_gps::CallbackHandler_::func_
Callback func_
the callback function to handle the message
Definition: callback.h:114
ublox_gps::CallbackHandler::mutex_
boost::mutex mutex_
Lock for the handler.
Definition: callback.h:59
ROS_DEBUG_COND
#define ROS_DEBUG_COND(cond,...)
ublox::Reader::pos
iterator pos()
ublox_gps
Definition: async_worker.h:43
data
data
ublox_gps::CallbackHandler_::Callback
boost::function< void(const T &)> Callback
A callback function.
Definition: callback.h:70
ublox_gps::CallbackHandlers::read
bool read(T &message, const boost::posix_time::time_duration &timeout)
Read a u-blox message of the given type.
Definition: callback.h:206
console.h
ublox_gps::CallbackHandlers::Callbacks
std::multimap< std::pair< uint8_t, uint8_t >, boost::shared_ptr< CallbackHandler > > Callbacks
Definition: callback.h:260
ublox_gps::CallbackHandlers::insert
void insert(typename CallbackHandler_< T >::Callback callback)
Definition: callback.h:129
ROS_DEBUG
#define ROS_DEBUG(...)
ublox_gps::CallbackHandler
A callback handler for a u-blox message.
Definition: callback.h:43
ublox::Reader::search
iterator search()
ublox::Reader::messageId
uint8_t messageId()
ublox::Reader
ublox_gps::CallbackHandlers::callbacks_
Callbacks callbacks_
Definition: callback.h:263
ublox_gps::CallbackHandlers::handle_nmea
void handle_nmea(ublox::Reader &reader)
Calls the callback handler for the nmea messages in the reader.
Definition: callback.h:183
ublox_gps::CallbackHandlers::callback_nmea_
boost::function< void(const std::string &)> callback_nmea_
Callback handler for nmea messages.
Definition: callback.h:267
ublox::Reader::classId
uint8_t classId()
ublox::Reader::found
bool found()
ublox::Reader::read
bool read(typename boost::call_traits< T >::reference message, bool search=false)
ublox_gps::CallbackHandlers::set_nmea_callback
void set_nmea_callback(boost::function< void(const std::string &)> callback)
Add a callback handler for nmea messages.
Definition: callback.h:160
ublox_gps::CallbackHandlers::callback_mutex_
boost::mutex callback_mutex_
Definition: callback.h:264
ublox::Reader::getUnusedData
const std::string & getUnusedData() const
ublox_gps::CallbackHandler::handle
virtual void handle(ublox::Reader &reader)=0
Decode the u-blox message.
ublox_gps::CallbackHandler::condition_
boost::condition_variable condition_
Condition for the handler lock.
Definition: callback.h:60
ublox_gps::CallbackHandlers::insert
void insert(typename CallbackHandler_< T >::Callback callback, unsigned int message_id)
Definition: callback.h:146
ublox_gps::CallbackHandlers::readCallback
void readCallback(unsigned char *data, std::size_t &size)
Processes u-blox messages in the given buffer & clears the read messages from the buffer.
Definition: callback.h:235
ublox::Reader::iterator
const typedef uint8_t * iterator
ublox_gps::debug
int debug
Used to determine which debug messages to display.
Definition: async_worker.h:45


ublox_gps
Author(s): Johannes Meyer
autogenerated on Wed Dec 7 2022 03:47:53