martes, 26 de abril de 2016

Máquina de Estados Finitos en Python

Una máquina de estado o autómata finito (Finite State Machine en inglés) es un modelo computacional bastante útil en robótica y automatización. Para este ejemplo haremos una implementación por software de una máquina de estados en Python que puede ser fácilmente adaptada para algún proyecto en una Raspberry Pi. Esta implementación es bastante sencilla, para FSM's más robustas basadas en clases recomiendo checar aquí y aquí. El diagrama de estados para FSM de esté ejemplo será el siguiente:
Este tipo particular de FSM es llamada Máquina de Moore ya que la transición de estado sólo depende del estado actual y del valor de la entrada. Esta implementación en Python aprovechará una característica peculiar de los diccionarios que permite asociar una función con una llave [ref]. De esta manera los estados quedan definidos como funciones dónde podemos incluir todas las acciones que nos interese realizar durante dicho estado (o durante las transiciones). El programa completo:

# -*- coding: utf-8 -*-
"""
Created on Thu Feb  4 23:36:28 2016

@author: Rodolfo
"""

from time import sleep
from random import randint

#Variable global
estado = 'i'

#Estados
def EDOi(entrada):
    global estado
    print('Estado Inicial')
    #Transiciónes
    sleep(2)
    if entrada == 0:
        estado = 'i'
    if entrada == 1:
        estado = 0
        print(u'Transición hacia 0...')

def EDO0(entrada):
    global estado
    print('Estado 0')
    #Transiciones
    sleep(2)
    if entrada == 0:
        estado = 1
        print(u'Transición hacia 1...')
    if entrada == 1:
        estado = 2
        print(u'Transición hacia 2...')
        
def EDO1(entrada):
    global estado
    print('Estado 1')
    #Transiciones
    sleep(2)
    if entrada == 0:
        estado = 0
        print(u'Transición hacia 0...')
    if entrada == 1:
        estado = 2
        print(u'Transición hacia 2...')

def EDO2(entrada):
    global estado
    print('Estado 2')
    #Transiciones
    sleep(2)
    if entrada == 0:
        estado = 1
        print(u'Transición hacia 1...')
    if entrada == 1:
        estado = 0
        print(u'Transición hacia 0...')

#Finite State Machine (FSM)   
def FSM(entrada):
    global estado
    switch = {
       'i':EDOi,
        0 :EDO0,
        1 :EDO1,
        2 :EDO2,
    }
    func = switch.get(estado, lambda: None)
    return func(entrada)

#Programa Principal
while True:    
 FSM(randint(0,1))
 sleep(2)


Salida del programa en la consola en Raspberry:
En caso de que te interese una implementación en lenguaje C, aquí tengo otra entrada dónde explico como hacerlo.

No hay comentarios: