-
-
Notifications
You must be signed in to change notification settings - Fork 163
Tutorial Creating a Custom Plugin
Olivier Michel edited this page Jun 21, 2021
·
7 revisions
Since webots_ros2
1.1.0 the package includes the webots_ros2_driver
. The main objectives of the sub-package are:
- It automatically creates a ROS 2 interface out of a Webots robot model.
- It allows users to configure the ROS 2 interface in URDF files.
- It allows users to extend the interface using the
pluginlib
plugin mechanism.
In this tutorial, we will explain how to create a custom plugin that utilizes the webots_ros2_driver
plugin mechanism.
Please take a look at the picture below to get a better idea of the plugin system architecture.
The tree below depicts the minimal file structure for a custom plugin.
.
├── include
│ └── webots_ros2_plugin_example
│ └── WebotsRos2PluginExample.hpp
├── src
│ └── WebotsRos2PluginExample.cpp
├── webots_ros2_plugin_example.xml
├── CMakeLists.txt
└── package.xml
- The
include/webots_ros2_plugin_example/WebotsRos2PluginExample.hpp
file, see the Plugin C++ Header File section. - The
src/WebotsRos2PluginExample
file, see the Plugin C++ Implementation File section. - The
webots_ros2_plugin_example.xml
pluginlib
description file (see thepluginlib
Description File section). - The
CMakeLists.txt
file (see the Plugin CMake File section).
This section shows the critical files used for creating a Webots plugin package (and pluginlib
packages in general).
#ifndef WEBOTS_ROS2_PLUGIN_EXAMPLE_HPP
#define WEBOTS_ROS2_PLUGIN_EXAMPLE_HPP
#include "rclcpp/macros.hpp"
#include "webots_ros2_driver/PluginInterface.hpp"
#include "webots_ros2_driver/WebotsNode.hpp"
namespace webots_ros2_plugin_example
{
class WebotsRos2PluginExample : public webots_ros2_driver::PluginInterface
{
public:
// Your plugin has to override step() and init() methods
void step() override;
void init(webots_ros2_driver::WebotsNode *node, std::unordered_map<std::string, std::string> ¶meters) override;
};
}
#endif
#include "webots_ros2_plugin_example/WebotsRos2PluginExample.hpp"
namespace webots_ros2_plugin_example
{
void WebotsRos2PluginExample::init(webots_ros2_driver::WebotsNode *node, std::unordered_map<std::string, std::string> ¶meters)
{
// This method is executed once the plugin is loaded by the `webots_ros2_driver` package.
// The `webots_ros2_driver::WebotsNode` inherits the `rclcpp::Node`, so you have all methods available from there.
// In addition, from the `webots_ros2_driver::WebotsNode` instance you can also get a `webots::Robot` reference (`node.robot()`).
}
void WebotsRos2PluginExample::step()
{
// This method is executed on each Webots step
}
}
// The class has to be exported with `PLUGINLIB_EXPORT_CLASS` macro.
// The first argument is the name of your class, while the second is always `webots_ros2_driver::PluginInterface`
#include "pluginlib/class_list_macros.hpp"
PLUGINLIB_EXPORT_CLASS(webots_ros2_plugin_example::WebotsRos2PluginExample, webots_ros2_driver::PluginInterface)
This file is necessary for the pluginlib
to be able to find your Webots ROS 2 plugin.
<library path="webots_ros2_plugin_example">
<!-- The `type` attribute is a reference to the plugin class. -->
<!-- The `base_class_type` attribute is always `webots_ros2_driver::PluginInterface`. -->
<class type="webots_ros2_plugin_example::WebotsRos2PluginExample" base_class_type="webots_ros2_driver::PluginInterface">
<description>
This is a Webots ROS 2 plugin example
</description>
</class>
</library>
The CMake file slightly differs from typical ROS 2 CMake files as it includes Webots header files and pluginlib
.
cmake_minimum_required(VERSION 3.5)
project(webots_ros2_plugin_example)
if(NOT CMAKE_CXX_STANDARD)
set(CMAKE_CXX_STANDARD 14)
endif()
# Besides the package specific dependencies we also need the `pluginlib` and `webots_ros2_driver`
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(pluginlib REQUIRED)
find_package(webots_ros2_driver REQUIRED)
# Include the Webots header files
list(GET webots_ros2_driver_INCLUDE_DIRS 0 webots_ros2_driver_INCLUDE)
include_directories(
${webots_ros2_driver_INCLUDE}/webots/cpp
)
# Export the plugin configuration file
pluginlib_export_plugin_description_file(webots_ros2_driver webots_ros2_plugin_example.xml)
# The rest is standard ROS 2 packaging description
add_library(
${PROJECT_NAME}
SHARED
src/WebotsRos2PluginExample.cpp
)
target_include_directories(
${PROJECT_NAME}
PRIVATE
include
)
ament_target_dependencies(
${PROJECT_NAME}
pluginlib
rclcpp
webots_ros2_driver
)
install(TARGETS
${PROJECT_NAME}
ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib
RUNTIME DESTINATION bin
)
ament_export_include_directories(
include
)
ament_export_libraries(
${PROJECT_NAME}
)
ament_package()
- The Ros2Supervisor Node
- Using URDF or Xacro
- Import your URDF Robot in Webots
- Refresh or Add URDF a Robot in a Running Simulation
- Wheeled robots
- Robotic arms
- Automobiles
- Drones