#################################### ##FILL ME IN #################################### ## for a custom note with links: ## note = ## for the canned note of "This tutorial assumes that you have completed the previous tutorials:" just add the links ## note.0= [[robot_statemachine/Tutorials/RunRSM|Run RSM]] ## descriptive title for the tutorial ## title = Writing a Plugin State ## multi-line description to be displayed in search ## description = How to write a plugin state for the Robot Statemachine and properly setup the package where it will be in ## the next tutorial description (optional) ## next = ## links to next tutorial (optional) ## next.0.link= [[robot_statemachine/Tutorials/UsePluginStateInRSM|Use Plugin State in RSM]] ## next.1.link= ## what level user is this tutorial for ## level= AdvancedCategory ## keywords = #################################### <> <> ## AUTOGENERATED DO NOT DELETE ## TutorialCategory ## FILL IN THE STACK TUTORIAL CATEGORY HERE == 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 [[pluginlib/Tutorials/Writing and Using a Simple Plugin|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'': {{{ ... pluginlib pluginlib pluginlib rsm_core rsm_core rsm_core rsm_msgs rsm_msgs rsm_msgs ... }}} 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'': {{{ #!cplusplus #include #include #include namespace rsm { class ExampleState: public BaseState { public: ExampleState(); ~ExampleState(); void onSetup(); void onEntry(); void onActive(); void onExit(); void onExplorationStart(bool &success, std::string &message); void onExplorationStop(bool &success, std::string &message); void onWaypointFollowingStart(bool &success, std::string &message); void onWaypointFollowingStop(bool &success, std::string &message); void onInterrupt(int interrupt); }; } }}} ''ExampleState.cpp'': {{{ #!cplusplus #include "ExampleState.h" namespace rsm { ExampleState::ExampleState() { //... } ExampleState::~ExampleState() { //... } void ExampleState::onSetup() { //... } void ExampleState::onEntry() { //... } void ExampleState::onActive() { //... } void ExampleState::onExit() { //... } void ExampleState::onExplorationStart(bool &success, std::string &message) { //... } void ExampleState::onExplorationStop(bool &success, std::string &message) { //... } void ExampleState::onWaypointFollowingStart(bool &success, std::string &message) { //... } void ExampleState::onWaypointFollowingStop(bool &success, std::string &message) { //... } void ExampleState::onInterrupt(int interrupt) { //... } } PLUGINLIB_EXPORT_CLASS(rsm::ExampleState, 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'': {{{ This is the example state. ... }}} 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'': {{{ }}} ''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.