getting events out the state machine

Hi,

There is a way to get events IN a component with a statemachine by creating a port and write to it: something like
events_in = rtt.InputPort("string")
tc:addPort(events_in, "events_in", "rFSM event input port")
fsm.getevents = rfsm_rtt.gen_read_events(events_in)

But now I want to get the events OUT of a component with a statemachine ...
I figure something like:
events_out = rtt.OutputPort("string")
tc:addPort(events_out, "_events_out", "current events in this FSM")
rfsm_rtt.gen_write_events(events_out)

but this doesn't exist yet?

nick

getting events out the state machine

2011/7/11 Dominick Vanthienen <dominick [dot] vanthienen [..] ...>:
> Hi,
>
> There is a way to get events IN a component with a statemachine by creating a port and write to it: something like
>  events_in = rtt.InputPort("string")
>  tc:addPort(events_in, "events_in", "rFSM event input port")
>  fsm.getevents = rfsm_rtt.gen_read_events(events_in)
>
> But now I want to get the events OUT of a component with a statemachine ...
> I figure something like:
>  events_out = rtt.OutputPort("string")
>  tc:addPort(events_out, "_events_out", "current events in this FSM")
>  rfsm_rtt.gen_write_events(events_out)
>
> but this doesn't exist yet?

Why would you want to do that? The statemachine should receive events
and take appropriate actions, but sending out new events, to where?
Another state machine?

Steven

>
> nick
> --
> Orocos-Dev mailing list
> Orocos-Dev [..] ...
> http://lists.mech.kuleuven.be/mailman/listinfo/orocos-dev
>

getting events out the state machine

On Mon, 11 Jul 2011, Steven Bellens wrote:

> 2011/7/11 Dominick Vanthienen <dominick [dot] vanthienen [..] ...>:
>> Hi,
>>
>> There is a way to get events IN a component with a statemachine by creating a port and write to it: something like
>>  events_in = rtt.InputPort("string")
>>  tc:addPort(events_in, "events_in", "rFSM event input port")
>>  fsm.getevents = rfsm_rtt.gen_read_events(events_in)
>>
>> But now I want to get the events OUT of a component with a statemachine ...
>> I figure something like:
>>  events_out = rtt.OutputPort("string")
>>  tc:addPort(events_out, "_events_out", "current events in this FSM")
>>  rfsm_rtt.gen_write_events(events_out)
>>
>> but this doesn't exist yet?
>
>
> Why would you want to do that? The statemachine should receive events
> and take appropriate actions, but sending out new events, to where?
> Another state machine?

Of course! Hierarchical and parallel state machines are obvious FSM
architectures to have.

> Steven
>
>> nick

Herman

getting events out the state machine

On Jul 11, 2011, at 05:47 , Herman Bruyninckx wrote:

> On Mon, 11 Jul 2011, Steven Bellens wrote:
>
>> 2011/7/11 Dominick Vanthienen <dominick [dot] vanthienen [..] ...>:
>>> Hi,
>>>
>>> There is a way to get events IN a component with a statemachine by creating a port and write to it: something like
>>> events_in = rtt.InputPort("string")
>>> tc:addPort(events_in, "events_in", "rFSM event input port")
>>> fsm.getevents = rfsm_rtt.gen_read_events(events_in)
>>>
>>> But now I want to get the events OUT of a component with a statemachine ...
>>> I figure something like:
>>> events_out = rtt.OutputPort("string")
>>> tc:addPort(events_out, "_events_out", "current events in this FSM")
>>> rfsm_rtt.gen_write_events(events_out)
>>>
>>> but this doesn't exist yet?
>>
>>
>> Why would you want to do that? The statemachine should receive events
>> and take appropriate actions, but sending out new events, to where?
>> Another state machine?
>
> Of course! Hierarchical and parallel state machines are obvious FSM
> architectures to have.

Completely agreed. And this was, IMHO, the single most important thing that was available in v1, that was lost with the v2 transition. This is one of the primary reasons we have not upgraded to v2 - we can't live without this.
S

getting events out the state machine

On Mon, Jul 11, 2011 at 10:46:22AM +0200, Dominick Vanthienen wrote:
> Hi,
>
> There is a way to get events IN a component with a statemachine by creating a port and write to it: something like
> events_in = rtt.InputPort("string")
> tc:addPort(events_in, "events_in", "rFSM event input port")
> fsm.getevents = rfsm_rtt.gen_read_events(events_in)
>
> But now I want to get the events OUT of a component with a statemachine ...
> I figure something like:
> events_out = rtt.OutputPort("string")
> tc:addPort(events_out, "_events_out", "current events in this FSM")

So far this should work...

> rfsm_rtt.gen_write_events(events_out)
>
> but this doesn't exist yet?

Indeed. There is no default mechanism to send out events. Which events
precisely do you want get out? Only the ones you raised yourself, or
also the fsm internal (completion events)? For the first, to abstract
away from the port writing you can just create a "raise_event"
function yourself, for instance:

--- Generate an event raising function.
-- The generated function accepts zero to many arguments and writes
-- them to the given port.
-- @param port outport to write events to
-- @return function to send events to the port
function gen_raise_event(port)
return function (...) for
_,e in ipairs{...} do port:write(e) end
end
end

raise_event=gen_raise_event(events_out)

raise_event("e_1")
or multiple:

raise_event("e_1", "e_2", "e3")

If you do need to distribute the internal events (and have a good
reason to do that :-)), then we need to add a hook for that.

Markus

getting events out the state machine

Hi Markus, Hi Nick,

> From: Markus Klotzbuecher <markus [dot] klotzbuecher [..] ...>
> Subject: Re: [Orocos-Dev] getting events out the state machine
> To: Dominick Vanthienen <dominick [dot] vanthienen [..] ...>
> Cc: "orocos-dev [..] ..."
>        <orocos-dev [..] ...>
> Message-ID: <20110711094114.GD9795@PMA-10-048>
> Content-Type: text/plain; charset=us-ascii
>
> On Mon, Jul 11, 2011 at 10:46:22AM +0200, Dominick Vanthienen wrote:
>> Hi,
>>
>> There is a way to get events IN a component with a statemachine by creating a port and write to it: something like
>>   events_in = rtt.InputPort("string")
>>   tc:addPort(events_in, "events_in", "rFSM event input port")
>>   fsm.getevents = rfsm_rtt.gen_read_events(events_in)
>>
>> But now I want to get the events OUT of a component with a statemachine ...
>> I figure something like:
>>   events_out = rtt.OutputPort("string")
>>   tc:addPort(events_out, "_events_out", "current events in this FSM")
>
> So far this should work...
>
>>   rfsm_rtt.gen_write_events(events_out)
>>
>> but this doesn't exist yet?
>
> Indeed. There is no default mechanism to send out events.

I definitely agree with the fact that raising an event should be part
of the FSM metamodel!

> Which events
> precisely do you want get out? Only the ones you raised yourself, or
> also the fsm internal (completion events)? For the first, to abstract
> away from the port writing you can just create a "raise_event"
> function yourself, for instance:
>
> --- Generate an event raising function.
> -- The generated function accepts zero to many arguments and writes
> -- them to the given port.
> -- @param port outport to write events to
> -- @return function to send events to the port
> function gen_raise_event(port)
>   return function (...) for
>          _,e in ipairs{...} do port:write(e) end
>    end
> end
>
> raise_event=gen_raise_event(events_out)
>
> raise_event("e_1")
> or multiple:
>
> raise_event("e_1", "e_2", "e3")

