rfsm_await

Hi,

I made already a simple example on the use of the await plugin and then
everything seemed to work fine. Now I want to go to the next state when two
motion_generators finished their 'moveTo' command.

In the code I have:

move_to_start = state{
entry = function() ... end,
exit = function()
-- for debugging --

print(rttlib.port_clone_conn(motionGen1:getPort("events")):read())

print(rttlib.port_clone_conn(motionGen2:getPort("events")):read())
end,
},

trans { src='move_to_start', tgt='follow_traj',
events={"await(e_motionGen1_move_finished,e_motionGen2_move_finished)"},
guard=function() return moveToStartAccepted end },

The transition is done however when only one motion_generator has finished:
taskbrowser output:

NewData e_motionGen1_move_started
NewData e_motionGen2_move_finished
Global_Coordinator: STATE_EXIT root.AllReady.move_to_start
Global_Coordinator: STATE_ENTER root.AllReady.follow_traj

What could be the problem? Can await be combined with a guard?

Thanks,

Bert

rfsm_await

On Thu, Jan 31, 2013 at 09:31:46AM +0100, Bert Willaert wrote:
> Hi,
>
> I made already a simple example on the use of the await plugin and then
> everything seemed to work fine. Now I want to go to the next state when two
> motion_generators finished their 'moveTo' command.
>
> In the code I have:
>
> move_to_start = state{
> entry = function() ... end,
> exit = function()
> -- for debugging --
> print(rttlib.port_clone_conn(motionGen1:getPort
> ("events")):read())
> print(rttlib.port_clone_conn(motionGen2:getPort
> ("events")):read())
> end,
> },
>
>
> trans { src='move_to_start', tgt='follow_traj', events={"await
> (e_motionGen1_move_finished,e_motionGen2_move_finished)"}, guard=function()
> return moveToStartAccepted end },
>
> The transition is done however when only one motion_generator has finished:
> taskbrowser output:
>
> NewData e_motionGen1_move_started
> NewData e_motionGen2_move_finished
> Global_Coordinator: STATE_EXIT root.AllReady.move_to_start
> Global_Coordinator: STATE_ENTER root.AllReady.follow_traj
>
>
> What could be the problem? Can await be combined with a guard?

It can, but there was silly bug that caused the guard to be
ignored. Please pull for a fix.

That said, I'm not sure this is the cause of your problem. The output
of your print's will not be very reliable, because you are creating
the connections on the fly in exit, thus after you have received the
events you want to print. It would be better to create these
connections earlier and only once. Also keep in mind that ports are
not automatically cleaned up, hence in you example you are leaking
memory.

Best regards
Markus

rfsm_await

On Thu, Jan 31, 2013 at 10:36 AM, Markus Klotzbuecher <
markus [dot] klotzbuecher [..] ...> wrote:

> On Thu, Jan 31, 2013 at 09:31:46AM +0100, Bert Willaert wrote:
> > Hi,
> >
> > I made already a simple example on the use of the await plugin and then
> > everything seemed to work fine. Now I want to go to the next state when
> two
> > motion_generators finished their 'moveTo' command.
> >
> > In the code I have:
> >
> > move_to_start = state{
> > entry = function() ... end,
> > exit = function()
> > -- for debugging --
> > print(rttlib.port_clone_conn(motionGen1:getPort
> > ("events")):read())
> > print(rttlib.port_clone_conn(motionGen2:getPort
> > ("events")):read())
> > end,
> > },
> >
> >
> > trans { src='move_to_start', tgt='follow_traj', events={"await
> > (e_motionGen1_move_finished,e_motionGen2_move_finished)"},
> guard=function()
> > return moveToStartAccepted end },
> >
> > The transition is done however when only one motion_generator has
> finished:
> > taskbrowser output:
> >
> > NewData e_motionGen1_move_started
> > NewData e_motionGen2_move_finished
> > Global_Coordinator: STATE_EXIT root.AllReady.move_to_start
> > Global_Coordinator: STATE_ENTER root.AllReady.follow_traj
> >
> >
> > What could be the problem? Can await be combined with a guard?
>
> It can, but there was silly bug that caused the guard to be
> ignored. Please pull for a fix.
>

I did a pull of the rFSM dev branch but I still have the same problem...

>
> That said, I'm not sure this is the cause of your problem. The output
> of your print's will not be very reliable, because you are creating
> the connections on the fly in exit, thus after you have received the
> events you want to print. It would be better to create these
> connections earlier and only once.

I was actually doing this but to make the code shorter in the mail I wrote
it like that ( which can only lead to misunderstandings, so I won't do that
again ;))

local p1 = rttlib.port_clone_conn(motionGen1:getPort("events"))
local p2 = rttlib.port_clone_conn(motionGen2:getPort("events"))

return state {

move_to_start= state {
exit = function() print(p1:read()) print(p2:read()) end,
},

> Also keep in mind that ports are
> not automatically cleaned up, hence in you example you are leaking
> memory.
>
> Best regards
> Markus
>
>

rfsm_await

On Thu, Jan 31, 2013 at 11:45:23AM +0100, Bert Willaert wrote:
>
>
>
> On Thu, Jan 31, 2013 at 10:36 AM, Markus Klotzbuecher <
> markus [dot] klotzbuecher [..] ...> wrote:
>
> On Thu, Jan 31, 2013 at 09:31:46AM +0100, Bert Willaert wrote:
> > Hi,
> >
> > I made already a simple example on the use of the await plugin and then
> > everything seemed to work fine. Now I want to go to the next state when
> two
> > motion_generators finished their 'moveTo' command.
> >
> > In the code I have:
> >
> > move_to_start = state{
> > entry = function() ... end,
> > exit = function()
> > -- for debugging --
> > print(rttlib.port_clone_conn(motionGen1:getPort
> > ("events")):read())
> > print(rttlib.port_clone_conn(motionGen2:getPort
> > ("events")):read())
> > end,
> > },
> >
> >
> > trans { src='move_to_start', tgt='follow_traj', events={"await
> > (e_motionGen1_move_finished,e_motionGen2_move_finished)"}, guard=function
> ()
> > return moveToStartAccepted end },
> >
> > The transition is done however when only one motion_generator has
> finished:
> > taskbrowser output:
> >
> > NewData e_motionGen1_move_started
> > NewData e_motionGen2_move_finished
> > Global_Coordinator: STATE_EXIT root.AllReady.move_to_start
> > Global_Coordinator: STATE_ENTER root.AllReady.follow_traj
> >
> >
> > What could be the problem? Can await be combined with a guard?
>
> It can, but there was silly bug that caused the guard to be
> ignored. Please pull for a fix.
>
>
> I did a pull of the rFSM dev branch but I still have the same problem...

Ok.

> That said, I'm not sure this is the cause of your problem. The output
> of your print's will not be very reliable, because you are creating
> the connections on the fly in exit, thus after you have received the
> events you want to print. It would be better to create these
> connections earlier and only once.
>
>
> I was actually doing this but to make the code shorter in the mail I wrote it
> like that ( which can only lead to misunderstandings, so I won't do that again
> ;))

Yes, please :)

> local p1 = rttlib.port_clone_conn(motionGen1:getPort("events"))
> local p2 = rttlib.port_clone_conn(motionGen2:getPort("events"))
>
> return state {
>
> move_to_start= state {
> exit = function() print(p1:read()) print(p2:read()) end,
> },
>

The FSM could still transition *before* you see the event on the other
port. I would suggest that you enable FSM debugging (e.g. as in the
await example) so we can check whether both events are actually
received or not.

Markus

rfsm_await

On Thu, Jan 31, 2013 at 1:04 PM, Markus Klotzbuecher <
markus [dot] klotzbuecher [..] ...> wrote:

> On Thu, Jan 31, 2013 at 11:45:23AM +0100, Bert Willaert wrote:
> >
> >
> >
> > On Thu, Jan 31, 2013 at 10:36 AM, Markus Klotzbuecher <
> > markus [dot] klotzbuecher [..] ...> wrote:
> >
> > On Thu, Jan 31, 2013 at 09:31:46AM +0100, Bert Willaert wrote:
> > > Hi,
> > >
> > > I made already a simple example on the use of the await plugin and
> then
> > > everything seemed to work fine. Now I want to go to the next state
> when
> > two
> > > motion_generators finished their 'moveTo' command.
> > >
> > > In the code I have:
> > >
> > > move_to_start = state{
> > > entry = function() ... end,
> > > exit = function()
> > > -- for debugging --
> > > print(rttlib.port_clone_conn(motionGen1:getPort
> > > ("events")):read())
> > > print(rttlib.port_clone_conn(motionGen2:getPort
> > > ("events")):read())
> > > end,
> > > },
> > >
> > >
> > > trans { src='move_to_start', tgt='follow_traj',
> events={"await
> > > (e_motionGen1_move_finished,e_motionGen2_move_finished)"},
> guard=function
> > ()
> > > return moveToStartAccepted end },
> > >
> > > The transition is done however when only one motion_generator has
> > finished:
> > > taskbrowser output:
> > >
> > > NewData e_motionGen1_move_started
> > > NewData e_motionGen2_move_finished
> > > Global_Coordinator: STATE_EXIT
> root.AllReady.move_to_start
> > > Global_Coordinator: STATE_ENTER
> root.AllReady.follow_traj
> > >
> > >
> > > What could be the problem? Can await be combined with a guard?
> >
> > It can, but there was silly bug that caused the guard to be
> > ignored. Please pull for a fix.
> >
> >
> > I did a pull of the rFSM dev branch but I still have the same problem...
>
> Ok.
>
> > That said, I'm not sure this is the cause of your problem. The output
> > of your print's will not be very reliable, because you are creating
> > the connections on the fly in exit, thus after you have received the
> > events you want to print. It would be better to create these
> > connections earlier and only once.
> >
> >
> > I was actually doing this but to make the code shorter in the mail I
> wrote it
> > like that ( which can only lead to misunderstandings, so I won't do that
> again
> > ;))
>
> Yes, please :)
>
> > local p1 = rttlib.port_clone_conn(motionGen1:getPort("events"))
> > local p2 = rttlib.port_clone_conn(motionGen2:getPort("events"))
> >
> > return state {
> >
> > move_to_start= state {
> > exit = function() print(p1:read()) print(p2:read())
> end,
> > },
> >
>
> The FSM could still transition *before* you see the event on the other
> port. I would suggest that you enable FSM debugging (e.g. as in the
> await example) so we can check whether both events are actually
> received or not.
>

await: RAISED e_done [..] ...uring
await: STATE_ENTER root.AllReady.configuring
await: STATE_EXIT root.AllReady.configuring
await: EFFECT T={ src='root.AllReady.configuring',
tgt='root.AllReady.move_to_start', events='{}' }
pos_start :
{2.122013,0.788564,-0.549975,-1.420228,-2.701632,-1.056217,1.486454}
pos_start :
{1.122013,0.788564,-0.549975,-1.420228,-2.701632,-1.056217,1.486454}
await: RAISED e_done [..] ..._to_start
await: STATE_ENTER root.AllReady.move_to_start
27.714 [ Warning][Logger] FINISHED
NewData e_motionGen1_move_started
NewData e_motionGen2_move_finished
await: STATE_EXIT root.AllReady.move_to_start
await: EFFECT T={ src='root.AllReady.move_to_start',
tgt='root.AllReady.follow_traj', events='await(e_motionGen1_move_finished,
e_motionGen2_move_finished), e_motionGen1_move_finished,
e_motionGen2_move_finished' }
await: RAISED e_done [..] ..._traj
await: STATE_ENTER root.AllReady.follow_traj

In the naxes_motion_control/src/nAxesGeneratorPos.cpp file I added the
following line at the place the event is sent:

// send move_finished_event (once)
event_port.write(move_finished_event);
++ log(Warning)<<"FINISHED" <<endlog();

So only one warning in the taskbrowser, which shows that only one of the
two motionGenerators is finished already. Still the await dbg info
indicates that both events have been received, no?

> Markus
>

rfsm_await

Hi Bert,

Could you configure you email program to send plain text email instead
of html and even better to not auto wrap lines? That would make
reading dbg output much easier.

On Fri, Feb 01, 2013 at 11:58:51AM +0100, Bert Willaert wrote:
> On Thu, Jan 31, 2013 at 1:04 PM, Markus Klotzbuecher
> <markus [dot] klotzbuecher [..] ...> wrote:
>
> On Thu, Jan 31, 2013 at 11:45:23AM +0100, Bert Willaert wrote:
> >
> >
> >
> > On Thu, Jan 31, 2013 at 10:36 AM, Markus Klotzbuecher <
> > markus [dot] klotzbuecher [..] ...> wrote:
> >
> > On Thu, Jan 31, 2013 at 09:31:46AM +0100, Bert Willaert wrote:
> > > Hi,
> > >
> > > I made already a simple example on the use of the await plugin and
> then
> > > everything seemed to work fine. Now I want to go to the next state
> when
> > two
> > > motion_generators finished their 'moveTo' command.
> > >
> > > In the code I have:
> > >
> > > move_to_start = state{
> > > entry = function() ... end,
> > > exit = function()
> > > -- for debugging --
> > > print(rttlib.port_clone_conn(motionGen1:getPort
> > > ("events")):read())
> > > print(rttlib.port_clone_conn(motionGen2:getPort
> > > ("events")):read())
> > > end,
> > > },
> > >
> > >
> > > trans { src='move_to_start', tgt='follow_traj',
> events={"await
> > > (e_motionGen1_move_finished,e_motionGen2_move_finished)"},
> guard=function
> > ()
> > > return moveToStartAccepted end },
> > >
> > > The transition is done however when only one motion_generator has
> > finished:
> > > taskbrowser output:
> > >
> > > NewData e_motionGen1_move_started
> > > NewData e_motionGen2_move_finished
> > > Global_Coordinator: STATE_EXIT root.AllReady.move_to_start
> > > Global_Coordinator: STATE_ENTER root.AllReady.follow_traj
> > >
> > >
> > > What could be the problem? Can await be combined with a guard?
> >
> > It can, but there was silly bug that caused the guard to be
> > ignored. Please pull for a fix.
> >
> >
> > I did a pull of the rFSM dev branch but I still have the same problem...
>
> Ok.
> > That said, I'm not sure this is the cause of your problem. The output
> > of your print's will not be very reliable, because you are creating
> > the connections on the fly in exit, thus after you have received the
> > events you want to print. It would be better to create these
> > connections earlier and only once.
> >
> >
> > I was actually doing this but to make the code shorter in the mail I wrote
> it
> > like that ( which can only lead to misunderstandings, so I won't do that
> again
> > ;))
>
> Yes, please :)
> > local p1 = rttlib.port_clone_conn(motionGen1:getPort("events"))
> > local p2 = rttlib.port_clone_conn(motionGen2:getPort("events"))
> >
> > return state {
> >
> > move_to_start= state {
> > exit = function() print(p1:read()) print(p2:read()) end,
> > },
> >
>
> The FSM could still transition *before* you see the event on the other
> port. I would suggest that you enable FSM debugging (e.g. as in the
> await example) so we can check whether both events are actually
> received or not.
>
>
> await: RAISED e_done [..] ...uring
> await: STATE_ENTER root.AllReady.configuring
> await: STATE_EXIT root.AllReady.configuring
> await: EFFECT T={ src='root.AllReady.configuring',
> tgt='root.AllReady.move_to_start', events='{}' }
> pos_start :
> {2.122013,0.788564,-0.549975,-1.420228,-2.701632,-1.056217,1.486454}
> pos_start :
> {1.122013,0.788564,-0.549975,-1.420228,-2.701632,-1.056217,1.486454}
> await: RAISED e_done [..] ..._to_start
> await: STATE_ENTER root.AllReady.move_to_start
> 27.714 [ Warning][Logger] FINISHED
> NewData e_motionGen1_move_started
> NewData e_motionGen2_move_finished
> await: STATE_EXIT root.AllReady.move_to_start
> await: EFFECT T={ src='root.AllReady.move_to_start',
> tgt='root.AllReady.follow_traj', events='await(e_motionGen1_move_finished,
> e_motionGen2_move_finished), e_motionGen1_move_finished,
> e_motionGen2_move_finished' }
> await: RAISED e_done [..] ..._traj
> await: STATE_ENTER root.AllReady.follow_traj
> In the naxes_motion_control/src/nAxesGeneratorPos.cpp file I added the following
> line at the place the event is sent:
>
> // send move_finished_event (once)
> event_port.write(move_finished_event);
> ++ log(Warning)<<"FINISHED" <<endlog();
>
> So only one warning in the taskbrowser, which shows that only one of the two
> motionGenerators is finished already. Still the await dbg info indicates that
> both events have been received, no?

Why do you think so? I don't see any "RAISED e_motionGen[12]_move_finished"

at all, so I'm wondering why this transition happens at all.

Markus

rfsm_await

On Fri, Feb 01, 2013 at 01:11:23PM +0100, Markus Klotzbuecher wrote:
...

> Why do you think so? I don't see any "RAISED e_motionGen[12]_move_finished"
>
> at all, so I'm wondering why this transition happens at all.

For the record, it was a bug in await which is fixed on both master
and dev.

Markus

rfsm_await

On Fri, Feb 1, 2013 at 7:27 PM, Markus Klotzbuecher
<markus [dot] klotzbuecher [..] ...> wrote:
> On Fri, Feb 01, 2013 at 01:11:23PM +0100, Markus Klotzbuecher wrote:
> ...
>
>> Why do you think so? I don't see any "RAISED e_motionGen[12]_move_finished"
>>
>> at all, so I'm wondering why this transition happens at all.
>
> For the record, it was a bug in await which is fixed on both master
> and dev.

Isn't it about time to have a basic unit test suite for rfsm and its
extensions ?

Peter

rfsm_await

On Fri, Feb 01, 2013 at 09:36:11PM +0100, Peter Soetens wrote:
> On Fri, Feb 1, 2013 at 7:27 PM, Markus Klotzbuecher
> <markus [dot] klotzbuecher [..] ...> wrote:
> > On Fri, Feb 01, 2013 at 01:11:23PM +0100, Markus Klotzbuecher wrote:
> > ...
> >
> >> Why do you think so? I don't see any "RAISED e_motionGen[12]_move_finished"
> >>
> >> at all, so I'm wondering why this transition happens at all.
> >
> > For the record, it was a bug in await which is fixed on both master
> > and dev.
>
> Isn't it about time to have a basic unit test suite for rfsm and its
> extensions ?

We have have a rudimentary framework (see under tests/ ), but "await"
is not yet tested.

Markus

rfsm_await

Op zaterdag 2 februari 2013 schreef Markus Klotzbuecher (
markus [dot] klotzbuecher [..] ...) het volgende:

> On Fri, Feb 01, 2013 at 09:36:11PM +0100, Peter Soetens wrote:
> > On Fri, Feb 1, 2013 at 7:27 PM, Markus Klotzbuecher
> > <markus [dot] klotzbuecher [..] ... > > > On Fri, Feb 01, 2013 at 01:11:23PM +0100, Markus Klotzbuecher wrote:
> > > ...
> > >
> > >> Why do you think so? I don't see any "RAISED
> e_motionGen[12]_move_finished"
> > >>
> > >> at all, so I'm wondering why this transition happens at all.
> > >
> > > For the record, it was a bug in await which is fixed on both master
> > > and dev.
> >
> > Isn't it about time to have a basic unit test suite for rfsm and its
> > extensions ?
>
> We have have a rudimentary framework (see under tests/ ), but "await"
> is not yet tested.

Test -> code -> refactor

>
> Markus
>

Peter