Note: This tutorial assumes that you have completed the previous tutorials: Run RSM. |
Please ask about problems and questions regarding this tutorial on answers.ros.org. Don't forget to include in your question the link to this page, the versions of your OS & ROS, and also add appropriate tags. |
Writing a Plugin State
Description: How to write a plugin state for the Robot Statemachine and properly setup the package where it will be inTutorial Level: ADVANCED
Next Tutorial: Use Plugin State in RSM
Package Configuration
To create a plugin state to be used with the robot RSM follow the upcoming steps. This is very similar to the ROS tutorial Writing and Using a Simple Plugin but also includes some specific details for the RSM.
In your package, add the following code to the respective files:
CMakeLists.txt:
find_package(catkin REQUIRED COMPONENTS roscpp pluginlib rsm_core rsm_msgs ... )
package.xml:
... <build_depend>pluginlib</build_depend> <build_export_depend>pluginlib</build_export_depend> <exec_depend>pluginlib</exec_depend> <exec_depend>rsm_core</exec_depend> <build_depend>rsm_core</build_depend> <build_export_depend>rsm_core</build_export_depend> <build_depend>rsm_msgs</build_depend> <build_export_depend>rsm_msgs</build_export_depend> <exec_depend>rsm_msgs</exec_depend> ...
This adds all dependencies needed to use the pluginlib and include the Base State.
Plugin Implementation
Next, create a class consisting of a header and source file in the respective directory in your package. The class needs to inherit from the Base State, interact with the State Interface and declare it is a plugin. The code for header and source are shown below.
ExampleState.h:
1 #include <pluginlib/class_list_macros.h>
2 #include <rsm_core/BaseState.h>
3 #include <rsm_core/StateInterface.h>
4
5 namespace rsm {
6
7 class ExampleState: public BaseState {
8
9 public:
10 ExampleState();
11 ~ExampleState();
12 void onSetup();
13 void onEntry();
14 void onActive();
15 void onExit();
16 void onExplorationStart(bool &success, std::string &message);
17 void onExplorationStop(bool &success, std::string &message);
18 void onWaypointFollowingStart(bool &success, std::string &message);
19 void onWaypointFollowingStop(bool &success, std::string &message);
20 void onInterrupt(int interrupt);
21 };
22
23 }
ExampleState.cpp:
1 #include "ExampleState.h"
2
3 namespace rsm {
4
5 ExampleState::ExampleState() {
6 //...
7 }
8
9 ExampleState::~ExampleState() {
10 //...
11 }
12
13 void ExampleState::onSetup() {
14 //...
15 }
16
17 void ExampleState::onEntry() {
18 //...
19 }
20
21 void ExampleState::onActive() {
22 //...
23 }
24
25 void ExampleState::onExit() {
26 //...
27 }
28
29 void ExampleState::onExplorationStart(bool &success,
30 std::string &message) {
31 //...
32 }
33
34 void ExampleState::onExplorationStop(bool &success,
35 std::string &message) {
36 //...
37 }
38
39 void ExampleState::onWaypointFollowingStart(bool &success,
40 std::string &message) {
41 //...
42 }
43
44 void ExampleState::onWaypointFollowingStop(bool &success,
45 std::string &message) {
46 //...
47 }
48
49 void ExampleState::onInterrupt(int interrupt) {
50 //...
51 }
52
53 }
54
55 PLUGINLIB_EXPORT_CLASS(rsm::ExampleState,
56 rsm::BaseState)
The state plugin needs to implement all methods declared in the Base State as virtual and enables to add arbitrary functionality to them. The PLUGINLIB_EXPORT_CLASS macro registers the class as a plugin to the pluginlib.
Plugin Export
To make the plugin available to ROS, an XML file needs to be added in the package that declares them as a library. The file should look like this:
rsm_example_plugins.xml:
<library path="lib/librsm_example_plugins"> <class type="rsm::ExampleState" base_class_type="rsm::BaseState"> <description>This is the example state.</description> </class> ... </library>
It can feature multiple classes to declare in the same manner. The plugin library needs to be exported as well. Therefore the following lines need to be added to the package.xml:
<export> <rsm_core plugin="${prefix}/rsm_example_plugins.xml" /> </export>
Note: There can only be one export bracket in each package.xml.
Check Plugin Implementation
With the following statement you can check in the terminal if the plugin was registered correctly:
rospack plugins --attrib=plugin rsm_core
It should show:
"your_package_name" /"your_workspace_path"/src/"your_package_name"/rsm_example_plugins.xml rsm_additions /"your_workspace_path"/src/robot_statemachine/rsm_additions/rsm_plugins.xml
You can now use the plugin state in the RSM.