6.4 Typical Use Cases For Subcribers
A set of use cases have been deemed to be common and will be detailed below in order to give a good starting point for customer specific solutions.
6.4.1 Reacting to new messages on a topic
If you are waiting for an event that is published on a given topic, you can use the read() method on the subscriber handle directly. It will block until such a message arrives.
# Place the following somewhere it will only be executed once, such as BeforeStart
myHandle = ros_subscriber_factory(topic="<your topic here>", msg_type="<your message type here>")
# The following call will block until a new message is available.
myMessage = myHandle.read()
6.4.2 Getting the latest message from a subscriber
If you read from a topic publishing state changes, and want the latest state published, you need to access the history of the topic.
# Place the following somewhere it will only be executed once, such as BeforeStart
myHandle = ros_subscriber_factory(topic="<your topic here>", msg_type="<your message type here>", history="keep_last", depth=1, durability="transient_local")
# The following call will return immediately with an anonymous struct containing at most one item
lastMessageList = myHandle.read_history(1)
# Only if a message existed in the history will the anonymous struct have any members
if length(lastMessageList)>0:
lastMessage = lastMessageList[0]
end
Note that the subscriber is created specifying three optional parameters:
history=”keep_last” means that the subscriber expects a history to be used.
depth=1 means that only the last item remains in the history
durability=”transient_local” mean we require the publisher to keep track of previous messages for us, so that we can access messages published before we started subscribing. If the publisher does not do so, the call will fail with a runtime exception.
It is also important to realize that ROS2 guarantees a message will only be read by each subscriber once. Thus when a state has been extracted, it should be stored locally as subsequent return values from read_history will have no members until another state change is published.
6.4.3 Reacting to all messages
No guarantee can be given that all messages can be reacted to, as any publisher might be able to produce more data that can be handled by a subscriber. Any messages published that is not read before the history is full will be dropped.
In practice all messages can be read from nearly all topics, and this is done using read_history:
# Place the following somewhere it will only be executed once, such as BeforeStart
myHandle = ros_subscriber_factory(topic="<your topic here>", msg_type="<your message type here>", history="keep_all")
while (True):
# The following call will return immediately with an anonymous struct containing at most ten items
messageList = myHandle.read_history(10)
# Only if a message existed in the history will the anonymous struct have any members
i = 0
while (i<length(messageList)):
nextMessage = messageList[0]
# handle nextMessage
i = i + 1
end
end
The subscriber is configured to retain all messages, and will consume excessive amount of memory if the subscriber is unable to keep up. Keeping a limited history should be considered if missing messages is acceptable.
The code will loop indefinitely, and read up to 10 items at a time from the topics history, beginning with the oldest message. Each read_history has an overhead of at least a few milliseconds, and the more is read at once, the less of these overheads are incurred. 10 is arbitrarily chosen, but it will allocate space for the maximum number of messages, and as such restraint should be exercised.