您的位置:首页 > 其它

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

2015-07-06 16:46 453 查看
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); //跳转到事件处理流程,进行状态转换

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: