Introduction to FSM - Page 1
Forum section: electronics / beginners

author: ea_man
author_rank: Contributor
timestamp: January 08, 2017, 08:24:25 pm
content: I'm going to design the software for a rover and I think I'm going to use state machines to implement the various functions, I've done some simple tutorial online about the use of the switch control structure and enum and that is ok for me.I could use some structured info about how to design these things: I feel like I could use a better approach to manage transitions between states, some hierarchical structure, concurrent, maybe something to "dispatch signals" to multiple concurrent FMS...The most meaningful resources I've found on the web gogglin' for FMS are about video-games design: can you recommend something more suited do uC (I'm using arduino now for prototypes, later AVR or ARM maybe) or well, something good anyway...Thanks!

author: ataradov
author_rank: Super Contributor
timestamp: January 08, 2017, 09:26:08 pm
content: I can't recommend a resource, since I never had a problem dealing with FSMs. But I can recommend a design approach. Do not invent FSM frameworks. Use plain switch-case statements. People reading your code will thank you for thatAs for examples, one of my projects is Atmel Lightweight Mesh stack (http://www.atmel.com/tools/lightweight_mesh.aspx) is based on FSMs of all sorts. You can have a look at that for a clean (IMO) example of that.

author: ea_man
author_rank: Contributor
timestamp: January 08, 2017, 09:51:40 pm
content: Quote from: ataradov on January 08, 2017, 09:26:08 pmThanks for the advice.Is there an archive where I can read that without having to create an account on microchip / atmel site?

author: ataradov
author_rank: Super Contributor
timestamp: January 08, 2017, 09:56:08 pm
content: Sure. Here it ishttps://dl.dropboxusercontent.com/u/6121480/work/lightweight_mesh_stack_v1.2.1.zip

author: ea_man
author_rank: Contributor
timestamp: January 08, 2017, 10:41:17 pm
content: Quote from: ataradov on January 08, 2017, 09:56:08 pmMuch obliged.Up to my reading list.

author: rstofer
author_rank: Super Contributor
timestamp: January 08, 2017, 10:54:19 pm
content: One problem with FSMs is that you can get to a state and hang waiting on an event that never occurs. In turn, things that should have happened didn't.There is the concept of a Super Loop - a simplewhile(1) {<all of the code, probably broken up by states>}So, basically, you go through the super loop looking for something to do. You don't hang waiting on something. If a task isn't ready (input signal, etc), we move right along to the next test.In the "old days" of games on the Commodore 64, we had even and odd passes through the super loop. That way the loop itself didn't take as long and we could deal with some issues on the next pass.All of my FPGA projects use FSMs, a LOT of FSMs, but I'm pretty sure that I can't get stuck in a state and, so far, I have been successful. But that's not how I would do robotics or anything like that.I would prefer to use a full Real Time Operating System (probably FreeRTOS) and have tasks wait on semaphores and other tasks send signals to semaphores. Input events are queued and processed in due time. Outputs are buffered (thinking about UART) and that task runs autonomously. And so on...One of the things you get for the effort of using an RTOS is the concept of priority. Input tasks are probably of a higher priority than output tasks. Updating a screen might be the lowest priority. Don't get carried away with priority but it's still a nice concept.Spend some time looking at FreeRTOS. If you decide not to use it, fine. At least you will have had some exposure to the ideas.

author: tggzzz
author_rank: Super Contributor
timestamp: January 08, 2017, 11:56:08 pm
content: Quote from: ataradov on January 08, 2017, 09:26:08 pmAt first. Then other people will add a little bit of functionality. And different people will add another.And soon you will have if-then-else or case statements nested10 deep. Seen that. Shuddered. Ran away, fast.Use a design pattern that allows you to separate states from each other (into classes in an OOP), and separates each event processing into a separate function within each state. That way you will be able to simply:determine which function in which class should be changed, in the knowledge that the changes won't affect other parts of the FSMlog event reception and state trajectory, which is invaluable for post-mortem dump analysis

author: ataradov
author_rank: Super Contributor
timestamp: January 09, 2017, 12:13:37 am
content: Quote from: tggzzz on January 08, 2017, 11:56:08 pmAny code can be turned into crap, it is not FSMs fault. I personally never had this problem.

