Hi all,
A few weeks ago I've spent some time prototyping some rFSM state
machines. The focus was on integrating it in an existing system
architecture, and not so much on implementing the functionality. I
must say that the end result was with mixed feelings. I felt there
were 2 major issues remaining with *using* rFSM : Syntax for new
people or people not using it on a daily basis and scalability of
string events:
1. Syntax
There is just too little sugar available for neat rFSM 'programs'.
What I mean is, in the end, it is a comma separated table,
tab-indented slightly to appear as a functional description.
Especially comparing the readability of an rFSM transition with an RTT
scripting transition is quite a difference. For example:
- transitions are in the parent state instead of the source state.
This makes looking up transitions quite hard, unless you go to one of
the rFSM dot tools for visualisation
- compare a transition in RTT fsm versus an rFSM fsm:
RTT:
transition eventname( arg ) if arg < foo then { comp.doIt(); } select BAR_STATE
rFSM:
rfsm.trans { src='FOO_STATE', tgt='BAR_STATE', events='eventname',
guard=function() return args < foo end, effect = function()
comp:doIt() end, }
apart from the fact that there is no easy way to get the 'arg' data
out of an event in rFSM (see next point), it just doesn't read. I
wonder if it would be possible to improve on this.
2. strings as events
How easy this is for small prototypes, how more insane this is for any
reasonable system. It's completely unmaintainable. How to guarantee
that there are no typos in your string names ? Both on the sending
side and on the events='...' side ? How to sync the C++ side with the
Lua side ? I understand the rFSM independence of RTT (so there is no
C++ side strictly speaking), but for RTT + rFSM examples, using string
events on ports should be plainly banned.
Even more, in its current form rFSM *itself* does not allow to have
pay-loaded events since the events='...' is a comparison of data, so
the contents of the event must be known in advance fully in order to
trigger a transition. I can't think of a sane way to synchronize some
string event with some data associated with it on another port. For
any kind of coordination above the trivial, a payload is required to
be able to take the correct supervisory decisions. The reason a
payload is needed is that the events come in asynchronously, so the
system state may already have changed. The event is the only place
where that state information can be stored.
We definitely need to formulate an alternative to strings as an Orocos
community here. I already tried actually. I have written a
readEvents() function which automates linking a random data port type
with an event name ( ie still a string, required by rFSM ) and a
variable which contains the port data. But I may want to take it
further, events may actually be required as RTT extensions, building
on top of our trustworthy ports, in order to define this link to the
state machines, such that each state machine can check if a certain
event exists or not. Something like that...
3. And as a bonus: doo
It's not clear to me why we need to add our own while true do ... end
loop in doo. It's a classical omission and will basically clutter up
any doo function. If you don't want a while true do ... end loop in
your do, you could equally put the code in entry and omit doo itself.
Peter
rFSM usability & scalability feedback
Hi Peter,
On Sat, Nov 10, 2012 at 12:16:43AM +0100, Peter Soetens wrote:
> A few weeks ago I've spent some time prototyping some rFSM state
> machines. The focus was on integrating it in an existing system
> architecture, and not so much on implementing the functionality. I
> must say that the end result was with mixed feelings. I felt there
> were 2 major issues remaining with *using* rFSM : Syntax for new
> people or people not using it on a daily basis and scalability of
> string events:
>
> 1. Syntax
> There is just too little sugar available for neat rFSM 'programs'.
> What I mean is, in the end, it is a comma separated table,
> tab-indented slightly to appear as a functional description.
> Especially comparing the readability of an rFSM transition with an RTT
> scripting transition is quite a difference. For example:
> - transitions are in the parent state instead of the source state.
> This makes looking up transitions quite hard, unless you go to one of
> the rFSM dot tools for visualisation
> - compare a transition in RTT fsm versus an rFSM fsm:
> RTT:
> transition eventname( arg ) if arg < foo then { comp.doIt(); } select BAR_STATE
>
> rFSM:
> rfsm.trans { src='FOO_STATE', tgt='BAR_STATE', events='eventname',
> guard=function() return args < foo end, effect = function()
> comp:doIt() end, }
>
> apart from the fact that there is no easy way to get the 'arg' data
> out of an event in rFSM (see next point), it just doesn't read. I
> wonder if it would be possible to improve on this.
Yes, I think ultimately we should come up with a real syntax and
write/generate a real C parser for it. Then we can create Lua bindings
to it and transparently allow both syntax. Would you be interested to
contribute here? On the other hand it might be better to go straight
to graphical editing. And I disagree with adding the successor state
to the source state though, since that breaks composability of the
latter.
> 2. strings as events
> How easy this is for small prototypes, how more insane this is for any
> reasonable system. It's completely unmaintainable. How to guarantee
> that there are no typos in your string names ? Both on the sending
> side and on the events='...' side ? How to sync the C++ side with the
> Lua side ? I understand the rFSM independence of RTT (so there is no
> C++ side strictly speaking), but for RTT + rFSM examples, using string
> events on ports should be plainly banned.
>
> Even more, in its current form rFSM *itself* does not allow to have
> pay-loaded events since the events='...' is a comparison of data, so
> the contents of the event must be known in advance fully in order to
> trigger a transition. I can't think of a sane way to synchronize some
> string event with some data associated with it on another port. For
> any kind of coordination above the trivial, a payload is required to
> be able to take the correct supervisory decisions. The reason a
> payload is needed is that the events come in asynchronously, so the
> system state may already have changed. The event is the only place
> where that state information can be stored.
>
> We definitely need to formulate an alternative to strings as an Orocos
> community here. I already tried actually. I have written a
> readEvents() function which automates linking a random data port type
> with an event name ( ie still a string, required by rFSM ) and a
> variable which contains the port data. But I may want to take it
> further, events may actually be required as RTT extensions, building
> on top of our trustworthy ports, in order to define this link to the
> state machines, such that each state machine can check if a certain
> event exists or not. Something like that...
Nice rant :-), but I do agree.
Ok, three things: scalability, error-proneness and payloads. String
events are indeed not scalable, but on the other hand we surely don't
want people writing statemachines triggered by numbers. As you
suggest, I think the only way to deal with this is to "standardize"
within the RTT community on some kind of event model and
representation _and_ suggested use in components.
I have had in mind the following. Firstly, the events a component can
raise should become introspectable at runtime. This could be as simple
as a string->number map using a read-only property. To ensure
uniqueness across the system, a raised event number needs to be
prepended (automatically) with a unique component id (do we have
this?)
Once we have that, we're basically done. An rFSM developer can
continue to use the convenient string (or whatever) like
"component.event" as triggers. Using a preprocessing plugin, at load
time we transform all string events to number events by looking these
up in the component interfaces. This way we also verify that a
component really does raise the specified event.
(BTW: there is a rfsm_checkevents plugin to help detect typos. When
loaded and an event is received that is not used on any transition of
the FSM, a warning is printed).
We can even define an RTT dbg function that converts the numbers back
to their string names in debug messages.
Regarding the payload, it is less clear to me what we really
need. Maybe you can describe a real world use-case you had.
> 3. And as a bonus: doo
> It's not clear to me why we need to add our own while true do ... end
> loop in doo. It's a classical omission and will basically clutter up
> any doo function. If you don't want a while true do ... end loop in
> your do, you could equally put the code in entry and omit doo itself.
You don't need the while ... end. You just need it if you want to
continunously call the same code again, while giving up control at a
yield. You could also have a non-looping doo:
function doo()
dothis();
yield();
dothat();
yield();
foo();
end
We could achieve the same by introducing doo parameters 'oneshot' and
'periodic', and then allowing specifying periodic doo's without while
... end. Would you prefer that?
Thanks a lot for the feedback!
Markus
rFSM usability & scalability feedback
On 11/10/2012 09:57 AM, Markus Klotzbuecher wrote:
> Ok, three things: scalability, error-proneness and payloads. String
> events are indeed not scalable, but on the other hand we surely don't
> want people writing statemachines triggered by numbers. As you
> suggest, I think the only way to deal with this is to "standardize"
> within the RTT community on some kind of event model and
> representation _and_ suggested use in components.
>
> I have had in mind the following. Firstly, the events a component can
> raise should become introspectable at runtime. This could be as simple
> as a string->number map using a read-only property. To ensure
> uniqueness across the system, a raised event number needs to be
> prepended (automatically) with a unique component id (do we have
> this?)
FYI
http://www.rock-robotics.org/stable/documentation/orogen/task_states.htm...
The 'state' name is a misnomer, as -- in the end -- we use it more as
events than numbers. orocos.rb does the number-to-symbol convertion for
the Ruby scripts (which, then, never see the actual number).
oroGen does a number-to-symbol match (not available at the introspection
level, but could be exported into a common interface) and the C++ API
only uses the enums (i.e., numbers)
rFSM usability & scalability feedback
On Mon, Nov 12, 2012 at 09:11:34AM +0100, Sylvain Joyeux wrote:
> On 11/10/2012 09:57 AM, Markus Klotzbuecher wrote:
> >Ok, three things: scalability, error-proneness and payloads. String
> >events are indeed not scalable, but on the other hand we surely don't
> >want people writing statemachines triggered by numbers. As you
> >suggest, I think the only way to deal with this is to "standardize"
> >within the RTT community on some kind of event model and
> >representation _and_ suggested use in components.
> >
> >I have had in mind the following. Firstly, the events a component can
> >raise should become introspectable at runtime. This could be as simple
> >as a string->number map using a read-only property. To ensure
> >uniqueness across the system, a raised event number needs to be
> >prepended (automatically) with a unique component id (do we have
> >this?)
> FYI http://www.rock-robotics.org/stable/documentation/orogen/task_states.htm...
>
> The 'state' name is a misnomer, as -- in the end -- we use it more
> as events than numbers. orocos.rb does the number-to-symbol
> convertion for the Ruby scripts (which, then, never see the actual
> number).
>
> oroGen does a number-to-symbol match (not available at the
> introspection level, but could be exported into a common interface)
> and the C++ API only uses the enums (i.e., numbers)
That's exactly what I had in mind. How do you ensure uniqueness across
a distributed application?
Markus
rFSM usability & scalability feedback
On 11/12/2012 10:17 AM, Markus Klotzbuecher wrote:
> On Mon, Nov 12, 2012 at 09:11:34AM +0100, Sylvain Joyeux wrote:
>> On 11/10/2012 09:57 AM, Markus Klotzbuecher wrote:
>>> Ok, three things: scalability, error-proneness and payloads. String
>>> events are indeed not scalable, but on the other hand we surely don't
>>> want people writing statemachines triggered by numbers. As you
>>> suggest, I think the only way to deal with this is to "standardize"
>>> within the RTT community on some kind of event model and
>>> representation _and_ suggested use in components.
>>>
>>> I have had in mind the following. Firstly, the events a component can
>>> raise should become introspectable at runtime. This could be as simple
>>> as a string->number map using a read-only property. To ensure
>>> uniqueness across the system, a raised event number needs to be
>>> prepended (automatically) with a unique component id (do we have
>>> this?)
>> FYI http://www.rock-robotics.org/stable/documentation/orogen/task_states.htm...
>>
>> The 'state' name is a misnomer, as -- in the end -- we use it more
>> as events than numbers. orocos.rb does the number-to-symbol
>> convertion for the Ruby scripts (which, then, never see the actual
>> number).
>>
>> oroGen does a number-to-symbol match (not available at the
>> introspection level, but could be exported into a common interface)
>> and the C++ API only uses the enums (i.e., numbers)
> That's exactly what I had in mind. How do you ensure uniqueness across
> a distributed application?
States get interpreted locally to the component that generate them. I.e.
when I get 20 from component A, I may interpret it differently from when
I get 20 from component B (and that's transparent to the user).
rFSM usability & scalability feedback
On Sat, Nov 10, 2012 at 9:57 AM, Markus Klotzbuecher
<markus [dot] klotzbuecher [..] ...> wrote:
> Hi Peter,
>
> On Sat, Nov 10, 2012 at 12:16:43AM +0100, Peter Soetens wrote:
>
>> A few weeks ago I've spent some time prototyping some rFSM state
>> machines. The focus was on integrating it in an existing system
>> architecture, and not so much on implementing the functionality. I
>> must say that the end result was with mixed feelings. I felt there
>> were 2 major issues remaining with *using* rFSM : Syntax for new
>> people or people not using it on a daily basis and scalability of
>> string events:
>>
>> 1. Syntax
>> There is just too little sugar available for neat rFSM 'programs'.
>> What I mean is, in the end, it is a comma separated table,
>> tab-indented slightly to appear as a functional description.
>> Especially comparing the readability of an rFSM transition with an RTT
>> scripting transition is quite a difference. For example:
>> - transitions are in the parent state instead of the source state.
>> This makes looking up transitions quite hard, unless you go to one of
>> the rFSM dot tools for visualisation
>> - compare a transition in RTT fsm versus an rFSM fsm:
>> RTT:
>> transition eventname( arg ) if arg < foo then { comp.doIt(); } select BAR_STATE
>>
>> rFSM:
>> rfsm.trans { src='FOO_STATE', tgt='BAR_STATE', events='eventname',
>> guard=function() return args < foo end, effect = function()
>> comp:doIt() end, }
>>
>> apart from the fact that there is no easy way to get the 'arg' data
>> out of an event in rFSM (see next point), it just doesn't read. I
>> wonder if it would be possible to improve on this.
>
> Yes, I think ultimately we should come up with a real syntax and
> write/generate a real C parser for it. Then we can create Lua bindings
> to it and transparently allow both syntax. Would you be interested to
> contribute here?
So you're suggesting to write a parser which parses the rfsm structure
and passes lua statements on to the lua parser ?
We'll need a volunteer to have a go at this...
> On the other hand it might be better to go straight
> to graphical editing.
Requires more resources, unless there's a drop-in editor already available .. ?
> And I disagree with adding the successor state
> to the source state though, since that breaks composability of the
> latter.
You're right on this one. It's still far less readable though.
>
>> 2. strings as events
>> How easy this is for small prototypes, how more insane this is for any
>> reasonable system. It's completely unmaintainable. How to guarantee
>> that there are no typos in your string names ? Both on the sending
>> side and on the events='...' side ? How to sync the C++ side with the
>> Lua side ? I understand the rFSM independence of RTT (so there is no
>> C++ side strictly speaking), but for RTT + rFSM examples, using string
>> events on ports should be plainly banned.
>>
>> Even more, in its current form rFSM *itself* does not allow to have
>> pay-loaded events since the events='...' is a comparison of data, so
>> the contents of the event must be known in advance fully in order to
>> trigger a transition. I can't think of a sane way to synchronize some
>> string event with some data associated with it on another port. For
>> any kind of coordination above the trivial, a payload is required to
>> be able to take the correct supervisory decisions. The reason a
>> payload is needed is that the events come in asynchronously, so the
>> system state may already have changed. The event is the only place
>> where that state information can be stored.
>>
>> We definitely need to formulate an alternative to strings as an Orocos
>> community here. I already tried actually. I have written a
>> readEvents() function which automates linking a random data port type
>> with an event name ( ie still a string, required by rFSM ) and a
>> variable which contains the port data. But I may want to take it
>> further, events may actually be required as RTT extensions, building
>> on top of our trustworthy ports, in order to define this link to the
>> state machines, such that each state machine can check if a certain
>> event exists or not. Something like that...
>
> Nice rant :-), but I do agree.
>
> Ok, three things: scalability, error-proneness and payloads. String
> events are indeed not scalable, but on the other hand we surely don't
> want people writing statemachines triggered by numbers.
I wasn't hinting at numbers at all. The scalability argument is not
for 'the size of a string / copying cost of a string / comparing a
string', but for the maintainability of all these strings accross a
big application. There's no type checking.
> As you
> suggest, I think the only way to deal with this is to "standardize"
> within the RTT community on some kind of event model and
> representation _and_ suggested use in components.
Ack.
>
> I have had in mind the following. Firstly, the events a component can
> raise should become introspectable at runtime. This could be as simple
> as a string->number map using a read-only property. To ensure
> uniqueness across the system, a raised event number needs to be
> prepended (automatically) with a unique component id (do we have
> this?)
I don't know if this is where we want to go. There's always this
subtle variation between knowing who raised the event or 'anonymous'
events. RTT 1.x had event + source, current rFSM ( and all Orocos
ports) uses anonymous events. For me, the source should act as an
optional guard, but anyone should be able to raise event type 'E'.
Also, I don't see the advantage of working with numbers, unless they
are purely a behind-the-API optimisation.
I do agree however in having events declared in the C++ part, such
that runtime tools can check for available events. Ports do this, they
are event sources and sinks, but used in a dataflow context. I was
thinking 'RTT extension' as in 'RTT component service'. Intelligent
rFSM bindings would then query this service to know what's available
in the current components & system setup.
>
> Once we have that, we're basically done. An rFSM developer can
> continue to use the convenient string (or whatever) like
> "component.event" as triggers. Using a preprocessing plugin, at load
> time we transform all string events to number events by looking these
> up in the component interfaces. This way we also verify that a
> component really does raise the specified event.
This would not solve the payload argument.
What the solution should also provide is:
* a generic getevents implementation such that it's not required for
RTT users to write one.
* I would also suggest to have a 'protocol' event port (each event is
presented one at a time at the rFSM) and a 'priority' event port (all
received events since last time are presented to the rFSM and
discarded after transition).
* Have some clarity over 'edge' triggering and 'level' triggering. RTT
1.x events were level triggered, you could wait until a combination of
events became true. I don't see how this can happen in rFSM, unless
you use a really awkward design to circumvent this omission ?
>
> (BTW: there is a rfsm_checkevents plugin to help detect typos. When
> loaded and an event is received that is not used on any transition of
> the FSM, a warning is printed).
>
> We can even define an RTT dbg function that converts the numbers back
> to their string names in debug messages.
>
> Regarding the payload, it is less clear to me what we really
> need. Maybe you can describe a real world use-case you had.
struct WayPointPassedEvent
{
KDL::Frame pose;
int wpnumber;
};
There are really many of these examples (collision detected (where?),
object grasped (where?), joint failed (which one?),...) although there
are equally many where there is no payload.
>
>> 3. And as a bonus: doo
>> It's not clear to me why we need to add our own while true do ... end
>> loop in doo. It's a classical omission and will basically clutter up
>> any doo function. If you don't want a while true do ... end loop in
>> your do, you could equally put the code in entry and omit doo itself.
>
> You don't need the while ... end. You just need it if you want to
> continunously call the same code again, while giving up control at a
> yield. You could also have a non-looping doo:
>
> function doo()
> dothis();
> yield();
> dothat();
> yield();
> foo();
> end
Has this use case ever been encountered in real code or is this a
theoretical argument ?
>
> We could achieve the same by introducing doo parameters 'oneshot' and
> 'periodic', and then allowing specifying periodic doo's without while
> ... end. Would you prefer that?
I would prefer that doo is executed as long as no transition is taken.
I don't see the case for a one-shot doo since this is equal to putting
code in entry.
>
>
> Thanks a lot for the feedback!
You're welcome :-) We'll probably need some REP or wiki to at least
keep track over what the issues are, what solutions there exist and
what the current consensus is...
Peter
rFSM usability & scalability feedback
On Sat, Nov 10, 2012 at 05:07:11PM +0100, Peter Soetens wrote:
> On Sat, Nov 10, 2012 at 9:57 AM, Markus Klotzbuecher
> <markus [dot] klotzbuecher [..] ...> wrote:
> > Hi Peter,
> >
> > On Sat, Nov 10, 2012 at 12:16:43AM +0100, Peter Soetens wrote:
> >
> >> A few weeks ago I've spent some time prototyping some rFSM state
> >> machines. The focus was on integrating it in an existing system
> >> architecture, and not so much on implementing the functionality. I
> >> must say that the end result was with mixed feelings. I felt there
> >> were 2 major issues remaining with *using* rFSM : Syntax for new
> >> people or people not using it on a daily basis and scalability of
> >> string events:
> >>
> >> 1. Syntax
> >> There is just too little sugar available for neat rFSM 'programs'.
> >> What I mean is, in the end, it is a comma separated table,
> >> tab-indented slightly to appear as a functional description.
> >> Especially comparing the readability of an rFSM transition with an RTT
> >> scripting transition is quite a difference. For example:
> >> - transitions are in the parent state instead of the source state.
> >> This makes looking up transitions quite hard, unless you go to one of
> >> the rFSM dot tools for visualisation
> >> - compare a transition in RTT fsm versus an rFSM fsm:
> >> RTT:
> >> transition eventname( arg ) if arg < foo then { comp.doIt(); } select BAR_STATE
> >>
> >> rFSM:
> >> rfsm.trans { src='FOO_STATE', tgt='BAR_STATE', events='eventname',
> >> guard=function() return args < foo end, effect = function()
> >> comp:doIt() end, }
> >>
> >> apart from the fact that there is no easy way to get the 'arg' data
> >> out of an event in rFSM (see next point), it just doesn't read. I
> >> wonder if it would be possible to improve on this.
> >
> > Yes, I think ultimately we should come up with a real syntax and
> > write/generate a real C parser for it. Then we can create Lua bindings
> > to it and transparently allow both syntax. Would you be interested to
> > contribute here?
>
> So you're suggesting to write a parser which parses the rfsm structure
> and passes lua statements on to the lua parser ?
> We'll need a volunteer to have a go at this...
It could be an option, and the parsing would be pretty simple, since
we don't need to parse functions themselves.
> > On the other hand it might be better to go straight
> > to graphical editing.
>
> Requires more resources, unless there's a drop-in editor already available .. ?
The visualization incl. layout is non-trivial, but doing a simple EMF
based graphical editor shouldn't be too hard. I think the choice
should be driven by what the current rFSM users would like to have.
> > And I disagree with adding the successor state
> > to the source state though, since that breaks composability of the
> > latter.
>
> You're right on this one. It's still far less readable though.
>
> >
> >> 2. strings as events
> >> How easy this is for small prototypes, how more insane this is for any
> >> reasonable system. It's completely unmaintainable. How to guarantee
> >> that there are no typos in your string names ? Both on the sending
> >> side and on the events='...' side ? How to sync the C++ side with the
> >> Lua side ? I understand the rFSM independence of RTT (so there is no
> >> C++ side strictly speaking), but for RTT + rFSM examples, using string
> >> events on ports should be plainly banned.
> >>
> >> Even more, in its current form rFSM *itself* does not allow to have
> >> pay-loaded events since the events='...' is a comparison of data, so
> >> the contents of the event must be known in advance fully in order to
> >> trigger a transition. I can't think of a sane way to synchronize some
> >> string event with some data associated with it on another port. For
> >> any kind of coordination above the trivial, a payload is required to
> >> be able to take the correct supervisory decisions. The reason a
> >> payload is needed is that the events come in asynchronously, so the
> >> system state may already have changed. The event is the only place
> >> where that state information can be stored.
> >>
> >> We definitely need to formulate an alternative to strings as an Orocos
> >> community here. I already tried actually. I have written a
> >> readEvents() function which automates linking a random data port type
> >> with an event name ( ie still a string, required by rFSM ) and a
> >> variable which contains the port data. But I may want to take it
> >> further, events may actually be required as RTT extensions, building
> >> on top of our trustworthy ports, in order to define this link to the
> >> state machines, such that each state machine can check if a certain
> >> event exists or not. Something like that...
> >
> > Nice rant :-), but I do agree.
> >
> > Ok, three things: scalability, error-proneness and payloads. String
> > events are indeed not scalable, but on the other hand we surely don't
> > want people writing statemachines triggered by numbers.
>
> I wasn't hinting at numbers at all. The scalability argument is not
> for 'the size of a string / copying cost of a string / comparing a
> string', but for the maintainability of all these strings accross a
> big application. There's no type checking.
>
> > As you
> > suggest, I think the only way to deal with this is to "standardize"
> > within the RTT community on some kind of event model and
> > representation _and_ suggested use in components.
>
> Ack.
>
> >
> > I have had in mind the following. Firstly, the events a component can
> > raise should become introspectable at runtime. This could be as simple
> > as a string->number map using a read-only property. To ensure
> > uniqueness across the system, a raised event number needs to be
> > prepended (automatically) with a unique component id (do we have
> > this?)
>
> I don't know if this is where we want to go. There's always this
> subtle variation between knowing who raised the event or 'anonymous'
> events. RTT 1.x had event + source, current rFSM ( and all Orocos
> ports) uses anonymous events. For me, the source should act as an
> optional guard, but anyone should be able to raise event type 'E'.
That's why I suggested that the component(-id) should be part of the
event-id.
> Also, I don't see the advantage of working with numbers, unless they
> are purely a behind-the-API optimisation.
Yes, they should be, just as Sylvain does for ROCK.
> I do agree however in having events declared in the C++ part, such
> that runtime tools can check for available events. Ports do this, they
> are event sources and sinks, but used in a dataflow context. I was
I don't understand how do ports by themselves achieve this?
> thinking 'RTT extension' as in 'RTT component service'. Intelligent
> rFSM bindings would then query this service to know what's available
> in the current components & system setup.
Yes, it would be nice to have a standard API. Something to declare an
event port plus the possible events that can be emitted out of
it. That would allow to do a lot of verification!
> > Once we have that, we're basically done. An rFSM developer can
> > continue to use the convenient string (or whatever) like
> > "component.event" as triggers. Using a preprocessing plugin, at load
> > time we transform all string events to number events by looking these
> > up in the component interfaces. This way we also verify that a
> > component really does raise the specified event.
>
> This would not solve the payload argument.
> What the solution should also provide is:
>
> * a generic getevents implementation such that it's not required for
> RTT users to write one.
> * I would also suggest to have a 'protocol' event port (each event is
> presented one at a time at the rFSM) and a 'priority' event port (all
> received events since last time are presented to the rFSM and
> discarded after transition).
That's an important pattern I have encountered too. How should this be
supported?
> * Have some clarity over 'edge' triggering and 'level' triggering. RTT
> 1.x events were level triggered, you could wait until a combination of
> events became true. I don't see how this can happen in rFSM, unless
> you use a really awkward design to circumvent this omission ?
The mechanism I've used to realize that is one port per level
triggered event and then query that or the combination in the
guard. This is easy but probably awkward for more than a couple of
events. A more scalable solution would require standardizing events,
so that we can raise "hi" and "low" events. Then we can invent a
syntax t
> > (BTW: there is a rfsm_checkevents plugin to help detect typos. When
> > loaded and an event is received that is not used on any transition of
> > the FSM, a warning is printed).
> >
> > We can even define an RTT dbg function that converts the numbers back
> > to their string names in debug messages.
> >
> > Regarding the payload, it is less clear to me what we really
> > need. Maybe you can describe a real world use-case you had.
>
> struct WayPointPassedEvent
> {
> KDL::Frame pose;
> int wpnumber;
> };
>
> There are really many of these examples (collision detected (where?),
> object grasped (where?), joint failed (which one?),...) although there
> are equally many where there is no payload.
Why do you need this information in the coordinator? Probably because
you need to pass it on to some other component? Isn't this introducing
needless coupling? Can't it be communicated directly? I do agree that
we need more information, but I think it should be something like
this:
struct event {
uint64_t uid;
uint64_t ref;
};
The "uid" identifies the type of event and "ref" points to the
instance: a handle where for example the grasp position can be found
in the world model component.
Rationale: if you feel the need to send a lot of data through the
states of your FSM you might be better of with a data flowchart.
> >> 3. And as a bonus: doo
> >> It's not clear to me why we need to add our own while true do ... end
> >> loop in doo. It's a classical omission and will basically clutter up
> >> any doo function. If you don't want a while true do ... end loop in
> >> your do, you could equally put the code in entry and omit doo itself.
> >
> > You don't need the while ... end. You just need it if you want to
> > continunously call the same code again, while giving up control at a
> > yield. You could also have a non-looping doo:
> >
> > function doo()
> > dothis();
> > yield();
> > dothat();
> > yield();
> > foo();
> > end
>
> Has this use case ever been encountered in real code or is this a
> theoretical argument ?
It's theoretical, as a matter of fact I've seldomly used doo at all.
> > We could achieve the same by introducing doo parameters 'oneshot' and
> > 'periodic', and then allowing specifying periodic doo's without while
> > ... end. Would you prefer that?
>
> I would prefer that doo is executed as long as no transition is taken.
> I don't see the case for a one-shot doo since this is equal to putting
> code in entry.
The difference is indeed, as Ruben points out, that entry should be
kept as short as possible, since it impacts the worst-case transition
latency as outgoing transitions will only be taken after it. But point
taken, common things should be made simple, not more exotic
cases. I'll think about it!
> > Thanks a lot for the feedback!
>
> You're welcome :-) We'll probably need some REP or wiki to at least
RTT Enhancement Protocol?
> keep track over what the issues are, what solutions there exist and
> what the current consensus is...
Yes, definitely!
And I really need to start documenting all these rFSM-RTT patterns on
the wiki. I've just too little time right now.
Markus
rFSM usability & scalability feedback
On 11/12/2012 10:13 AM, Markus Klotzbuecher wrote:
> On Sat, Nov 10, 2012 at 05:07:11PM +0100, Peter Soetens wrote:
>> On Sat, Nov 10, 2012 at 9:57 AM, Markus Klotzbuecher
>> <markus [dot] klotzbuecher [..] ...> wrote:
>>> Hi Peter,
>>>
>>> On Sat, Nov 10, 2012 at 12:16:43AM +0100, Peter Soetens wrote:
>>>
>>>> A few weeks ago I've spent some time prototyping some rFSM state
>>>> machines. The focus was on integrating it in an existing system
>>>> architecture, and not so much on implementing the functionality. I
>>>> must say that the end result was with mixed feelings. I felt there
>>>> were 2 major issues remaining with *using* rFSM : Syntax for new
>>>> people or people not using it on a daily basis and scalability of
>>>> string events:
>>>>
>>>> 1. Syntax
>>>> There is just too little sugar available for neat rFSM 'programs'.
>>>> What I mean is, in the end, it is a comma separated table,
>>>> tab-indented slightly to appear as a functional description.
>>>> Especially comparing the readability of an rFSM transition with an RTT
>>>> scripting transition is quite a difference. For example:
>>>> - transitions are in the parent state instead of the source state.
>>>> This makes looking up transitions quite hard, unless you go to one of
>>>> the rFSM dot tools for visualisation
>>>> - compare a transition in RTT fsm versus an rFSM fsm:
>>>> RTT:
>>>> transition eventname( arg ) if arg < foo then { comp.doIt(); } select BAR_STATE
>>>>
>>>> rFSM:
>>>> rfsm.trans { src='FOO_STATE', tgt='BAR_STATE', events='eventname',
>>>> guard=function() return args < foo end, effect = function()
>>>> comp:doIt() end, }
>>>>
>>>> apart from the fact that there is no easy way to get the 'arg' data
>>>> out of an event in rFSM (see next point), it just doesn't read. I
>>>> wonder if it would be possible to improve on this.
>>>
>>> Yes, I think ultimately we should come up with a real syntax and
>>> write/generate a real C parser for it. Then we can create Lua bindings
>>> to it and transparently allow both syntax. Would you be interested to
>>> contribute here?
>>
>> So you're suggesting to write a parser which parses the rfsm structure
>> and passes lua statements on to the lua parser ?
>> We'll need a volunteer to have a go at this...
>
> It could be an option, and the parsing would be pretty simple, since
> we don't need to parse functions themselves.
>
>>> On the other hand it might be better to go straight
>>> to graphical editing.
>>
>> Requires more resources, unless there's a drop-in editor already available .. ?
>
> The visualization incl. layout is non-trivial, but doing a simple EMF
> based graphical editor shouldn't be too hard. I think the choice
> should be driven by what the current rFSM users would like to have.
>
>>> And I disagree with adding the successor state
>>> to the source state though, since that breaks composability of the
>>> latter.
>>
>> You're right on this one. It's still far less readable though.
>>
>>>
>>>> 2. strings as events
>>>> How easy this is for small prototypes, how more insane this is for any
>>>> reasonable system. It's completely unmaintainable. How to guarantee
>>>> that there are no typos in your string names ? Both on the sending
>>>> side and on the events='...' side ? How to sync the C++ side with the
>>>> Lua side ? I understand the rFSM independence of RTT (so there is no
>>>> C++ side strictly speaking), but for RTT + rFSM examples, using string
>>>> events on ports should be plainly banned.
>>>>
>>>> Even more, in its current form rFSM *itself* does not allow to have
>>>> pay-loaded events since the events='...' is a comparison of data, so
>>>> the contents of the event must be known in advance fully in order to
>>>> trigger a transition. I can't think of a sane way to synchronize some
>>>> string event with some data associated with it on another port. For
>>>> any kind of coordination above the trivial, a payload is required to
>>>> be able to take the correct supervisory decisions. The reason a
>>>> payload is needed is that the events come in asynchronously, so the
>>>> system state may already have changed. The event is the only place
>>>> where that state information can be stored.
>>>>
>>>> We definitely need to formulate an alternative to strings as an Orocos
>>>> community here. I already tried actually. I have written a
>>>> readEvents() function which automates linking a random data port type
>>>> with an event name ( ie still a string, required by rFSM ) and a
>>>> variable which contains the port data. But I may want to take it
>>>> further, events may actually be required as RTT extensions, building
>>>> on top of our trustworthy ports, in order to define this link to the
>>>> state machines, such that each state machine can check if a certain
>>>> event exists or not. Something like that...
>>>
>>> Nice rant :-), but I do agree.
>>>
>>> Ok, three things: scalability, error-proneness and payloads. String
>>> events are indeed not scalable, but on the other hand we surely don't
>>> want people writing statemachines triggered by numbers.
>>
>> I wasn't hinting at numbers at all. The scalability argument is not
>> for 'the size of a string / copying cost of a string / comparing a
>> string', but for the maintainability of all these strings accross a
>> big application. There's no type checking.
>>
>>> As you
>>> suggest, I think the only way to deal with this is to "standardize"
>>> within the RTT community on some kind of event model and
>>> representation _and_ suggested use in components.
>>
>> Ack.
>>
>>>
>>> I have had in mind the following. Firstly, the events a component can
>>> raise should become introspectable at runtime. This could be as simple
>>> as a string->number map using a read-only property. To ensure
>>> uniqueness across the system, a raised event number needs to be
>>> prepended (automatically) with a unique component id (do we have
>>> this?)
>>
>> I don't know if this is where we want to go. There's always this
>> subtle variation between knowing who raised the event or 'anonymous'
>> events. RTT 1.x had event + source, current rFSM ( and all Orocos
>> ports) uses anonymous events. For me, the source should act as an
>> optional guard, but anyone should be able to raise event type 'E'.
>
> That's why I suggested that the component(-id) should be part of the
> event-id.
>
>> Also, I don't see the advantage of working with numbers, unless they
>> are purely a behind-the-API optimisation.
>
> Yes, they should be, just as Sylvain does for ROCK.
>
>> I do agree however in having events declared in the C++ part, such
>> that runtime tools can check for available events. Ports do this, they
>> are event sources and sinks, but used in a dataflow context. I was
>
> I don't understand how do ports by themselves achieve this?
>
>> thinking 'RTT extension' as in 'RTT component service'. Intelligent
>> rFSM bindings would then query this service to know what's available
>> in the current components & system setup.
>
> Yes, it would be nice to have a standard API. Something to declare an
> event port plus the possible events that can be emitted out of
> it. That would allow to do a lot of verification!
>
>>> Once we have that, we're basically done. An rFSM developer can
>>> continue to use the convenient string (or whatever) like
>>> "component.event" as triggers. Using a preprocessing plugin, at load
>>> time we transform all string events to number events by looking these
>>> up in the component interfaces. This way we also verify that a
>>> component really does raise the specified event.
>>
>> This would not solve the payload argument.
>> What the solution should also provide is:
>>
>> * a generic getevents implementation such that it's not required for
>> RTT users to write one.
+1
>> * I would also suggest to have a 'protocol' event port (each event is
>> presented one at a time at the rFSM) and a 'priority' event port (all
>> received events since last time are presented to the rFSM and
>> discarded after transition).
>
> That's an important pattern I have encountered too. How should this be
> supported?
+1
How do these work? your protocol port has a buffer, that is emptied one at a time? So if you receive more events than 'clock triggers', you will flood your buffer?
Why do you call the last priority?
in iTaSC, I also use three types of event (ports):
Common events: Communicated over a buffered connection
Priority events: Communicated over a buffered connection on event-triggered ports
Trigger events: Communicated over a non-buffered connection on event-triggered ports
Here I always read all events in the buffer (since multiple events can happen within the same time step).
Maybe trigger event port could also be a standard one? I use it to handle events that can't wait for the next time step (intentionally).
>
>> * Have some clarity over 'edge' triggering and 'level' triggering. RTT
>> 1.x events were level triggered, you could wait until a combination of
>> events became true. I don't see how this can happen in rFSM, unless
>> you use a really awkward design to circumvent this omission ?
>
> The mechanism I've used to realize that is one port per level
> triggered event and then query that or the combination in the
> guard. This is easy but probably awkward for more than a couple of
> events. A more scalable solution would require standardizing events,
> so that we can raise "hi" and "low" events. Then we can invent a
> syntax t
also used in iTaSC: (in the code snippet below to wait for all components in the table to have responded, could be put in a general library?!)
function guardMultipleEvents(tr, table, prefix, appendix)
local x=false
for i=1,#table do
local x_temp_name = prefix .. table[i] .. appendix
local x_temp = tr.src.emem[x_temp_name]
if i>1 then
x = x and x_temp and x_temp > 0
else
x = x_temp and x_temp > 0
end
end
if x then return true end
return false
end
>
>>> (BTW: there is a rfsm_checkevents plugin to help detect typos. When
>>> loaded and an event is received that is not used on any transition of
>>> the FSM, a warning is printed).
>>>
>>> We can even define an RTT dbg function that converts the numbers back
>>> to their string names in debug messages.
>>>
>>> Regarding the payload, it is less clear to me what we really
>>> need. Maybe you can describe a real world use-case you had.
>>
>> struct WayPointPassedEvent
>> {
>> KDL::Frame pose;
>> int wpnumber;
>> };
>>
>> There are really many of these examples (collision detected (where?),
>> object grasped (where?), joint failed (which one?),...) although there
>> are equally many where there is no payload.
>
> Why do you need this information in the coordinator? Probably because
> you need to pass it on to some other component? Isn't this introducing
> needless coupling? Can't it be communicated directly? I do agree that
> we need more information, but I think it should be something like
> this:
>
> struct event {
> uint64_t uid;
> uint64_t ref;
> };
>
> The "uid" identifies the type of event and "ref" points to the
> instance: a handle where for example the grasp position can be found
> in the world model component.
>
> Rationale: if you feel the need to send a lot of data through the
> states of your FSM you might be better of with a data flowchart.
>
>>>> 3. And as a bonus: doo
>>>> It's not clear to me why we need to add our own while true do ... end
>>>> loop in doo. It's a classical omission and will basically clutter up
>>>> any doo function. If you don't want a while true do ... end loop in
>>>> your do, you could equally put the code in entry and omit doo itself.
>>>
>>> You don't need the while ... end. You just need it if you want to
>>> continunously call the same code again, while giving up control at a
>>> yield. You could also have a non-looping doo:
>>>
>>> function doo()
>>> dothis();
>>> yield();
>>> dothat();
>>> yield();
>>> foo();
>>> end
>>
>> Has this use case ever been encountered in real code or is this a
>> theoretical argument ?
>
> It's theoretical, as a matter of fact I've seldomly used doo at all.
>
>>> We could achieve the same by introducing doo parameters 'oneshot' and
>>> 'periodic', and then allowing specifying periodic doo's without while
>>> ... end. Would you prefer that?
>>
>> I would prefer that doo is executed as long as no transition is taken.
>> I don't see the case for a one-shot doo since this is equal to putting
>> code in entry.
>
> The difference is indeed, as Ruben points out, that entry should be
> kept as short as possible, since it impacts the worst-case transition
> latency as outgoing transitions will only be taken after it. But point
> taken, common things should be made simple, not more exotic
> cases. I'll think about it!
>
>>> Thanks a lot for the feedback!
>>
>> You're welcome :-) We'll probably need some REP or wiki to at least
>
> RTT Enhancement Protocol?
>
>> keep track over what the issues are, what solutions there exist and
>> what the current consensus is...
>
> Yes, definitely!
>
> And I really need to start documenting all these rFSM-RTT patterns on
> the wiki. I've just too little time right now.
>
> Markus
>
>
>
rFSM usability & scalability feedback
On Sat, Nov 10, 2012 at 5:07 PM, Peter Soetens <peter [..] ...> wrote:
> On Sat, Nov 10, 2012 at 9:57 AM, Markus Klotzbuecher
> <markus [dot] klotzbuecher [..] ...> wrote:
>> Hi Peter,
>>
>> On Sat, Nov 10, 2012 at 12:16:43AM +0100, Peter Soetens wrote:
>>
>>> A few weeks ago I've spent some time prototyping some rFSM state
>>> machines. The focus was on integrating it in an existing system
>>> architecture, and not so much on implementing the functionality. I
>>> must say that the end result was with mixed feelings. I felt there
>>> were 2 major issues remaining with *using* rFSM : Syntax for new
>>> people or people not using it on a daily basis and scalability of
>>> string events:
>>>
>>> 1. Syntax
>>> There is just too little sugar available for neat rFSM 'programs'.
>>> What I mean is, in the end, it is a comma separated table,
>>> tab-indented slightly to appear as a functional description.
>>> Especially comparing the readability of an rFSM transition with an RTT
>>> scripting transition is quite a difference. For example:
>>> - transitions are in the parent state instead of the source state.
>>> This makes looking up transitions quite hard, unless you go to one of
>>> the rFSM dot tools for visualisation
>>> - compare a transition in RTT fsm versus an rFSM fsm:
>>> RTT:
>>> transition eventname( arg ) if arg < foo then { comp.doIt(); } select BAR_STATE
>>>
>>> rFSM:
>>> rfsm.trans { src='FOO_STATE', tgt='BAR_STATE', events='eventname',
>>> guard=function() return args < foo end, effect = function()
>>> comp:doIt() end, }
>>>
>>> apart from the fact that there is no easy way to get the 'arg' data
>>> out of an event in rFSM (see next point), it just doesn't read. I
>>> wonder if it would be possible to improve on this.
>>
>> Yes, I think ultimately we should come up with a real syntax and
>> write/generate a real C parser for it. Then we can create Lua bindings
>> to it and transparently allow both syntax. Would you be interested to
>> contribute here?
>
> So you're suggesting to write a parser which parses the rfsm structure
> and passes lua statements on to the lua parser ?
> We'll need a volunteer to have a go at this...
>
>> On the other hand it might be better to go straight
>> to graphical editing.
>
> Requires more resources, unless there's a drop-in editor already available .. ?
>
>> And I disagree with adding the successor state
>> to the source state though, since that breaks composability of the
>> latter.
>
> You're right on this one. It's still far less readable though.
I do not see the problem here, no one prevents you from putting the
transitions related to some state directly underneath the state, you
do not have to group all transitions or am I missing something?
>>
>>> 2. strings as events
>>> How easy this is for small prototypes, how more insane this is for any
>>> reasonable system. It's completely unmaintainable. How to guarantee
>>> that there are no typos in your string names ? Both on the sending
>>> side and on the events='...' side ? How to sync the C++ side with the
>>> Lua side ? I understand the rFSM independence of RTT (so there is no
>>> C++ side strictly speaking), but for RTT + rFSM examples, using string
>>> events on ports should be plainly banned.
>>>
>>> Even more, in its current form rFSM *itself* does not allow to have
>>> pay-loaded events since the events='...' is a comparison of data, so
>>> the contents of the event must be known in advance fully in order to
>>> trigger a transition. I can't think of a sane way to synchronize some
>>> string event with some data associated with it on another port. For
>>> any kind of coordination above the trivial, a payload is required to
>>> be able to take the correct supervisory decisions. The reason a
>>> payload is needed is that the events come in asynchronously, so the
>>> system state may already have changed. The event is the only place
>>> where that state information can be stored.
>>>
>>> We definitely need to formulate an alternative to strings as an Orocos
>>> community here. I already tried actually. I have written a
>>> readEvents() function which automates linking a random data port type
>>> with an event name ( ie still a string, required by rFSM ) and a
>>> variable which contains the port data. But I may want to take it
>>> further, events may actually be required as RTT extensions, building
>>> on top of our trustworthy ports, in order to define this link to the
>>> state machines, such that each state machine can check if a certain
>>> event exists or not. Something like that...
>>
>> Nice rant :-), but I do agree.
>>
>> Ok, three things: scalability, error-proneness and payloads. String
>> events are indeed not scalable, but on the other hand we surely don't
>> want people writing statemachines triggered by numbers.
>
> I wasn't hinting at numbers at all. The scalability argument is not
> for 'the size of a string / copying cost of a string / comparing a
> string', but for the maintainability of all these strings accross a
> big application. There's no type checking.
>
>> As you
>> suggest, I think the only way to deal with this is to "standardize"
>> within the RTT community on some kind of event model and
>> representation _and_ suggested use in components.
>
> Ack.
>
>>
>> I have had in mind the following. Firstly, the events a component can
>> raise should become introspectable at runtime. This could be as simple
>> as a string->number map using a read-only property. To ensure
>> uniqueness across the system, a raised event number needs to be
>> prepended (automatically) with a unique component id (do we have
>> this?)
>
> I don't know if this is where we want to go. There's always this
> subtle variation between knowing who raised the event or 'anonymous'
> events. RTT 1.x had event + source, current rFSM ( and all Orocos
> ports) uses anonymous events. For me, the source should act as an
> optional guard, but anyone should be able to raise event type 'E'.
> Also, I don't see the advantage of working with numbers, unless they
> are purely a behind-the-API optimisation.
>
> I do agree however in having events declared in the C++ part, such
> that runtime tools can check for available events. Ports do this, they
> are event sources and sinks, but used in a dataflow context. I was
> thinking 'RTT extension' as in 'RTT component service'. Intelligent
> rFSM bindings would then query this service to know what's available
> in the current components & system setup.
>
>>
>> Once we have that, we're basically done. An rFSM developer can
>> continue to use the convenient string (or whatever) like
>> "component.event" as triggers. Using a preprocessing plugin, at load
>> time we transform all string events to number events by looking these
>> up in the component interfaces. This way we also verify that a
>> component really does raise the specified event.
>
> This would not solve the payload argument.
> What the solution should also provide is:
>
> * a generic getevents implementation such that it's not required for
> RTT users to write one.
> * I would also suggest to have a 'protocol' event port (each event is
> presented one at a time at the rFSM) and a 'priority' event port (all
> received events since last time are presented to the rFSM and
> discarded after transition).
> * Have some clarity over 'edge' triggering and 'level' triggering. RTT
> 1.x events were level triggered, you could wait until a combination of
> events became true. I don't see how this can happen in rFSM, unless
> you use a really awkward design to circumvent this omission ?
>
>>
>> (BTW: there is a rfsm_checkevents plugin to help detect typos. When
>> loaded and an event is received that is not used on any transition of
>> the FSM, a warning is printed).
>>
>> We can even define an RTT dbg function that converts the numbers back
>> to their string names in debug messages.
>>
>> Regarding the payload, it is less clear to me what we really
>> need. Maybe you can describe a real world use-case you had.
>
> struct WayPointPassedEvent
> {
> KDL::Frame pose;
> int wpnumber;
> };
>
> There are really many of these examples (collision detected (where?),
> object grasped (where?), joint failed (which one?),...) although there
> are equally many where there is no payload.
>
>>
>>> 3. And as a bonus: doo
>>> It's not clear to me why we need to add our own while true do ... end
>>> loop in doo. It's a classical omission and will basically clutter up
>>> any doo function. If you don't want a while true do ... end loop in
>>> your do, you could equally put the code in entry and omit doo itself.
>>
>> You don't need the while ... end. You just need it if you want to
>> continunously call the same code again, while giving up control at a
>> yield. You could also have a non-looping doo:
>>
>> function doo()
>> dothis();
>> yield();
>> dothat();
>> yield();
>> foo();
>> end
>
> Has this use case ever been encountered in real code or is this a
> theoretical argument ?
>
>>
>> We could achieve the same by introducing doo parameters 'oneshot' and
>> 'periodic', and then allowing specifying periodic doo's without while
>> ... end. Would you prefer that?
>
> I would prefer that doo is executed as long as no transition is taken.
> I don't see the case for a one-shot doo since this is equal to putting
> code in entry.
AFAIK this is not really true, since entry cannot be preempted by
events/transitions while doo can. But I can be wrong ... Markus?
Ruben
>>
>>
>> Thanks a lot for the feedback!
>
> You're welcome :-) We'll probably need some REP or wiki to at least
> keep track over what the issues are, what solutions there exist and
> what the current consensus is...
>
> Peter
> --
> Orocos-Users mailing list
> Orocos-Users [..] ...
> http://lists.mech.kuleuven.be/mailman/listinfo/orocos-users
rFSM usability & scalability feedback
On Mon, Nov 12, 2012 at 09:13:42AM +0100, Ruben Smits wrote:
> On Sat, Nov 10, 2012 at 5:07 PM, Peter Soetens <peter [..] ...> wrote:
> > On Sat, Nov 10, 2012 at 9:57 AM, Markus Klotzbuecher
> > <markus [dot] klotzbuecher [..] ...> wrote:
> >> On Sat, Nov 10, 2012 at 12:16:43AM +0100, Peter Soetens wrote:
> >>
> >>> A few weeks ago I've spent some time prototyping some rFSM state
> >>> machines. The focus was on integrating it in an existing system
> >>> architecture, and not so much on implementing the functionality. I
> >>> must say that the end result was with mixed feelings. I felt there
> >>> were 2 major issues remaining with *using* rFSM : Syntax for new
> >>> people or people not using it on a daily basis and scalability of
> >>> string events:
> >>>
> >>> 1. Syntax
> >>> There is just too little sugar available for neat rFSM 'programs'.
> >>> What I mean is, in the end, it is a comma separated table,
> >>> tab-indented slightly to appear as a functional description.
> >>> Especially comparing the readability of an rFSM transition with an RTT
> >>> scripting transition is quite a difference. For example:
> >>> - transitions are in the parent state instead of the source state.
> >>> This makes looking up transitions quite hard, unless you go to one of
> >>> the rFSM dot tools for visualisation
> >>> - compare a transition in RTT fsm versus an rFSM fsm:
> >>> RTT:
> >>> transition eventname( arg ) if arg < foo then { comp.doIt(); } select BAR_STATE
> >>>
> >>> rFSM:
> >>> rfsm.trans { src='FOO_STATE', tgt='BAR_STATE', events='eventname',
> >>> guard=function() return args < foo end, effect = function()
> >>> comp:doIt() end, }
> >>>
> >>> apart from the fact that there is no easy way to get the 'arg' data
> >>> out of an event in rFSM (see next point), it just doesn't read. I
> >>> wonder if it would be possible to improve on this.
> >>
> >> Yes, I think ultimately we should come up with a real syntax and
> >> write/generate a real C parser for it. Then we can create Lua bindings
> >> to it and transparently allow both syntax. Would you be interested to
> >> contribute here?
> >
> > So you're suggesting to write a parser which parses the rfsm structure
> > and passes lua statements on to the lua parser ?
> > We'll need a volunteer to have a go at this...
> >
> >> On the other hand it might be better to go straight
> >> to graphical editing.
> >
> > Requires more resources, unless there's a drop-in editor already available .. ?
> >
> >> And I disagree with adding the successor state
> >> to the source state though, since that breaks composability of the
> >> latter.
> >
> > You're right on this one. It's still far less readable though.
>
> I do not see the problem here, no one prevents you from putting the
> transitions related to some state directly underneath the state, you
> do not have to group all transitions or am I missing something?
Yes, you can do that! The specification order is irrelevant.
> >>> 3. And as a bonus: doo
> >>> It's not clear to me why we need to add our own while true do ... end
> >>> loop in doo. It's a classical omission and will basically clutter up
> >>> any doo function. If you don't want a while true do ... end loop in
> >>> your do, you could equally put the code in entry and omit doo itself.
> >>
> >> You don't need the while ... end. You just need it if you want to
> >> continunously call the same code again, while giving up control at a
> >> yield. You could also have a non-looping doo:
> >>
> >> function doo()
> >> dothis();
> >> yield();
> >> dothat();
> >> yield();
> >> foo();
> >> end
> >
> > Has this use case ever been encountered in real code or is this a
> > theoretical argument ?
> >
> >>
> >> We could achieve the same by introducing doo parameters 'oneshot' and
> >> 'periodic', and then allowing specifying periodic doo's without while
> >> ... end. Would you prefer that?
> >
> > I would prefer that doo is executed as long as no transition is taken.
> > I don't see the case for a one-shot doo since this is equal to putting
> > code in entry.
>
> AFAIK this is not really true, since entry cannot be preempted by
> events/transitions while doo can. But I can be wrong ... Markus?
You're right!
But one could argue that such a oneshot doo, which yields several
times, could be just as well implemented as multiple
substates.
Markus
rFSM usability & scalability feedback
On Sat, Nov 10, 2012 at 09:57:04AM +0100, Markus Klotzbuecher wrote:
> Yes, I think ultimately we should come up with a real syntax and
> write/generate a real C parser for it. Then we can create Lua bindings to it
> and transparently allow both syntax. Would you be interested to contribute
> here? On the other hand it might be better to go straight to graphical
> editing.
If I may suggest -- I believe it might be better to rather capture an abstract
syntax of the FSM language by the use of EMF-like techniques (*) and then use
it as a basis of both textual and graphical editors, code generators, etc.
(*) I decided to avoid the term "meta-model," since its meaning differs among
the readers of this mailing list.
rFSM usability & scalability feedback
On Sat, Nov 10, 2012 at 02:23:06PM +0100, Piotr Trojanek wrote:
> On Sat, Nov 10, 2012 at 09:57:04AM +0100, Markus Klotzbuecher wrote:
> > Yes, I think ultimately we should come up with a real syntax and
> > write/generate a real C parser for it. Then we can create Lua bindings to it
> > and transparently allow both syntax. Would you be interested to contribute
> > here? On the other hand it might be better to go straight to graphical
> > editing.
>
> If I may suggest -- I believe it might be better to rather capture an abstract
> syntax of the FSM language by the use of EMF-like techniques (*) and then use
> it as a basis of both textual and graphical editors, code generators, etc.
Sure, having a complementary, user-friendly graphical+Xtext frontend
would be nice. I have a rFSM Ecore model, if anyone would like to take
a shot at it :-)
> (*) I decided to avoid the term "meta-model," since its meaning differs among
> the readers of this mailing list.
Markus
rFSM usability & scalability feedback
On Sat, Nov 10, 2012 at 03:03:47PM +0100, Markus Klotzbuecher wrote:
> On Sat, Nov 10, 2012 at 02:23:06PM +0100, Piotr Trojanek wrote:
> > On Sat, Nov 10, 2012 at 09:57:04AM +0100, Markus Klotzbuecher wrote:
> > > Yes, I think ultimately we should come up with a real syntax and
> > > write/generate a real C parser for it. Then we can create Lua bindings to it
> > > and transparently allow both syntax. Would you be interested to contribute
> > > here? On the other hand it might be better to go straight to graphical
> > > editing.
> >
> > If I may suggest -- I believe it might be better to rather capture an abstract
> > syntax of the FSM language by the use of EMF-like techniques (*) and then use
> > it as a basis of both textual and graphical editors, code generators, etc.
>
> Sure, having a complementary, user-friendly graphical+Xtext frontend would be
> nice.
I guess that graphical+textual editor is the way to go. rFSM mixes two
concerns: data processing (which is entirely in textual Lua code) and FSM
(which conforms to its own abstract syntax and have an obvious graphical
representation).
> I have a rFSM Ecore model, if anyone would like to take a shot at it :-)
Please do not hesitate to publish it!
>
> > (*) I decided to avoid the term "meta-model," since its meaning differs among
> > the readers of this mailing list.
>
> Markus
rFSM usability & scalability feedback
I too have fears about the safety of using strings as events, that are not
statically typechecked. We do not want our UAV to crash because of a typo
in a string name somewhere. Is this already resolved by some simulator
tool that has full state transition coverage? Even then, I think that
would only guarantee that the lua is internally consistent, not consistent
with the C++.
In Leuven we (HIGHWIND) basically never automated experiments at all, just
relying on a pilot who knew how the system worked, and manually typed
commands at the orocos deployer REPL.
Here in Freiburg, we've switched over to rttlua for deployment scripts, and
our deployment scripts are rapidly devolving into a big mess of switches
and special cases to try to handle different use cases, and also different
failure cases safely. We already had one "crash" with a dummy plane
(actually just a soccer ball) just while testing, so I'm eager to find a
better way.
In another thread someone mentioned this:
Yakindu
http://statecharts.org/
Maybe integrating the code generated from that into orocos would be a good
direction for the community to go in?
Cheers,
Andrew
On Tue, Dec 4, 2012 at 2:45 PM, Piotr Trojanek <piotr [dot] trojanek [..] ...>
wrote:
> On Sat, Nov 10, 2012 at 03:03:47PM +0100, Markus Klotzbuecher wrote:
> > On Sat, Nov 10, 2012 at 02:23:06PM +0100, Piotr Trojanek wrote:
> > > On Sat, Nov 10, 2012 at 09:57:04AM +0100, Markus Klotzbuecher wrote:
> > > > Yes, I think ultimately we should come up with a real syntax and
> > > > write/generate a real C parser for it. Then we can create Lua
> bindings to it
> > > > and transparently allow both syntax. Would you be interested to
> contribute
> > > > here? On the other hand it might be better to go straight to
> graphical
> > > > editing.
> > >
> > > If I may suggest -- I believe it might be better to rather capture an
> abstract
> > > syntax of the FSM language by the use of EMF-like techniques (*) and
> then use
> > > it as a basis of both textual and graphical editors, code generators,
> etc.
> >
> > Sure, having a complementary, user-friendly graphical+Xtext frontend
> would be
> > nice.
>
> I guess that graphical+textual editor is the way to go. rFSM mixes two
> concerns: data processing (which is entirely in textual Lua code) and FSM
> (which conforms to its own abstract syntax and have an obvious graphical
> representation).
>
> > I have a rFSM Ecore model, if anyone would like to take a shot at it :-)
>
> Please do not hesitate to publish it!
>
> >
> > > (*) I decided to avoid the term "meta-model," since its meaning
> differs among
> > > the readers of this mailing list.
> >
> > Markus
> > --
> > Orocos-Users mailing list
> > Orocos-Users [..] ...
> > http://lists.mech.kuleuven.be/mailman/listinfo/orocos-users
>
> --
> Piotr Trojanek
> --
> Orocos-Users mailing list
> Orocos-Users [..] ...
> http://lists.mech.kuleuven.be/mailman/listinfo/orocos-users
>
rFSM usability & scalability feedback
On Thu, 10 Jul 2014, Andrew Wagner wrote:
> I too have fears about the safety of using strings as events, that are not statically
> typechecked. We do not want our UAV to crash because of a typo in a string name somewhere. Is
> this already resolved by some simulator tool that has full state transition coverage? Even
> then, I think that would only guarantee that the lua is internally consistent, not consistent
> with the C++.
I think the only real road forward is to use tools to _generate_ both
parts, so that the consistency is guaranteed _by construction_. Such tools
can (should...) do more than "typechecking", namely _semantic_ checks.
Future work... But the RTT mechanism is ready for it. (Within our Rodinia
prototype tool, this is what is being done, and for which we are improving
the (poor!) state of the practice in such tooling. Slowly...)
> In Leuven we (HIGHWIND) basically never automated experiments at all, just relying on a pilot
> who knew how the system worked, and manually typed commands at the orocos deployer REPL.
>
> Here in Freiburg, we've switched over to rttlua for deployment scripts, and our deployment
> scripts are rapidly devolving into a big mess of switches and special cases to try to handle
> different use cases, and also different failure cases safely. We already had one "crash" with a
> dummy plane (actually just a soccer ball) just while testing, so I'm eager to find a better way.
The "better" way is to bring in hierarchy based on _semantically_
motivated structure. Such as the natural hierarchy in bringing up a complex
system, by configuring "from bottom up" and starting/freezing/stopping
"from top down", where "bottom" and "top" are dictated by the
mechanical/actuation/OS/computational HW hierarchy.
> In another thread someone mentioned this:
>
> Yakindue
> http://statecharts.org/
>
> Maybe integrating the code generated from that into orocos would be a good direction for the
> community to go in?
This is not a good direction to go in, because that tool stimulates the
coupling of the structural part of the discrete states, with the behaviour
that is active in a state; this does not survive distributing or
concurrency, because the model does not cover the domain-specific semantics
of such concurrency. Some "more advanced" tools rely on formal models such
as Petri nets to Verify&Validate "distributed state machines", but they
neglect the fact that communication takes finite time, and that all of the
infrastructure resources are always available with a full 100% Quality of
Service.
We have spent _lots_ of man months on these issues, since Markus'
email about these issues (enclosed below), and the 'result' is not so
positive: detting the state machines "right", "robust" and "reliable" is
one of the most difficult things to automate in complex system design...
> Cheers,
> Andrew
Herman
> On Tue, Dec 4, 2012 at 2:45 PM, Piotr Trojanek <piotr [dot] trojanek [..] ...> wrote:
> On Sat, Nov 10, 2012 at 03:03:47PM +0100, Markus Klotzbuecher wrote:
> > On Sat, Nov 10, 2012 at 02:23:06PM +0100, Piotr Trojanek wrote:
> > > On Sat, Nov 10, 2012 at 09:57:04AM +0100, Markus Klotzbuecher wrote:
> > > > Yes, I think ultimately we should come up with a real syntax and
> > > > write/generate a real C parser for it. Then we can create Lua bindings to it
> > > > and transparently allow both syntax. Would you be interested to contribute
> > > > here? On the other hand it might be better to go straight to graphical
> > > > editing.
> > >
> > > If I may suggest -- I believe it might be better to rather capture an abstract
> > > syntax of the FSM language by the use of EMF-like techniques (*) and then use
> > > it as a basis of both textual and graphical editors, code generators, etc.
> >
> > Sure, having a complementary, user-friendly graphical+Xtext frontend would be
> > nice.
>
> I guess that graphical+textual editor is the way to go. rFSM mixes two
> concerns: data processing (which is entirely in textual Lua code) and FSM
> (which conforms to its own abstract syntax and have an obvious graphical
> representation).
>
> > I have a rFSM Ecore model, if anyone would like to take a shot at it :-)
>
> Please do not hesitate to publish it!
>
> > > (*) I decided to avoid the term "meta-model," since its meaning differs among
> > > the readers of this mailing list.
> >
> > Markus
rFSM usability & scalability feedback
Hello Herman,
Thanks for the update! Could the sort of offline correctness checks you're
talking about be implemented in rfsm when using rttlua for deployment? It
seems like it might not be too hard to layer in a bunch of error-checking
once deployment and the state machine is all defined in lua...
Cheers,
Andrew
On Thu, Jul 10, 2014 at 7:54 PM, Herman Bruyninckx <
Herman [dot] Bruyninckx [..] ...> wrote:
> On Thu, 10 Jul 2014, Andrew Wagner wrote:
>
> I too have fears about the safety of using strings as events, that are
>> not statically
>> typechecked. We do not want our UAV to crash because of a typo in a
>> string name somewhere. Is
>> this already resolved by some simulator tool that has full state
>> transition coverage? Even
>> then, I think that would only guarantee that the lua is internally
>> consistent, not consistent
>> with the C++.
>>
>
> I think the only real road forward is to use tools to _generate_ both
> parts, so that the consistency is guaranteed _by construction_. Such tools
> can (should...) do more than "typechecking", namely _semantic_ checks.
> Future work... But the RTT mechanism is ready for it. (Within our Rodinia
> prototype tool, this is what is being done, and for which we are improving
> the (poor!) state of the practice in such tooling. Slowly...)
>
>
> In Leuven we (HIGHWIND) basically never automated experiments at all,
>> just relying on a pilot
>> who knew how the system worked, and manually typed commands at the orocos
>> deployer REPL.
>>
>> Here in Freiburg, we've switched over to rttlua for deployment scripts,
>> and our deployment
>> scripts are rapidly devolving into a big mess of switches and special
>> cases to try to handle
>> different use cases, and also different failure cases safely. We already
>> had one "crash" with a
>> dummy plane (actually just a soccer ball) just while testing, so I'm
>> eager to find a better way.
>>
>
> The "better" way is to bring in hierarchy based on _semantically_
> motivated structure. Such as the natural hierarchy in bringing up a complex
> system, by configuring "from bottom up" and starting/freezing/stopping
> "from top down", where "bottom" and "top" are dictated by the
> mechanical/actuation/OS/computational HW hierarchy.
>
> In another thread someone mentioned this:
>>
>> Yakindue
>>
>> http://statecharts.org/
>>
>> Maybe integrating the code generated from that into orocos would be a
>> good direction for the
>> community to go in?
>>
>
> This is not a good direction to go in, because that tool stimulates the
> coupling of the structural part of the discrete states, with the behaviour
> that is active in a state; this does not survive distributing or
> concurrency, because the model does not cover the domain-specific semantics
> of such concurrency. Some "more advanced" tools rely on formal models such
> as Petri nets to Verify&Validate "distributed state machines", but they
> neglect the fact that communication takes finite time, and that all of the
> infrastructure resources are always available with a full 100% Quality of
> Service.
>
> We have spent _lots_ of man months on these issues, since Markus' email
> about these issues (enclosed below), and the 'result' is not so
> positive: detting the state machines "right", "robust" and "reliable" is
> one of the most difficult things to automate in complex system design...
>
> Cheers,
>> Andrew
>>
>
> Herman
>
>
> On Tue, Dec 4, 2012 at 2:45 PM, Piotr Trojanek <piotr [dot] trojanek [..] ...>
>> wrote:
>> On Sat, Nov 10, 2012 at 03:03:47PM +0100, Markus Klotzbuecher wrote:
>> > On Sat, Nov 10, 2012 at 02:23:06PM +0100, Piotr Trojanek wrote:
>> > > On Sat, Nov 10, 2012 at 09:57:04AM +0100, Markus Klotzbuecher
>> wrote:
>> > > > Yes, I think ultimately we should come up with a real syntax
>> and
>> > > > write/generate a real C parser for it. Then we can create Lua
>> bindings to it
>> > > > and transparently allow both syntax. Would you be interested
>> to contribute
>> > > > here? On the other hand it might be better to go straight to
>> graphical
>> > > > editing.
>> > >
>> > > If I may suggest -- I believe it might be better to rather
>> capture an abstract
>> > > syntax of the FSM language by the use of EMF-like techniques
>> (*) and then use
>> > > it as a basis of both textual and graphical editors, code
>> generators, etc.
>> >
>> > Sure, having a complementary, user-friendly graphical+Xtext
>> frontend would be
>> > nice.
>>
>> I guess that graphical+textual editor is the way to go. rFSM mixes two
>> concerns: data processing (which is entirely in textual Lua code) and FSM
>> (which conforms to its own abstract syntax and have an obvious graphical
>> representation).
>>
>> > I have a rFSM Ecore model, if anyone would like to take a shot at it :-)
>>
>> Please do not hesitate to publish it!
>>
>> > > (*) I decided to avoid the term "meta-model," since its meaning
>> differs among
>> > > the readers of this mailing list.
>> >
>> > Markus
>
>
rFSM usability & scalability feedback
On Fri, 11 Jul 2014, Andrew Wagner wrote:
> Hello Herman,
> Thanks for the update! Could the sort of offline correctness checks you're talking about be
> implemented in rfsm when using rttlua for deployment?
Yes, since lua is a general purpose progamming language :-) But whether it
is _the best_ approach, I don't know.
> It seems like it might not be too hard to
> layer in a bunch of error-checking once deployment and the state machine is all defined in
> lua...
Markus already created another small framework project, umf,
<https://github.com/kmarkus/uMF>
meant to do constraint checking in Lua. We use it almost all the time
together with our C/Lua developments. It is (by far) not the 100% full
semantic V&V tool, and it might not be strong enough for what you have in
mind, but for our robotics applications it is an extremely useful little
tool.
> Cheers,
> Andrew
Herman
> On Thu, Jul 10, 2014 at 7:54 PM, Herman Bruyninckx <Herman [dot] Bruyninckx [..] ...> wrote:
> On Thu, 10 Jul 2014, Andrew Wagner wrote:
>
> I too have fears about the safety of using strings as events, that are
> not statically
> typechecked. We do not want our UAV to crash because of a typo in a
> string name somewhere. Is
> this already resolved by some simulator tool that has full state
> transition coverage? Even
> then, I think that would only guarantee that the lua is internally
> consistent, not consistent
> with the C++.
>
>
> I think the only real road forward is to use tools to _generate_ both
> parts, so that the consistency is guaranteed _by construction_. Such tools
> can (should...) do more than "typechecking", namely _semantic_ checks.
> Future work... But the RTT mechanism is ready for it. (Within our Rodinia
> prototype tool, this is what is being done, and for which we are improving
> the (poor!) state of the practice in such tooling. Slowly...)
>
> In Leuven we (HIGHWIND) basically never automated experiments at all, just
> relying on a pilot
> who knew how the system worked, and manually typed commands at the orocos
> deployer REPL.
>
> Here in Freiburg, we've switched over to rttlua for deployment scripts, and
> our deployment
> scripts are rapidly devolving into a big mess of switches and special cases to
> try to handle
> different use cases, and also different failure cases safely. We already had
> one "crash" with a
> dummy plane (actually just a soccer ball) just while testing, so I'm eager to
> find a better way.
>
>
> The "better" way is to bring in hierarchy based on _semantically_
> motivated structure. Such as the natural hierarchy in bringing up a complex
> system, by configuring "from bottom up" and starting/freezing/stopping
> "from top down", where "bottom" and "top" are dictated by the
> mechanical/actuation/OS/computational HW hierarchy.
>
> In another thread someone mentioned this:
>
> Yakindue
> http://statecharts.org/
>
> Maybe integrating the code generated from that into orocos would be a good direction
> for the
> community to go in?
>
>
> This is not a good direction to go in, because that tool stimulates the
> coupling of the structural part of the discrete states, with the behaviour
> that is active in a state; this does not survive distributing or
> concurrency, because the model does not cover the domain-specific semantics
> of such concurrency. Some "more advanced" tools rely on formal models such
> as Petri nets to Verify&Validate "distributed state machines", but they
> neglect the fact that communication takes finite time, and that all of the
> infrastructure resources are always available with a full 100% Quality of
> Service.
>
> We have spent _lots_ of man months on these issues, since Markus' email about these issues
> (enclosed below), and the 'result' is not so
> positive: detting the state machines "right", "robust" and "reliable" is
> one of the most difficult things to automate in complex system design...
>
> Cheers,
> Andrew
>
>
> Herman
>
> On Tue, Dec 4, 2012 at 2:45 PM, Piotr Trojanek <piotr [dot] trojanek [..] ...>
> wrote:
> On Sat, Nov 10, 2012 at 03:03:47PM +0100, Markus Klotzbuecher wrote:
> > On Sat, Nov 10, 2012 at 02:23:06PM +0100, Piotr Trojanek wrote:
> > > On Sat, Nov 10, 2012 at 09:57:04AM +0100, Markus Klotzbuecher wrote:
> > > > Yes, I think ultimately we should come up with a real syntax and
> > > > write/generate a real C parser for it. Then we can create Lua
> bindings to it
> > > > and transparently allow both syntax. Would you be interested to
> contribute
> > > > here? On the other hand it might be better to go straight to
> graphical
> > > > editing.
> > >
> > > If I may suggest -- I believe it might be better to rather capture
> an abstract
> > > syntax of the FSM language by the use of EMF-like techniques (*) and
> then use
> > > it as a basis of both textual and graphical editors, code
> generators, etc.
> >
> > Sure, having a complementary, user-friendly graphical+Xtext frontend
> would be
> > nice.
>
> I guess that graphical+textual editor is the way to go. rFSM mixes two
> concerns: data processing (which is entirely in textual Lua code) and FSM
> (which conforms to its own abstract syntax and have an obvious graphical
> representation).
>
> > I have a rFSM Ecore model, if anyone would like to take a shot at it :-)
>
> Please do not hesitate to publish it!
>
> > > (*) I decided to avoid the term "meta-model," since its meaning differs
> among
> > > the readers of this mailing list.
> >
> > Markus
Real-Time and RTT-State-Machines
Hi,
does a rtt state machine have any effect on the real time behavior of a task context? I control a task context with a state machine, which is loaded activated and started during configureHook. For testing issues I overloaded the new and delete operator. It seems, that the state machine evaluation calls new and delete, when the task context is already started. Require state switches new and delete calls (or any other heap allocation)?
Thanks
Sandra
Orocos 2.7rc9
Real-Time and RTT-State-Machines
Hi Sandra,
On Fri, Jul 11, 2014 at 1:48 PM, Sandra Beyer <sandra [dot] beyer [..] ...>
wrote:
> Hi,
> does a rtt state machine have any effect on the real time behavior of a
> task context? I control a task context with a state machine, which is
> loaded activated and started during configureHook. For testing issues I
> overloaded the new and delete operator. It seems, that the state machine
> evaluation calls new and delete, when the task context is already started.
> Require state switches new and delete calls (or any other heap allocation)?
>
Could you provide a trace of this ? Whose new and delete operators are
called ? an executing state machine should not cause any new or delete,
unless you have inproper use of strings or log things to the console or
similar.
It does use the TLSF allocator for operations which is in RTT, but which is
real-time.
Peter
rFSM usability & scalability feedback
2012/11/10 Markus Klotzbuecher <markus [dot] klotzbuecher [..] ...>
> Hi Peter,
>
> On Sat, Nov 10, 2012 at 12:16:43AM +0100, Peter Soetens wrote:
>
> > A few weeks ago I've spent some time prototyping some rFSM state
> > machines. The focus was on integrating it in an existing system
> > architecture, and not so much on implementing the functionality. I
> > must say that the end result was with mixed feelings. I felt there
> > were 2 major issues remaining with *using* rFSM : Syntax for new
> > people or people not using it on a daily basis and scalability of
> > string events:
> >
> > 1. Syntax
> > There is just too little sugar available for neat rFSM 'programs'.
> > What I mean is, in the end, it is a comma separated table,
> > tab-indented slightly to appear as a functional description.
> > Especially comparing the readability of an rFSM transition with an RTT
> > scripting transition is quite a difference. For example:
> > - transitions are in the parent state instead of the source state.
> > This makes looking up transitions quite hard, unless you go to one of
> > the rFSM dot tools for visualisation
> > - compare a transition in RTT fsm versus an rFSM fsm:
> > RTT:
> > transition eventname( arg ) if arg < foo then { comp.doIt(); } select
> BAR_STATE
> >
> > rFSM:
> > rfsm.trans { src='FOO_STATE', tgt='BAR_STATE', events='eventname',
> > guard=function() return args < foo end, effect = function()
> > comp:doIt() end, }
> >
> > apart from the fact that there is no easy way to get the 'arg' data
> > out of an event in rFSM (see next point), it just doesn't read. I
> > wonder if it would be possible to improve on this.
>
> Yes, I think ultimately we should come up with a real syntax and
> write/generate a real C parser for it. Then we can create Lua bindings
> to it and transparently allow both syntax. Would you be interested to
> contribute here? On the other hand it might be better to go straight
> to graphical editing. And I disagree with adding the successor state
> to the source state though, since that breaks composability of the
> latter.
>
RTT state machines have a really nice syntax that is very readable and very
kind to use as a developper, even in big systems. It's has also be a pain
for me when switching from RTT state machines to rFSM due to some
readability loss (but lua brings many other things that are not possible in
RTT, such as having a real scripting language).
I'm using state machines extensively, with a very high rate of code
dynamics (I mean it changes really often), for my robot strategic part in
competitions, and manual writing and textual debugging of state machine is
just a pain that generates (sooooo) many (stupid) bugs. I definitely think
that graphical edition/debug is the only way to go. And one good reason for
this in the industrial world is that you can share graphical snapshots and
you can't do the same with textual FSM. So in the end you keep a "power
point" version of the state machine that you hardly draw by hand.
I know that in the end the problem is still the same : ressources, but
from a user point of view, I'll jump on the first graphical state machine
editor as soon as it exists, even if the FSM part underneath is not the
best.
>
>
> 2. strings as events
> > How easy this is for small prototypes, how more insane this is for any
> > reasonable system. It's completely unmaintainable. How to guarantee
> > that there are no typos in your string names ? Both on the sending
> > side and on the events='...' side ? How to sync the C++ side with the
> > Lua side ? I understand the rFSM independence of RTT (so there is no
> > C++ side strictly speaking), but for RTT + rFSM examples, using string
> > events on ports should be plainly banned.
> >
> > Even more, in its current form rFSM *itself* does not allow to have
> > pay-loaded events since the events='...' is a comparison of data, so
> > the contents of the event must be known in advance fully in order to
> > trigger a transition. I can't think of a sane way to synchronize some
> > string event with some data associated with it on another port. For
> > any kind of coordination above the trivial, a payload is required to
> > be able to take the correct supervisory decisions. The reason a
> > payload is needed is that the events come in asynchronously, so the
> > system state may already have changed. The event is the only place
> > where that state information can be stored.
> >
> > We definitely need to formulate an alternative to strings as an Orocos
> > community here. I already tried actually. I have written a
> > readEvents() function which automates linking a random data port type
> > with an event name ( ie still a string, required by rFSM ) and a
> > variable which contains the port data. But I may want to take it
> > further, events may actually be required as RTT extensions, building
> > on top of our trustworthy ports, in order to define this link to the
> > state machines, such that each state machine can check if a certain
> > event exists or not. Something like that...
>
> Nice rant :-), but I do agree.
>
> Ok, three things: scalability, error-proneness and payloads. String
> events are indeed not scalable, but on the other hand we surely don't
> want people writing statemachines triggered by numbers. As you
> suggest, I think the only way to deal with this is to "standardize"
> within the RTT community on some kind of event model and
> representation _and_ suggested use in components.
>
> I have had in mind the following. Firstly, the events a component can
> raise should become introspectable at runtime. This could be as simple
> as a string->number map using a read-only property. To ensure
> uniqueness across the system, a raised event number needs to be
> prepended (automatically) with a unique component id (do we have
> this?)
>
> Once we have that, we're basically done. An rFSM developer can
> continue to use the convenient string (or whatever) like
> "component.event" as triggers. Using a preprocessing plugin, at load
> time we transform all string events to number events by looking these
> up in the component interfaces. This way we also verify that a
> component really does raise the specified event.
>
> (BTW: there is a rfsm_checkevents plugin to help detect typos. When
> loaded and an event is received that is not used on any transition of
> the FSM, a warning is printed).
>
> We can even define an RTT dbg function that converts the numbers back
> to their string names in debug messages.
>
> Regarding the payload, it is less clear to me what we really
> need. Maybe you can describe a real world use-case you had.
>
> > 3. And as a bonus: doo
> > It's not clear to me why we need to add our own while true do ... end
> > loop in doo. It's a classical omission and will basically clutter up
> > any doo function. If you don't want a while true do ... end loop in
> > your do, you could equally put the code in entry and omit doo itself.
>
> You don't need the while ... end. You just need it if you want to
> continunously call the same code again, while giving up control at a
> yield. You could also have a non-looping doo:
>
> function doo()
> dothis();
> yield();
> dothat();
> yield();
> foo();
> end
>
> We could achieve the same by introducing doo parameters 'oneshot' and
> 'periodic', and then allowing specifying periodic doo's without while
> ... end. Would you prefer that?
>
>
> Thanks a lot for the feedback!
>
> Markus
> --
> Orocos-Users mailing list
> Orocos-Users [..] ...
> http://lists.mech.kuleuven.be/mailman/listinfo/orocos-users
>