2010-10-14 14 views
5

Sto utilizzando la nuova libreria Boost 1.44.0 MSM per produrre una macchina a stati. In questa macchina a stati ci sono due classi di eventi class1 e class2. Gli eventi class1 possono essere elaborati da entrambi gli stati S1 o S2 mentre gli eventi class2 possono essere elaborati solo dallo stato S2.Booster MSM che elabora solo le transizioni interne

Un evento speciale class1upgrade_req richiede un aggiornamento dallo stato S1 allo stato S2.

Ho implementato che nel Boost :: MSM come segue:

// State S1 and S2 allow any class1 events 
struct class1 {}; 
// Only state S2 allows class2 events 
struct class2 {}; 

// an upgrade request is a class1 event that requests an upgrade to state 2 
struct upgrade_req : public class1 {}; 

struct MyFSM : public msm::front::state_machine_def<MyFSM> 
{ 
    /// State 1. Allows any class1 event 
    struct S1 : public msm::front::state<> 
    { 
     /// functor says "processing event in State 1" 
     struct ProcessEvent { /* ... */ }; 

     struct internal_transition_table : mpl::vector< 
      //  Event Action  Guard 
      //  +-------+-------------+------------+ 
      Internal< class1, ProcessEvent, none > 
     > {}; 
    }; // S1 

    /// State 2. Allows any class1 or class2 events 
    struct S2 : public msm::front::state<> 
    { 
     /// functor says "processing event in State 2" 
     struct ProcessEvent { /* ... */ }; 

     struct internal_transition_table : mpl::vector< 
      //  Event Action  Guard 
      //  +-------+-------------+------------+ 
      Internal< class1, ProcessEvent, none >, 
      Internal< class2, ProcessEvent, none > 
     > {}; 
    }; // S2 

    /// everybody starts in state 1 
    typedef S1 initial_state; 

    /// send an error if a class2 event was received for state1 
    struct SendError { /* ... */ }; 

    /// Send a response to the upgrade request 
    struct SendUpgradeRsp { /* ... */ }; 

    /// functor returns true if the request to upgrade to state 2 is OK. 
    struct VerifyUpgradeReq { /* ... */ }; 

    struct transition_table : mpl::vector< 
     // Start Event   Next Action   Guard 
     // +------+-------------+------+----------------+------------------+ 
     Row< S1, class1,  none, none,   none, 
     Row< S1, class2,  S1, SendError,  none >, 
     Row< S1, upgrade_req, S2, SendUpgradRsp, VerifyUpgradeReq >, 

     Row< S2, class1,  none, none,   none, 
     Row< S2, class2,  none, none,   none > 
    > {}; 
}; // MyFSM 

il mio problema è che quando uso questo come è, l'evento upgrade_req viene mai elaborato dal principale MyFSM::transition_table. Viene elaborato solo dal S1::internal_transition_table.

Ad esempio:

int main(int argc, char* argv[]) 
{ 
    msm::back::state_machine<MyFSM> sm; 
    sm.start(); 
    sm.process_event(class1()); 
    sm.process_event(upgrade_req()); 
    sm.process_event(class2()); 
    return 0; 
} 

Una cosa voglio l'uscita di questo essere: evento

trasformazione in Stato 1.
aggiornamento Richiesta OK.
evento trasformazione in Stato 2.

Ma, ciò che ottengo è questo: evento

trasformazione in Stato 1.
evento di trasformazione in Stato 1.
errore. Ricevuto evento di classe 2 nello Stato 1.

Qualcuno ha un suggerimento su come posso risolvere questo problema?

Grazie, Paulh

risposta

5

tuo problema è che la priorità delle transizioni interne sia superiore a quelle definite nella tabella transizione. E update_req essendo una classe1, il transiton interno si attiva. Questo è in realtà conforme allo standard UML. MSM offre una seconda soluzione, è possibile definire la transizione interna di S1 ​​con una Riga senza nessuno come destinazione all'interno di transition_table invece di utilizzare internal_transition_table. Se lo definisci PRIMA della transizione S1 + upgrade_reg -> S2, avrà un valore inferiore e verrà provato solo se l'altro non può essere considerato.

Se è assolutamente necessario un internal_transition_table, è possibile fornire una protezione per rifiutare class1 solo se non è un update_req.

HTH, Christophe Henry

PS: ho trovato solo questo post di fortuna. La pubblicazione nell'elenco degli utenti di boost ti garantirà una risposta molto più rapida.

Problemi correlati