Documentation Status

common: actionlib | bfl | tinyxml | yaml_cpp

Package Summary

Documented

The actionlib package provides a standardized interface for interfacing with preemptible tasks. Examples of this include moving the base to a target location, performing a laser scan and returning the resulting point cloud, detecting the handle of a door, etc.

actionlib

Package Summary

Documented

The actionlib package provides a standardized interface for interfacing with preemptible tasks. Examples of this include moving the base to a target location, performing a laser scan and returning the resulting point cloud, detecting the handle of a door, etc.

Package Summary

Released Continuous integration Documented

The actionlib stack provides a standardized interface for interfacing with preemptable tasks. Examples of this include moving the base to a target location, performing a laser scan and returning the resulting point cloud, detecting the handle of a door, etc.

  • Maintainer status: maintained
  • Maintainer: Dirk Thomas <dthomas AT osrfoundation DOT org>
  • Author: Eitan Marder-Eppstein, Vijay Pradeep
  • License: BSD
  • Source: git https://github.com/ros/actionlib.git (branch: groovy-devel)

Package Summary

Released Continuous integration Documented

The actionlib stack provides a standardized interface for interfacing with preemptable tasks. Examples of this include moving the base to a target location, performing a laser scan and returning the resulting point cloud, detecting the handle of a door, etc.

  • Maintainer status: maintained
  • Maintainer: Esteve Fernandez <esteve AT osrfoundation DOT org>
  • Author: Eitan Marder-Eppstein, Vijay Pradeep
  • License: BSD
  • Source: git https://github.com/ros/actionlib.git (branch: hydro-devel)

Package Summary

Released Continuous integration Documented

The actionlib stack provides a standardized interface for interfacing with preemptable tasks. Examples of this include moving the base to a target location, performing a laser scan and returning the resulting point cloud, detecting the handle of a door, etc.

  • Maintainer status: maintained
  • Maintainer: Esteve Fernandez <esteve AT osrfoundation DOT org>
  • Author: Eitan Marder-Eppstein, Vijay Pradeep
  • License: BSD
  • Source: git https://github.com/ros/actionlib.git (branch: indigo-devel)
Cannot load information on name: actionlib, distro: jade, which means that it is not yet in our index. Please see this page for information on how to submit your repository to our index.

Overview

In any large ROS based system, there are cases when someone would like to send a request to a node to perform some task, and also receive a reply to the request. This can currently be achieved via ROS services.

In some cases, however, if the service takes a long time to execute, the user might want the ability to cancel the request during execution or get periodic feedback about how the request is progressing. The actionlib package provides tools to create servers that execute long-running goals that can be preempted. It also provides a client interface in order to send requests to the server.

Detailed Description

For a full discussion of how actionlib operates "under the hood", please see the Detailed Description.

Client-Server Interaction

The ActionClient and ActionServer communicate via a "ROS Action Protocol", which is built on top of ROS messages. The client and server then provide a simple API for users to request goals (on the client side) or to execute goals (on the server side) via function calls and callbacks.

client_server_interaction.png

Action Specification: Goal, Feedback, & Result

In order for the client and server to communicate, we need to define a few messages on which they communicate. This is with an action specification. This defines the Goal, Feedback, and Result messages with which clients and servers communicate:

Goal
To accomplish tasks using actions, we introduce the notion of a goal that can be sent to an ActionServer by an ActionClient. In the case of moving the base, the goal would be a PoseStamped message that contains information about where the robot should move to in the world. For controlling the tilting laser scanner, the goal would contain the scan parameters (min angle, max angle, speed, etc).

Feedback
Feedback provides server implementers a way to tell an ActionClient about the incremental progress of a goal. For moving the base, this might be the robot's current pose along the path. For controlling the tilting laser scanner, this might be the time left until the scan completes.

