ROS Resources: Documentation | Support | Discussion Forum | Service Status | Q&A answers.ros.org

Introducing the SMACC State Machine Library

SMACC State Machine Library

To all the coders out there,
I'd like to announce the release of the SMACC State Machine Library.

An Event-Driven, Asynchronous, Behavioral State Machine Library for real-time ROS applications written in C++.

With a constantly growing library of out-of-the-box reference state machines, guaranteed to compile and run, you can jumpstart your development efforts by choosing a state machine that is closest to your needs, and then customize and extend it to meet the specific requirements of your robotic application. All the while knowing that the library supports advanced functionalities required for actual working robots.

Check it out for yourself….

A few important points about SMACC


  • It’ written in C++, and suitable for Real-Time Applications.
  • It works out of the box with MoveBase & MoveIt!
  • It’s a behavioral state machine library. – This is Huge!
  • It’s based on David Harel’s Statecharts, and includes orthogonals. - This is Huge!
  • It’s distributed under a BSD-3 license.
  • It’s fast. We’ve clocked SMACC at over 1 KHz on a normal, everyday PC.
  • It uses C++ template-metaprogramming to validate your state machine at compile time.

And we've got a Free Viewer (GUI)...


To download the viewer via apt-get, go to http://smacc.ninja/smacc-viewer/

Try It Out

If you’ve got a tough project, and your current state machine isn’t cutting it, you should give SMACC a try.

Why start from scratch?

Acknowledgements

I’d like to thank and recognize the contributions of the great Andreas Huber Donni for his original ground-breaking work with Boost Statechart, and to Pablo Inigo Blasco. If it wasn’t for Pablo, and his tremendous programming skills, creativity, flexibility and guts, this project would have never made it.

Get Involved

If you’d like to talk to us about using SMACC in your project, be sure drop us a line…

And if you’re interested in contributing and joining our client or core teams, then I insist you drop us a line;). We’ve got a lot to accomplish.

You ain't seen nothing yet,

Brett W. Aldrich
brett@reelrobotix.com

P.S. We are going to be coming out with a version of the Library for ROS2.

16 Likes

Hi Everyone,
Thank you for all of the likes so far!

Something I would also like to mention as an important part of SMACC is the use of a component based architecture, particularly in the client library.

This was inspired by the use of Component Based Architecture in video game development technologies (such as Unity). This approach is already quite mature, and offers an interesting path to explore in robotics.

Because of this we were able to tackle problems related to the development of clients for the library such as MoveBaseZ for the Navigation stack, and MoveIt!Z for MoveIt! in an iterative way and intuitive way that in the end provides reusable client behaviors for the State Machine programmer.

Cheers,

1 Like

Hey guys, thanks for the contribution and great documentation!!

I have 2 questions/suggestions that may help with adoption by the community.

  1. Are you going to provide an installable and if yes, for which ROS distros? I believe most of the community consumes upstream packages from deb packages as opposed to source.

  2. For anyone already using a state machine library, how would SMACC compare to them? Given that you guys have created a library you must have had very good reasons. How about highlighting them in a feature-matrix comparing to SMACH and perhaps Behaviour Trees?

I think adding these two bits of info could really help people place this project on the map :wink:

5 Likes

Very cool to finally see a ROS-tailored c++ state machine library! Does this allow remote inspection and human intervention like FlexBE has?

1 Like

They list comparisons on their site. Here is the requested one for smacc-vs-BT: http://smacc.ninja/smacc-vs-behavior-trees/
Under the head-title ‘concept’ you can visit more comparisons. The others are quite neutral. But the linked one here has some statements in it, that I do not share.
Here are some of them:

[…]new paradigm known as behavior trees is the path forward for robotics programming.
These voices, have lost their minds.

I repeat, this ([Behavior Trees]) will not work, this will not scale, and whatever the benefits are of behavior trees, they will not find widespread use in the field of complex robotics.

Calling BS [= Bull Shit]

