SCXML,我不能在事件中使用fireEvent

时间:2013-10-05 17:35:02

标签: java apache-commons scxml apache-commons-scxml

我正在使用Apache Commons SCXML来创建FSM。使用Apache的StopWatch示例,我创建了一个FSM。

SCXML:

<scxml initial="Iddle" version="0.9" xmlns="http://www.w3.org/2005/07/scxml">
 <state id="Iddle">
  <transition event="continueDriving" target="DriveForward"></transition>
 </state>
 <state id="DriveForward">
  <transition event="continueDriving" target="DriveForward"></transition>
  <transition event="detectingWall" target="DetectWall"></transition>
  <transition event="lowBattery" target="Disconnect"></transition>
 </state>
 <state id="DetectWall">
  <transition event="continueDriving" target="DriveForward"></transition>
<transition event="lowBattery" target="Disconnect"></transition>
 </state>
 <final id="Disconnect"></final>
</scxml>

主程序: 在主程序中,这个想法不会引发任何事件。

    package jab.lejos.liverobots.brity;

    import jab.lejos.liverobots.brity.fsm.BrityFSM4;

    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    import java.net.MalformedURLException;
    import java.util.Properties;

    import org.apache.log4j.Logger;
    import org.apache.log4j.PropertyConfigurator;

    public class BrityFSMTest4 {

    private BrityFSM4 brityFSM;

    final Logger logger = Logger.getLogger(BrityFSMTest1.class);

    public static void main(String[] args) throws FileNotFoundException, IOException {

        final String configPath = "/lib/log4j.properties";
        String path = System.getProperty("user.dir") + configPath;
        Properties props = new Properties();
        props.load(new FileInputStream(path));
        PropertyConfigurator.configure(props);

        new BrityFSMTest4();
    }

    public BrityFSMTest4() throws MalformedURLException {
        brityFSM = new BrityFSM4();

    }

}

FSM:

package jab.lejos.liverobots.brity.fsm;

import jab.lejos.liverobots.brity.model.RobotSimulated;

import java.io.File;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;

import org.apache.commons.scxml.env.AbstractStateMachine;
import org.apache.commons.scxml.model.State;
import org.apache.commons.scxml.model.Transition;
import org.apache.log4j.Logger;

/**
 * 
 * Based on this example:
 * http://commons.apache.org/proper/commons-scxml/xref-test/org/apache/commons/scxml/env/StopWatch.html
 *  
 * @author jabrena
 *
 */
public class BrityFSM4 extends AbstractStateMachine{

    Logger logger = Logger.getLogger(BrityFSM4.class);

    private static final String SCXML_CONFIG = "./lib/BrityModel.scxml";

    private RobotSimulated robot;

    public BrityFSM4() throws MalformedURLException{
        super(new File(SCXML_CONFIG).toURI().toURL());
        robot = RobotSimulated.getInstance();
    }

    //User methods
    public String getCurrentStateId() {
        Set<?> states = getEngine().getCurrentStatus().getStates();
        State state = (State) states.iterator().next();
        return state.getId();
    }

    public State getCurrentState() {
        Set<?> states = getEngine().getCurrentStatus().getStates();
        return ( (State) states.iterator().next());
    }

    public Collection<?> getCurrentStateEvents() {
        return getEngine().getCurrentStatus().getEvents();
    }

    //FSM Methods
    public void Iddle() {
        Logger logger = Logger.getLogger(BrityFSM4.class);
        logger.info("STATE: Iddle");
        //this.fireEvent(BrityFSMTransitions.continueDriving.toString());
        List<String> list = new ArrayList<String>();
        List<Transition> transitionList = this.getCurrentState().getTransitionsList();
        if(transitionList.size() > 0){
            list.clear();
            for (Transition transition : transitionList) {
                list.add(transition.getEvent());
                logger.info("EVENT: " + transition.getEvent());
            }
        }
    }

    public void DriveForward() {
        logger.info("STATE: DriveForward");
    }

    public void DetectWall() {
        logger.info("STATE: DetectWall");
    }

    public void Disconnect() {
        //TODO Improve log4j usage
        logger.info("STATE: disconnected");
    }

}

我的问题是,为什么在FSM类中,我无法执行该方法:

//this.fireEvent(BrityFSMTransitions.continueDriving.toString());

public void Iddle() {
    Logger logger = Logger.getLogger(BrityFSM4.class);
    logger.info("STATE: Iddle");
    //this.fireEvent(BrityFSMTransitions.continueDriving.toString());
    List<String> list = new ArrayList<String>();
    List<Transition> transitionList = this.getCurrentState().getTransitionsList();
    if(transitionList.size() > 0){
        list.clear();
        for (Transition transition : transitionList) {
            list.add(transition.getEvent());
            logger.info("EVENT: " + transition.getEvent());
        }
    }
}

但是如果我在主程序中执行方法,我没有任何问题。

任何想法。

当前控制台:

   2013-10-05 19:00:10,463  INFO [main] (BrityFSM4.java:57) - STATE: Iddle
    2013-10-05 19:00:10,469 ERROR [main] (AbstractStateMachine.java:298) - 
    java.lang.reflect.InvocationTargetException
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.apache.commons.scxml.env.AbstractStateMachine.invoke(AbstractStateMachine.java:256)
        at org.apache.commons.scxml.env.AbstractStateMachine$EntryListener.onEntry(AbstractStateMachine.java:312)
        at org.apache.commons.scxml.NotificationRegistry.fireOnEntry(NotificationRegistry.java:130)
        at org.apache.commons.scxml.NotificationRegistry.fireOnEntry(NotificationRegistry.java:114)
        at org.apache.commons.scxml.semantics.SCXMLSemanticsImpl.executeActions(SCXMLSemanticsImpl.java:247)
        at org.apache.commons.scxml.SCXMLExecutor.reset(SCXMLExecutor.java:252)
        at org.apache.commons.scxml.SCXMLExecutor.go(SCXMLExecutor.java:351)
        at org.apache.commons.scxml.env.AbstractStateMachine.initialize(AbstractStateMachine.java:184)
        at org.apache.commons.scxml.env.AbstractStateMachine.<init>(AbstractStateMachine.java:132)
        at org.apache.commons.scxml.env.AbstractStateMachine.<init>(AbstractStateMachine.java:103)
        at jab.lejos.liverobots.brity.fsm.BrityFSM4.<init>(BrityFSM4.java:34)
        at jab.lejos.liverobots.brity.BrityFSMTest4.<init>(BrityFSMTest4.java:34)
        at jab.lejos.liverobots.brity.BrityFSMTest4.main(BrityFSMTest4.java:28)
    Caused by: java.util.NoSuchElementException
        at java.util.HashMap$HashIterator.nextEntry(HashMap.java:796)
        at java.util.HashMap$KeyIterator.next(HashMap.java:828)
        at jab.lejos.liverobots.brity.fsm.BrityFSM4.getCurrentState(BrityFSM4.java:47)
        at jab.lejos.liverobots.brity.fsm.BrityFSM4.Iddle(BrityFSM4.java:60)
        ... 17 more

0 个答案:

没有答案