Result
A result is sent from the ActionServer to the ActionClient upon completion of the goal. This is different than feedback, since it is sent exactly once. This is extremely useful when the purpose of the action is to provide some sort of information. For move base, the result isn't very important, but it might contain the final pose of the robot. For controlling the tilting laser scanner, the result might contain a point cloud generated from the requested scan.

.action File

The action specification is defined using a .action file. The .action file has the goal definition, followed by the result definition, followed by the feedback definition, with each section separated by 3 hyphens (---).

These files are placed in a package's ./action directory, and look extremely similar to a service's .srv file. An action specification for doing the dishes might look like the following:

./action/DoDishes.action

# Define the goal
uint32 dishwasher_id  # Specify which dishwasher we want to use
---
# Define the result
uint32 total_dishes_cleaned
---
# Define a feedback message
float32 percent_complete

Based on this .action file, 6 messages need to be generated in order for the client and server to communicate. This generation can be automatically triggered during the make process:

Catkin

Add the following to your CMakeLists.txt file before catkin_package().

find_package(catkin REQUIRED genmsg actionlib_msgs actionlib)
add_action_files(DIRECTORY action FILES DoDishes.action)
generate_messages(DEPENDENCIES actionlib_msgs)

Additionally, the package's package.xml must include the following dependencies:

<build_depend>actionlib</build_depend>
<build_depend>actionlib_msgs</build_depend>
<run_depend>actionlib</run_depend>
<run_depend>actionlib_msgs</run_depend>

Rosbuild

If you are using rosbuild instead of catkin, instead add the following before rosbuild_init().

rosbuild_find_ros_package(actionlib_msgs)
include(${actionlib_msgs_PACKAGE_PATH}/cmake/actionbuild.cmake)
genaction()

Then, after the output paths, uncomment (or add)

rosbuild_genmsg()

Note: rosbuild_genmsg() must be called after the output paths have been set.

For 1.0 series (i.e. boxturtle) use:

rosbuild_find_ros_package(actionlib)
include(${actionlib_PACKAGE_PATH}/cmake/actionbuild.cmake)
genaction()
rosbuild_genmsg()

Additionally, the package's manifest.xml must include the following dependencies:

<depend package="actionlib"/>
<depend package="actionlib_msgs"/>

Results

For the DoDishes.action, the following messages are generated by genaction.py:

  • DoDishesAction.msg

  • DoDishesActionGoal.msg

  • DoDishesActionResult.msg

  • DoDishesActionFeedback.msg

  • DoDishesGoal.msg

  • DoDishesResult.msg

  • DoDishesFeedback.msg

These messages are then used internally by actionlib to communicate between the ActionClient and ActionServer.

Using the ActionClient

C++ SimpleActionClient

Full API Reference for the C++ SimpleActionClient

Quickstart Guide:
Suppose you have defined DoDishes.action in the chores package. The following snippet shows how to send a goal to a DoDishes ActionServer called "do_dishes".

   1 #include <chores/DoDishesAction.h>
   2 #include <actionlib/client/simple_action_client.h>
   3 
   4 typedef actionlib::SimpleActionClient<chores::DoDishesAction> Client;
   5 
   6 int main(int argc, char** argv)
   7 {
   8   ros::init(argc, argv, "do_dishes_client");
   9   Client client("do_dishes", true); // true -> don't need ros::spin()
  10   client.waitForServer();
  11   chores::DoDishesGoal goal;
  12   // Fill in goal here
  13   client.sendGoal(goal);
  14   client.waitForResult(ros::Duration(5.0));
  15   if (client.getState() == actionlib::SimpleClientGoalState::SUCCEEDED)
  16     printf("Yay! The dishes are now clean");
  17   printf("Current State: %s\n", client.getState().toString().c_str());
  18   return 0;
  19 }

Note: For the C++ SimpleActionClient, the waitForServer method will only work if a separate thread is servicing the client's callback queue. This requires passing in true for the spin_thread option of the client's constructor, running with a multi-threaded spinner, or using your own thread to service ROS callback queues.

Python SimpleActionClient

Full API reference for the Python SimpleActionClient

