Интеграция SCXML в узел ROS с использованием PYSCXML

В последние недели я столкнулся с проблемой, которую я так и не смог найти:

Я выполняю узел ROS, который запускает объект StateMachine из pyscxml. При первом получении этим узлом сообщения от другого узла отправляется событие в StateMachine, и все работает нормально. Но кажется, что SM остается в заблокированном состоянии, и в следующий раз, когда локальный узел получает новое сообщение от другого узла, больше нет шансов "переместить" SM из предыдущего состояния. Кажется, что объект SM всегда один и тот же, но идентификатор потока узла ROS меняется при каждом вызове!!!????? Я пробовал разные варианты создания экземпляра SM (@staticmethod, собственный поток и т. Д.), Но не смог найти решение.

Если я использую клиента, который создает анонимный узел Ros и (например, каждые 3 секунды) отправляет сообщение на узел, где работает SM, это работает!! SM изменяется от состояния к другому в зависимости от события с любой проблемой.

Проблема возникает, когда соединение между двумя узлами закрыто на x секунд, и мы хотим отправить новые события на SM.

Это мой Ros Node и определение схемы SM. В любом случае, похоже, что у схемы scxml нет проблем.

Большое спасибо за Вашу помощь

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

@author: frk
'''
import roslib; roslib.load_manifest('beginner_tutorials')
from beginner_tutorials.de.frank.dm.scxml.pyscxml import StateMachine
from beginner_tutorials.de.frank.utils.Logger import LogUtils
from beginner_tutorials.de.frank.utils.constants 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
rospy.init_node(RosChannel.NODE_WORKFLOW)

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

STATE_WAIT = "WAIT"
STATE_RUN = "RUN"
STATE_MUSIC = "MUSIC"
STATE_NEWS = "NEWS"
STATE_FINAL = "FINAL"
STATE_MAIN_MENU = "MAIN_MENU"

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

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

def parseRosMsg(message):
    event = str(message.data)
    sendSafeEventToMachine(event)
    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)
        time.sleep(0.5)
        index = index + 0.5

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



if __name__ == '__main__':
    try:

        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)

        rospy.spin()

    except rospy.ROSInterruptException:
        pass  

И это документ SCXML

<script>
    from beginner_tutorials.de.frank.dm.mainWorkflowManager import *
</script>

<state id="INITIAL">
    <onentry>
        <log label="-----[SCXML-Main-Menu]" expr="'in INITIAL'" />
    </onentry>
    <transition event="startMenu" target="WAIT" />
</state>

<state id="WAIT">
    <onentry>
        <log label="-----[SCXML-Main-Menu]" expr="'in WAIT'" />
        <script>w
            declareStateMachineStatus("WAIT")
        </script>

    </onentry>
    <transition event="toMenu" target="MAIN_MENU" />
    <transition event="toFinal" target="FINAL" />
</state>


<state id="MAIN_MENU">
    <onentry>
        <log label="-----[SCXML-Main-Menu]" expr="'in MAIN_MENU'" />
        <script>
            declareStateMachineStatus("MAIN_MENU")
            triggerStartMainMenuEvent()
        </script>
    </onentry>
    <transition event="toWait" target="WAIT" />
    <transition event="toFinal" target="FINAL" />
</state>


<final id="FINAL">
    <onentry>
        <log label="-----[SCXML-Main-Menu]" expr="'in FINAL'" />
        <script>
            declareStateMachineStatus("FINAL")
        </script>
    </onentry>
</final>

0 ответов

Другие вопросы по тегам