FSM fsm_simple() { FSM fsm; int even = fsm.addState("Even", true); int odd = fsm.addState("Odd"); fsm.addTransition(even, even, 1, "1"); fsm.addTransition(even, odd, 0, "0"); fsm.addTransition(odd, odd, 1, "1"); fsm.addTransition(odd, even, 0, "0"); return fsm; }
FSM fsm_moonman() { FSM fsm; int start = fsm.addState("No Input"); int bogus = fsm.addState("Not MOONMAN"); int m1 = fsm.addState("M"); int o1 = fsm.addState("O"); int o2 = fsm.addState("O"); int n1 = fsm.addState("N"); int m2 = fsm.addState("M"); int a1 = fsm.addState("A"); int n2 = fsm.addState("N", true); fsm.addTransition(start, m1, (int) 'M', "M"); // 1 fsm.addTransition(m1, o1, (int) 'O', "O"); // 2 fsm.addTransition(o1, o2, (int) 'O', "O"); // 3 fsm.addTransition(o2, n1, (int) 'N', "N"); // 4 fsm.addTransition(n1, m2, (int) 'M', "M"); // 5 fsm.addTransition(m2, a1, (int) 'A', "A"); // 6 fsm.addTransition(a1, n2, (int) 'N', "N"); // 7 fsm.addTransition(start, bogus, (int) 'X', "X"); // 8 fsm.addTransition(m1, bogus, (int) 'X', "X"); // 9 fsm.addTransition(o1, bogus, (int) 'X', "X"); // 10 fsm.addTransition(o2, bogus, (int) 'X', "X"); // 11 fsm.addTransition(n1, bogus, (int) 'X', "X"); // 12 fsm.addTransition(m2, bogus, (int) 'X', "X"); // 13 fsm.addTransition(a1, bogus, (int) 'X', "X"); // 14 fsm.addTransition(n2, bogus, (int) 'X', "X"); // 15 return fsm; }
FSM* IRParser::parseFSM(llvm::MDNode* node){ FSM* fsm = new FSM(); //Parse initial state MDString* initialState = cast<MDString>(node->getOperand(0)); //Parse all fsm state MDNode* stateArray = cast<MDNode>(node->getOperand(1)); for (unsigned i = 0, e = stateArray->getNumOperands(); i != e; ++i){ MDString* stateMD = cast<MDString>(stateArray->getOperand(i)); fsm->addState(stateMD->getString()); } // set the initial state after initializing the states fsm->setInitialState(initialState->getString()); //Parse transition MDNode* transitionsArray = cast<MDNode>(node->getOperand(2)); for (unsigned i = 0, e = transitionsArray->getNumOperands(); i != e; ++i){ MDNode* transitionArray = cast<MDNode>(transitionsArray->getOperand(i)); MDString* source = cast<MDString>(transitionArray->getOperand(0)); Value* targetValue = transitionArray->getOperand(1); //In case of "undefined" state, no target are given if (targetValue != NULL){ MDNode* targetsArray = cast<MDNode>(targetValue); for (unsigned j = 0, f = targetsArray->getNumOperands() ; j != f; ++j){ MDNode* targetArray = cast<MDNode>(targetsArray->getOperand(j)); Action* action = getAction(cast<MDNode>(targetArray->getOperand(0))); MDString* target = cast<MDString>(targetArray->getOperand(1)); fsm->addTransition(source->getString(), target->getString(), action); } } } return fsm; }
FSM* IRWriter::writeFSM(FSM* fsm){ list<llvm::Function*>::iterator it; FSM* newFSM = new FSM(); //Copy states of the source fsm std::map<std::string, FSM::State*>::iterator itState; std::map<std::string, FSM::State*>* states = fsm->getStates(); for (itState = states->begin(); itState != states->end(); itState++){ newFSM->addState(itState->first); } //Copy transitions of the source fsm map<string, Action*>::iterator itActionsMap; std::map<std::string, FSM::Transition*>::iterator itTransition; std::map<std::string, FSM::Transition*>* transitions = fsm->getTransitions(); for (itTransition = transitions->begin(); itTransition != transitions->end(); itTransition++){ FSM::Transition* transition = itTransition->second; FSM::State* sourceState = transition->getSourceState(); list<FSM::NextStateInfo*>::iterator itNextStateInfo; list<FSM::NextStateInfo*>* nextStateInfos = transition->getNextStateInfo(); for (itNextStateInfo = nextStateInfos->begin(); itNextStateInfo != nextStateInfos->end(); itNextStateInfo++){ FSM::State* targetState = (*itNextStateInfo)->getTargetState(); Action* targetAction = (*itNextStateInfo)->getAction(); newFSM->addTransition(sourceState->getName(), targetState->getName(), getAction(targetAction)); } } //Set initiale state of the FSM newFSM->setInitialState(fsm->getInitialState()->getName()); return newFSM; }
FSM * buildFSM( FSMDescrip & fsmDescrip, Agents::SimulatorInterface * sim, bool VERBOSE ) { // Acquire the spatial query instance SPATIAL_QUERY = sim->getSpatialQuery(); //Global Simulator interface SIMULATOR = sim; bool valid = true; const size_t AGT_COUNT = sim->getNumAgents(); FSM * fsm = new FSM( sim ); // Build the fsm //we'll need this iterator later std::vector< VelModifier * >::iterator vItr; // Map of state names to state IDs. std::map< std::string, size_t > stateNameMap; // Copy the GoalSets fsm->_goalSets.clear(); fsm->_goalSets.insert( fsmDescrip._goalSets.begin(), fsmDescrip._goalSets.end() ); fsmDescrip._goalSets.clear(); // 1. Create states // a. Add velocity components and actions // b. add to fsm std::list< StateDescrip * >::const_iterator sItr = fsmDescrip._states.begin(); for ( ; sItr != fsmDescrip._states.end(); ++sItr ) { StateDescrip * sData = *sItr; State * s = fsmDescrip.addState( sData ); if ( s == 0x0 ) { logger << Logger::ERR_MSG << "Error creating state!"; delete fsm; return 0x0; } if ( VERBOSE ) logger << Logger::INFO_MSG << "\tAdding state: " << s->getName() << "(" << s->getID() << ")\n"; // State's goal selector GoalSelector * gs = sData->_goalSelector; if ( gs == 0x0 ) { logger << Logger::WARN_MSG << "The state " << sData->_name << " doesn't specify a goal selector. The identity goal selector will be used."; gs = new IdentityGoalSelector(); } try { gs->setGoalSet( fsm->getGoalSets() ); // possibly throws GoalSelectorException s->setGoalSelector( gs ); // possibly throws GoalSelectorException } catch ( GoalSelectorException ) { logger << Logger::ERR_MSG << "Problem initializing the goal selector for the state " << s->getName() << "."; delete fsm; return 0x0; } sData->_goalSelector = 0x0; // construct each velocity component if ( sData->_velComponent == 0x0 ) { logger << Logger::WARN_MSG << "The state " << sData->_name << " doesn't specify a velocity component. The zero velocity component will be used."; s->setVelComponent( new ZeroVelComponent() ); } else { s->setVelComponent( sData->_velComponent ); sData->_velComponent = 0x0; } // transfer each action std::list< Action * >::iterator aItr = sData->_actions.begin(); for ( ; aItr != sData->_actions.end(); ++aItr ) { s->addAction( *aItr ); } sData->_actions.clear(); //transfer velocity modifiers from the state description vItr = sData->_velModifiers.begin(); for ( ; vItr != sData->_velModifiers.end(); ++vItr ) { s->addVelModifier( *vItr ); } sData->_velModifiers.clear(); // Set start node size_t stateID = fsm->addNode( s ); stateNameMap[ sData->_name ] = stateID; } // Connect all shared goal selectors std::map< std::string, size_t >::iterator stateItr = stateNameMap.begin(); for ( ; stateItr != stateNameMap.end(); ++stateItr ) { std::string stateName = stateItr->first; size_t stateID = stateItr->second; State * state = fsm->getNode( stateID ); SharedGoalSelector * gs = dynamic_cast< SharedGoalSelector * >( state->getGoalSelector() ); if ( gs != 0x0 ) { if ( stateNameMap.count( gs->_stateName ) == 0 ) { logger << Logger::ERR_MSG << "Found shared goal selector defined on line " << gs->_lineNo << ", but unable to locate state with the provided name: \"" << gs->_stateName << "\"."; delete fsm; return 0x0; } State * src = fsm->getNode( stateNameMap[ gs->_stateName ] ); if ( dynamic_cast< SharedGoalSelector * >( src->getGoalSelector() ) ) { logger << Logger::ERR_MSG << "Shared goal selector defined on line " << gs->_lineNo << " references a state with a shared goal. The source state must have a full goal selector definition."; delete fsm; return 0x0; } state->clearGoalSelector(); GoalSelector * srcGS = src->getGoalSelector(); srcGS->setPersistence( true ); state->setGoalSelector( srcGS ); } } if ( VERBOSE ) logger << Logger::INFO_MSG << "There are " << fsmDescrip._transitions.size() << " transitions\n"; // 2. Create transitions std::map< std::string, std::list< Transition * > >::iterator stItr = fsmDescrip._transitions.begin(); for ( ; stItr != fsmDescrip._transitions.end(); ++stItr ) { const std::string fromName = stItr->first; std::list< Transition * > & tList = stItr->second; // Determine if the origin state is valid if ( fsmDescrip._stateNameMap.find( fromName ) == fsmDescrip._stateNameMap.end() ) { logger << Logger::ERR_MSG << "Transition with invalid from node name: " << fromName << "."; delete fsm; return 0x0; } // Try to connect the transitions to the destination(s) std::list< Transition * >::iterator tItr = tList.begin(); for ( ; tItr != tList.end(); ++tItr ) { Transition * t = *tItr; if ( ! t->connectStates( fsmDescrip._stateNameMap ) ) { delete fsm; return 0x0; } fsm->addTransition( stateNameMap[ fromName ], t ); } tList.clear(); } fsmDescrip._transitions.clear(); ////////////// // copy over the velocity modifiers vItr = fsmDescrip._velModifiers.begin(); for ( ; vItr != fsmDescrip._velModifiers.end(); ++vItr ) { //TODO: replace global vel mod initalizer fsm->addVelModifier( *vItr ); } fsmDescrip._velModifiers.clear(); // 3. Query simulator and fsm for possible reasons to have a task fsm->collectTasks(); for ( std::list< Task * >::iterator itr = fsmDescrip._tasks.begin(); itr != fsmDescrip._tasks.end(); ++itr ) { fsm->addTask( (*itr) ); } fsmDescrip._tasks.clear(); // spatial query and elevation tasks fsm->addTask( SPATIAL_QUERY->getTask() ); if ( sim->getElevationInstance() ) { // NOTE: The elevation instance is null because none were specified. // Eventually, the default elevation will be set. // HOWEVER, if the default ever changes such that it requires a task, // this won't catch it!!! So, make sure the default never requires // a task. fsm->addTask( sim->getElevationInstance()->getTask() ); } logger << Logger::INFO_MSG << "There are " << fsm->getTaskCount() << " registered tasks.\n"; fsm->doTasks(); // 5. Initialize all agents if ( VERBOSE ) logger << Logger::INFO_MSG << "Initializing agents:\n"; Agents::SimulatorState * initState = sim->getInitialState(); for ( size_t a = 0; a < AGT_COUNT; ++a ) { Agents::BaseAgent * agt = sim->getAgent( a ); // update current state to class-appropriate value const std::string stateName = initState->getAgentState( agt->_id ); std::map< std::string, size_t >::iterator stateIDItr = stateNameMap.find( stateName ); if ( stateIDItr == stateNameMap.end() ) { logger << Logger::ERR_MSG << "Agent " << agt->_id << " requested to start in an unknown state: " << stateName << "."; delete fsm; return 0x0; } size_t stateID = stateIDItr->second; // initialize velocity to preferred velocity State * cState = fsm->getNode( stateID ); if ( VERBOSE ) { logger << Logger::INFO_MSG << "Agent " << agt->_id << " starts in " << cState->getName() << "."; } fsm->setCurrentState( agt, stateID ); cState->enter( agt ); // TODO: Restore support for defining inital velocity state: zero or preferred agt->_vel.set( Vector2( 0.f, 0.f ) ); //register the agent for all vel modifiers vItr = fsm->_velModifiers.begin(); for ( ; vItr != fsm->_velModifiers.end(); ++vItr ) { //TODO: replace global vel mod initalizer ( *vItr )->registerAgent(agt); } } ACTIVE_FSM = fsm; return fsm; }
FSM fsm_brain_bag() { FSM fsm; int S = fsm.addState("Start State"); int Z = fsm.addState("Bogus State"); int b = fsm.addState("B"); int i = fsm.addState("I"); int r = fsm.addState("R"); int a = fsm.addState("A"); int n = fsm.addState("N", true); int g = fsm.addState("G", true); int a2 = fsm.addState("A", true); int s = fsm.addState("S", true); int i2 = fsm.addState("I"); int n2 = fsm.addState("N", true); fsm.addTransition(S, b, (int) 'B', "B"); fsm.addTransition(b, i, (int) 'I', "I"); fsm.addTransition(b, r, (int) 'R', "R"); fsm.addTransition(b, a, (int) 'A', "A"); fsm.addTransition(i, n, (int) 'N', "N"); fsm.addTransition(i, g, (int) 'G', "G"); fsm.addTransition(r, a2, (int) 'A', "A"); fsm.addTransition(a, g, (int) 'G', "G"); fsm.addTransition(n, s, (int) 'S', "S"); fsm.addTransition(a2, s, (int) 'S', "S"); fsm.addTransition(a2, i2, (int) 'I', "I"); fsm.addTransition(i2, n2, (int) 'N', "N"); fsm.addTransition(n2, s, (int) 'S', "S"); fsm.addTransition(S, Z, -1, "Bogus"); fsm.addTransition(b, Z, -1, "Bogus"); fsm.addTransition(i, Z, -1, "Bogus"); fsm.addTransition(r, Z, -1, "Bogus"); fsm.addTransition(a, Z, -1, "Bogus"); fsm.addTransition(n, Z, -1, "Bogus"); fsm.addTransition(g, Z, -1, "Bogus"); fsm.addTransition(a2, Z, -1, "Bogus"); fsm.addTransition(s, Z, -1, "Bogus"); fsm.addTransition(i2, Z, -1, "Bogus"); fsm.addTransition(n2, Z, -1, "Bogus"); return fsm; }