author: tggzzz
author_rank: Super Contributor
timestamp: January 09, 2017, 12:28:11 am
content: Quote from: ataradov on January 09, 2017, 12:13:37 amSure.But your statement was in favour of if/case statements. While those can work for one-person small projects, they fail for multi-person long-term projects. And they don't provide easy logging that can beveryuseful when locating problemsanddeflecting the blame for problems/failure away from you your team and your company and onto other people/teams/companies.

author: ea_man
author_rank: Contributor
timestamp: January 09, 2017, 01:55:00 am
content: Quote from: rstofer on January 08, 2017, 10:54:19 pmThanks, actually I'd like to spend some time studying FSMs as I came from hi level programming (OOP, events) and I'd like to face the limits of FMSs.Yet working on a FMS and a RTOS implementation at the same time could prove interesting, in case as I'm going to do the very first easy steps on Arduino would it make sense to test Arduino_FreeRTOS_Library?-https://www.hackster.io/feilipu/using-freertos-multi-tasking-in-arduino-ebc3cc-https://github.com/feilipu/Arduino_FreeRTOS_LibraryI guess an other easy option could be using Energia on a MSP432 as that would be very much Arduino-like (well I have one board around at least).-http://energia.nu/guide/multitasking/Otherwise I have a STM Nucleo board, one Teensey 3.1, Rpi.Thanks all

author: tggzzz
author_rank: Super Contributor
timestamp: January 09, 2017, 09:34:35 am
content: Quote from: rstofer on January 08, 2017, 10:54:19 pmOften you want the input tasks to belowerpriority than the processing and output tasks, so they can exert flow control via back-pressure. I all depends on the overallsystemcharacteristics.Task priority is a rathole that should be avoided where ever possible as itfrequentlyleads to subtle rare problems that are impossible to predict. One infamous example is the Mars Pathfinder. Now space is just aboutthecanonical definition of where careful high-rel design practices are followed, but:Quote from: wackypediaBloody lucky! If they can get it wrong, so will most teams!The best current approach to real-time communicating processes are the methods/libraries/patterns based on Hoare's CSP. Priority should be limited to background processing and grab-the-input-ISRs.

author: rstofer
author_rank: Super Contributor
timestamp: January 09, 2017, 07:21:38 pm
content: Quote from: tggzzz on January 09, 2017, 09:34:35 amYup! Priority is a rathole and priority inversion is a real problem.OTOH, consider a card reader (old school): It better have a real high priority for column interrupts because the card keeps moving. Memory wasn't always dirt cheap and large buffers weren't always common, especially on low end systems.I think the Apollo guidance computer might be a good example of a priority based system. The section under Operating System Architecture is very interesting.http://history.nasa.gov/computers/Ch2-6.htmlBut, yes, keep priority usage to a minimum.

author: tggzzz
author_rank: Super Contributor
timestamp: January 09, 2017, 07:31:43 pm
content: Quote from: rstofer on January 09, 2017, 07:21:38 pmAnd certainly don't tweak task priorities while designing/commissioning a system to avoid glitches and get the right result! That's been done too many times, usually with good short term and bad medium/long term outcomes!

