ROS Actions

ROS Actions. Similar to an ROS Service except you can do other things while the action is running. Actions are asynchronous.

ROS Actions

Similar to an ROS Service except you can do other things while the action is running. Actions are asynchronous.

Action Servers and Action Clients

Action Server contains the functionality

Action Client calls the Action Server to perform a functionality.

Commands

1
rostopic list  # Look for /<action_server_name>/<unique_msg>

Action Message

Message that defines an action. It contains 3 parts: Goal, Result, Feedback.

Goal is the arguments for the action.

Result is the result when the action is complete.

Feedback is feedback as the action is in progress

1
2
3
4
5
6
7
8
# Goal
int32 nseconds
---
# Result
sensor_msgs/CompressedImage[] allPictures
---
# Feedback
sensor_msgs/CompressedImage lastImage

Python ROS Action Client

 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
import rospy
import time
import actionlib
from ardrone_as.msg import ArdroneAction, ArdroneGoal, ArdroneResult, ArdroneFeedback

nImage = 1

# Feedback callback
def feedback_callback(feedback):
    global nImage
    print('[Feedback] image n.%d received'%nImage)
    nImage += 1

# Init the action client node
rospy.init_node('drone_action_client')

# Create connection to the action server
client = actionlib.SimpleActionClient('/ardrone_action_server', ArdroneAction)
# waits until the action server is up and running
client.wait_for_server()

# create a goal to send to the action server
goal = ArdroneGoal()
goal.nseconds = 10

# Send the goal to the action server, specifying which feedback function
# to call when feeback received
client.send_goal(goal, feeback_cb=feedback_callback)

client.wait_for_result()

print('[Result] State: %d'%(client.get_state()))

Wait for Result

Using ```wait_for_result()`` is like using a service.

Get State

Instead of waiting for result, you can call get_state() and continue to run while it is running.

1
2
3
4
5
0 = PENDING
1 = ACTIVE
2 = DONE
3 = WARN
4 = ERROR

Use a While loop and while the value returned is less than 2, you know it is still running.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
PENDING = 0
ACTIVE = 1
DONE = 2
WARN = 3
ERROR = 4

state_result = client.get_state()

rate = rospy.Rate(1)

rospy.loginfo("state_result " + str(state_result))

while state_result < DONE:
    rospy.loginfo("Doing Stuff while waiting for the server to give a result...")
    rate.sleep()
    state_result = client.get_state()
    rospy.loginfo("state_result: " + str(state_result))

rospy.loginfo("[Result] State: " + str(state_result))
if state_result == ERROR:
    rospy.logerr("Something went wrong in the server side")
if state_result == WARN:
    rospy.logwarn("There is a warning in the Server Side")

More Details

comments powered by Disqus