-
Notifications
You must be signed in to change notification settings - Fork 0
/
slros_generic_pubsub.h
133 lines (114 loc) · 3.94 KB
/
slros_generic_pubsub.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/* Copyright 2014-2015 The MathWorks, Inc. */
#ifndef _SLROS_GENERIC_PUBSUB_H_
#define _SLROS_GENERIC_PUBSUB_H_
#include <iostream>
#include <ros/ros.h>
#include <ros/callback_queue.h>
extern ros::NodeHandle * SLROSNodePtr; ///< The global node handle that is used by all ROS entities in the model
/**
* Class for subscribing to ROS messages in C++.
*
* This class is used by code generated from the Simulink ROS
* subscriber blocks and is templatized by the ROS message type and
* Simulink bus type.
*/
template <class MsgType, class BusType>
class SimulinkSubscriber
{
public:
void subscriberCallback(const boost::shared_ptr<MsgType const>&);
void createSubscriber(std::string const& topic, uint32_t queueSize);
bool getLatestMessage(BusType* busPtr); // returns true iff message is new
private:
boost::shared_ptr<ros::CallbackQueue> _customCallbackQueuePtr;
ros::Subscriber _subscriber;
bool _newMessageReceived;
boost::shared_ptr<MsgType const> _lastMsgPtr;
};
/**
* Callback that is triggered when a new message is received
*
* This function will store the message as latest message.
* @param msgPtr The received message
*/
template <class MsgType, class BusType>
void SimulinkSubscriber<MsgType,BusType>::subscriberCallback(const boost::shared_ptr<MsgType const>& msgPtr)
{
_lastMsgPtr = msgPtr; // copy the shared_ptr
_newMessageReceived = true;
}
/**
* Create a C++ subscriber object
*
* @param topic The topic name to subscribe to
* @param queueSize The length of incoming message queue
*/
template <class MsgType, class BusType>
void SimulinkSubscriber<MsgType,BusType>::createSubscriber(std::string const& topic, uint32_t queueSize)
{
_customCallbackQueuePtr.reset( new ros::CallbackQueue() );
ros::SubscribeOptions opts;
opts.init<MsgType>(topic, queueSize,
boost::bind(&SimulinkSubscriber<MsgType,BusType>::subscriberCallback, this, _1));
opts.callback_queue = _customCallbackQueuePtr.get();
_subscriber = SLROSNodePtr->subscribe(opts);
}
/**
* Get the latest received message
*
* @param busPtr Simulink bus structure that should be populated with message contents
* @return =TRUE, then a new message has been received and *busPtr holds the newly-received message.
* =FALSE when a new message has not been received and *busPtr is unchanged.
*/
template <class MsgType, class BusType>
bool SimulinkSubscriber<MsgType,BusType>::getLatestMessage(BusType* busPtr)
{
_customCallbackQueuePtr->callOne();
if (_newMessageReceived) {
convertToBus(busPtr, _lastMsgPtr.get());
_newMessageReceived = false;
return true; // message is new
} else {
return false; // message is not new
}
}
/**
* Class for publishing ROS messages in C++.
*
* This class is used by code generated from the Simulink ROS
* publisher blocks and is templatized by the ROS message type and
* Simulink bus type.
*/
template <class MsgType, class BusType>
class SimulinkPublisher
{
public:
void createPublisher(std::string const& topic, uint32_t queueSize);
void publish(BusType* busPtr);
private:
ros::Publisher _publisher; ///< The ROS publisher object
MsgType _msg; ///< A prototype of the message to publish (will be filled based on Simulink bus structure)
};
/**
* Create a publisher to a topic
*
* @param topic The name of the topic to advertise
* @param queueSize The length of outgoing publishing message queue
*/
template <class MsgType, class BusType>
void SimulinkPublisher<MsgType,BusType>::createPublisher(std::string const& topic, uint32_t queueSize)
{
_publisher = SLROSNodePtr->advertise<MsgType>(topic, queueSize);
}
/**
* Publish a message
*
* @param busPtr Pointer to the bus structure for the outgoing message
*/
template <class MsgType, class BusType>
void SimulinkPublisher<MsgType,BusType>::publish(BusType* busPtr)
{
convertFromBus(&_msg, busPtr);
_publisher.publish(_msg);
}
#endif