Integrating SCXML in ROS using PYSCXML [closed]

asked 2013-05-14 12:04:03 -0500

this post is marked as community wiki

This post is a wiki. Anyone with karma >75 is welcome to improve it.

Hi everyone,

In the last weeks a faced a problem that still I could not find a solution:

I execute a ROS node that starts a StateMachine object from pyscxml. The first time that this node receives a message from another node, an event is send to the StateMachine and everything works fine. But it seems the SM remains in a blocked status, and the next time when the local node where the SM was started, receives a new message from another node, there is no more a chance to 'move' the SM from the previous state. It seems that the SM object is the same always, but the thread id of the ROS node changes in every call !!!????? I tried different options to instantiate the SM (@staticmethod, own thread, etc), but I could not find a solution.

If I use a client that creates a anonymous Ros node and (e.g. every 3 seconds) sends a message to the Node where the SM runs, it works!! the SM change from a state to another one depending on the event.

The problem comes when the connection between the two nodes is closed for x seconds and we want to send new events to the SM.

At the bottom you can see my Ros Node and the SM schema definition. Anyway it does not seem that the scxml schema has any problem.

Thank you very much for your help

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
Created on 07/12/2012

@author: frk
import roslib; roslib.load_manifest('beginner_tutorials')
from import StateMachine
from import LogUtils
from import RosChannel
from std_msgs.msg._String import String
import rospy
import time

LOG = LogUtils("WorkFlowManager", "stateMachine.log")
sm = None
event = None
receivedEvent = None

## NODE initialization

## Publishers ##
pubMainmenu = rospy.Publisher(RosChannel.TOPIC_START_MENU, String) 
pubMusicBox = rospy.Publisher(RosChannel.TOPIC_MUSICBOX, String)


def init_machine():
    global sm
    sm = StateMachine("workflowMain.xml")
    return sm    

def getStateMachine():
    global sm
    if None != sm:
        return sm
        return init_machine()

def parseRosMsg(message):
    event = str(
    LOG.debug("[" + getState() + "]" + " AFTER sending '" + event + "'")

def declareStateMachineStatus(value):
    rospy.set_param(RosChannel.P_STATE_MACHINE_STATUS, value)

def getState():
    return str(rospy.get_param(RosChannel.P_STATE_MACHINE_STATUS))

def sendSafeEventToMachine(event):
    global receivedEvent
    receivedEvent = False
    index = 0
    LOG.debug("[" + getState() + "] Sending to Main STATE MACHINE event: '" + event + "'")
    while index < 2: # this is a workaround, it avoids the issue sending sometimes evens that are obviated by the sm
        getStateMachine().send(event, 0)
        index = index + 0.5

def triggerStartMainMenuEvent():
    LOG.debug("[" + getState() + "] Publishing 'startMenu'")

if __name__ == '__main__':

        LOG.debug("Started nodeWorkflow with STATE 'WAIT'")
        rospy.set_param(RosChannel.P_STATE_MACHINE_STATUS, STATE_WAIT)

        ## Subscribers ##
        rospy.Subscriber(RosChannel.TOPIC_WORKFLOW, String, parseRosMsg)
        rospy.Subscriber(RosChannel.TOPIC_JULIUS, String, parseRosMsg)


    except rospy.ROSInterruptException:

And this is the StateMachine Schema

    from import *
</script ...
edit retag flag offensive reopen merge delete

Closed for the following reason question is not relevant or outdated by tfoote
close date 2016-07-27 18:10:54.637806