rfsm troubles

I started working with rFSM and quickly found something unexpected. I don't know why one of these machines works and the other doesn't. I'd appreciate some guidance.

Essentially, the following machines are identical, it's just that one has an extra state and some extra transitions. The idea is that there's two primary states, and inside one of those states are a handful of sub-states. Those substates are configured (essentially) where there's one initial sub-state that can transition to any of the others. And the others can transition from one to the next (in one direction). There is also an "error" state (the "last" state) that all sub-states can transition to, and it can transition back to the initial sub-state. With 5 sub-states, it works. With 6, I get errors.

The state machine(s), I switch back and forth by selectively commenting the "5" or "6" section:
/**
return rfsm.state
{
sA = rfsm.state{ entry=function() print("sA") end },

sB = rfsm.state{ entry=function() print("sB") end,

initial = rfsm.conn{},
rfsm.trans {src="initial", tgt="sB_s1"},

sB_s1 = rfsm.state{ entry=function() print("sB_s1") end },
sB_s2 = rfsm.state{ entry=function() print("sB_s2") end },
sB_s3 = rfsm.state{ entry=function() print("sB_s3") end },
sB_s4 = rfsm.state{ entry=function() print("sB_s4") end },
sB_s5 = rfsm.state{ entry=function() print("sB_s5") end },

-- 5 states
rfsm.trans {src="sB_s1", tgt="sB_s2", events={'e_sB_s2'}},
rfsm.trans {src="sB_s1", tgt="sB_s3", events={'e_sB_s3'}},
rfsm.trans {src="sB_s1", tgt="sB_s4", events={'e_sB_s4'}},

rfsm.trans {src="sB_s2", tgt="sB_s3", events={'e_sB_s3'}},
rfsm.trans {src="sB_s3", tgt="sB_s4", events={'e_sB_s4'}},

rfsm.trans {src="sB_s1", tgt="sB_s5", events={'e_sB_s5'}},
rfsm.trans {src="sB_s2", tgt="sB_s5", events={'e_sB_s5'}},
rfsm.trans {src="sB_s3", tgt="sB_s5", events={'e_sB_s5'}},
rfsm.trans {src="sB_s4", tgt="sB_s5", events={'e_sB_s5'}},
rfsm.trans {src="sB_s5", tgt="sB_s1", events={'e_sB_s1'}},

-- 6 states
-- sB_s6 = rfsm.state{ entry=function() print("sB_s6") end },

-- rfsm.trans {src="sB_s1", tgt="sB_s2", events={'e_sB_s2'}},
-- rfsm.trans {src="sB_s1", tgt="sB_s3", events={'e_sB_s3'}},
-- rfsm.trans {src="sB_s1", tgt="sB_s4", events={'e_sB_s4'}},
-- rfsm.trans {src="sB_s1", tgt="sB_s5", events={'e_sB_s5'}},

-- rfsm.trans {src="sB_s2", tgt="sB_s3", events={'e_sB_s3'}},
-- rfsm.trans {src="sB_s3", tgt="sB_s4", events={'e_sB_s4'}},
-- rfsm.trans {src="sB_s4", tgt="sB_s5", events={'e_sB_s5'}},

-- rfsm.trans {src="sB_s1", tgt="sB_s6", events={'e_sB_s6'}},
-- rfsm.trans {src="sB_s2", tgt="sB_s6", events={'e_sB_s6'}},
-- rfsm.trans {src="sB_s3", tgt="sB_s6", events={'e_sB_s6'}},
-- rfsm.trans {src="sB_s4", tgt="sB_s6", events={'e_sB_s6'}},
-- rfsm.trans {src="sB_s5", tgt="sB_s6", events={'e_sB_s6'}},
-- rfsm.trans {src="sB_s6", tgt="sB_s1", events={'e_sB_s1'}},
},

initial = rfsm.conn{},
rfsm.trans {src="initial", tgt="sA"},

rfsm.trans {src="sA", tgt="sB", events={'e_sB'}},
rfsm.trans {src="sB", tgt="sA", events={'e_sA'}},
}
**/

When I run rfsm-sim, I get the following output

/** with 5 states
$ rosrun rfsm rfsm-sim test.lua
Lua 5.1.4 Copyright (C) 1994-2008 Lua.org<http://Lua.org>, PUC-Rio
rFSM simulator v0.1, type 'help()' to list available commands
> pp()
root
sA[LS]
sB[CS]
sB_s5[LS]
sB_s3[LS]
sB_s4[LS]
sB_s2[LS]
sB_s1[LS]

> run()
sA
active: root.sA(done)
queue:
>
**/