Also I’m not sure if the “facts” that are stated in this are 100% correct.

I’m currently building up my knowledge about this and want to check if all the facts about BT hold true. It would be great if someone with more knowledge and maybe a neural stand point could clarify this.

1 Like

It is a fact, that I am in no way a neutral party in this area.

And I do admit that I should have reviewed, and edited the BS thing from the page. I went too far…
The other comments are being taken out of context.

But I will try to briefly summarize my viewpoint…

Behavior Trees evolved from Gaming NPC’s, SMACC evolved from D.Harels’s statecharts, which he developed while working as a consultant at Israeli Aircraft Industries. The features that Harel’s work added to the previous concept of FSM’s, namely Orthogonality, Hierarchy, and History emerged due to the complexities inherent in fighter aircraft.

And I believe that complex robots have far more in common with fighter aircraft.

And this is where orthogonality comes in. SMACC is unique to the SM’s mentioned (BT’s SMACH, Flexbe) in terms of supporting orthogonality (referred to as concurrency in SMACH + Flexbe, but is actually quite different - which I’ll cover later).

Behavior trees have one solution for orthogonals, spawing threads. But that doesn’t scale.

With what I view as a complex robot you could get to 35 orthogonals quite easily. Are you going to have 35 threads in just your state machine node? What about all the other ROS nodes in that system? What about the other parts of the system outside ROS that might require their own threads? Once you’ve got your 150 threaded system, how are you going to get it to meet real-time requirements?

And beyond real-time requirements, what about debuggability with a 35 thread state machine node? What about reuseablility? or readability? Both would be dramatically different.

I think if you’re talking about more simplistic robots, like swarms of ant-like or mosquito-like insect robots for instance, that have one or maybe two orthogonals, and run on mcu’s or something, behavior trees might really shine. Because you wouldn’t have to worry about about getting every transition right, every state being in the correct parent state to actually work, etc. etc. (Although it should be noted that the C++ Template Metaprogramming aspect of does this for you). Maybe you would also get more reliable behavior from the insect bots in that their behavior would be more condition based and be better to able to respond to use cases unforseen by the developer, but this is conjecture on my part.

So, to sum up my thoughts on this issue…

SMACC is designed to support complex robots, comprising multiple physical subsystems, and was built upon a theoretical foundation made to support fighter aircraft.

While BT’s game from gaming NPC and can be (or perhaps are best) used in robotic systems that are more similar to NPC’s and the fundamentally different complexity, cost and liablility associated with those systems.


Last, I would like to point out as a practical example of the principals I’m discussing above, the sm_move_it reference state machine in the SMACC reference library, and seen here, as an example of what can be done with orthogonals.
Here, we were able to build a state machine that controls the ROS Navigation Stack, MoveIt! and a perception node simultaneously and its a simple matter to add and integrate more sensors and actuators as needed.

1 Like

I am going to assert that all statements about global optimality are hyperbole. I would also wager that you shouldn’t believe everything you read on the internet. ROS lets you perform experiments to determine what method works best for your particular domain and use-case.

I don’t think having a debate over the superiority of state machines or behavior trees, especially here, is going to be ultimately productive. This isn’t a zero sum game. Both approaches can exist simultaneously, and have merit in different contexts.

8 Likes

Hi Bence,

With regards to question 1…

We do currently provide debians for Kinetic & Melodic, but they are not part of the ROS distros yet.
But, that is a great idea. We’ll get that done right away:)

Kind regards.

Time to join the conversation, I guess (people who know me probably were waiting for this to happen :wink:).

First of all, let me tell you that it is a good thing that there are multiple solutions available in the community to solve the problem of task planning.

If SMACC can offer that, it is great. Let’s also remember RAFCON, for the sake of completeness.

Secondary, I don’t have any particular interest in saying that Behavior Trees are great. Actually, I have the feeling that they are different from Hierarchical State Machines, but not necessary better.

