开源HSM学习笔记---状态机的运行

原创 2015年07月06日 16:46:23

1、状态机的创建

/************************************
State Table(下面每个状态的parent state需要在create中实现),状态列表中成员信息依次为当前状态id、父母状态id、跳转列表、入口动作、出口动作、行为动作、父母状态

************************************/
static state m_stateList_SampleHSM[MAX_STATEID]=
{
{0,0,0,0,0,0},//STATEID_NULL
{ROOT_STATE,STATEID_NULL,&transitionTable_SampleHSM[ROOT_STATE],0,0,0,0},//ROOT_STATE


{STATE_1,ROOT_STATE,&transitionTable_SampleHSM[STATE_1],State1_Entry,State1_Exit,State1_Do,0},//STATE_1


{STATE1_1,STATE_1,&transitionTable_SampleHSM[STATE1_1],State1_1_entry,State1_1_Exit,0,0},//STATE1_1


{STATE1_2,STATE_1,&transitionTable_SampleHSM[STATE1_2],State1_2_entry,State1_2_exit,State1_2_Do,0},//STATE1_2


{STATE_2,ROOT_STATE,&transitionTable_SampleHSM[STATE_2],State2_entry,State2_exit,0,0},//STATE_2


{STATE2_1,STATE_2,&transitionTable_SampleHSM[STATE2_1],State2_1Entry,State2_1Exit,0,0},//STATE2_1


{STATE2_1_1,STATE2_1,&transitionTable_SampleHSM[STATE2_1_1],State2_1_1_Entry,State2_1_1_Exit,0,0},//STATE2_1_1


{STATE_3,ROOT_STATE,&transitionTable_SampleHSM[STATE_3],State3_Entry,State3_Exit,0,0},//STATE_3


{State4,ROOT_STATE,&transitionTable_SampleHSM[State4],State4Entry,State4Exit,State4_Do,0}//State4
};


用户创建状态机函数
/************************************/
/*!
   \fn void SampleHSM_HSM_Create(void)
*  \brief Creating the HSM
*  \return void
*/
/************************************/
void SampleHSM_HSM_Create(void)
{
 hsm_create(m_stateList_SampleHSM,9);

}


基本创建函数

/*! \fn void hsm_create(state *stateList,unsigned int noOfStates) 
*  \brief This function creates the HSM
*  \param *stateList The pointer to the statelist.
*  \param noOfStates Number of states in the HSM
*  \return void
*/
void hsm_create(state *stateList,unsigned int noOfStates)
{
unsigned int stateID = 0;
unsigned int parentID = 0;
hsm_stateList = stateList;


for (stateID = 0; stateID <= noOfStates ;stateID++)
{
parentID = hsm_stateList[stateID].parentID;
hsm_stateList[stateID].parentState = &hsm_stateList[parentID];    //指定其parent state
//printf(" state = %d  ",hsm_stateList[stateID].stateID);
//printf(" state parent = %d \n ",(hsm_stateList[stateID].parentState)->stateID);


}
if(noOfStates > 0)      //指定初始状态
{
hsm_currentState = &hsm_stateList[STATE_START];//set the current state as the root state. the root state shall be the first state.
}


}



2、状态机的开启

/************************************/
/*!
   \fn void SampleHSM_HSM_Start(void)
*  \brief Starting the HSM
*  \return void
*/
/************************************/
void SampleHSM_HSM_Start(void)
{
 hsm_start();
}



/*! \fn void hsm_start(void) 
*  \brief This function is used to start the HSM. 
*   Here ROOT state enters to the Default child state
*  \param void
*  \return void
*/
void hsm_start(void)
{

//printf(" state before = %d  ",hsm_currentState->stateID);
hsm_onEvent(EV_DEFAULT);


}


激活状态机的触发事件

/*! \fn void hsm_onEvent(EventID eventId) 
*  \brief This function is used to fire events to HSM
*  From here the Event Processing function is called 
*  \param eventId The ID of the Current Event
*  \return void
*/
void hsm_onEvent(EventID eventId)
{
   hsm_ProcessEvent(eventId);
   
}


