SMACHA Documentation¶
SMACHA is a meta-scripting, templating, and code generation engine for rapid prototyping of ROS SMACH state machines.
SMACH is an exceptionally useful and comprehensive task-level architecture for state machine construction in ROS-based robot control systems. However, while it provides much in terms of power and flexibility, its overall task-level simplicity can often be obfuscated at the script-level by boilerplate code, intricate structure and lack of code reuse between state machine prototypes.
SMACHA (short for “State Machine Assembler”, pronounced “smasha”) aims at distilling the task-level simplicity of SMACH into compact YAML scripts in the foreground, while retaining all of its power and flexibility in Jinja2-based templates and a custom code generation engine in the background. Thus SMACHA does not aim to replace SMACH, but to augment it.
Overview¶
Here is a high-level illustration of the main components of the SMACHA API:
Here is a video demonstrating the use of SMACHA with the Baxter robot simulator using the baxter_smacha package:
Why SMACHA?¶
SMACHA allows for arbitrarily complex SMACH state machine programs to be written as much shorter YAML scripts that can be directly executed with ROS. Here is the “Nesting State Machines” example from the SMACH Tutorials described in a SMACHA script:
--- # Nesting State Machines Tutorial SMACHA script.
name: sm_top
template: Base
manifest: smacha
node_name: smach_example_state_machine
outcomes: [outcome5]
states:
- BAS: {template: Bas, transitions: {outcome3: SUB}}
- SUB:
template: StateMachine
outcomes: [outcome4]
transitions: {outcome4: outcome5}
states:
- FOO: {template: Foo, transitions: {outcome1: BAR, outcome2: outcome4}}
- BAR: {template: Bar, transitions: {outcome1: FOO}}
This demonstrates a reduction from 80 lines of raw SMACH Python code to 14 lines of SMACHA script. Not bad. However, if we employ YAML inline format and SMACHA shorthand script syntax, we can get this down to 5 lines:
--- # Nesting State Machines Tutorial SMACHA script.
{n: sm_top, T: Base, m: smacha, nn: smach_example_state_machine, o: [outcome5],
s: [BAS: {T: Bas, t: {outcome3: SUB}},
SUB: {T: StateMachine, o: [outcome4], t: {outcome4: outcome5},
s: [FOO: {T: Foo, t: {outcome1: BAR, outcome2: outcome4}},
BAR: {T: Bar, t: {outcome1: FOO}}]}]}
Outside of script brevity, SMACHA provides many other benefits and tools to help rapidly prototype complex state machines for robot control.
Scripting¶
SMACHA Scripts are parsed by the Parser module and direct the Generator module on how to combine SMACHA templates using the Templater module.
Some of the benefits of meta-scripting in this way include:
- quick, at-a-glance overviews of state machine program intent,
- easy script manipulation, reuse and restructuring - SMACHA provides
various utilities to automate some common script manipulation tasks, e.g.
- the Contain Tool for automatic containerization of state sequences,
- the Extract Tool for automatic conversion of commonly used container states to reusable sub-scripts,
- streamlined ROS integration, e.g.
- loading of scripts onto the ROS parameter server and
- executing them with service calls.
Templating¶
SMACHA Templates are filled out by the Templater module as directed by the Generator module and as determined by the structure of the SMACHA scripts parsed by the Parser module.
The use of templates comes with its own additional benefits:
- intricate boilerplate code can be automatically filled,
- increased code reusability and modularity, e.g.
- common design patterns can be easily turned into state templates,
- template macros make it easy to repeat common patterns between templates,
- template inheritance helps avoid repetitive code blocks,
- templates could be designed for use with frameworks other than SMACH and Python
Code Generation¶
The SMACHA Code Generator recursively processes SMACHA Scripts parsed by The Parser Module, manages the use of SMACHA Templates that are filled out by The Templater Module, and renders the final result to executable Python SMACH code.
Installation¶
Simply clone into the src
directory of your catkin workspace,
update dependencies, and run
catkin_make
or catkin build
from the root of the workspace.
$ cd ~/catkin_ws/src
$ git clone git@github.com:ReconCell/smacha.git
$ cd ..
$ rosdep install --from-paths src --ignore-src --rosdistro kinetic -y
$ catkin build
$ source ~/catkin_ws/devel/setup.bash
Usage¶
Generate¶
Given a SMACHA script (seq_nesting_1.yml
) and a set of templates, e.g. to replicate the code from
the SMACH Nesting State Machines tutorial, SMACH
Python code can be generated with the following command:
$ rosrun smacha generate -t `rospack find smacha`/test/smacha_templates/executive_smach_tutorials -o state_machine_nesting2.py -v `rospack find smacha`/test/smacha_scripts/executive_smach_tutorials/state_machine_nesting2.yml
Here, the -t
argument specifies custom template directories for this
particular tutorial, which may contain templates that override the core
templates.
The -o
argument specifies a custom name for the generated output
file.
The -v
argument tells SMACHA to print verbose processing output to
the terminal.
Further arguments and options may be explored by running
rosrun smacha generate -h
or rosrun smacha generate --help
.
Execute¶
The script from the above example can also be directly executed provided that a roscore is running:
$ rosrun smacha execute -t `rospack find smacha`/test/smacha_templates/executive_smach_tutorials -v `rospack find smacha`/test/smacha_scripts/executive_smach_tutorials/state_machine_nesting2.yml
Again, further arguments and options may be explored by running
rosrun smacha execute -h
or rosrun smacha execute --help
.
Important
A roscore must be running in order to execute scripts in this way!
Help¶
Help information may be printed for any template that contains a metadata block by running, e.g. the following command for the PrintUserdataState template:
$ rosrun smacha help PrintUserdataState
Testing¶
Tests may be performed by running:
$ python `rospack find smacha`/test/executive_smach_tutorials_test.py
$ python `rospack find smacha`/test/smacha_test_examples.py
Passing the -h
argument as follows will bring up a list of some
other options.
Passing the -w
argument will write the generated output files to
disk, which can subsequently be run as follows, e.g. for the
state_machine_nesting2.py
example:
$ rosrun smacha state_machine_nesting2_generate_output.py
To run the original file script, use the following command:
$ rosrun smacha state_machine_nesting2.py
SMACHA API¶
Modules¶
These are the main smacha package submodules:
- Parser: provides the
smacha.parser.Parser
class for parsing SMACHA Scripts. - Templater: provides the
smacha.templater.Templater
class as well as other functions for processing SMACHA Templates. - Generator: provides the
smacha.generator.Generator
class for generating executable Python SMACH code. - Util: provides various utilities.
- Exceptions: provides exception definitions.
Templates¶
These are the core smacha package templates:
Container Templates¶
- StateMachine: used for inserting a StateMachine container.
- Concurrence: used for inserting a Concurrence container.
State Templates¶
- CallbacksState: used for creating lambda function callbacks.
- ConditionalOutcomeState: used for conditionally selecting an outcome.
- DeleteFileState: used for deleting files from the file system.
- PrintUserdataState: used for printing userdata entries to standard output.
- RandomOutcomeState: used for selecting a random outcome from a specified list of outcomes.
- WriteCSVFileState: used for writing CSV files to the file system.
Other SMACHA Packages¶
SMACHA ROS¶
The SMACHA ROS provides ROS oriented templates and contains a SMACHA server that provides ROS services, ROS parameter server integration, and other functions.
SMACHA GUI¶
The SMACHA GUI package provides a visual programming interface for SMACHA for use within the ReconCell Project.
References/Citations¶
If you use SMACHA in your work, please consider citing the following paper:
B. Ridge, T. Gašpar, and A. Ude. Rapid State Machine Assembly for Modular Robot Control using Meta-Scripting, Templating and Code Generation. In IEEE-RAS 17th International Conference on Humanoid Robots (Humanoids), pages 661–668, Birmingham, UK, November 2017.