I have no agenda and even if I spent 1 year in my career developing trying to implement the absolute best implementation of BT, BehaviorTree.CPP, but I will be happy to throw it in the garbage as soon as I find a better solution.

Said that, I must reply to the comments about the SMACC vs BT comparison mentioned earlier and the comments from @brettpac.

I am trying to be as fair as I can and not “partisan” in any way :stuck_out_tongue_winking_eye:

Orthogonality/Concurrency

It is not true that BT can’t provide it, in fact, the number one priority of BT.CPP was to find a valid model of Reactive Behaviors, using ReactiveSequence, ParallelNode, etc.

We may argue which approach is better or more intuitive, but eventually the user is the ultimate judge.
I don’t have a strong opinion myself and maybe SMACC can do that better, who knows ?

Poor scalability, no real-time, many threads etc.

Again, mostly false or implementation dependent. BT.CPP discourage those Actions that spawns their own thread, even if that is possible.

On the other hand, I admit that the event-based approach is better than the “polling” (AKA “check conditions in a loop”) approach.
But there is no reason why that can’t be implemented in BT too (who knows, maybe in the future).

Readability

Some things are more readable in Behavior Trees, others are in State Machines.
The argument and example of “bake a cake”, provided in the page, is unfair and misleading, to say the least.

BT force you to think about what happen if an action fails. If you add that to State Machines too (you should) your SM will be equally or more complex that a BT.

“States really do exist”

Here I agree with the author. I realized that this is something where BT struggle.

No problem admitting that it is the biggest weakness of BT.

“Only for games” and “not used on real robots”

Don’t tell my boss, because we use them on our 1 tonne robot.

Summarizing…

Everybody is entitled to have his/her own opinion ¯_(ツ)_/¯,

My opinion is: use the paradigm and the implementation that makes you more productive.

8 Likes

There seems to be quite a few straw man arguments and universal claims being flung around here (not endearing me at all to this project).

Robotics is pretty complex. The problems you need to solve are weird, wonderful and varied, like no other field - they run the gamut from embedded to highly computational, control to scenario to ai-like decision making and they cross programming language boundaries frequently. It shouldn’t be surprising that solutions need to be varied too, their requirements can be wildly different. Trying to satisfy them all runs you into pareto-optimal situations.

I certainly haven’t found a silver bullet and have built and used several flavours of fsm’s and trees over the years - in a complex robot, I’ve always had multiple solutions attending to different problems at different layers. The fact that there are so many flavours should be indicative of the situation. As Katerine notes - try them, see if they fit your problem (or fit close enough).

Hi Stonier,
With regards to your comments regarding “Robotics is pretty complex…”
That’s one way of looking at it.

I agree, it is complex, and further I agree that multiple tools are sometimes needed.
And I’m pretty sure I’ve never said that “Every project should use SMACC and only SMACC.”

But another way of looking at it, is that standardization is the answer. Perhaps even sub-optimal standardizations (And I’m not saying SMACC is sub-optimal;).

Automotive mechanics is also pretty complex. With sub-areas like engine dynamics, suspension systems, driver safety, etc.

Further, these problems required different solutions depending on the application, both in, say 1932, as well as today. However, Henry Ford was able to standardize the engine, for a broad swath of applications, with the development of the Ford flathead V8. And further, I would submit that this reduction of complexity (for the end users) paved the way for the hot-rodders of the late 1940’s and 50’s (and beyond) that didn’t have to worry about what customized engine solution would meet their power needs and instead just modified the standard Flathead V8, and took engine performance to new heights for their era.

It’s my belief that if we had something akin to a Flathead Ford V8 for state machines in ROS, written in C++, it would greatly decrease the current complexity of robotics, allow us to focus on doing even more complex things, and take robot performance to new heights.

We use the Navigation Stack for a broad variety of navigation problems…
We use MoveIt! for a broad variety of robot arm & manipulation problems…
We use ROS for a broad variety of inter-process communication problems (among other things)…

Why not standardize the way we handle robot states with a state machine library?