I like this: It cleanly separates the semantics of the statemachine
(raising events) from the mechanism it is implemented with in orocos
(2.x), ie. using ports.
Could you make the raise_event "call" by default part of your lua FSM
(ie. adding it to the metamodel, instead of letting the user implement
it him/herself?

regards,

Klaas
--
Orocos-Dev mailing list
Orocos-Dev [..] ...
http://lists.mech.kuleuven.be/mailman/listinfo/orocos-dev

getting events out the state machine

Hi Klaas,

On Mon, Jul 11, 2011 at 01:56:52PM +0200, Klaas Gadeyne wrote:
> Hi Markus, Hi Nick,
>
> > From: Markus Klotzbuecher <markus [dot] klotzbuecher [..] ...>
> > Subject: Re: [Orocos-Dev] getting events out the state machine
> > To: Dominick Vanthienen <dominick [dot] vanthienen [..] ...>
> > Cc: "orocos-dev [..] ..."
> >        <orocos-dev [..] ...>
> > Message-ID: <20110711094114.GD9795@PMA-10-048>
> > Content-Type: text/plain; charset=us-ascii
> >
> > On Mon, Jul 11, 2011 at 10:46:22AM +0200, Dominick Vanthienen wrote:
> >> Hi,
> >>
> >> There is a way to get events IN a component with a statemachine by creating a port and write to it: something like
> >>   events_in = rtt.InputPort("string")
> >>   tc:addPort(events_in, "events_in", "rFSM event input port")
> >>   fsm.getevents = rfsm_rtt.gen_read_events(events_in)
> >>
> >> But now I want to get the events OUT of a component with a statemachine ...
> >> I figure something like:
> >>   events_out = rtt.OutputPort("string")
> >>   tc:addPort(events_out, "_events_out", "current events in this FSM")
> >
> > So far this should work...
> >
> >>   rfsm_rtt.gen_write_events(events_out)
> >>
> >> but this doesn't exist yet?
> >
> > Indeed. There is no default mechanism to send out events.
>
> I definitely agree with the fact that raising an event should be part
> of the FSM metamodel!
>
> > Which events
> > precisely do you want get out? Only the ones you raised yourself, or
> > also the fsm internal (completion events)? For the first, to abstract
> > away from the port writing you can just create a "raise_event"
> > function yourself, for instance:
> >
> > --- Generate an event raising function.
> > -- The generated function accepts zero to many arguments and writes
> > -- them to the given port.
> > -- @param port outport to write events to
> > -- @return function to send events to the port
> > function gen_raise_event(port)
> >   return function (...) for
> >          _,e in ipairs{...} do port:write(e) end
> >    end
> > end
> >
> > raise_event=gen_raise_event(events_out)
> >
> > raise_event("e_1")
> > or multiple:
> >
> > raise_event("e_1", "e_2", "e3")
>
> I like this: It cleanly separates the semantics of the statemachine
> (raising events) from the mechanism it is implemented with in orocos
> (2.x), ie. using ports.
> Could you make the raise_event "call" by default part of your lua FSM
> (ie. adding it to the metamodel, instead of letting the user implement
> it him/herself?

That is something that would be done automatically if you choose to
run your FSM using the RTT skin...

Markus

getting events out the state machine

On Mon, 11 Jul 2011, Klaas Gadeyne wrote:

> Hi Markus, Hi Nick,
>
>> From: Markus Klotzbuecher <markus [dot] klotzbuecher [..] ...>
>> Subject: Re: [Orocos-Dev] getting events out the state machine
>> To: Dominick Vanthienen <dominick [dot] vanthienen [..] ...>
>> Cc: "orocos-dev [..] ..."
>>        <orocos-dev [..] ...>
>> Message-ID: <20110711094114.GD9795@PMA-10-048>
>> Content-Type: text/plain; charset=us-ascii
>>
>> On Mon, Jul 11, 2011 at 10:46:22AM +0200, Dominick Vanthienen wrote:
>>> Hi,
>>>
>>> There is a way to get events IN a component with a statemachine by creating a port and write to it: something like
>>>   events_in = rtt.InputPort("string")
>>>   tc:addPort(events_in, "events_in", "rFSM event input port")
>>>   fsm.getevents = rfsm_rtt.gen_read_events(events_in)
>>>
>>> But now I want to get the events OUT of a component with a statemachine ...
>>> I figure something like:
>>>   events_out = rtt.OutputPort("string")
>>>   tc:addPort(events_out, "_events_out", "current events in this FSM")
>>
>> So far this should work...
>>
>>>   rfsm_rtt.gen_write_events(events_out)
>>>
>>> but this doesn't exist yet?
>>
>> Indeed. There is no default mechanism to send out events.
>
> I definitely agree with the fact that raising an event should be part
> of the FSM metamodel!
>
>> Which events
>> precisely do you want get out? Only the ones you raised yourself, or
>> also the fsm internal (completion events)? For the first, to abstract
>> away from the port writing you can just create a "raise_event"
>> function yourself, for instance:
>>
>> --- Generate an event raising function.
>> -- The generated function accepts zero to many arguments and writes
>> -- them to the given port.
>> -- @param port outport to write events to
>> -- @return function to send events to the port
>> function gen_raise_event(port)
>>   return function (...) for
>>          _,e in ipairs{...} do port:write(e) end
>>    end
>> end
>>
>> raise_event=gen_raise_event(events_out)
>>
>> raise_event("e_1")
>> or multiple:
>>
>> raise_event("e_1", "e_2", "e3")
>
> I like this: It cleanly separates the semantics of the statemachine
> (raising events) from the mechanism it is implemented with in orocos
> (2.x), ie. using ports.

+1

> Could you make the raise_event "call" by default part of your lua FSM
> (ie. adding it to the metamodel, instead of letting the user implement
> it him/herself?

What do you suggest exactly...?

> regards,
>
> Klaas

Herman

getting events out the state machine

[...]
>> Could you make the raise_event "call" by default part of your lua FSM
>> (ie. adding it to the metamodel, instead of letting the user implement
>> it him/herself?
>
> What do you suggest exactly...?

Implementation wise, I suggested adding the API to the
"rfsm_rtt.lua" helper module as Markus already seem to have suggested:
<http://www.orocos.org/forum/rtt/rtt-dev/getting-events-out-state-machine#comment-31768>

(rfsm_rtt.lua contains the FSM metamodel, right?)

regards,

Klaas

getting events out the state machine

On Mon, Jul 11, 2011 at 02:20:29PM +0200, Klaas Gadeyne wrote:
> [...]
> >> Could you make the raise_event "call" by default part of your lua FSM
> >> (ie. adding it to the metamodel, instead of letting the user implement
> >> it him/herself?
> >
> > What do you suggest exactly...?
>
> Implementation wise, I suggested adding the API to the
> "rfsm_rtt.lua" helper module as Markus already seem to have suggested:
> <http://www.orocos.org/forum/rtt/rtt-dev/getting-events-out-state-machine#comment-31768>
>
> (rfsm_rtt.lua contains the FSM metamodel, right?)

It contains helper functions like the one proposed in this thread to
simplify using rFSM together with RTT.

Markus

getting events out the state machine

On Jul 11, 2011, at 07:56 , Klaas Gadeyne wrote:

> Hi Markus, Hi Nick,
>
>> From: Markus Klotzbuecher <markus [dot] klotzbuecher [..] ...>
>> Subject: Re: [Orocos-Dev] getting events out the state machine
>> To: Dominick Vanthienen <dominick [dot] vanthienen [..] ...>
>> Cc: "orocos-dev [..] ..."
>> <orocos-dev [..] ...>
>> Message-ID: <20110711094114.GD9795@PMA-10-048>
>> Content-Type: text/plain; charset=us-ascii
>>
>> On Mon, Jul 11, 2011 at 10:46:22AM +0200, Dominick Vanthienen wrote:
>>> Hi,
>>>
>>> There is a way to get events IN a component with a statemachine by creating a port and write to it: something like
>>> events_in = rtt.InputPort("string")
>>> tc:addPort(events_in, "events_in", "rFSM event input port")
>>> fsm.getevents = rfsm_rtt.gen_read_events(events_in)
>>>
>>> But now I want to get the events OUT of a component with a statemachine ...
>>> I figure something like:
>>> events_out = rtt.OutputPort("string")
>>> tc:addPort(events_out, "_events_out", "current events in this FSM")
>>
>> So far this should work...
>>
>>> rfsm_rtt.gen_write_events(events_out)
>>>
>>> but this doesn't exist yet?
>>
>> Indeed. There is no default mechanism to send out events.
>
> I definitely agree with the fact that raising an event should be part
> of the FSM metamodel!
>
>> Which events
>> precisely do you want get out? Only the ones you raised yourself, or
>> also the fsm internal (completion events)? For the first, to abstract
>> away from the port writing you can just create a "raise_event"
>> function yourself, for instance:
>>
>> --- Generate an event raising function.
>> -- The generated function accepts zero to many arguments and writes
>> -- them to the given port.
>> -- @param port outport to write events to
>> -- @return function to send events to the port
>> function gen_raise_event(port)
>> return function (...) for
>> _,e in ipairs{...} do port:write(e) end
>> end
>> end
>>
>> raise_event=gen_raise_event(events_out)
>>
>> raise_event("e_1")
>> or multiple:
>>
>> raise_event("e_1", "e_2", "e3")
>
> I like this: It cleanly separates the semantics of the statemachine
> (raising events) from the mechanism it is implemented with in orocos
> (2.x), ie. using ports.
> Could you make the raise_event "call" by default part of your lua FSM
> (ie. adding it to the metamodel, instead of letting the user implement
> it him/herself?
>
> regards,
>
> Klaas

The code outline above suggests that raising an event with parameters would be supported also, right? What would that code look like to the user?

raise_event("e_1", ???)

getting events out the state machine

On Mon, Jul 11, 2011 at 02:00:46PM +0200, S Roderick wrote:
> On Jul 11, 2011, at 07:56 , Klaas Gadeyne wrote:
>
> > Hi Markus, Hi Nick,
> >
> >> From: Markus Klotzbuecher <markus [dot] klotzbuecher [..] ...>
> >> Subject: Re: [Orocos-Dev] getting events out the state machine
> >> To: Dominick Vanthienen <dominick [dot] vanthienen [..] ...>
> >> Cc: "orocos-dev [..] ..."
> >> <orocos-dev [..] ...>
> >> Message-ID: <20110711094114.GD9795@PMA-10-048>
> >> Content-Type: text/plain; charset=us-ascii
> >>
> >> On Mon, Jul 11, 2011 at 10:46:22AM +0200, Dominick Vanthienen wrote:
> >>> Hi,
> >>>
> >>> There is a way to get events IN a component with a statemachine by creating a port and write to it: something like
> >>> events_in = rtt.InputPort("string")
> >>> tc:addPort(events_in, "events_in", "rFSM event input port")
> >>> fsm.getevents = rfsm_rtt.gen_read_events(events_in)
> >>>
> >>> But now I want to get the events OUT of a component with a statemachine ...
> >>> I figure something like:
> >>> events_out = rtt.OutputPort("string")
> >>> tc:addPort(events_out, "_events_out", "current events in this FSM")
> >>
> >> So far this should work...
> >>
> >>> rfsm_rtt.gen_write_events(events_out)
> >>>
> >>> but this doesn't exist yet?
> >>
> >> Indeed. There is no default mechanism to send out events.
> >
> > I definitely agree with the fact that raising an event should be part
> > of the FSM metamodel!
> >
> >> Which events
> >> precisely do you want get out? Only the ones you raised yourself, or
> >> also the fsm internal (completion events)? For the first, to abstract
> >> away from the port writing you can just create a "raise_event"
> >> function yourself, for instance:
> >>
> >> --- Generate an event raising function.
> >> -- The generated function accepts zero to many arguments and writes
> >> -- them to the given port.
> >> -- @param port outport to write events to
> >> -- @return function to send events to the port
> >> function gen_raise_event(port)
> >> return function (...) for
> >> _,e in ipairs{...} do port:write(e) end
> >> end
> >> end
> >>
> >> raise_event=gen_raise_event(events_out)
> >>
> >> raise_event("e_1")
> >> or multiple:
> >>
> >> raise_event("e_1", "e_2", "e3")
> >
> > I like this: It cleanly separates the semantics of the statemachine
> > (raising events) from the mechanism it is implemented with in orocos
> > (2.x), ie. using ports.
> > Could you make the raise_event "call" by default part of your lua FSM
> > (ie. adding it to the metamodel, instead of letting the user implement
> > it him/herself?
> >
> > regards,
> >
> > Klaas
>
> The code outline above suggests that raising an event with parameters would be supported also, right? What would that code look like to the user?
>
> raise_event("e_1", ???)

You tell me!

raise_event{event="e_1", vel={0.1,0,0}} ?

BTW: that is a hot discussion topic: Should events be parametrizable
and thus allowed to carry data or is it better (and why?) to define
events as pure identity carrying?

Markus

getting events out the state machine

On 07/11/2011 11:41 AM, Markus Klotzbuecher wrote:
> On Mon, Jul 11, 2011 at 10:46:22AM +0200, Dominick Vanthienen wrote:
>> Hi,
>>
>> There is a way to get events IN a component with a statemachine by creating a port and write to it: something like
>> events_in = rtt.InputPort("string")
>> tc:addPort(events_in, "events_in", "rFSM event input port")
>> fsm.getevents = rfsm_rtt.gen_read_events(events_in)
>>
>> But now I want to get the events OUT of a component with a statemachine ...
>> I figure something like:
>> events_out = rtt.OutputPort("string")
>> tc:addPort(events_out, "_events_out", "current events in this FSM")
> So far this should work...
>
>> rfsm_rtt.gen_write_events(events_out)
>>
>> but this doesn't exist yet?
> Indeed. There is no default mechanism to send out events. Which events
> precisely do you want get out? Only the ones you raised yourself, or
> also the fsm internal (completion events)?
What internal events do exist? e_done?
That wouldn't make sense to send to another statemachine
So I think I just need the events I raised myself

> For the first, to abstract
> away from the port writing you can just create a "raise_event"
> function yourself, for instance:
>
> --- Generate an event raising function.
> -- The generated function accepts zero to many arguments and writes
> -- them to the given port.
> -- @param port outport to write events to
> -- @return function to send events to the port
> function gen_raise_event(port)
> return function (...) for
> _,e in ipairs{...} do port:write(e) end
> end
> end
>
> raise_event=gen_raise_event(events_out)
>
> raise_event("e_1")
> or multiple:
>
> raise_event("e_1", "e_2", "e3")
This means that I have to make sure I do two things?:
raise it internally: rfsm.send_events(fsm, "e_stopGlobal")
raise it externally (=putting it on a port): what you described above ...

(I 'll add the internal raise to the function above ...)
> If you do need to distribute the internal events (and have a good
> reason to do that :-)), then we need to add a hook for that.
>
> Markus
>
>
>
>
>

getting events out the state machine

On Mon, Jul 11, 2011 at 12:08:45PM +0200, Dominick Vanthienen wrote:
>
>
> On 07/11/2011 11:41 AM, Markus Klotzbuecher wrote:
> > On Mon, Jul 11, 2011 at 10:46:22AM +0200, Dominick Vanthienen wrote:
> >> Hi,
> >>
> >> There is a way to get events IN a component with a statemachine by creating a port and write to it: something like
> >> events_in = rtt.InputPort("string")
> >> tc:addPort(events_in, "events_in", "rFSM event input port")
> >> fsm.getevents = rfsm_rtt.gen_read_events(events_in)
> >>
> >> But now I want to get the events OUT of a component with a statemachine ...
> >> I figure something like:
> >> events_out = rtt.OutputPort("string")
> >> tc:addPort(events_out, "_events_out", "current events in this FSM")
> > So far this should work...
> >
> >> rfsm_rtt.gen_write_events(events_out)
> >>
> >> but this doesn't exist yet?
> > Indeed. There is no default mechanism to send out events. Which events
> > precisely do you want get out? Only the ones you raised yourself, or
> > also the fsm internal (completion events)?
> What internal events do exist? e_done?
> That wouldn't make sense to send to another statemachine
> So I think I just need the events I raised myself

Currently AFAICR there are only the completion events. I'm sure there
are cases when it does make sense to distribute these too, but
probably not for fsm developers but rather for automatic generation of
parallel or hierarchical fsm graphs.

> > For the first, to abstract
> > away from the port writing you can just create a "raise_event"
> > function yourself, for instance:
> >
> > --- Generate an event raising function.
> > -- The generated function accepts zero to many arguments and writes
> > -- them to the given port.
> > -- @param port outport to write events to
> > -- @return function to send events to the port
> > function gen_raise_event(port)
> > return function (...) for
> > _,e in ipairs{...} do port:write(e) end
> > end
> > end
> >
> > raise_event=gen_raise_event(events_out)
> >
> > raise_event("e_1")
> > or multiple:
> >
> > raise_event("e_1", "e_2", "e3")
> This means that I have to make sure I do two things?:
> raise it internally: rfsm.send_events(fsm, "e_stopGlobal")
> raise it externally (=putting it on a port): what you described above ...

I would suggest to add it like below:

--- Generate an event raising function.
-- The generated function accepts zero to many arguments and writes
-- them to the given port and optionally to the internal queue of fsm.
-- @param port outport to write events to
-- @param fsm events are sent to this fsm's internal queue (optional)
-- @return function to send events to the port
function gen_raise_event(port, fsm)
return function (...) for
_,e in ipairs{...} do port:write(e) end
if fsm then send_events(fsm, ...) end
end
end

If you can confirm this works for you I'll add it to the
"rfsm_rtt.lua" helper module.

Markus

getting events out the state machine

On 07/11/2011 12:19 PM, Markus Klotzbuecher wrote:
> On Mon, Jul 11, 2011 at 12:08:45PM +0200, Dominick Vanthienen wrote:
>>
>> On 07/11/2011 11:41 AM, Markus Klotzbuecher wrote:
>>> On Mon, Jul 11, 2011 at 10:46:22AM +0200, Dominick Vanthienen wrote:
>>>> Hi,
>>>>
>>>> There is a way to get events IN a component with a statemachine by creating a port and write to it: something like
>>>> events_in = rtt.InputPort("string")
>>>> tc:addPort(events_in, "events_in", "rFSM event input port")
>>>> fsm.getevents = rfsm_rtt.gen_read_events(events_in)
>>>>
>>>> But now I want to get the events OUT of a component with a statemachine ...
>>>> I figure something like:
>>>> events_out = rtt.OutputPort("string")
>>>> tc:addPort(events_out, "_events_out", "current events in this FSM")
>>> So far this should work...
>>>
>>>> rfsm_rtt.gen_write_events(events_out)
>>>>
>>>> but this doesn't exist yet?
>>> Indeed. There is no default mechanism to send out events. Which events
>>> precisely do you want get out? Only the ones you raised yourself, or
>>> also the fsm internal (completion events)?
>> What internal events do exist? e_done?
>> That wouldn't make sense to send to another statemachine
>> So I think I just need the events I raised myself
> Currently AFAICR there are only the completion events. I'm sure there
> are cases when it does make sense to distribute these too, but
> probably not for fsm developers but rather for automatic generation of
> parallel or hierarchical fsm graphs.
I'm working on a hierarchical fsm, depending on what you see as an hierarchical fsm of course
(I've a global fsm, whose events trigger itasc fsm transitions, whose events on their turn trigger different task fsm's transitions ...)
>>> For the first, to abstract
>>> away from the port writing you can just create a "raise_event"
>>> function yourself, for instance:
>>>
>>> --- Generate an event raising function.
>>> -- The generated function accepts zero to many arguments and writes
>>> -- them to the given port.
>>> -- @param port outport to write events to
>>> -- @return function to send events to the port
>>> function gen_raise_event(port)
>>> return function (...) for
>>> _,e in ipairs{...} do port:write(e) end
>>> end
>>> end
>>>
>>> raise_event=gen_raise_event(events_out)
>>>
>>> raise_event("e_1")
>>> or multiple:
>>>
>>> raise_event("e_1", "e_2", "e3")
>> This means that I have to make sure I do two things?:
>> raise it internally: rfsm.send_events(fsm, "e_stopGlobal")
>> raise it externally (=putting it on a port): what you described above ...
> I would suggest to add it like below:
>
> --- Generate an event raising function.
> -- The generated function accepts zero to many arguments and writes
> -- them to the given port and optionally to the internal queue of fsm.
> -- @param port outport to write events to
> -- @param fsm events are sent to this fsm's internal queue (optional)
> -- @return function to send events to the port
> function gen_raise_event(port, fsm)
> return function (...) for
> _,e in ipairs{...} do port:write(e) end
> if fsm then send_events(fsm, ...) end
it should be rfsm.send_events...
> end
> end
>
> If you can confirm this works for you I'll add it to the
> "rfsm_rtt.lua" helper module.
it works partially:
gen_raise_event(common_events_out, fsm)("e_event")
works
but
defining the following (in my supervisor or fsm script itself)
raise_common_event=gen_raise_event(common_events_out, fsm)
and then use
raise_common_event("e_event")
doesn't work, it returns
ENTRYerror executing entry of root.ConfiguringApplication: ../scripts/GlobalSuperVisor.lua:76: attempt to index upvalue 'port' (a nil value)

> Markus

getting events out the state machine

On Mon, 11 Jul 2011, Dominick Vanthienen wrote:

>
>
> On 07/11/2011 12:19 PM, Markus Klotzbuecher wrote:
>> On Mon, Jul 11, 2011 at 12:08:45PM +0200, Dominick Vanthienen wrote:
>>>
>>> On 07/11/2011 11:41 AM, Markus Klotzbuecher wrote:
>>>> On Mon, Jul 11, 2011 at 10:46:22AM +0200, Dominick Vanthienen wrote:
>>>>> Hi,
>>>>>
>>>>> There is a way to get events IN a component with a statemachine by creating a port and write to it: something like
>>>>> events_in = rtt.InputPort("string")
>>>>> tc:addPort(events_in, "events_in", "rFSM event input port")
>>>>> fsm.getevents = rfsm_rtt.gen_read_events(events_in)
>>>>>
>>>>> But now I want to get the events OUT of a component with a statemachine ...
>>>>> I figure something like:
>>>>> events_out = rtt.OutputPort("string")
>>>>> tc:addPort(events_out, "_events_out", "current events in this FSM")
>>>> So far this should work...
>>>>
>>>>> rfsm_rtt.gen_write_events(events_out)
>>>>>
>>>>> but this doesn't exist yet?
>>>> Indeed. There is no default mechanism to send out events. Which events
>>>> precisely do you want get out? Only the ones you raised yourself, or
>>>> also the fsm internal (completion events)?
>>> What internal events do exist? e_done?
>>> That wouldn't make sense to send to another statemachine
>>> So I think I just need the events I raised myself
>> Currently AFAICR there are only the completion events. I'm sure there
>> are cases when it does make sense to distribute these too, but
>> probably not for fsm developers but rather for automatic generation of
>> parallel or hierarchical fsm graphs.
> I'm working on a hierarchical fsm, depending on what you see as an hierarchical fsm of course
> (I've a global fsm, whose events trigger itasc fsm transitions, whose events on their turn trigger different task fsm's transitions ...)

I think this is an example of set of parallel (or rather, distributed) FSMs
that you want to let behave as one single hierarchical FSM. This is
definitely a very common use case.

I am curious to see how your design deals with making the distribution
(in)transparant... I imagine there will be extra states (= "Communication
Coordination") in the distributed case, but they should _only_ be
coordinating the distribution, and not the "logical" hierarchical FSM.

>>>> For the first, to abstract
>>>> away from the port writing you can just create a "raise_event"
>>>> function yourself, for instance:
>>>>
>>>> --- Generate an event raising function.
>>>> -- The generated function accepts zero to many arguments and writes
>>>> -- them to the given port.
>>>> -- @param port outport to write events to
>>>> -- @return function to send events to the port
>>>> function gen_raise_event(port)
>>>> return function (...) for
>>>> _,e in ipairs{...} do port:write(e) end
>>>> end
>>>> end
>>>>
>>>> raise_event=gen_raise_event(events_out)
>>>>
>>>> raise_event("e_1")
>>>> or multiple:
>>>>
>>>> raise_event("e_1", "e_2", "e3")
>>> This means that I have to make sure I do two things?:
>>> raise it internally: rfsm.send_events(fsm, "e_stopGlobal")
>>> raise it externally (=putting it on a port): what you described above ...
>> I would suggest to add it like below:
>>
>> --- Generate an event raising function.
>> -- The generated function accepts zero to many arguments and writes
>> -- them to the given port and optionally to the internal queue of fsm.
>> -- @param port outport to write events to
>> -- @param fsm events are sent to this fsm's internal queue (optional)
>> -- @return function to send events to the port
>> function gen_raise_event(port, fsm)
>> return function (...) for
>> _,e in ipairs{...} do port:write(e) end
>> if fsm then send_events(fsm, ...) end
> it should be rfsm.send_events...
>> end
>> end
>>
>> If you can confirm this works for you I'll add it to the
>> "rfsm_rtt.lua" helper module.
> it works partially:
> gen_raise_event(common_events_out, fsm)("e_event")
> works
> but
> defining the following (in my supervisor or fsm script itself)
> raise_common_event=gen_raise_event(common_events_out, fsm)
> and then use
> raise_common_event("e_event")
> doesn't work, it returns
> ENTRYerror executing entry of root.ConfiguringApplication: ../scripts/GlobalSuperVisor.lua:76: attempt to index upvalue 'port' (a nil value)
>
>> Markus

Herman

getting events out the state machine

On 07/11/2011 03:41 PM, Herman Bruyninckx wrote:
> On Mon, 11 Jul 2011, Dominick Vanthienen wrote:
>
>>
>> On 07/11/2011 12:19 PM, Markus Klotzbuecher wrote:
>>> On Mon, Jul 11, 2011 at 12:08:45PM +0200, Dominick Vanthienen wrote:
>>>> On 07/11/2011 11:41 AM, Markus Klotzbuecher wrote:
>>>>> On Mon, Jul 11, 2011 at 10:46:22AM +0200, Dominick Vanthienen wrote:
>>>>>> Hi,
>>>>>>
>>>>>> There is a way to get events IN a component with a statemachine by creating a port and write to it: something like
>>>>>> events_in = rtt.InputPort("string")
>>>>>> tc:addPort(events_in, "events_in", "rFSM event input port")
>>>>>> fsm.getevents = rfsm_rtt.gen_read_events(events_in)
>>>>>>
>>>>>> But now I want to get the events OUT of a component with a statemachine ...
>>>>>> I figure something like:
>>>>>> events_out = rtt.OutputPort("string")
>>>>>> tc:addPort(events_out, "_events_out", "current events in this FSM")
>>>>> So far this should work...
>>>>>
>>>>>> rfsm_rtt.gen_write_events(events_out)
>>>>>>
>>>>>> but this doesn't exist yet?
>>>>> Indeed. There is no default mechanism to send out events. Which events
>>>>> precisely do you want get out? Only the ones you raised yourself, or
>>>>> also the fsm internal (completion events)?
>>>> What internal events do exist? e_done?
>>>> That wouldn't make sense to send to another statemachine
>>>> So I think I just need the events I raised myself
>>> Currently AFAICR there are only the completion events. I'm sure there
>>> are cases when it does make sense to distribute these too, but
>>> probably not for fsm developers but rather for automatic generation of
>>> parallel or hierarchical fsm graphs.
>> I'm working on a hierarchical fsm, depending on what you see as an hierarchical fsm of course
>> (I've a global fsm, whose events trigger itasc fsm transitions, whose events on their turn trigger different task fsm's transitions ...)
> I think this is an example of set of parallel (or rather, distributed) FSMs
> that you want to let behave as one single hierarchical FSM. This is
> definitely a very common use case.
>
> I am curious to see how your design deals with making the distribution
> (in)transparant... I imagine there will be extra states (= "Communication
> Coordination") in the distributed case, but they should _only_ be
> coordinating the distribution, and not the "logical" hierarchical FSM.
I don't know whether I understand correctly
an example of my case:
global FSM has a state configuring, in which one of the things he does, is the raising of an event 'configureItasc'
another FSM, itascFSM, will get this event and will change his state to 'configuring'
>>>>> For the first, to abstract
>>>>> away from the port writing you can just create a "raise_event"
>>>>> function yourself, for instance:
>>>>>
>>>>> --- Generate an event raising function.
>>>>> -- The generated function accepts zero to many arguments and writes
>>>>> -- them to the given port.
>>>>> -- @param port outport to write events to
>>>>> -- @return function to send events to the port
>>>>> function gen_raise_event(port)
>>>>> return function (...) for
>>>>> _,e in ipairs{...} do port:write(e) end
>>>>> end
>>>>> end
>>>>>
>>>>> raise_event=gen_raise_event(events_out)
>>>>>
>>>>> raise_event("e_1")
>>>>> or multiple:
>>>>>
>>>>> raise_event("e_1", "e_2", "e3")
>>>> This means that I have to make sure I do two things?:
>>>> raise it internally: rfsm.send_events(fsm, "e_stopGlobal")
>>>> raise it externally (=putting it on a port): what you described above ...
>>> I would suggest to add it like below:
>>>
>>> --- Generate an event raising function.
>>> -- The generated function accepts zero to many arguments and writes
>>> -- them to the given port and optionally to the internal queue of fsm.
>>> -- @param port outport to write events to
>>> -- @param fsm events are sent to this fsm's internal queue (optional)
>>> -- @return function to send events to the port
>>> function gen_raise_event(port, fsm)
>>> return function (...) for
>>> _,e in ipairs{...} do port:write(e) end
>>> if fsm then send_events(fsm, ...) end
>> it should be rfsm.send_events...
>>> end
>>> end
>>>
>>> If you can confirm this works for you I'll add it to the
>>> "rfsm_rtt.lua" helper module.
>> it works partially:
>> gen_raise_event(common_events_out, fsm)("e_event")
>> works
>> but
>> defining the following (in my supervisor or fsm script itself)
>> raise_common_event=gen_raise_event(common_events_out, fsm)
>> and then use
>> raise_common_event("e_event")
>> doesn't work, it returns
>> ENTRYerror executing entry of root.ConfiguringApplication: ../scripts/GlobalSuperVisor.lua:76: attempt to index upvalue 'port' (a nil value)
>>
>>> Markus
> Herman

getting events out the state machine

On Jul 11, 2011, at 06:19 , Markus Klotzbuecher wrote:

> On Mon, Jul 11, 2011 at 12:08:45PM +0200, Dominick Vanthienen wrote:
>>
>>
>> On 07/11/2011 11:41 AM, Markus Klotzbuecher wrote:
>>> On Mon, Jul 11, 2011 at 10:46:22AM +0200, Dominick Vanthienen wrote:
>>>> Hi,
>>>>
>>>> There is a way to get events IN a component with a statemachine by creating a port and write to it: something like
>>>> events_in = rtt.InputPort("string")
>>>> tc:addPort(events_in, "events_in", "rFSM event input port")
>>>> fsm.getevents = rfsm_rtt.gen_read_events(events_in)
>>>>
>>>> But now I want to get the events OUT of a component with a statemachine ...
>>>> I figure something like:
>>>> events_out = rtt.OutputPort("string")
>>>> tc:addPort(events_out, "_events_out", "current events in this FSM")
>>> So far this should work...
>>>
>>>> rfsm_rtt.gen_write_events(events_out)
>>>>
>>>> but this doesn't exist yet?
>>> Indeed. There is no default mechanism to send out events. Which events
>>> precisely do you want get out? Only the ones you raised yourself, or
>>> also the fsm internal (completion events)?
>> What internal events do exist? e_done?
>> That wouldn't make sense to send to another statemachine
>> So I think I just need the events I raised myself
>
> Currently AFAICR there are only the completion events. I'm sure there
> are cases when it does make sense to distribute these too, but
> probably not for fsm developers but rather for automatic generation of
> parallel or hierarchical fsm graphs.
>
>>> For the first, to abstract
>>> away from the port writing you can just create a "raise_event"
>>> function yourself, for instance:
>>>
>>> --- Generate an event raising function.
>>> -- The generated function accepts zero to many arguments and writes
>>> -- them to the given port.
>>> -- @param port outport to write events to
>>> -- @return function to send events to the port
>>> function gen_raise_event(port)
>>> return function (...) for
>>> _,e in ipairs{...} do port:write(e) end
>>> end
>>> end
>>>
>>> raise_event=gen_raise_event(events_out)
>>>
>>> raise_event("e_1")
>>> or multiple:
>>>
>>> raise_event("e_1", "e_2", "e3")
>> This means that I have to make sure I do two things?:
>> raise it internally: rfsm.send_events(fsm, "e_stopGlobal")
>> raise it externally (=putting it on a port): what you described above ...
>
> I would suggest to add it like below:
>
> --- Generate an event raising function.
> -- The generated function accepts zero to many arguments and writes
> -- them to the given port and optionally to the internal queue of fsm.
> -- @param port outport to write events to
> -- @param fsm events are sent to this fsm's internal queue (optional)
> -- @return function to send events to the port
> function gen_raise_event(port, fsm)
> return function (...) for
> _,e in ipairs{...} do port:write(e) end
> if fsm then send_events(fsm, ...) end
> end
> end
>
> If you can confirm this works for you I'll add it to the
> "rfsm_rtt.lua" helper module.

That seems awfully complicated, compared to v1 syntax of

#Robot.osd
...
state Moving {
run {
...
do faultDetected() // emit event
...
}
transition faultDetected() select NotMoving // react to event internally
}
...

#Executive.osd
...
state SomeMotionState {
run {
...
}
transition Robot.faultDetected() select SomeOtherState // react to event externally
}

getting events out the state machine

Hi all,

> On Jul 11, 2011, at 06:58 , Markus Klotzbuecher wrote:
>> On Mon, Jul 11, 2011 at 12:55:08PM +0200, S Roderick wrote:
>>> On Jul 11, 2011, at 06:19 , Markus Klotzbuecher wrote:
>>>> On Mon, Jul 11, 2011 at 12:08:45PM +0200, Dominick Vanthienen wrote:

[...]
>>> That seems awfully complicated, compared to v1 syntax of
>>>
>>> #Robot.osd
>>> ...
>>> state Moving {
>>>      run {
>>>              ...
>>>              do faultDetected()                                                                      // emit event
>>>              ...
>>>      }
>>>      transition faultDetected() select NotMoving                                     // react to event internally
>>> }
>>> ...
>>>
>>> #Executive.osd
>>> ...
>>> state SomeMotionState {
>>>      run {
>>>              ...
>>>      }
>>>      transition Robot.faultDetected() select SomeOtherState          // react to event externally
>>> }
>>
>> And you think this wasn't complicated internally?
>
> Of course it was, but we should be more interested in the user perspective. We had working functionality that was easy for the user in v1, and now we have nothing. What you suggest above reminds me of the work required for v1 type/transport plugins, which thankfully are much easier for the user in v2 (I hear).

I think this was a consideration to make when deciding to drop the
Event API from orocos components and replacing it by the port
mechanism. In orocos 1.x the events in the statemachines mapped
1-to-1 onto the component event API.
Indeed, I think the "complicated internally" argument is not one that
you can use for convincing users. However (please correct me if I'm
wrong): in 1.x the syntax you could/can indeed raise events easily in
the osd syntax, _but_ otoh you had to specify the _instance_ name of
the component you (or your statemachine) were listening to. This was
very ugly to and is "solved" by using the ports mechanism.

However, for users, I think the coupling between FSM events and ports
could be hidden more (automatic port creation?) by orocos itself.

regards,

Klaas
--
Orocos-Dev mailing list
Orocos-Dev [..] ...
http://lists.mech.kuleuven.be/mailman/listinfo/orocos-dev

getting events out the state machine

On Mon, Jul 11, 2011 at 12:55:08PM +0200, S Roderick wrote:
> On Jul 11, 2011, at 06:19 , Markus Klotzbuecher wrote:
>
> > On Mon, Jul 11, 2011 at 12:08:45PM +0200, Dominick Vanthienen wrote:
> >>
> >>
> >> On 07/11/2011 11:41 AM, Markus Klotzbuecher wrote:
> >>> On Mon, Jul 11, 2011 at 10:46:22AM +0200, Dominick Vanthienen wrote:
> >>>> Hi,
> >>>>
> >>>> There is a way to get events IN a component with a statemachine by creating a port and write to it: something like
> >>>> events_in = rtt.InputPort("string")
> >>>> tc:addPort(events_in, "events_in", "rFSM event input port")
> >>>> fsm.getevents = rfsm_rtt.gen_read_events(events_in)
> >>>>
> >>>> But now I want to get the events OUT of a component with a statemachine ...
> >>>> I figure something like:
> >>>> events_out = rtt.OutputPort("string")
> >>>> tc:addPort(events_out, "_events_out", "current events in this FSM")
> >>> So far this should work...
> >>>
> >>>> rfsm_rtt.gen_write_events(events_out)
> >>>>
> >>>> but this doesn't exist yet?
> >>> Indeed. There is no default mechanism to send out events. Which events
> >>> precisely do you want get out? Only the ones you raised yourself, or
> >>> also the fsm internal (completion events)?
> >> What internal events do exist? e_done?
> >> That wouldn't make sense to send to another statemachine
> >> So I think I just need the events I raised myself
> >
> > Currently AFAICR there are only the completion events. I'm sure there
> > are cases when it does make sense to distribute these too, but
> > probably not for fsm developers but rather for automatic generation of
> > parallel or hierarchical fsm graphs.
> >
> >>> For the first, to abstract
> >>> away from the port writing you can just create a "raise_event"
> >>> function yourself, for instance:
> >>>
> >>> --- Generate an event raising function.
> >>> -- The generated function accepts zero to many arguments and writes
> >>> -- them to the given port.
> >>> -- @param port outport to write events to
> >>> -- @return function to send events to the port
> >>> function gen_raise_event(port)
> >>> return function (...) for
> >>> _,e in ipairs{...} do port:write(e) end
> >>> end
> >>> end
> >>>
> >>> raise_event=gen_raise_event(events_out)
> >>>
> >>> raise_event("e_1")
> >>> or multiple:
> >>>
> >>> raise_event("e_1", "e_2", "e3")
> >> This means that I have to make sure I do two things?:
> >> raise it internally: rfsm.send_events(fsm, "e_stopGlobal")
> >> raise it externally (=putting it on a port): what you described above ...
> >
> > I would suggest to add it like below:
> >
> > --- Generate an event raising function.
> > -- The generated function accepts zero to many arguments and writes
> > -- them to the given port and optionally to the internal queue of fsm.
> > -- @param port outport to write events to
> > -- @param fsm events are sent to this fsm's internal queue (optional)
> > -- @return function to send events to the port
> > function gen_raise_event(port, fsm)
> > return function (...) for
> > _,e in ipairs{...} do port:write(e) end
> > if fsm then send_events(fsm, ...) end
> > end
> > end
> >
> > If you can confirm this works for you I'll add it to the
> > "rfsm_rtt.lua" helper module.
>
>
> That seems awfully complicated, compared to v1 syntax of
>
> #Robot.osd
> ...
> state Moving {
> run {
> ...
> do faultDetected() // emit event
> ...
> }
> transition faultDetected() select NotMoving // react to event internally
> }
> ...
>
> #Executive.osd
> ...
> state SomeMotionState {
> run {
> ...
> }
> transition Robot.faultDetected() select SomeOtherState // react to event externally
> }

And you think this wasn't complicated internally?
Markus

getting events out the state machine

On Jul 11, 2011, at 06:58 , Markus Klotzbuecher wrote:

> On Mon, Jul 11, 2011 at 12:55:08PM +0200, S Roderick wrote:
>> On Jul 11, 2011, at 06:19 , Markus Klotzbuecher wrote:
>>
>>> On Mon, Jul 11, 2011 at 12:08:45PM +0200, Dominick Vanthienen wrote:
>>>>
>>>>
>>>> On 07/11/2011 11:41 AM, Markus Klotzbuecher wrote:
>>>>> On Mon, Jul 11, 2011 at 10:46:22AM +0200, Dominick Vanthienen wrote:
>>>>>> Hi,
>>>>>>
>>>>>> There is a way to get events IN a component with a statemachine by creating a port and write to it: something like
>>>>>> events_in = rtt.InputPort("string")
>>>>>> tc:addPort(events_in, "events_in", "rFSM event input port")
>>>>>> fsm.getevents = rfsm_rtt.gen_read_events(events_in)
>>>>>>
>>>>>> But now I want to get the events OUT of a component with a statemachine ...
>>>>>> I figure something like:
>>>>>> events_out = rtt.OutputPort("string")
>>>>>> tc:addPort(events_out, "_events_out", "current events in this FSM")
>>>>> So far this should work...
>>>>>
>>>>>> rfsm_rtt.gen_write_events(events_out)
>>>>>>
>>>>>> but this doesn't exist yet?
>>>>> Indeed. There is no default mechanism to send out events. Which events
>>>>> precisely do you want get out? Only the ones you raised yourself, or
>>>>> also the fsm internal (completion events)?
>>>> What internal events do exist? e_done?
>>>> That wouldn't make sense to send to another statemachine
>>>> So I think I just need the events I raised myself
>>>
>>> Currently AFAICR there are only the completion events. I'm sure there
>>> are cases when it does make sense to distribute these too, but
>>> probably not for fsm developers but rather for automatic generation of
>>> parallel or hierarchical fsm graphs.
>>>
>>>>> For the first, to abstract
>>>>> away from the port writing you can just create a "raise_event"
>>>>> function yourself, for instance:
>>>>>
>>>>> --- Generate an event raising function.
>>>>> -- The generated function accepts zero to many arguments and writes
>>>>> -- them to the given port.
>>>>> -- @param port outport to write events to
>>>>> -- @return function to send events to the port
>>>>> function gen_raise_event(port)
>>>>> return function (...) for
>>>>> _,e in ipairs{...} do port:write(e) end
>>>>> end
>>>>> end
>>>>>
>>>>> raise_event=gen_raise_event(events_out)
>>>>>
>>>>> raise_event("e_1")
>>>>> or multiple:
>>>>>
>>>>> raise_event("e_1", "e_2", "e3")
>>>> This means that I have to make sure I do two things?:
>>>> raise it internally: rfsm.send_events(fsm, "e_stopGlobal")
>>>> raise it externally (=putting it on a port): what you described above ...
>>>
>>> I would suggest to add it like below:
>>>
>>> --- Generate an event raising function.
>>> -- The generated function accepts zero to many arguments and writes
>>> -- them to the given port and optionally to the internal queue of fsm.
>>> -- @param port outport to write events to
>>> -- @param fsm events are sent to this fsm's internal queue (optional)
>>> -- @return function to send events to the port
>>> function gen_raise_event(port, fsm)
>>> return function (...) for
>>> _,e in ipairs{...} do port:write(e) end
>>> if fsm then send_events(fsm, ...) end
>>> end
>>> end
>>>
>>> If you can confirm this works for you I'll add it to the
>>> "rfsm_rtt.lua" helper module.
>>
>>
>> That seems awfully complicated, compared to v1 syntax of
>>
>> #Robot.osd
>> ...
>> state Moving {
>> run {
>> ...
>> do faultDetected() // emit event
>> ...
>> }
>> transition faultDetected() select NotMoving // react to event internally
>> }
>> ...
>>
>> #Executive.osd
>> ...
>> state SomeMotionState {
>> run {
>> ...
>> }
>> transition Robot.faultDetected() select SomeOtherState // react to event externally
>> }
>
> And you think this wasn't complicated internally?
> Markus

Of course it was, but we should be more interested in the user perspective. We had working functionality that was easy for the user in v1, and now we have nothing. What you suggest above reminds me of the work required for v1 type/transport plugins, which thankfully are much easier for the user in v2 (I hear).
S

getting events out the state machine

On Mon, Jul 11, 2011 at 01:01:53PM +0200, Stephen Roderick wrote:
> On Jul 11, 2011, at 06:58 , Markus Klotzbuecher wrote:
>
> > On Mon, Jul 11, 2011 at 12:55:08PM +0200, S Roderick wrote:
> >> On Jul 11, 2011, at 06:19 , Markus Klotzbuecher wrote:
> >>
> >>> On Mon, Jul 11, 2011 at 12:08:45PM +0200, Dominick Vanthienen wrote:
> >>>>
> >>>>
> >>>> On 07/11/2011 11:41 AM, Markus Klotzbuecher wrote:
> >>>>> On Mon, Jul 11, 2011 at 10:46:22AM +0200, Dominick Vanthienen wrote:
> >>>>>> Hi,
> >>>>>>
> >>>>>> There is a way to get events IN a component with a statemachine by creating a port and write to it: something like
> >>>>>> events_in = rtt.InputPort("string")
> >>>>>> tc:addPort(events_in, "events_in", "rFSM event input port")
> >>>>>> fsm.getevents = rfsm_rtt.gen_read_events(events_in)
> >>>>>>
> >>>>>> But now I want to get the events OUT of a component with a statemachine ...
> >>>>>> I figure something like:
> >>>>>> events_out = rtt.OutputPort("string")
> >>>>>> tc:addPort(events_out, "_events_out", "current events in this FSM")
> >>>>> So far this should work...
> >>>>>
> >>>>>> rfsm_rtt.gen_write_events(events_out)
> >>>>>>
> >>>>>> but this doesn't exist yet?
> >>>>> Indeed. There is no default mechanism to send out events. Which events
> >>>>> precisely do you want get out? Only the ones you raised yourself, or
> >>>>> also the fsm internal (completion events)?
> >>>> What internal events do exist? e_done?
> >>>> That wouldn't make sense to send to another statemachine
> >>>> So I think I just need the events I raised myself
> >>>
> >>> Currently AFAICR there are only the completion events. I'm sure there
> >>> are cases when it does make sense to distribute these too, but
> >>> probably not for fsm developers but rather for automatic generation of
> >>> parallel or hierarchical fsm graphs.
> >>>
> >>>>> For the first, to abstract
> >>>>> away from the port writing you can just create a "raise_event"
> >>>>> function yourself, for instance:
> >>>>>
> >>>>> --- Generate an event raising function.
> >>>>> -- The generated function accepts zero to many arguments and writes
> >>>>> -- them to the given port.
> >>>>> -- @param port outport to write events to
> >>>>> -- @return function to send events to the port
> >>>>> function gen_raise_event(port)
> >>>>> return function (...) for
> >>>>> _,e in ipairs{...} do port:write(e) end
> >>>>> end
> >>>>> end
> >>>>>
> >>>>> raise_event=gen_raise_event(events_out)
> >>>>>
> >>>>> raise_event("e_1")
> >>>>> or multiple:
> >>>>>
> >>>>> raise_event("e_1", "e_2", "e3")
> >>>> This means that I have to make sure I do two things?:
> >>>> raise it internally: rfsm.send_events(fsm, "e_stopGlobal")
> >>>> raise it externally (=putting it on a port): what you described above ...
> >>>
> >>> I would suggest to add it like below:
> >>>
> >>> --- Generate an event raising function.
> >>> -- The generated function accepts zero to many arguments and writes
> >>> -- them to the given port and optionally to the internal queue of fsm.
> >>> -- @param port outport to write events to
> >>> -- @param fsm events are sent to this fsm's internal queue (optional)
> >>> -- @return function to send events to the port
> >>> function gen_raise_event(port, fsm)
> >>> return function (...) for
> >>> _,e in ipairs{...} do port:write(e) end
> >>> if fsm then send_events(fsm, ...) end
> >>> end
> >>> end
> >>>
> >>> If you can confirm this works for you I'll add it to the
> >>> "rfsm_rtt.lua" helper module.
> >>
> >>
> >> That seems awfully complicated, compared to v1 syntax of
> >>
> >> #Robot.osd
> >> ...
> >> state Moving {
> >> run {
> >> ...
> >> do faultDetected() // emit event
> >> ...
> >> }
> >> transition faultDetected() select NotMoving // react to event internally
> >> }
> >> ...
> >>
> >> #Executive.osd
> >> ...
> >> state SomeMotionState {
> >> run {
> >> ...
> >> }
> >> transition Robot.faultDetected() select SomeOtherState // react to event externally
> >> }
> >
> > And you think this wasn't complicated internally?
> > Markus
>
> Of course it was, but we should be more interested in the user
> perspective. We had working functionality that was easy for the user

The code you show only works for RTT, while the new FSMs are framework
agnostic. Hence some additional glue is required, which as you see is
increasingly autogenerated.

> in v1, and now we have nothing. What you suggest above reminds me of
> the work required for v1 type/transport plugins, which thankfully
> are much easier for the user in v2 (I hear).

We are working towards getting the usability back, but it will take
some time.

Markus

getting events out the state machine

On Jul 11, 2011, at 07:19 , Markus Klotzbuecher wrote:

> On Mon, Jul 11, 2011 at 01:01:53PM +0200, Stephen Roderick wrote:
>> On Jul 11, 2011, at 06:58 , Markus Klotzbuecher wrote:
>>
>>> On Mon, Jul 11, 2011 at 12:55:08PM +0200, S Roderick wrote:
>>>> On Jul 11, 2011, at 06:19 , Markus Klotzbuecher wrote:
>>>>
>>>>> On Mon, Jul 11, 2011 at 12:08:45PM +0200, Dominick Vanthienen wrote:
>>>>>>
>>>>>>
>>>>>> On 07/11/2011 11:41 AM, Markus Klotzbuecher wrote:
>>>>>>> On Mon, Jul 11, 2011 at 10:46:22AM +0200, Dominick Vanthienen wrote:
>>>>>>>> Hi,
>>>>>>>>
>>>>>>>> There is a way to get events IN a component with a statemachine by creating a port and write to it: something like
>>>>>>>> events_in = rtt.InputPort("string")
>>>>>>>> tc:addPort(events_in, "events_in", "rFSM event input port")
>>>>>>>> fsm.getevents = rfsm_rtt.gen_read_events(events_in)
>>>>>>>>
>>>>>>>> But now I want to get the events OUT of a component with a statemachine ...
>>>>>>>> I figure something like:
>>>>>>>> events_out = rtt.OutputPort("string")
>>>>>>>> tc:addPort(events_out, "_events_out", "current events in this FSM")
>>>>>>> So far this should work...
>>>>>>>
>>>>>>>> rfsm_rtt.gen_write_events(events_out)
>>>>>>>>
>>>>>>>> but this doesn't exist yet?
>>>>>>> Indeed. There is no default mechanism to send out events. Which events
>>>>>>> precisely do you want get out? Only the ones you raised yourself, or
>>>>>>> also the fsm internal (completion events)?
>>>>>> What internal events do exist? e_done?
>>>>>> That wouldn't make sense to send to another statemachine
>>>>>> So I think I just need the events I raised myself
>>>>>
>>>>> Currently AFAICR there are only the completion events. I'm sure there
>>>>> are cases when it does make sense to distribute these too, but
>>>>> probably not for fsm developers but rather for automatic generation of
>>>>> parallel or hierarchical fsm graphs.
>>>>>
>>>>>>> For the first, to abstract
>>>>>>> away from the port writing you can just create a "raise_event"
>>>>>>> function yourself, for instance:
>>>>>>>
>>>>>>> --- Generate an event raising function.
>>>>>>> -- The generated function accepts zero to many arguments and writes
>>>>>>> -- them to the given port.
>>>>>>> -- @param port outport to write events to
>>>>>>> -- @return function to send events to the port
>>>>>>> function gen_raise_event(port)
>>>>>>> return function (...) for
>>>>>>> _,e in ipairs{...} do port:write(e) end
>>>>>>> end
>>>>>>> end
>>>>>>>
>>>>>>> raise_event=gen_raise_event(events_out)
>>>>>>>
>>>>>>> raise_event("e_1")
>>>>>>> or multiple:
>>>>>>>
>>>>>>> raise_event("e_1", "e_2", "e3")
>>>>>> This means that I have to make sure I do two things?:
>>>>>> raise it internally: rfsm.send_events(fsm, "e_stopGlobal")
>>>>>> raise it externally (=putting it on a port): what you described above ...
>>>>>
>>>>> I would suggest to add it like below:
>>>>>
>>>>> --- Generate an event raising function.
>>>>> -- The generated function accepts zero to many arguments and writes
>>>>> -- them to the given port and optionally to the internal queue of fsm.
>>>>> -- @param port outport to write events to
>>>>> -- @param fsm events are sent to this fsm's internal queue (optional)
>>>>> -- @return function to send events to the port
>>>>> function gen_raise_event(port, fsm)
>>>>> return function (...) for
>>>>> _,e in ipairs{...} do port:write(e) end
>>>>> if fsm then send_events(fsm, ...) end
>>>>> end
>>>>> end
>>>>>
>>>>> If you can confirm this works for you I'll add it to the
>>>>> "rfsm_rtt.lua" helper module.
>>>>
>>>>
>>>> That seems awfully complicated, compared to v1 syntax of
>>>>
>>>> #Robot.osd
>>>> ...
>>>> state Moving {
>>>> run {
>>>> ...
>>>> do faultDetected() // emit event
>>>> ...
>>>> }
>>>> transition faultDetected() select NotMoving // react to event internally
>>>> }
>>>> ...
>>>>
>>>> #Executive.osd
>>>> ...
>>>> state SomeMotionState {
>>>> run {
>>>> ...
>>>> }
>>>> transition Robot.faultDetected() select SomeOtherState // react to event externally
>>>> }
>>>
>>> And you think this wasn't complicated internally?
>>> Markus
>>
>> Of course it was, but we should be more interested in the user
>> perspective. We had working functionality that was easy for the user
>
> The code you show only works for RTT, while the new FSMs are framework
> agnostic. Hence some additional glue is required, which as you see is
> increasingly autogenerated.
>
>> in v1, and now we have nothing. What you suggest above reminds me of
>> the work required for v1 type/transport plugins, which thankfully
>> are much easier for the user in v2 (I hear).
>
> We are working towards getting the usability back, but it will take
> some time.

I'm curious to know the plan here ... however vague or precise it might be ...
S

getting events out the state machine

On Mon, Jul 11, 2011 at 01:20:51PM +0200, Stephen Roderick wrote:
> On Jul 11, 2011, at 07:19 , Markus Klotzbuecher wrote:
>
> > On Mon, Jul 11, 2011 at 01:01:53PM +0200, Stephen Roderick wrote:
> >> On Jul 11, 2011, at 06:58 , Markus Klotzbuecher wrote:
> >>
> >>> On Mon, Jul 11, 2011 at 12:55:08PM +0200, S Roderick wrote:
> >>>> On Jul 11, 2011, at 06:19 , Markus Klotzbuecher wrote:
> >>>>
> >>>>> On Mon, Jul 11, 2011 at 12:08:45PM +0200, Dominick Vanthienen wrote:
> >>>>>>
> >>>>>>
> >>>>>> On 07/11/2011 11:41 AM, Markus Klotzbuecher wrote:
> >>>>>>> On Mon, Jul 11, 2011 at 10:46:22AM +0200, Dominick Vanthienen wrote:
> >>>>>>>> Hi,
> >>>>>>>>
> >>>>>>>> There is a way to get events IN a component with a statemachine by creating a port and write to it: something like
> >>>>>>>> events_in = rtt.InputPort("string")
> >>>>>>>> tc:addPort(events_in, "events_in", "rFSM event input port")
> >>>>>>>> fsm.getevents = rfsm_rtt.gen_read_events(events_in)
> >>>>>>>>
> >>>>>>>> But now I want to get the events OUT of a component with a statemachine ...
> >>>>>>>> I figure something like:
> >>>>>>>> events_out = rtt.OutputPort("string")
> >>>>>>>> tc:addPort(events_out, "_events_out", "current events in this FSM")
> >>>>>>> So far this should work...
> >>>>>>>
> >>>>>>>> rfsm_rtt.gen_write_events(events_out)
> >>>>>>>>
> >>>>>>>> but this doesn't exist yet?
> >>>>>>> Indeed. There is no default mechanism to send out events. Which events
> >>>>>>> precisely do you want get out? Only the ones you raised yourself, or
> >>>>>>> also the fsm internal (completion events)?
> >>>>>> What internal events do exist? e_done?
> >>>>>> That wouldn't make sense to send to another statemachine
> >>>>>> So I think I just need the events I raised myself
> >>>>>
> >>>>> Currently AFAICR there are only the completion events. I'm sure there
> >>>>> are cases when it does make sense to distribute these too, but
> >>>>> probably not for fsm developers but rather for automatic generation of
> >>>>> parallel or hierarchical fsm graphs.
> >>>>>
> >>>>>>> For the first, to abstract
> >>>>>>> away from the port writing you can just create a "raise_event"
> >>>>>>> function yourself, for instance:
> >>>>>>>
> >>>>>>> --- Generate an event raising function.
> >>>>>>> -- The generated function accepts zero to many arguments and writes
> >>>>>>> -- them to the given port.
> >>>>>>> -- @param port outport to write events to
> >>>>>>> -- @return function to send events to the port
> >>>>>>> function gen_raise_event(port)
> >>>>>>> return function (...) for
> >>>>>>> _,e in ipairs{...} do port:write(e) end
> >>>>>>> end
> >>>>>>> end
> >>>>>>>
> >>>>>>> raise_event=gen_raise_event(events_out)
> >>>>>>>
> >>>>>>> raise_event("e_1")
> >>>>>>> or multiple:
> >>>>>>>
> >>>>>>> raise_event("e_1", "e_2", "e3")
> >>>>>> This means that I have to make sure I do two things?:
> >>>>>> raise it internally: rfsm.send_events(fsm, "e_stopGlobal")
> >>>>>> raise it externally (=putting it on a port): what you described above ...
> >>>>>
> >>>>> I would suggest to add it like below:
> >>>>>
> >>>>> --- Generate an event raising function.
> >>>>> -- The generated function accepts zero to many arguments and writes
> >>>>> -- them to the given port and optionally to the internal queue of fsm.
> >>>>> -- @param port outport to write events to
> >>>>> -- @param fsm events are sent to this fsm's internal queue (optional)
> >>>>> -- @return function to send events to the port
> >>>>> function gen_raise_event(port, fsm)
> >>>>> return function (...) for
> >>>>> _,e in ipairs{...} do port:write(e) end
> >>>>> if fsm then send_events(fsm, ...) end
> >>>>> end
> >>>>> end
> >>>>>
> >>>>> If you can confirm this works for you I'll add it to the
> >>>>> "rfsm_rtt.lua" helper module.
> >>>>
> >>>>
> >>>> That seems awfully complicated, compared to v1 syntax of
> >>>>
> >>>> #Robot.osd
> >>>> ...
> >>>> state Moving {
> >>>> run {
> >>>> ...
> >>>> do faultDetected() // emit event
> >>>> ...
> >>>> }
> >>>> transition faultDetected() select NotMoving // react to event internally
> >>>> }
> >>>> ...
> >>>>
> >>>> #Executive.osd
> >>>> ...
> >>>> state SomeMotionState {
> >>>> run {
> >>>> ...
> >>>> }
> >>>> transition Robot.faultDetected() select SomeOtherState // react to event externally
> >>>> }
> >>>
> >>> And you think this wasn't complicated internally?
> >>> Markus
> >>
> >> Of course it was, but we should be more interested in the user
> >> perspective. We had working functionality that was easy for the user
> >
> > The code you show only works for RTT, while the new FSMs are framework
> > agnostic. Hence some additional glue is required, which as you see is
> > increasingly autogenerated.
> >
> >> in v1, and now we have nothing. What you suggest above reminds me of
> >> the work required for v1 type/transport plugins, which thankfully
> >> are much easier for the user in v2 (I hear).
> >
> > We are working towards getting the usability back, but it will take
> > some time.
>
> I'm curious to know the plan here ... however vague or precise it might be ...

Autogenerating common patterns like the above, later support a kind of
"profile" mechanism to group framework specific patterns, support this
with graphical tooling...

It also depends on what input we get from users... I'm certainly
paying attention to your rants :-)

Markus

getting events out the LUA-state machine

it concerns a lua statemachine

On 07/11/2011 10:46 AM, Dominick Vanthienen wrote:
> Hi,
>
> There is a way to get events IN a component with a statemachine by creating a port and write to it: something like
> events_in = rtt.InputPort("string")
> tc:addPort(events_in, "events_in", "rFSM event input port")
> fsm.getevents = rfsm_rtt.gen_read_events(events_in)
>
> But now I want to get the events OUT of a component with a statemachine ...
> I figure something like:
> events_out = rtt.OutputPort("string")
> tc:addPort(events_out, "_events_out", "current events in this FSM")
> rfsm_rtt.gen_write_events(events_out)
>
> but this doesn't exist yet?
>
> nick