Suppose the DoDishes.action exists in the chores package. The following snippet shows how to send a goal to a DoDishes ActionServer called "do_dishes" using Python.

   1 #! /usr/bin/env python
   2 
   3 import roslib; roslib.load_manifest('my_pkg_name')
   4 import rospy
   5 import actionlib
   6 
   7 from chores.msg import *
   8 
   9 if __name__ == '__main__':
  10     rospy.init_node('do_dishes_client')
  11     client = actionlib.SimpleActionClient('do_dishes', DoDishesAction)
  12     client.wait_for_server()
  13 
  14     goal = DoDishesGoal()
  15     # Fill in the goal here
  16     client.send_goal(goal)
  17     client.wait_for_result(rospy.Duration.from_sec(5.0))

Implementing an ActionServer

C++ SimpleActionServer

Full API Reference for the C++ SimpleActionServer

Quickstart Guide:
Suppose you have defined DoDishes.action in the chores package. The following snippet shows how to write a DoDishes ActionServer called "do_dishes".

   1 #include <chores/DoDishesAction.h>
   2 #include <actionlib/server/simple_action_server.h>
   3 
   4 typedef actionlib::SimpleActionServer<chores::DoDishesAction> Server;
   5 
   6 void execute(const chores::DoDishesGoalConstPtr& goal, Server* as)
   7 {
   8   // Do lots of awesome groundbreaking robot stuff here
   9   as->setSucceeded();
  10 }
  11 
  12 int main(int argc, char** argv)
  13 {
  14   ros::init(argc, argv, "do_dishes_server");
  15   ros::NodeHandle n;
  16   Server server(n, "do_dishes", boost::bind(&execute, _1, &server), false);
  17   server.start();
  18   ros::spin();
  19   return 0;
  20 }

Python SimpleActionServer

Full API Reference for the Python SimpleActionServer

Quickstart Guide:
Suppose you have defined DoDishes.action in the chores package. The following snippet shows how to write a DoDishes ActionServer called "do_dishes".

   1 #! /usr/bin/env python
   2 
   3 import roslib; roslib.load_manifest('my_pkg_name')
   4 import rospy
   5 import actionlib
   6 
   7 from chores.msg import *
   8 
   9 class DoDishesServer:
  10   def __init__(self):
  11     self.server = actionlib.SimpleActionServer('do_dishes', DoDishesAction, self.execute, False)
  12     self.server.start()
  13 
  14   def execute(self, goal):
  15     # Do lots of awesome groundbreaking robot stuff here
  16     self.server.set_succeeded()
  17 
  18 
  19 if __name__ == '__main__':
  20   rospy.init_node('do_dishes_server')
  21   server = DoDishesServer()
  22   rospy.spin()

SimpleActionServer Goal Policies

The SimpleActionServer implements a single goal policy on top of the ActionServer class. The specification of the policy is as follows:

  • Only one goal can have an active status at a time
  • New goals preempt previous goals based on the stamp in their GoalID field (later goals preempt earlier ones)
  • An explicit preempt goal preempts all goals with timestamps that are less than or equal to the stamp associated with the preempt
  • Accepting a new goal implies successful preemption of any old goal and the status of the old goal will be change automatically to reflect this

Calling acceptNewGoal accepts a new goal when one is available The status of this goal is set to active upon acceptance, and the status of any previously active goal is set to preempted. Preempts received for the new goal between checking if isNewGoalAvailable or invokation of a goal callback and the acceptNewGoal call will not trigger a preempt callback. This means, isPreemptRequested should be called after accepting the goal even for callback-based implementations to make sure the new goal does not have a pending preempt request.

Tutorials

Please refer to the Tutorials page

Report a Bug

Use trac to report bugs or request features. [View active tickets]

Code Quality

A set of Code Metrics representing the quality of the code. The metrics are classified into file-, function-, and class-metrics. Only C++ files are considered during analysis. Information about the code quantity are provided in section Lines of Code. For more information please visit the code quality main page.