And you may disagree with me, but I believe that that every robot is basically a big state machine.


… I’m aware that you aren’t proposing a complete abandonment of current robot technology that is standardized in favor of custom solutions everywhere. But I am making a point about standardization, and that specifically in the field of states, state machines, their operations and requirements, for a broad swath of robotics systems using ROS, the problems faced by roboticists today may in fact not be as “weird, wonderful, and varied, like no other field…” as the viewpoint taken in your post would suggest.

Whether or not people want to use SMACC specifically, of course is another question. But this is the SMACC announcement thread;)

2 Likes

Hi stonier,

And with regards to straw man arguments and universal claims, would you mind being specific?

Also, I’d be curious to hear about some of the fsm libraries you have used over the years.
I’m not sure if you’re aware, SMACC is built upon Boost Statechart, and inherits many features from it that may not have been present in libraries you’ve used previously.

1 Like

If you work in pick / place and complex manipulation, I’d find it hard to find serious solutions that aren’t using behavior trees for this. I align with Davide’s statements on its a tool, but there are of course other tools in our roboticists’ toolchest. I’m not sold that behavior trees make sense for everything, but they certainly make sense for alot of things. Some of the statements you mention seem representative of a library or particular work you interacted with in the past but I assure you that it is not representative of the field of behavior trees for robotics as a whole. I worked for companies building robot applications that were relatively simple so a FSM made alot of sense. I’ve also worked on designing navigation systems orchestrating between N different planner and controller algorithms for specialized situations where the number of FSM transitions would be totally infeasible to model (it would literally be thousands).

I’m glad to see another state machine library, but I think we should keep things positive; tell us why your library is great and support users that want to use it. I don’t think we need to address other methods for which you clearly have a passionate opinion on. If anything, we really should be discussing your new state machine library and why its awesome against other FSM analogs that exist.

2 Likes

Hi Steven, and everyone else…

Look, I’m keeping it positive. The only reason this conversation has gotten off to a bit of a rough start is that the thread was, in my opinion, rudely hijacked by Mr. Gramb, who took it upon himself to quickly answer the first question asked in this announcement, which was clearly addressed to me. He then took quotations out of context from things I had written some time ago on a web page where I was collecting my thoughts (but was public so I should have edited better) regarding behavior trees in general and not specifically Mr. Faconti’s implementation of a BT library in BehaviorTrees.cpp, but I digress…

And with all due respect, I think that the advantages and disadvantages of state machines (and SMACC specifically) vs. behavior trees is an important topic for serious developers to discuss.

Further, we now have Mr. Faconti, the author of BehaviorTrees.cpp, and Mr. Stonier, who I’ve recently discovered is the author of py_trees, presumably a python based behavior tree library, and myself, all on one post together. This is a rare and important opportunity to engage in discourse.

One thing that I think would be helpful to advance this discussion, is for all those joining the discussion and particularly those commenting about BT’s is to actually post links where we can see working examples of BT code in action, as opposed to tutorials, or hearsay examples.

Then we would be able to compare code side by side.

Example state machines for the SMACC library can be found here. And an instructional video on how to get these state machines running on your system can be found here.



I would like to thank Mr. Davide Faconti for joining the thread. I very much admire Mr. Faconti's work and character. This is a man that seeks the truth.

From Mr. Faconti’s post, I think he and I can agree on the following…

Polling vs. Event-Based

BT's rely on a polling pattern, whereas SMACC (and SM's in general) use an event-based approach. And I think he and I both agree that an event-based approach is generally better, particularly in an asynchronous environment.

That States really do exist

We agree on this as well and that this is an advantage for state machines in general.

And it seems that there are (at least;) two areas that we disagree on…

Readability

For this one, there is obviously a fair amount of subjectivity at play, but for the uninformed, one major difference between the way SM's and BT's are structured is rooted in the fact that SM's use states whereas BT's use conditions.

