Factory Demo (C++)
This tutorial demonstrates how to load YASMIN state machines from XML
files using the YasminFactory in C++. This approach
separates the FSM structure from the code, making it easier to design,
share, and modify state machines without recompiling.
Background
The YASMIN Factory provides:
- Declarative FSM definition using XML
- Plugin-based state loading (Python and C++ states)
- Visual editing with YASMIN Editor
- Reusable state machine configurations
1. Create an XML State Machine
Define your state machine structure in an XML file (e.g.,
demo_1.xml):
<StateMachine outcomes="outcome4">
<State name="Foo" type="py" module="yasmin_demos.foo_state" class="FooState">
<Transition from="outcome1" to="Bar"/>
<Transition from="outcome2" to="outcome4"/>
</State>
<State name="Bar" type="cpp" class="yasmin_demos/BarState">
<Transition from="outcome3" to="Foo"/>
</State>
</StateMachine>
Running the Demo
ros2 run yasmin_demos factory_demo
Source Code
You can find the full source code in the yasmin_demos package.
#include <iostream>
#include <memory>
#include <string>
#include "ament_index_cpp/get_package_share_directory.hpp"
#include "rclcpp/rclcpp.hpp"
#include "yasmin/state_machine.hpp"
#include "yasmin_factory/yasmin_factory.hpp"
#include "yasmin_ros/ros_logs.hpp"
int main(int argc, char *argv[]) {
YASMIN_LOG_INFO("yasmin_factory_demo");
rclcpp::init(argc, argv);
// Set up ROS 2 loggers
yasmin_ros::set_ros_loggers();
std::string outcome;
// Create the factory in a scope
yasmin_factory::YasminFactory factory;
// Load state machine from XML file
std::string xml_file =
ament_index_cpp::get_package_share_directory("yasmin_demos") +
"/state_machines/demo_2.xml";
// Create the state machine from the XML file
auto sm = factory.create_sm_from_file(xml_file);
// Execute the state machine
try {
std::string outcome = (*sm.get())();
YASMIN_LOG_INFO(outcome.c_str());
} catch (const std::exception &e) {
YASMIN_LOG_WARN(e.what());
}
// Shutdown ROS 2
rclcpp::shutdown();
return 0;
}
YASMIN