Loading...
Searching...
No Matches
lcm-cpp.hpp
#ifndef __lcm_cpp_hpp__
#define __lcm_cpp_hpp__
#ifndef LCM_CXX_11_ENABLED
#if __cplusplus >= 201103L
#define LCM_CXX_11_ENABLED 1
#else
#define LCM_CXX_11_ENABLED 0
#endif
#endif
#include <cstdio> /* needed for FILE* */
#include <string>
#include <vector>
#include "lcm.h"
#if LCM_CXX_11_ENABLED
#include <functional>
#endif
namespace lcm {
class Subscription;
struct ReceiveBuffer;
class LCM {
public:
inline LCM(std::string lcm_url = "");
inline LCM(lcm_t *lcm_in);
inline ~LCM();
inline bool good() const;
inline int publish(const std::string &channel, const void *data, unsigned int datalen);
template <class MessageType>
inline int publish(const std::string &channel, const MessageType *msg);
inline int getFileno();
*
* @return 0 on success, -1 if something went wrong.
* @sa lcm_handle()
*/
inline int handle();
*
* @return >0 if a message was handled, 0 if the function timed out,
* and <0 if an error occured.
* @sa lcm_handle_timeout()
*/
inline int handleTimeout(int timeout_millis);
* arrives on the specified channel. Prior to method invocation, LCM
* will attempt to automatically decode the message to the specified
* message type @c MessageType @c , which should be a class generated
* by @c lcm-gen @c . If message
* decoding fails, the callback method is not invoked and an error
* message is printed to stderr.
*
* The callback method is invoked during calls to LCM::handle().
* Callback methods are invoked by the same thread that invokes
* LCM::handle(), in the order that they were subscribed.
*
* For example:
*
* \code
* #include <exlcm/example_t.lcm>
* #include <lcm/lcm-cpp.hpp>
*
* class MyMessageHandler {
* void onMessage(const lcm::ReceiveBuffer* rbuf, const std::string& channel,
* const exlcm::example_t* msg) {
* // do something with the message
* }
* };
*
* int main(int argc, char** argv) {
* lcm::LCM lcm;
* MyMessageHandler handler;
* lcm.subscribe("CHANNEL", &MyMessageHandler::onMessage, &handler);
* while(true)
* lcm.handle();
* return 0;
* }
* \endcode
*
* @param channel The channel to subscribe to. This is treated as a
* regular expression implicitly surrounded by '^' and '$'.
* @param handlerMethod A class method pointer identifying the callback
* method.
* @param handler A class instance that the callback method will be
* invoked on.
*
* @return a Subscription object that can be used to adjust the
* subscription and unsubscribe. The Subscription object is managed by
* the LCM class, and is automatically destroyed when its LCM instance
* is destroyed.
*/
template <class MessageType, class MessageHandlerClass>
Subscription *subscribe(const std::string &channel,
void (MessageHandlerClass::*handlerMethod)(const ReceiveBuffer *rbuf,
const std::string &channel,
const MessageType *msg),
MessageHandlerClass *handler);
* This method is designed for use when automatic message decoding is
* not desired.
*
* The callback method will be invoked on the object when a message
* arrives on the specified channel. Callback methods are invoked
* during calls to LCM::handle(), by the same thread that calls
* LCM::handle(). Callbacks are invoked in the order that they were
* subscribed.
*
* For example:
*
* \code
* #include <lcm/lcm-cpp.hpp>
*
* class MyMessageHandler {
* void onMessage(const lcm::ReceiveBuffer* rbuf, const std::string& channel) {
* // do something with the message. Raw message bytes are
* // accessible via rbuf->data
* }
* };
*
* int main(int argc, char** argv) {
* lcm::LCM lcm;
* MyMessageHandler handler;
* lcm.subscribe("CHANNEL", &MyMessageHandler::onMessage, &handler);
* while(true)
* lcm.handle();
* return 0;
* }
* \endcode
*
* @param channel The channel to subscribe to. This is treated as a
* regular expression implicitly surrounded by '^' and '$'.
* @param handlerMethod A class method pointer identifying the callback
* method.
* @param handler A class instance that the callback method will be
* invoked on.
*
* @return a Subscription object that can be used to adjust the
* subscription and unsubscribe. The Subscription object is managed by
* the LCM class, and is automatically destroyed when its LCM instance
* is destroyed.
*/
template <class MessageHandlerClass>
Subscription *subscribe(const std::string &channel,
void (MessageHandlerClass::*handlerMethod)(const ReceiveBuffer *rbuf,
const std::string &channel),
MessageHandlerClass *handler);
*
* This method is designed for use with static member functions and
* C-style functions.
*
* The callback function will be invoked on the object when a message
* arrives on the specified channel. Prior to callback invocation, LCM
* will attempt to automatically decode the message to the specified
* message type @c MessageType @c , which should be a class generated
* by @c lcm-gen @c . If message decoding fails, the callback function
* is not invoked and an error message is printed to stderr.
*
* The callback function is invoked during calls to LCM::handle().
* Callbacks are invoked by the same thread that invokes
* LCM::handle(), in the order that they were subscribed.
*
* For example:
*
* \code
* #include <lcm/lcm-cpp.hpp>
*
* class State {
* public:
* lcm::LCM lcm;
* int usefulVariable;
* };
*
* void onMessage(const lcm::ReceiveBuffer* rbuf, const std::string& channel, const MessageType*
* msg, State* state) {
* // do something with the message.
* }
*
* int main(int argc, char** argv) {
* State* state = new State;
* state->lcm.subscribe("CHANNEL", onMessage, state);
* while(true)
* state->lcm.handle();
* delete state;
* return 0;
* }
* \endcode
*
* @param channel The channel to subscribe to. This is treated as a
* regular expression implicitly surrounded by '^' and '$'.
* @param handler A function pointer identifying the callback
* function.
* @param context A context variable that will be passed to the
* callback function. This can be used to pass state or other
* information to the callback function. If not needed, then @c
* ContextClass @c can be set to void*, and this argument set to NULL.
*
* @return a Subscription object that can be used to adjust the
* subscription and unsubscribe. The Subscription object is managed by
* the LCM class, and is automatically destroyed when its LCM instance
* is destroyed.
*/
template <class MessageType, class ContextClass>
Subscription *subscribeFunction(const std::string &channel,
void (*handler)(const ReceiveBuffer *rbuf,
const std::string &channel,
const MessageType *msg, ContextClass context),
ContextClass context);
* This method is designed for use when automatic message decoding is
* not desired.
*
* For example:
*
* \code
* #include <lcm/lcm-cpp.hpp>
*
* void onMessage(const lcm::ReceiveBuffer* rbuf, const std::string& channel, void*) {
* // do something with the message. Raw message bytes are
* // accessible via rbuf->data
* }
*
* int main(int argc, char** argv) {
* LCM::lcm lcm;
* lcm.subscribe("CHANNEL", onMessage, NULL);
* while(true)
* lcm.handle();
* return 0;
* }
* \endcode
*
* @param channel The channel to subscribe to. This is treated as a
* regular expression implicitly surrounded by '^' and '$'.
* @param handler A function pointer identifying the callback
* function.
* @param context A context variable that will be passed to the
* callback function. This can be used to pass state or other
* information to the callback function. If not needed, then @c
* ContextClass @c can be set to void*, and this argument set to NULL.
*
* @return a Subscription object that can be used to adjust the
* subscription and unsubscribe. The Subscription object is managed by
* the LCM class, and is automatically destroyed when its LCM instance
* is destroyed.
*/
template <class ContextClass>
Subscription *subscribeFunction(const std::string &channel,
void (*handler)(const ReceiveBuffer *rbuf,
const std::string &channel,
ContextClass context),
ContextClass context);
#if LCM_CXX_11_ENABLED
template <class MessageType>
using HandlerFunction = std::function<void(const ReceiveBuffer *rbuf,
const std::string &channel, const MessageType *msg)>;
template <class MessageType>
Subscription *subscribe(const std::string &channel, HandlerFunction<MessageType> handler);
#endif
inline int unsubscribe(Subscription *subscription);
inline lcm_t *getUnderlyingLCM();
private:
lcm_t *lcm;
bool owns_lcm;
std::vector<Subscription *> subscriptions;
};
struct ReceiveBuffer {
void *data;
uint32_t data_size;
int64_t recv_utime;
};
class Subscription {
public:
virtual ~Subscription() {}
inline int setQueueCapacity(int num_messages);
inline int getQueueSize() const;
friend class LCM;
protected:
Subscription() { channel_buf.reserve(LCM_MAX_CHANNEL_NAME_LENGTH); };
lcm_subscription_t *c_subs;
// A "workspace" string that is overwritten with the channel name during
// message handling. This string serves to eliminate a heap allocation that
// would otherwise occur and which could preclude use in real-time
// applications.
std::string channel_buf;
};
struct LogEvent {
int64_t eventnum;
int64_t timestamp;
std::string channel;
int32_t datalen;
void *data;
};
class LogFile {
public:
inline LogFile(const std::string &path, const std::string &mode);
inline ~LogFile();
inline bool good() const;
inline const LogEvent *readNextEvent();
inline int seekToTimestamp(int64_t timestamp);
inline int writeEvent(LogEvent *event);
inline FILE *getFilePtr();
private:
LogEvent curEvent;
lcm_eventlog_t *eventlog;
lcm_eventlog_event_t *last_event;
};
#define __lcm_cpp_impl_ok__
#include "lcm-cpp-impl.hpp"
#undef __lcm_cpp_impl_ok__
} // namespace lcm
#endif
lcm::LCM::HandlerFunction
std::function< void(const ReceiveBuffer *rbuf, const std::string &channel, const MessageType *msg)> HandlerFunction
Definition lcm-cpp.hpp:376
lcm::LCM::subscribe
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::LCM::LCM
LCM(std::string lcm_url="")
Constructor.
Definition lcm-cpp.hpp:128
lcm::LCM::subscribe
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
lcm::LCM::subscribeFunction
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::LCM::~LCM
~LCM()
Destructor.
Definition lcm-cpp.hpp:143
lcm::LCM::good
bool good() const
Checks if initialization succeeded during object construction.
Definition lcm-cpp.hpp:138
lcm::LCM::getUnderlyingLCM
lcm_t * getUnderlyingLCM()
retrives the lcm_t C data structure wrapped by this class.
Definition lcm-cpp.hpp:318
lcm::LCM::publish
int publish(const std::string &channel, const void *data, unsigned int datalen)
Publishes a raw data message.
Definition lcm-cpp.hpp:153
lcm::LCM::handleTimeout
int handleTimeout(int timeout_millis)
Waits for and dispatches messages, with a timeout.
Definition lcm-cpp.hpp:210
lcm::LCM::handle
int handle()
Waits for and dispatches messages.
Definition lcm-cpp.hpp:201
lcm::LCM::getFileno
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
lcm::LCM::unsubscribe
int unsubscribe(Subscription *subscription)
Unsubscribes a message handler.
Definition lcm-cpp.hpp:173
lcm::LogFile::readNextEvent
const LogEvent * readNextEvent()
Definition lcm-cpp.hpp:343
lcm::LogFile::good
bool good() const
Definition lcm-cpp.hpp:338
lcm::LogFile::writeEvent
int writeEvent(LogEvent *event)
Definition lcm-cpp.hpp:364
lcm::LogFile::~LogFile
~LogFile()
Definition lcm-cpp.hpp:328
lcm::LogFile::getFilePtr
FILE * getFilePtr()
retrives the underlying FILE* wrapped by this class.
Definition lcm-cpp.hpp:376
lcm::LogFile::seekToTimestamp
int seekToTimestamp(int64_t timestamp)
Definition lcm-cpp.hpp:359
lcm::LogFile::LogFile
LogFile(const std::string &path, const std::string &mode)
Definition lcm-cpp.hpp:323
lcm::Subscription
Represents a channel subscription, and can be used to unsubscribe and set options.
Definition lcm-cpp.hpp:500
lcm::Subscription::getQueueSize
int getQueueSize() const
Query the current number of unhandled messages queued up for this subscription.
Definition lcm-cpp.hpp:15
lcm::Subscription::c_subs
lcm_subscription_t * c_subs
Definition lcm-cpp.hpp:534
lcm::Subscription::setQueueCapacity
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
lcm_subscription_t
struct _lcm_subscription_t lcm_subscription_t
Definition lcm.h:55
lcm_t
struct _lcm_t lcm_t
Definition lcm.h:50
lcm::LogEvent
Represents a single event (message) in a log file.
Definition lcm-cpp.hpp:554
lcm::LogEvent::data
void * data
Definition lcm-cpp.hpp:576
lcm::LogEvent::eventnum
int64_t eventnum
Definition lcm-cpp.hpp:559
lcm::LogEvent::channel
std::string channel
Definition lcm-cpp.hpp:568
lcm::LogEvent::timestamp
int64_t timestamp
Definition lcm-cpp.hpp:564
lcm::LogEvent::datalen
int32_t datalen
Definition lcm-cpp.hpp:572
lcm::ReceiveBuffer
Stores the raw bytes and timestamp of a received message.
Definition lcm-cpp.hpp:471
lcm::ReceiveBuffer::data
void * data
Definition lcm-cpp.hpp:475
lcm::ReceiveBuffer::data_size
uint32_t data_size
Definition lcm-cpp.hpp:479
lcm::ReceiveBuffer::recv_utime
int64_t recv_utime
Definition lcm-cpp.hpp:484