/** with 6 states
$ rosrun rfsm rfsm-sim test.lua
Lua 5.1.4 Copyright (C) 1994-2008 Lua.org<http://Lua.org>, PUC-Rio
rFSM simulator v0.1, type 'help()' to list available commands
> pp()
root
sA[LS]
sB[CS]
sB_s5[LS]
sB_s3[LS]
sB_s4[LS]
sB_s2[LS]
sB_s6[LS]
sB_s1[LS]

> run()
sA
/opt/orocos/rfsm/tools/rfsm-sim: line 10: 14520 Aborted (core dumped) env $LUA -i $SCRIPTPATH/rfsm-sim.lua $1
**/

What's weird is that when I run these through rfsm-viz to generate UML diagrams, they both work fine.

Why does 5 work and 6 fail? Why, in the 6 state one, is sB_s6 so low in the pp() list?

--
Dustin Gooding
NASA/JSC Robotics
IM: dgooding [..] ...<xmpp:dgooding [..] ...>

rfsm troubles

Hi Dustin,

On Wed, Jan 09, 2013 at 10:23:07AM -0600, Gooding, Dustin R. (JSC-ER411) wrote:
> I started working with rFSM and quickly found something unexpected. I don't
> know why one of these machines works and the other doesn't. I'd appreciate
> some guidance.
>
> Essentially, the following machines are identical, it's just that one has an
> extra state and some extra transitions. The idea is that there's two primary
> states, and inside one of those states are a handful of sub-states. Those
> substates are configured (essentially) where there's one initial sub-state that
> can transition to any of the others. And the others can transition from one to
> the next (in one direction). There is also an "error" state (the "last" state)
> that all sub-states can transition to, and it can transition back to the
> initial sub-state. With 5 sub-states, it works. With 6, I get errors.
>
> The state machine(s), I switch back and forth by selectively commenting the "5"
> or "6" section:
> /**
> return rfsm.state
> {
> sA = rfsm.state{ entry=function() print("sA") end },
>
> sB = rfsm.state{ entry=function() print("sB") end,
>
> initial = rfsm.conn{},
> rfsm.trans {src="initial", tgt="sB_s1"},
>
> sB_s1 = rfsm.state{ entry=function() print("sB_s1") end },
> sB_s2 = rfsm.state{ entry=function() print("sB_s2") end },
> sB_s3 = rfsm.state{ entry=function() print("sB_s3") end },
> sB_s4 = rfsm.state{ entry=function() print("sB_s4") end },
> sB_s5 = rfsm.state{ entry=function() print("sB_s5") end },
>
> -- 5 states
> rfsm.trans {src="sB_s1", tgt="sB_s2", events={'e_sB_s2'}},
> rfsm.trans {src="sB_s1", tgt="sB_s3", events={'e_sB_s3'}},
> rfsm.trans {src="sB_s1", tgt="sB_s4", events={'e_sB_s4'}},
>
> rfsm.trans {src="sB_s2", tgt="sB_s3", events={'e_sB_s3'}},
> rfsm.trans {src="sB_s3", tgt="sB_s4", events={'e_sB_s4'}},
>
> rfsm.trans {src="sB_s1", tgt="sB_s5", events={'e_sB_s5'}},
> rfsm.trans {src="sB_s2", tgt="sB_s5", events={'e_sB_s5'}},
> rfsm.trans {src="sB_s3", tgt="sB_s5", events={'e_sB_s5'}},
> rfsm.trans {src="sB_s4", tgt="sB_s5", events={'e_sB_s5'}},
> rfsm.trans {src="sB_s5", tgt="sB_s1", events={'e_sB_s1'}},
>
> -- 6 states
> -- sB_s6 = rfsm.state{ entry=function() print("sB_s6") end },
>
> -- rfsm.trans {src="sB_s1", tgt="sB_s2", events={'e_sB_s2'}},
> -- rfsm.trans {src="sB_s1", tgt="sB_s3", events={'e_sB_s3'}},
> -- rfsm.trans {src="sB_s1", tgt="sB_s4", events={'e_sB_s4'}},
> -- rfsm.trans {src="sB_s1", tgt="sB_s5", events={'e_sB_s5'}},
>
> -- rfsm.trans {src="sB_s2", tgt="sB_s3", events={'e_sB_s3'}},
> -- rfsm.trans {src="sB_s3", tgt="sB_s4", events={'e_sB_s4'}},
> -- rfsm.trans {src="sB_s4", tgt="sB_s5", events={'e_sB_s5'}},
>
> -- rfsm.trans {src="sB_s1", tgt="sB_s6", events={'e_sB_s6'}},
> -- rfsm.trans {src="sB_s2", tgt="sB_s6", events={'e_sB_s6'}},
> -- rfsm.trans {src="sB_s3", tgt="sB_s6", events={'e_sB_s6'}},
> -- rfsm.trans {src="sB_s4", tgt="sB_s6", events={'e_sB_s6'}},
> -- rfsm.trans {src="sB_s5", tgt="sB_s6", events={'e_sB_s6'}},
> -- rfsm.trans {src="sB_s6", tgt="sB_s1", events={'e_sB_s1'}},
> },
>
> initial = rfsm.conn{},
> rfsm.trans {src="initial", tgt="sA"},
>
> rfsm.trans {src="sA", tgt="sB", events={'e_sB'}},
> rfsm.trans {src="sB", tgt="sA", events={'e_sA'}},
> }
> **/
>
>
>
>
> When I run rfsm-sim, I get the following output
>
> /** with 5 states
> $ rosrun rfsm rfsm-sim test.lua
> Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio
> rFSM simulator v0.1, type 'help()' to list available commands
> > pp()
> root
> sA[LS]
> sB[CS]
> sB_s5[LS]
> sB_s3[LS]
> sB_s4[LS]
> sB_s2[LS]
> sB_s1[LS]
>
> > run()
> sA
> active: root.sA(done)
> queue:
> >
> **/
>
> /** with 6 states
> $ rosrun rfsm rfsm-sim test.lua
> Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio
> rFSM simulator v0.1, type 'help()' to list available commands
> > pp()
> root
> sA[LS]
> sB[CS]
> sB_s5[LS]
> sB_s3[LS]
> sB_s4[LS]
> sB_s2[LS]
> sB_s6[LS]
> sB_s1[LS]
>
> > run()
> sA
> /opt/orocos/rfsm/tools/rfsm-sim: line 10: 14520 Aborted (core
> dumped) env $LUA -i $SCRIPTPATH/rfsm-sim.lua $1
> **/

