LCM
Loading...
Searching...
No Matches
lcm-cpp.hpp
1#ifndef __lcm_cpp_hpp__
2#define __lcm_cpp_hpp__
3
4#ifndef LCM_CXX_11_ENABLED
5#if __cplusplus >= 201103L
6#define LCM_CXX_11_ENABLED 1
7#else
8#define LCM_CXX_11_ENABLED 0
9#endif
10#endif
11
12#include <cstdio> /* needed for FILE* */
13#include <string>
14#include <vector>
16#include "lcm.h"
17
18#if LCM_CXX_11_ENABLED
19#include <functional>
20#endif
21
22namespace lcm {
23
34
35class Subscription;
36
37struct ReceiveBuffer;
38
44class LCM {
45 public:
55 inline LCM(std::string lcm_url = "");
56
64 inline LCM(lcm_t *lcm_in);
65
72 inline ~LCM();
73
81 inline bool good() const;
82
92 inline int publish(const std::string &channel, const void *data, unsigned int datalen);
93
105 template <class MessageType>
106 inline int publish(const std::string &channel, const MessageType *msg);
107
124 inline int getFileno();
125
129 * @return 0 on success, -1 if something went wrong.
130 * @sa lcm_handle()
131 */
132 inline int handle();
137
139 * @return >0 if a message was handled, 0 if the function timed out,
140 * and <0 if an error occured.
141 * @sa lcm_handle_timeout()
142 */
143 inline int handleTimeout(int timeout_millis);
144
152
153 * arrives on the specified channel. Prior to method invocation, LCM
154 * will attempt to automatically decode the message to the specified
155 * message type @c MessageType @c , which should be a class generated
156 * by @c lcm-gen @c . If message
157 * decoding fails, the callback method is not invoked and an error
158 * message is printed to stderr.
159 *
160 * The callback method is invoked during calls to LCM::handle().
161 * Callback methods are invoked by the same thread that invokes
162 * LCM::handle(), in the order that they were subscribed.
164 * For example:
165 *
166 * \code
167 * #include <exlcm/example_t.lcm>
168 * #include <lcm/lcm-cpp.hpp>
169 *
170 * class MyMessageHandler {
171 * void onMessage(const lcm::ReceiveBuffer* rbuf, const std::string& channel,
172 * const exlcm::example_t* msg) {
173 * // do something with the message
174 * }
175 * };
176 *
177 * int main(int argc, char** argv) {
178 * lcm::LCM lcm;
179 * MyMessageHandler handler;
180 * lcm.subscribe("CHANNEL", &MyMessageHandler::onMessage, &handler);
181 * while(true)
182 * lcm.handle();
183 * return 0;
184 * }
185 * \endcode
186 *
187 * @param channel The channel to subscribe to. This is treated as a
188 * regular expression implicitly surrounded by '^' and '$'.
189 * @param handlerMethod A class method pointer identifying the callback
190 * method.
191 * @param handler A class instance that the callback method will be
192 * invoked on.
193 *
194 * @return a Subscription object that can be used to adjust the
195 * subscription and unsubscribe. The Subscription object is managed by
196 * the LCM class, and is automatically destroyed when its LCM instance
197 * is destroyed.
198 */
199 template <class MessageType, class MessageHandlerClass>
200 Subscription *subscribe(const std::string &channel,
201 void (MessageHandlerClass::*handlerMethod)(const ReceiveBuffer *rbuf,
202 const std::string &channel,
203 const MessageType *msg),
204 MessageHandlerClass *handler);
205
209
210 * This method is designed for use when automatic message decoding is
211 * not desired.
212 *
213 * The callback method will be invoked on the object when a message
214 * arrives on the specified channel. Callback methods are invoked
215 * during calls to LCM::handle(), by the same thread that calls
216 * LCM::handle(). Callbacks are invoked in the order that they were
217 * subscribed.
218 *
219 * For example:
221 * \code
222 * #include <lcm/lcm-cpp.hpp>
223 *
224 * class MyMessageHandler {
225 * void onMessage(const lcm::ReceiveBuffer* rbuf, const std::string& channel) {
226 * // do something with the message. Raw message bytes are
227 * // accessible via rbuf->data
228 * }
229 * };
230 *
231 * int main(int argc, char** argv) {
232 * lcm::LCM lcm;
233 * MyMessageHandler handler;
234 * lcm.subscribe("CHANNEL", &MyMessageHandler::onMessage, &handler);
235 * while(true)
236 * lcm.handle();
237 * return 0;
238 * }
239 * \endcode
240 *
241 * @param channel The channel to subscribe to. This is treated as a
242 * regular expression implicitly surrounded by '^' and '$'.
243 * @param handlerMethod A class method pointer identifying the callback
244 * method.
245 * @param handler A class instance that the callback method will be
246 * invoked on.
247 *
248 * @return a Subscription object that can be used to adjust the
249 * subscription and unsubscribe. The Subscription object is managed by
250 * the LCM class, and is automatically destroyed when its LCM instance
251 * is destroyed.
252 */
253 template <class MessageHandlerClass>
254 Subscription *subscribe(const std::string &channel,
255 void (MessageHandlerClass::*handlerMethod)(const ReceiveBuffer *rbuf,
256 const std::string &channel),
257 MessageHandlerClass *handler);
258
260
263 * This method is designed for use with static member functions and
264 * C-style functions.
265 *
266 * The callback function will be invoked on the object when a message
267 * arrives on the specified channel. Prior to callback invocation, LCM
268 * will attempt to automatically decode the message to the specified
269 * message type @c MessageType @c , which should be a class generated
270 * by @c lcm-gen @c . If message decoding fails, the callback function
271 * is not invoked and an error message is printed to stderr.
272 *
273 * The callback function is invoked during calls to LCM::handle().
274 * Callbacks are invoked by the same thread that invokes
275 * LCM::handle(), in the order that they were subscribed.
276 *
277 * For example:
278 *
279 * \code
280 * #include <lcm/lcm-cpp.hpp>
281 *
282 * class State {
283 * public:
284 * lcm::LCM lcm;
285 * int usefulVariable;
286 * };
287 *
288 * void onMessage(const lcm::ReceiveBuffer* rbuf, const std::string& channel, const MessageType*
289 * msg, State* state) {
290 * // do something with the message.
291 * }
292 *
293 * int main(int argc, char** argv) {
294 * State* state = new State;
295 * state->lcm.subscribe("CHANNEL", onMessage, state);
296 * while(true)
297 * state->lcm.handle();
298 * delete state;
299 * return 0;
300 * }
301 * \endcode
302 *
303 * @param channel The channel to subscribe to. This is treated as a
304 * regular expression implicitly surrounded by '^' and '$'.
305 * @param handler A function pointer identifying the callback
306 * function.
307 * @param context A context variable that will be passed to the
308 * callback function. This can be used to pass state or other
309 * information to the callback function. If not needed, then @c
310 * ContextClass @c can be set to void*, and this argument set to NULL.
311 *
312 * @return a Subscription object that can be used to adjust the
313 * subscription and unsubscribe. The Subscription object is managed by
314 * the LCM class, and is automatically destroyed when its LCM instance
315 * is destroyed.
316 */
317 template <class MessageType, class ContextClass>
318 Subscription *subscribeFunction(const std::string &channel,
319 void (*handler)(const ReceiveBuffer *rbuf,
320 const std::string &channel,
321 const MessageType *msg, ContextClass context),
322 ContextClass context);
327
328 * This method is designed for use when automatic message decoding is
329 * not desired.
330 *
331 * For example:
332 *
333 * \code
334 * #include <lcm/lcm-cpp.hpp>
335 *
336 * void onMessage(const lcm::ReceiveBuffer* rbuf, const std::string& channel, void*) {
337 * // do something with the message. Raw message bytes are
338 * // accessible via rbuf->data
339 * }
340 *
341 * int main(int argc, char** argv) {
342 * LCM::lcm lcm;
343 * lcm.subscribe("CHANNEL", onMessage, NULL);
344 * while(true)
345 * lcm.handle();
346 * return 0;
347 * }
348 * \endcode
349 *
350 * @param channel The channel to subscribe to. This is treated as a
351 * regular expression implicitly surrounded by '^' and '$'.
352 * @param handler A function pointer identifying the callback
353 * function.
354 * @param context A context variable that will be passed to the
355 * callback function. This can be used to pass state or other
356 * information to the callback function. If not needed, then @c
357 * ContextClass @c can be set to void*, and this argument set to NULL.
358 *
359 * @return a Subscription object that can be used to adjust the
360 * subscription and unsubscribe. The Subscription object is managed by
361 * the LCM class, and is automatically destroyed when its LCM instance
362 * is destroyed.
363 */
364 template <class ContextClass>
365 Subscription *subscribeFunction(const std::string &channel,
366 void (*handler)(const ReceiveBuffer *rbuf,
367 const std::string &channel,
368 ContextClass context),
369 ContextClass context);
370
371#if LCM_CXX_11_ENABLED
375 template <class MessageType>
376 using HandlerFunction = std::function<void(const ReceiveBuffer *rbuf,
377 const std::string &channel, const MessageType *msg)>;
380
426 template <class MessageType>
427 Subscription *subscribe(const std::string &channel, HandlerFunction<MessageType> handler);
428#endif
429
444 inline int unsubscribe(Subscription *subscription);
445
457 inline lcm_t *getUnderlyingLCM();
458
459 private:
460 lcm_t *lcm;
461 bool owns_lcm;
462
463 std::vector<Subscription *> subscriptions;
464};
465
475 void *data;
479 uint32_t data_size;
484 int64_t recv_utime;
485};
486
500class Subscription {
501 public:
502 virtual ~Subscription() {}
517 inline int setQueueCapacity(int num_messages);
518
523 inline int getQueueSize() const;
524
525 friend class LCM;
526
527 protected:
528 Subscription() { channel_buf.reserve(LCM_MAX_CHANNEL_NAME_LENGTH); };
529
535
536 // A "workspace" string that is overwritten with the channel name during
537 // message handling. This string serves to eliminate a heap allocation that
538 // would otherwise occur and which could preclude use in real-time
539 // applications.
540 std::string channel_buf;
541};
542
554struct LogEvent {
559 int64_t eventnum;
564 int64_t timestamp;
568 std::string channel;
572 int32_t datalen;
576 void *data;
577};
578
588class LogFile {
589 public:
597 inline LogFile(const std::string &path, const std::string &mode);
598
602 inline ~LogFile();
603
607 inline bool good() const;
608
618 inline const LogEvent *readNextEvent();
619
629 inline int seekToTimestamp(int64_t timestamp);
630
641 inline int writeEvent(LogEvent *event);
642
653 inline FILE *getFilePtr();
654
655 private:
656 LogEvent curEvent;
657 lcm_eventlog_t *eventlog;
658 lcm_eventlog_event_t *last_event;
659};
660
664
665#define __lcm_cpp_impl_ok__
666#include "lcm-cpp-impl.hpp"
667#undef __lcm_cpp_impl_ok__
668} // namespace lcm
669
670#endif
std::function< void(const ReceiveBuffer *rbuf, const std::string &channel, const MessageType *msg)> HandlerFunction
Definition lcm-cpp.hpp:376
Subscription * subscribe(const std::string &channel, void(MessageHandlerClass::*handlerMethod)(const ReceiveBuffer *rbuf, const std::string &channel), MessageHandlerClass *handler)
Subscribe a callback method of an object to a channel, without automatic message decoding.
Definition lcm-cpp.hpp:242
LCM(std::string lcm_url="")
Constructor.
Definition lcm-cpp.hpp:128
Subscription * subscribe(const std::string &channel, void(MessageHandlerClass::*handlerMethod)(const ReceiveBuffer *rbuf, const std::string &channel, const MessageType *msg), MessageHandlerClass *handler)
Subscribes a callback method of an object to a channel, with automatic message decoding.
Definition lcm-cpp.hpp:220
Subscription * subscribeFunction(const std::string &channel, void(*handler)(const ReceiveBuffer *rbuf, const std::string &channel, const MessageType *msg, ContextClass context), ContextClass context)
Subscribe a function callback to a channel, with automatic message decoding.
Definition lcm-cpp.hpp:262
~LCM()
Destructor.
Definition lcm-cpp.hpp:143
bool good() const
Checks if initialization succeeded during object construction.
Definition lcm-cpp.hpp:138
lcm_t * getUnderlyingLCM()
retrives the lcm_t C data structure wrapped by this class.
Definition lcm-cpp.hpp:318
int publish(const std::string &channel, const void *data, unsigned int datalen)
Publishes a raw data message.
Definition lcm-cpp.hpp:153
int handleTimeout(int timeout_millis)
Waits for and dispatches messages, with a timeout.
Definition lcm-cpp.hpp:210
int handle()
Waits for and dispatches messages.
Definition lcm-cpp.hpp:201
int getFileno()
Returns a file descriptor or socket that can be used with select(), poll(), or other event loops for ...
Definition lcm-cpp.hpp:192
int unsubscribe(Subscription *subscription)
Unsubscribes a message handler.
Definition lcm-cpp.hpp:173
const LogEvent * readNextEvent()
Definition lcm-cpp.hpp:343
bool good() const
Definition lcm-cpp.hpp:338
int writeEvent(LogEvent *event)
Definition lcm-cpp.hpp:364
~LogFile()
Definition lcm-cpp.hpp:328
FILE * getFilePtr()
retrives the underlying FILE* wrapped by this class.
Definition lcm-cpp.hpp:376
int seekToTimestamp(int64_t timestamp)
Definition lcm-cpp.hpp:359
LogFile(const std::string &path, const std::string &mode)
Definition lcm-cpp.hpp:323
Represents a channel subscription, and can be used to unsubscribe and set options.
Definition lcm-cpp.hpp:500
int getQueueSize() const
Query the current number of unhandled messages queued up for this subscription.
Definition lcm-cpp.hpp:15
lcm_subscription_t * c_subs
Definition lcm-cpp.hpp:534
int setQueueCapacity(int num_messages)
Adjusts the maximum number of received messages that can be queued up for this subscription.
Definition lcm-cpp.hpp:10
struct _lcm_subscription_t lcm_subscription_t
Definition lcm.h:55
struct _lcm_t lcm_t
Definition lcm.h:50
Represents a single event (message) in a log file.
Definition lcm-cpp.hpp:554
void * data
Definition lcm-cpp.hpp:576
int64_t eventnum
Definition lcm-cpp.hpp:559
std::string channel
Definition lcm-cpp.hpp:568
int64_t timestamp
Definition lcm-cpp.hpp:564
int32_t datalen
Definition lcm-cpp.hpp:572
Stores the raw bytes and timestamp of a received message.
Definition lcm-cpp.hpp:471
void * data
Definition lcm-cpp.hpp:475
uint32_t data_size
Definition lcm-cpp.hpp:479
int64_t recv_utime
Definition lcm-cpp.hpp:484