事件处理流程中,丢一个触发事件进来,当前状态根据该触发事件进行跳转处理,当前状态无法处理触发事件的,则丢给其父母节点进行处理
/*! \fn void hsm_ProcessEvent(EventID eventId) 
*  \brief This function is used to process events fired to HSM
*  First it is found  who will be consuming the event. 
*  If the current state is not consuming the event the parent state is checked for it.
*  If nobody in the state hierarchy consumes the event the function does not perform any action. 
*  if the event consumer state is found state transition is executed.
*  \param eventId The ID of the Current Event
*  \return void
*/
void hsm_ProcessEvent(EventID eventId)
{
/*
*First find who will consume the event. If the current state is not consuming the event find the parent state
* who will be consuming it.If nobody in the state hierarchy consumes it do not perform any action. 
*if the state is found execute the exit and entry action sequence.
定义
#ifndef HSM_RESULT_NOK
#define HSM_RESULT_NOK 0
#endif
首先判断该事件是否能触发当前状态发生跳转,如果不能(result=0(HSM_RESULT_NOK)),在触发事件id不为null(EV_DEFAULT)的情况下,当前状态返回到其父母状态,否则,退出循环;

找到当前状态的跳转,则保存其下一次跳转的状态,并执行跳转动作hsm_doTransition

*/
unsigned int result = HSM_RESULT_NOK;
state * currentStateBackUp = hsm_currentState;
state *currentState = hsm_currentState;
unsigned int transitionID = 0;
while(
!result &&
currentState->stateID != STATEID_NULL
)                                                                                                                                    // 查找当前状态到目的状态的跳转路径
{
result = hsm_isEventConsumed(currentState,eventId,&transitionID) ;//checking if the event is consumed by the state,查找当前状态在触发事件下发生跳转的transitionID是否存在
if(HSM_RESULT_OK == result)
{
#ifdef SYSTEM_SIMULATION
printf(" Event consumed %d\n",eventId);
#endif
}
if(!result && eventId != EV_DEFAULT)
{
currentState = currentState->parentState;//setting the current state to parent state   ,当前状态到目的状态的直接路径不存在,且触发事件存在(表明当前状态无法处理该事件),则退出到当前状态的父母节点,查找该父母节点到目的状态的路径是否存在
}
else if(!result && eventId == EV_DEFAULT)          //跳转路径不存在,则退出循环,后面需要恢复当前状态的值
{
break;
}
else
{
hsm_nextState = &hsm_stateList[currentState->smTransition->transition[transitionID].toState];//setting the next state,找到跳转路径,保存目的状态
//printf(" next state  = %d\n  ",hsm_nextState->stateID);
}
}
if(result)
{


hsm_doTransition(transitionID,currentState);// if the event is consumed by the current state do the transition.       找到跳转路径,则执行状态的跳转处理流程

}
else
{
hsm_currentState = currentStateBackUp;
}


}

判断事件是否能触发状态机发生跳转

/*! \fn void hsm_isEventConsumed(state *currentState, EventID eventId,unsigned int *transitionIndex) 
*  \brief This functionchecks if the evnet is consumed by the state indicated by the currentState param.
*   If the event is consumed by a transition the return value is set to HSM_RESULT_OK and the 
*  *transitionIndex is set to the ID of the Transition consuming the event
*
*  \param[in] *currentState pointer to the current state
*  \param[in]  eventId ID of the current Event to be checked for
*  \param[out] *transitionIndex pointer to transitionIndex ID of the transition to be set by the function
*  where the event is consumed. (Here it is assumed that an event can be consumed by  multiple transitions based on transition condition)
*  \return result can be HSM_RESULT_OK or HSM_RESULT_NOK. If the event is consumed by a transition the return value is set to HSM_RESULT_OK and the 
*  *transitionIndex is set to the ID of the Transition consuming the event
*/
unsigned int hsm_isEventConsumed(state *currentState, EventID eventId,unsigned int *transitionIndex)
{
unsigned int result = HSM_RESULT_NOK;
unsigned int transitionID = 0;
unsigned int transitionCount = currentState->smTransition->transitionCount;    //获取当前状态的允许跳转的次数,一个状态根据不同的触发事件会发生多次跳转到不同的目的状态
for(transitionID = 0;transitionID < transitionCount;transitionID++)
{
if(eventId == currentState->smTransition->transition[transitionID].triggerID)          //找到当前状态满足该触发事件的跳转id----transitionID
{
if(currentState->smTransition->transition[transitionID].condition != 0)//execute the transition condition to know if the conditions are correct.,当前触发事件下,是否满足跳转条件
{
if(currentState->smTransition->transition[transitionID].condition()== HSM_RESULT_OK)
{
*transitionIndex = transitionID;//return the current transition Identifier to event processor      //满足触发条件,返回跳转id给事件处理流程
result = HSM_RESULT_OK;
break;
}
}
else
{
*transitionIndex = transitionID;//return the current transition Identifier to event processor     //满足触发事件,无跳转条件时,直接返回跳转id给事件处理流程
result = HSM_RESULT_OK;
break;
}


}
}
return result;


}


