IMPORTANT:
this is not a Support Forum! Experienced users might answer from time to time questions posted here. If you need a professional and reliable answer, or if you want to report a bug, please contact Altova Support instead.

StateMachine question Options · View
StefanG
Posted: Tuesday, May 22, 2012 8:39:46 AM
Rank: Newbie

Joined: 5/22/2012
Posts: 3
Location: Huskvarna, Sweden
Hi there,

I am currently evaluating UModel as a possible tool for a project we are starting. During this evaluation, I am testing the State Machine generation to see how it works and if it will be useful for our needs.

I do find the generated code to not execute as I expected within the initialization. The problem I see is that all state machine regions are initialized, even if they are not to be initialized. For example in the AirCondition sample the code for "OnEntryHeater" is executed when the Initialize() is called. The log/output looks like this:

======= Event 0 =========
BEGIN_INITIALIZE
SET_CURRENT_STATE: Off
SET_CURRENT_STATE: Heater
ACTION: OnEntryHeater
SET_CURRENT_STATE: Off
END_INITIALIZE

The generated code looks like this:

Code:
// Initialize the State Machine
        public void Initialize()
        {
            OnDebugMessage( "BEGIN_INITIALIZE" );
            AirCondition_MainRegion_Operating = new CAirCondition.MainRegion.Operating(this);
            AirCondition_MainRegion_Operating_RegionMode_Heater = new CAirCondition.MainRegion.Operating.RegionMode.Heater(this);
            AirCondition_MainRegion_Operating_RegionMode_Cooler = new CAirCondition.MainRegion.Operating.RegionMode.Cooler(this);
            AirCondition_MainRegion_Operating_RegionSpeed_High = new CAirCondition.MainRegion.Operating.RegionSpeed.High(this);
            AirCondition_MainRegion_Operating_RegionSpeed_Off = new CAirCondition.MainRegion.Operating.RegionSpeed.Off(this);
            AirCondition_MainRegion_Operating_RegionSpeed_Low = new CAirCondition.MainRegion.Operating.RegionSpeed.Low(this);
            AirCondition_MainRegion_Off = new CAirCondition.MainRegion.Off(this);
            AirCondition_MainRegion_Standby = new CAirCondition.MainRegion.Standby(this);

            rootState = new CAirCondition(this);

            CAirCondition.MainRegion.setCurrentState(this, CAirCondition.MainRegion.getInitState(this));
            CAirCondition.MainRegion.Operating.RegionMode.setCurrentState(this, CAirCondition.MainRegion.Operating.RegionMode.getInitState(this));
            CAirCondition.MainRegion.Operating.RegionSpeed.setCurrentState(this, CAirCondition.MainRegion.Operating.RegionSpeed.getInitState(this));
            OnDebugMessage( "END_INITIALIZE" );
        }


My problem here is that I thought that the entry code for the "Heater" state would only be executed when its parent state is entered, i.e. the "Operating" state. The current implementation would actually force a call to "OnEntryHeater" when it has not happened. If there would be an entry action on the "Low" state this would have (wrongly?) executed as well.

Is this on purpose (if so why?) or is it a bug in the generation?

For information: I have used some UML tools (like IBM Rhapsody and others) for 10+ years for embedded development (C/C++) and in their implementation, the "OnEntryHeater" would not be executed until its parent state is reached, i.e. after the first "powerButton()" event. As I am used to this interpretation of UML-to-code translation I was a little surprised with the UModel implemenentation and hence this question.

Another question, is there any way to customize/change how the code is generated for state machines? I did not find it in the SPL-files, but maybe I did not look good enough.

The UModel tool has however been a nice experience and it is looking like a good candidate so far... :)

Best regards
Stefan
StefanG
Posted: Wednesday, May 23, 2012 1:12:47 PM
Rank: Newbie

Joined: 5/22/2012
Posts: 3
Location: Huskvarna, Sweden
I got an answer from Altova:

Hi Stefan,

thank you for contacting us.

According to the developer responsible for the implementation:

When the statemachine is started all regions are initialised. The UML specification does not unfortunately define when this should happen. We implemented
it this way so that the user will have 2 possibilites to change this (if the events are bothersome)

1) In code: ignore the events during the Initialize call (this is why we generate our own Initialize method that you can call yourself)
2) in the UML model: insert a "dummy init state" e.g. in front of the Heater State.

With regards to spl: There are no spl templates for state machine code generation

Best Regards,



This means that I either have to live with this implementation and model with an extra init-state to avoid this, or to override the Initialize() and take over the code. Both ways will work for now, but I feel that something maybe should be done with this.

Anyhow, thanks for the quick answer Altova.

Regards
Stefan
cor
Posted: Friday, May 25, 2012 7:22:54 AM
Rank: Advanced Member

Joined: 9/28/2005
Posts: 371
Location: Vienna
Hi Stefan,

In case you choose possibility 1) I would suggest to not override Initialize and take over some code there.

If you want to react on "OnEntryHeater" in your code, you will have to override this method anyway, so can do this by something like:

Code:
public override void OnEntryHeater()
{
    if ( !m_bInitialized )
        return;
        
    // .. working code...
}


When starting the state machine, you can do this like:

Code:
MySTM m_STM = null;
bool m_bInitialized = false;

m_STM = new MySTM();
m_STM.Initialize();
m_bInitialized = true;
....

StefanG
Posted: Friday, May 25, 2012 10:52:12 AM
Rank: Newbie

Joined: 5/22/2012
Posts: 3
Location: Huskvarna, Sweden
Thanx for the suggestion!
We will most likely do something like that, or perhaps even use the "dummy" state concept.

I also have another idea regarding this. We have done a little "framework" (using a common base class) for STM's that basically enables the STM's to execute in a task and have all events queued onto a thread-locked queue (i.e. event blocking etc), more like how state machines work in Rhapsody (sorry...but rather used to that tool... ;). By using this, we have also managed to implement the UML "after" (timeouts in states) concept in the state machines as well. Anyway, this little minimal framework might also enable us to handle initialization as we want.

Best regards
Stefan
Users browsing this topic
guest

Forum Jump
You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.

Use of the Altova User Forum(s) is governed by the Altova Terms of Use.