Lines of Code

Type

# of Files

# of Code Lines

# of Comment Lines

C++

14

769

512

C/C++ Header

33

3212

1941

CMake

3

115

8

Python

24

1985

1163

XML

1

30

0

SUM

75

6111

3624

Code Metrics

File-based metrics

Comment to code ratio

This metric is defined to be the number of visible characters in comments divided by the number of visible characters outside comments. Comment delimiters are ignored. Whitespace characters in strings are treated as visible characters. A large metric value may indicate that there are too many comments - an attribute that can make a module difficult to read. A small value may indicate that there are not enough.

[No canvas support]
[No canvas support]
[No canvas support]

      Info

  • Distro average:
    0.86

  • Stack average:
    1.17

  • Thresholds:  
    0.2 < x < 2.0

  • In range:
    100.0 %

Function-based metrics

Maximum nesting of control structures

This metric is a measure of the maximum control flow nesting in your source code. You can reduce the value of this metric by turning your nesting into separate functions. This will improve the readability of the code by reducing both the nesting and the average cyclomatic complexity per function.

[No canvas support]
[No canvas support]
[No canvas support]

      Info

  • Distro average:
    1.01

  • Stack average:
    2.21

  • Thresholds:  
    0 < x < 5

  • In range:
    100.0 %

Number of executable lines

The count of lines of a function body (starting at the first non-comment token that follows the exception specification, through to the last brace) that contain tokens, where lines that only contain any of the following are not counted: {, }, comment and all tokens of declarations.

[No canvas support]
[No canvas support]
[No canvas support]

      Info

  • Distro average:
    10.63

  • Stack average:
    8.21

  • Thresholds:  
    1 < x < 70

  • In range:
    28.6 %

Cyclomatic complexity

Cyclomatic complexity is calculated as the number of decisions plus 1. High cyclomatic complexity indicates inadequate modularization or too much logic in one function. Software metric research has indicated that functions with a cyclomatic complexity greater than 10 tend to have problems related to their complexity.

[No canvas support]
[No canvas support]
[No canvas support]

      Info

  • Distro average:
    4.63

  • Stack average:
    12.14

  • Thresholds:  
    1 < x < 15

  • In range:
    64.3 %

Number of Function Calls

The number of function calls within a function. Functions with a large number of function calls are more difficult to understand because their functionality is spread across several components. Note that the calculation of STSUB is based on the number of function calls and not the number of distinct functions that are called.

[No canvas support]
[No canvas support]
[No canvas support]

      Info

  • Distro average:
    17.05

  • Stack average:
    32.64

  • Thresholds:  
    1 < x < 10

  • In range:
    21.4 %

Estimated static path count

This gives an upper bound on the number of possible paths in the control flow of the function. It is the number of non-cyclic execution paths in a function.

[No canvas support]
[No canvas support]
[No canvas support]

      Info

  • Distro average:
    10265104.76

  • Stack average:
    35714665.71

  • Thresholds:  
    1 < x < 250

  • In range:
    64.3 %

Class-based metrics

Number of methods available in class

The number of methods declared within a class. This does not include methods declared in base classes. Classes with a large number of methods will be difficult to understand.

[No canvas support]
[No canvas support]
[No canvas support]

      Info

  • Distro average:
    6.58

  • Stack average:
    7.0

  • Thresholds:  
    1 < x < 20

  • In range:
    100.0 %

Deepest level of inheritance

This represents the number of derivations from the furthest base class down to this class. A high figure may indicate that the class depends on accumulated functionality, which makes understanding the class potentially difficult. This is one of the metrics defined by Chidamber & Kemerer.

[No canvas support]
[No canvas support]
[No canvas support]

      Info

  • Distro average:
    0.36

  • Stack average:
    0.0

  • Thresholds:  
    1 < x < 5

  • In range:
    0.0 %

Wiki: actionlib (last edited 2014-03-27 11:21:24 by DenisStogl)