Mr. Faconti feels that the “bake a cake” example I had/have on the smacc.ninja page is unfair. So I would like to ask Mr. Faconti (and will do so offline) if he could provide us with a link to a sample he feels is a fair comparison. I would love to see it for my own understanding and I’ll incorporate it onto the smacc.ninja site as well.

Orthogonality (…and the real-timeness, scalability and modularity associated with it)

For this topic, I think being able to look at specific implementations of BT code would be particularly helpful. I think this is due to the fact that we are simultaneously discussing both runtime architecture (threads, nodes, etc.) and code modularity.

For myself, it’s hard for me to see how BT’s in general and this includes BehaviorTrees.cpp, would be able to handle robots that comprise many orthogonals, particularly when the sub-systems in those orthogonals are themselves complex (for instance, ROS Navigation, MoveIt! or a perception client vs. a low battery sensor or a thermostat), and maintain the code for each orthogonal/subsystem in different translation/compilation units to preserve modularity (so that you could later add another robot arm, 4 more sensors, or a pan-tilt unit, etc.), without resorting to spawning threads (or nodes) in one form or another…

I also think the fact that it’s a polling environment (vs. event-based) might also complicate this issue, but I admit that this is conjecture on my part.

But, I am not an expert in that library, or other BT libraries quite frankly. So perhaps it can be done…


Mr. Macenski's comments bring up another feature that we haven't discussed yet....

Transitions

There are two features of SMACC and other “statechart” based state machines that I also think are relevant to this discussion.

The first is that every SMACC state contains a transition table where you can either explicitly (the most usual way) or programmatically, define your transitions.

I think, and would love to hear Mr. Faconti’s opinion on this, that SM’s generally have the advantage of providing more precise control over transitions, (because in state x, which may be a corner case, you transition to state y on event z, whereas in state q you can… etc.), with the inherent disadvantage that, as a programmer you might screw that up, thus making BT’s somewhat more robust to developer error.

This danger is greatly mitigated with SMACC, specifically because it uses template metaprogramming to check all your transitions for correctness at compile time. And I think that this is one of the main advantages SMACC has over non-template based state machine libraries written in C++.

And the second, that is also unique to “statechart” based machines, is that SMACC offers programmatic control of transitions. Programmatic transitions (which Harel referred to as broadcast-communication) is one of the three main additions to FSMs David Harel brought to state machines in his famous 1987 paper.
With it you can do things like this…

Say we have a hierarchal state machine with two modes, “Run” and “Recovery”. In those two mode states, say we have 10 states in Run, and a 4 state recovery sequence in Recovery. We start operation in Run/State1 and for all states in Run, in the case of a error X, we want to transition to our recovery mode.

So we start operation in Run/State1, progress to Run/State3, throw error X and transition to Recovery/State1, we progress through the recovery sequence to Recovery/State4, succeed and…

Uh oh… Where do we transition to? How do we program that we want to go back to the state we originally left from (in this case Run/State3) in an explicit way?

Clearly this creates a problem and programmatic transitions solve this. Here is an example of our code that demonstrates this in action and shows the syntax of these transitions…

We currently inherit this functionality from Boost Statechart. Boost Statechart uses this in it’s use of state machine history, which is why it is usually used for advanced error recovery situations.

I think that this feature may have relevance to the example briefly mentioned by Mr. Macenski involving “navigation systems orchestrating between N different planner and controller algorithms for specialized situations” that supposedly made an FSM infeasible due to the number of transitions.

It’s hard to say given the limited information provided regarding that example, but I wonder if the programmatic transitions and compiler validation features present in SMACC may have made that problem quite tractable.

Another reason I question that statement, is that we already have two example state machines (here and here, along with videos here and here) that use navigation and load N different planners and have multiple controller algorithms. So again it’s hard to tell given what little I know about that example but I think this highlights that SMACC isn’t technically an FSM, in that it inherits from D. Harel’s statecharts, and that I question whether Mr. Macenski’s comments regarding the infeasibility of SM’s for that application are correct.


