I think it's clear that without the ability to poll multiple event sources, it's hard to implement efficient asynchronous IO. On the other hand, the opposite direction is really easy. Let's take the code from last time:
To perform a blocking receive, all you have to do is write this:rospy.poll(sub1, sub2) data = sub1.receive() if data is not None: rospy.loginfo(rospy.get_caller_id() + "I heard %s", data.data) data = sub2.receive() if data is not None: rospy.loginfo(rospy.get_caller_id() + "I heard %s", data.data)
rospy.poll(sub)
data = sub.receive()
So supporting polling does not push one into nonblocking IO, but not supporting it does push one into blocking IO.Now let's look a level higher at the actual messaging. ROS provides us with two tools here:
- topics allow multiple subscribers to receive all messages from multiple publishers;
- services allow multiple clients to send requests and receive replies from a single server.
Not on their own, but we could use a pair of topics or a pair of services to model a full-duplex connection:
orNode 1 Node 2 --- topic_12 --> Node 1 publishes to node 2 <-- topic_21 --- Node 2 publishes to node 1
In the first case, you basically send independent messages, in the second case each message gets a response as well. I also want to show a third topology:Node 1 Node 2 -- service_12 -> Node 1 is client of node 2 <- service_21 -- Node 2 is client of node 1
This is also full-duplex, and way better aligned to real-world needs. This approach comes rather naturally when designing a system:Node 1 Node 2 -- service_12 -> Node 1 is client of node 2 <-- topic_21 --- Node 2 publishes to node 1
- I (Node 1) want to give my robot (Node 2) commands, for this I need a service.
- I also want to know my robot's state, for this I need a topic.
- (and this approach, unlike the others, is easily extended to multiple clients)
No comments:
Post a Comment