Fortunately rFSM can't really crash by themself, so it means it's
somebody else fault :-)

My guess it is graphiz, which for unknown reasons sometimes crashes
during layout. Although you may not be using it directly, the figures
are still generated using rfsm-sim (probably we should not do that).

Could you try if the problem disappears with the attached patch
against rfsm-sim?

> What's weird is that when I run these through rfsm-viz to generate UML
> diagrams, they both work fine.
>
> Why does 5 work and 6 fail? Why, in the 6 state one, is sB_s6 so low in the
> pp() list?

The list is unordered and not sorted in any way.

Markus

diff --git a/tools/rfsm-sim.lua b/tools/rfsm-sim.lua
index ea447d8..4baba4c 100644

rfsm troubles

On Jan 9, 2013, at 10:43 AM, Markus Klotzbuecher <markus [dot] klotzbuecher [..] ...> wrote:

> Hi Dustin,
>
> On Wed, Jan 09, 2013 at 10:23:07AM -0600, Gooding, Dustin R. (JSC-ER411) wrote:
>> I started working with rFSM and quickly found something unexpected. I don't
>> know why one of these machines works and the other doesn't. I'd appreciate
>> some guidance.
>>
>> Essentially, the following machines are identical, it's just that one has an
>> extra state and some extra transitions. The idea is that there's two primary
>> states, and inside one of those states are a handful of sub-states. Those
>> substates are configured (essentially) where there's one initial sub-state that
>> can transition to any of the others. And the others can transition from one to
>> the next (in one direction). There is also an "error" state (the "last" state)
>> that all sub-states can transition to, and it can transition back to the
>> initial sub-state. With 5 sub-states, it works. With 6, I get errors.
>>
>> The state machine(s), I switch back and forth by selectively commenting the "5"
>> or "6" section:
>> /**
>> return rfsm.state
>> {
>> sA = rfsm.state{ entry=function() print("sA") end },
>>
>> sB = rfsm.state{ entry=function() print("sB") end,
>>
>> initial = rfsm.conn{},
>> rfsm.trans {src="initial", tgt="sB_s1"},
>>
>> sB_s1 = rfsm.state{ entry=function() print("sB_s1") end },
>> sB_s2 = rfsm.state{ entry=function() print("sB_s2") end },
>> sB_s3 = rfsm.state{ entry=function() print("sB_s3") end },
>> sB_s4 = rfsm.state{ entry=function() print("sB_s4") end },
>> sB_s5 = rfsm.state{ entry=function() print("sB_s5") end },
>>
>> -- 5 states
>> rfsm.trans {src="sB_s1", tgt="sB_s2", events={'e_sB_s2'}},
>> rfsm.trans {src="sB_s1", tgt="sB_s3", events={'e_sB_s3'}},
>> rfsm.trans {src="sB_s1", tgt="sB_s4", events={'e_sB_s4'}},
>>
>> rfsm.trans {src="sB_s2", tgt="sB_s3", events={'e_sB_s3'}},
>> rfsm.trans {src="sB_s3", tgt="sB_s4", events={'e_sB_s4'}},
>>
>> rfsm.trans {src="sB_s1", tgt="sB_s5", events={'e_sB_s5'}},
>> rfsm.trans {src="sB_s2", tgt="sB_s5", events={'e_sB_s5'}},
>> rfsm.trans {src="sB_s3", tgt="sB_s5", events={'e_sB_s5'}},
>> rfsm.trans {src="sB_s4", tgt="sB_s5", events={'e_sB_s5'}},
>> rfsm.trans {src="sB_s5", tgt="sB_s1", events={'e_sB_s1'}},
>>
>> -- 6 states
>> -- sB_s6 = rfsm.state{ entry=function() print("sB_s6") end },
>>
>> -- rfsm.trans {src="sB_s1", tgt="sB_s2", events={'e_sB_s2'}},
>> -- rfsm.trans {src="sB_s1", tgt="sB_s3", events={'e_sB_s3'}},
>> -- rfsm.trans {src="sB_s1", tgt="sB_s4", events={'e_sB_s4'}},
>> -- rfsm.trans {src="sB_s1", tgt="sB_s5", events={'e_sB_s5'}},
>>
>> -- rfsm.trans {src="sB_s2", tgt="sB_s3", events={'e_sB_s3'}},
>> -- rfsm.trans {src="sB_s3", tgt="sB_s4", events={'e_sB_s4'}},
>> -- rfsm.trans {src="sB_s4", tgt="sB_s5", events={'e_sB_s5'}},
>>
>> -- rfsm.trans {src="sB_s1", tgt="sB_s6", events={'e_sB_s6'}},
>> -- rfsm.trans {src="sB_s2", tgt="sB_s6", events={'e_sB_s6'}},
>> -- rfsm.trans {src="sB_s3", tgt="sB_s6", events={'e_sB_s6'}},
>> -- rfsm.trans {src="sB_s4", tgt="sB_s6", events={'e_sB_s6'}},
>> -- rfsm.trans {src="sB_s5", tgt="sB_s6", events={'e_sB_s6'}},
>> -- rfsm.trans {src="sB_s6", tgt="sB_s1", events={'e_sB_s1'}},
>> },
>>
>> initial = rfsm.conn{},
>> rfsm.trans {src="initial", tgt="sA"},
>>
>> rfsm.trans {src="sA", tgt="sB", events={'e_sB'}},
>> rfsm.trans {src="sB", tgt="sA", events={'e_sA'}},
>> }
>> **/
>>
>>
>>
>>
>> When I run rfsm-sim, I get the following output
>>
>> /** with 5 states
>> $ rosrun rfsm rfsm-sim test.lua
>> Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio
>> rFSM simulator v0.1, type 'help()' to list available commands
>>> pp()
>> root
>> sA[LS]
>> sB[CS]
>> sB_s5[LS]
>> sB_s3[LS]
>> sB_s4[LS]
>> sB_s2[LS]
>> sB_s1[LS]
>>
>>> run()
>> sA
>> active: root.sA(done)
>> queue:
>>>
>> **/
>>
>> /** with 6 states
>> $ rosrun rfsm rfsm-sim test.lua
>> Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio
>> rFSM simulator v0.1, type 'help()' to list available commands
>>> pp()
>> root
>> sA[LS]
>> sB[CS]
>> sB_s5[LS]
>> sB_s3[LS]
>> sB_s4[LS]
>> sB_s2[LS]
>> sB_s6[LS]
>> sB_s1[LS]
>>
>>> run()
>> sA
>> /opt/orocos/rfsm/tools/rfsm-sim: line 10: 14520 Aborted (core
>> dumped) env $LUA -i $SCRIPTPATH/rfsm-sim.lua $1
>> **/
>
> Fortunately rFSM can't really crash by themself, so it means it's
> somebody else fault :-)
>
> My guess it is graphiz, which for unknown reasons sometimes crashes
> during layout. Although you may not be using it directly, the figures
> are still generated using rfsm-sim (probably we should not do that).
>
> Could you try if the problem disappears with the attached patch
> against rfsm-sim?
>
>> What's weird is that when I run these through rfsm-viz to generate UML
>> diagrams, they both work fine.
>>
>> Why does 5 work and 6 fail? Why, in the 6 state one, is sB_s6 so low in the
>> pp() list?
>
> The list is unordered and not sorted in any way.
>
> Markus
>
>
>
> diff --git a/tools/rfsm-sim.lua b/tools/rfsm-sim.lua
> index ea447d8..4baba4c 100644

rfsm troubles

On Wed, Jan 09, 2013 at 10:59:02AM -0600, Gooding, Dustin R. (JSC-ER411) wrote:
...

> That change appears to make the sim work for the 6-state case. I
> tried it on my much larger machine that was also breaking and it's
> now working as well.
>
> Thanks!

Thanks for testing! I will apply a variant of that patch to the dev
branch. I'm thinking of only adding the graphviz generation hooks if
viztree or vizuml is run.

Markus