Writing a New State Estimator Plugin
Overview
This tutorial shows how to create your own State Estimator within the AeroStack2 framework. You may want to remember AeroStack2 Architecture and its State Estimator operation.
This tutorial will be a walktrough of one existing estimators to easily understand its creation. The one explained will be the mocap estimator plugin. The code used in this tutorial can be found in Github.
Requirements
ROS 2 Humble
AeroStack2
Tutorial Steps
1. Estimator Plugin Base
Following the plugin structure, all the estimators should inherit from a base class
as2_state_estimator_plugin_base::StateEstimatorBase
. The base class provides a set of
virtual methods to override with expected controller functionality. The list of methods is
presented in the table below:
Virtual method |
Method description |
Requires override? |
---|---|---|
on_setup() |
Setup the estimator. Declare subscribers to estimation sources. |
Yes |
get_earth_to_map_transform() |
Set transformation between earth and map. |
No |
2. Overriden methods
Setup
During the setup, mocap subscriber is created and a static transformation between map
and odom
is published as null into the tf tree. In the mocap callback, the transformation
between base_link
and map
is received from the mation capture system and published
into the tf tree. Moreover, the speed is also estimated based on the pose information and
published into the AeroStack2 designed topic (self_localization/twist
).
void on_setup() override {
mocap_pose_sub_ = node_ptr_->create_subscription<geometry_msgs::msg::PoseStamped>(
as2_names::topics::ground_truth::pose, as2_names::topics::ground_truth::qos,
std::bind(&Plugin::mocap_pose_callback, this, std::placeholders::_1));
geometry_msgs::msg::TransformStamped map_to_odom =
as2::tf::getTransformation(get_map_frame(), get_odom_frame(), 0, 0, 0, 0, 0, 0);
publish_static_transform(map_to_odom);
has_earth_to_map_ = false;
}
Transformation between earth
and map
is not implemented in this example.
3. Exporting the plugin
Now that we have created our new estimator, we need to export it so that it would be visible
to the State Estimator Node. Plugins are loaded at runtime and if they are not visible, then our
node won’t be able to load it. In ROS 2, exporting and loading plugins is handled
by pluginlib
.
To achieve that, class as2_state_estimator_plugin_mocap::Plugin
is loaded dynamically from
as2_state_estimator_plugin_base::StateEstimatorBase
which is the base class.
To export the controller, we need to provide two lines:
#include <pluginlib/class_list_macros.hpp>
PLUGINLIB_EXPORT_CLASS(as2_state_estimator_plugin_mocap::Plugin, as2_state_estimator_plugin_base::StateEstimatorBase)
It is good practice to place these lines at the end of the file but technically, you can also write at the top.
2. Next step would be to create plugin’s description file in the root directory of the package.
For example, plugins.xml
file in our tutorial package. This file contains following
information:
library path: Plugin’s library name and it’s location.
class name: Name of the class.
class type: Type of class.
base class: Name of the base class.
description: Description of the plugin.
<library path="as2_controller_plugin_speed_controller">
<class type="mocap::Plugin" base_class_type="as2_state_estimator_plugin_base::StateEstimatorBase">
<description>State estimator plugin for mocap optitrack.</description>
</class>
</library>
3. Next step would be to export plugin using CMakeLists.txt
by using cmake function
pluginlib_export_plugin_description_file()
. This function installs plugin description
file to share directory and sets ament indexes to make it discoverable.
pluginlib_export_plugin_description_file(${PROJECT_NAME} plugins.xml)
Compile and it should be registered. Next, we’ll use this plugin.
4. Launching
¿TBD?