author: Cerebus
author_rank: Super Contributor
timestamp: January 10, 2017, 11:55:16 pm
content: Some collected thoughts on FSMs, some prompted by various comments, some justbased on experience.First off, when you're designing your FSM there is, in my experience, nosubstitute for drawing the whole FSM out on a big, perhaps bloody big, sheetof paper. Circles for each state, big curved arrows between states labelledwith the signal/condition/input that causes a state change. If you need toyou can add things like timing constraints to the arrows - best colour coded.When you've finished your diagram you've something you can use to visuallydebug your design, code from, keep for documentation or just stick on thewall to demonstrate your brilliance to everybody.Quote from: rstofer on January 08, 2017, 10:54:19 pmThere's a lot to be said for having a default 'get out of jail' conditionfrom each and every state in your FSM. The condition can be a watchdog timerthat's set when you enter each state, or any 'should not/cannot happen'conditions while in that state. That condition should point to a state thatlets you recover from whatever has gone wrong. In most cases the recovery statepointed to can just be your reset or initial state, but you can go forsubtler or more complex recovery schemes if that's to your taste.Quote from: ea_man on January 09, 2017, 01:55:00 amA mathematical aside. The limits of FSMs are surprisingly high. Many types offinite computation can be computed by an FSM limited only by the usualtime/space constraints and some rather abstruse mathematics. It's well known(or at least ought to be) that a Turing Machine can can compute anythingcomputable including computations involving infinities. A class of machinescalled push-down automata is the next most computationally capable type ofmachine and FSMs are the next class of machines out from those.If you're into linguistic computation those three classes of machine are exactlythe classes of machine required to parse context-sensitive, context-free and regularlanguage grammars respectively. This leads to the true but initially rather implausibleconclusion that you could use the lex (or flex) scanner generator to specify and codean FSM in C. Having used lex and flex quite a lot, I wouldn't recommend it.I'm sure that I missed something I thought of yesterday and meant to add but I've run out of steam.Just remembered it (after posting, naturally).As far as priorities, avoiding deadlock, priority inversion and the like there is a very useful set oftechniques known as wait-free or block-free algorithms. One of the aspects of these techniques is that,used properly, they guaranteeprogressfor computations that use them.They are not generally well known and some aspects of them are definitely current researchprojects for the computer science community but there are practical algorithms and applicationsout there. You are more likely to find details reading papers rather than textbooks.

author: rstofer
author_rank: Super Contributor
timestamp: January 11, 2017, 12:39:53 am
content: It's clear that hardware uses FSMs. That's the majority of code for FPGAs (for my projects, anyway). But we know when we write the code how signals will (or should) behave. In addition, each FSM is fairly small and does little in each state. We make up for it in volume! There are LOTS of FSMs and they all run in parallel. Dozens and dozens of little processes all working on their own part of the puzzle. In parallel!I could see a super loop wandering through the processing of several FSMs but one big hairy FSM doesn't appeal to me. The transition matrix (if used) gets too large. Further, we spend compute cycles testing if something has (or should have) happened rather than just getting a notice that it has happened and it should be acknowledged (processed) when time is available.In other words, I would go for the RTOS every single time.A character comes in on the UART (hardware interrupt and char placed in queue). The interrupt handler sets (or increments) a count on a semaphore, the kernel notices this and, when time is available, it dispatches the task the handles UART processing. There's no time lost testing for things, the event causes the dispatcher to know that something has happened.The RTOS is so much cleaner. Tasks can be relatively small bits of code that do very clearly defined things. And that's all they do. Get in, do the job and get out!Shared resources is another reason for using an RTOS. If this applies in this project...

author: tggzzz
author_rank: Super Contributor
timestamp: January 11, 2017, 01:37:30 am
content: Quote from: rstofer on January 11, 2017, 12:39:53 amSo does software, of course. Frequently that is unclear (in several senses)QuoteThat might be interpreted as advocating one-task-per-FSM, which is a design anti-pattern. There are better ways. Actors and the half-async-half-sync design pattern are a good starting point. Hoare's CSP is another.

author: Cerebus
author_rank: Super Contributor
timestamp: January 11, 2017, 02:30:27 pm
content: Quote from: rstofer on January 11, 2017, 12:39:53 amIn the mathematical (or computer science) study of finite automata the 'several FSMs in parallel' is known as a Non-deterministic Finite Automaton (NFA), the "one big hairy FSM" as a Deterministic Finite Automaton (DFA). That is, the state machine for an NFA can be in multiple states simultaneously, the state machine for a DFA may only be in one state at a time. It can be proven that for every NFA there is an equivalent DFA and the good bit is that there are algorithms to convert an NFA into a DFA. The trick is that one state in a DFA can represent a superposition of states from an NFA.Problems are easier to specify and comprehend as NFAs but more efficiently represented and executed as DFAs. If you've got tools to do the transformation for you, you can reap the benefits of NFAs (easier specification, parallelism) with DFAs (less resource usage, serial execution with identical results to parallel execution).