跳转处理

/*! \fn void hsm_doTransition(unsigned int transitionID) 
*  \brief This function actually performs the stateTransition. For the state transition execution,
*   the exit functions corresponding to the current and its parent states(which is not the common parent for source and destination) 
*   are to be executed. and Entry function to be executed in the hierarchy order
*  \param transitionID The Id of the transition that need to be perfoemd by the current State
*  \return void
*/
void hsm_doTransition(unsigned int transitionID,state *currentState)
{


if ( hsm_nextState->stateID!= STATEID_NULL)
{
//call the exit hierarchically
executeExit();                           //出口动作,退出当前状态
//execute the state transition
if(NULL != currentState->smTransition)
{
if(NULL != currentState->smTransition->transition[transitionID].action)
{
  currentState->smTransition->transition[transitionID].action();//assuming only one action is there during transition,执行转换动作
}
}
//call the entry hierarchically ,入口动作,进入目的状态
executeEntry();

//execute state transition action
hsm_currentState = hsm_nextState;//do the state transition to next state ,进入目的状态后,就将目的状态设置为当前状态
hsm_nextState = STATEID_NULL;//change the next State  to NULL ,当前状态更新后,目的状态先初始化
//Call the DO action of the state
if(NULL != hsm_currentState )
{
if(NULL != hsm_currentState->doAction)
{
hsm_currentState->doAction();       //执行最新当前状态(即原来的目的状态)的行为动作
}
}
hsm_ProcessEvent(EV_DEFAULT);      //跳转到事件处理流程,进行状态转换
}

}




相关文章推荐

层次状态机

出处:http://xlambda.com/blog/2014/11/04/hierarchical-state-machine/ 计算机程序是写给人看的,只是顺便能运行。 —— 《计算机...

调度器学习笔记三:HSM状态机理解

今天心情不错,突然想明白了困扰自己几个月的HSM(层次状态机)问题,“顿悟”的感觉真是舒畅。这也再次证明不够聪明的人(我),应该勤能补拙。废话少说,把自己的体会总结如下。         HSM被称为...

HSM层次状态机实战

HSM层次状态机实战
  • xkarl
  • xkarl
  • 2013年04月18日 14:20
  • 1315

状态机的一些基础概念

在学习状态机的过程中,不可避免的有一些重要的概念或知识点不断出现,因此做一个大概的总结,加深...
  • alien75
  • alien75
  • 2014年07月16日 08:57
  • 2385

状态机的实现

现在很多人在利用比较流行的开源游戏引擎cocos2d-x开发游戏,在游戏中免不了使用状态机,这里给大家一种我自认为好的状态机的实现O(∩_∩)O~。 先贴上代码: #ifndef BASEST...

开源网络库【状态机】

http://code.google.com/p/bayonet/downloads/detail?name=bayonet_1.5.4.zip&can=2&q=   http://code.goog...

量子编程详解之一: QP-nano代码大餐之状态机函数详细注释

先把内容贴上来再说,下一步接着来 这个是量子编程的学习心得的第一篇 先是qepn.c 格式还弄不好 研究好了重发一篇 /*****************************...
  • lyqdy1
  • lyqdy1
  • 2011年12月19日 23:08
  • 6995

调度器学习笔记三:HSM状态机理解

今天心情不错,突然想明白了困扰自己几个月的HSM(层次状态机)问题,“顿悟”的感觉真是舒畅。这也再次证明不够聪明的人(我),应该勤能补拙。废话少说,把自己的体会总结如下。         HSM被称为...

Unity3D有限状态机(FSM)学习笔记【3】FSState类

本系列笔记转载自游戏蛮牛专栏作家Jackel的论坛文章,详细介绍了FSM的创建与使用,特与众分享。链接:http://www.manew.com/thread-37136-1-1.html 该类主要...

算法学习笔记(九)有限状态机 FSM 的应用

有限状态机(Finite-state machine)又称有限状态自动机,是表示有限个状态以及在这些状态之间的转移和动作等行为的数学模型。常用与:正则表达式引擎,编译器的词法和语法分析,游戏设计,网络...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:开源HSM学习笔记---状态机的运行
举报原因:
原因补充:

(最多只允许输入30个字)