Thank you,

And to those just joining the thread, I would again like to specify that my comments assume that we are talking about robots that generally look like this

P.S. Mr. Macenski, If you have any links or other evidence substantiating your comments on industry practices regarding behavior trees in the world of pick/place complex manipulation, I’d love to see it.

2 Likes

Miro Samek has another fantastic implementation of a hierarchical state machine framework that might be worth comparing in this conversation.

He has been developing it for 20 years, with modeling tool support, code generation, software tracing, unit testing, real-time performance, and many other aspects.

There is an open-source GPL license and says he would be willing to provide an licensing exception for using QP in ROS applications.

https://www.state-machine.com/

P.S. Miro has a wonderful programming course on YouTube as well:

Modern System Embedded Programming Course

I am not sure this is the right channel to enter into technical or philosophical details about this.

I surely don’t have, right now, the bandwidth to join this fascinating debate, since I am already busy with other open source projects, my daily job and this thing called “having a life” :wink:

My suggestion is:

  • People curious about SMACC should try it and see if its value in terms of expressiveness and user-friendliness.

  • Eventually a Working group of people interested about this subject might be created, but it is way too early to even consider this option, in my opinion.

1 Like

This is great news. Have been using boost::sml (works well with microcontrollers but not very ROS friendly) for a while now. Will definitely give it a try.

Cheers

It would be great if someday we have an appropriate channel for all of us to discuss details of state machines and behavior trees. Please keep us posted if a channel like that is ever created.

For my projects, I am hoping to use both your awesome BehaviorTree.CPP and state machines, like this SMACC library or Miro’s framework, combined.

I personally like the idea of using behavior trees at the highest levels of system architecture, especially if it needs to be modified by someone who is not necessarily a skilled programmer (like they are used in the gaming industry) and using state machines for lower levels in the system, especially anything embedded or requiring real-time.

1 Like

Hi @peterpolidoro
You bring up a really interesting topic in my opinion, the synthesis of behavior trees and state machines.

I’ve been thinking about this for only a few days, so I admit it might be half-baked, but here’s what I’m envisioning…

The first step would be to create a SMACC Behavior Tree client, (see the SMACC client library) that would contain the behavior tree logic. Then, for a given state, we would need to runtimeConfigure() the BT client to recieve information from whatever orthogonals we want as input (like we did here), and then have the BT client simply throw events x,y,z to trigger transitons a,b,c…

This would give us a BT with a persistent lifetime (that of the SM), but I’m thinking that things could really get exciting if we could encapsulate different BT’s inside plugins, similar to the way we load planners in the MoveBaseZ client allowing us to load different BT’s for different states.

This would allow you to write much simpler bt’s for each state, as opposed to needing one bt to control everything. And I think that would allow you to really up the complexity by using smaller, swappable trees by attacking the problems one state at a time.

And in states where you don’t need BT’s, you wouldn’t have to use them, which I suspect would also be important in terms of flexibility.

In this system, all the orthogonality, data flow, and event-handling would essentially be handled by SMACC, and the behavior tree client would be almost analogous to a portion of the brain like the pre-frontal cortex or something.

One last thing that has me so excited about this possibility, is that you could potentially get a system that could rely on two types of logic, which are symbolic logic, and whatever the name of the other one is that Mr. Faconti told me about but I can’t remember now…

Anyways, if you or anyone else is interested in trying to tackle this problem, PM me. I’d be happy to help.

Lastly, I just want to say that I disagree some of the commenters on this thread regarding the idea that ROS discourse is not the place to have these kind of discussions. This is exactly the right place.

1 Like

So you are suggesting having a state machine at the highest level of a system and embedding behavior trees inside of it? That is an interesting idea! Perhaps there could be alternating layers of state machines and behavior trees as state machines also seem ideal at very lowest levels of the system like in the embedded real-time processors. I do not know if that would end up making the system insanely complicated or brilliantly simplified, but definitely seems worth exploring!