[Bug 354] New: update() of taskcontext executed too often

For more information about this bug, visit
A new bug was added:
Summary: update() of taskcontext executed too often
Product: RTT
Version: orocos-trunk
Platform: All
OS/Version: All
Status: NEW
Severity: normal
Priority: P2
Component: Real-Time Toolkit (RTT)
AssignedTo: orocos-dev [..] ...
ReportedBy: wim [dot] meeussen [..] ...

The external interface of an Orocos component is defined by the methods,
commands, events, etc of its TaskContext. Internally, the "task" of of an
Orocos component is executed in the update() function of the TaskContext. The
internal task execution of a component should be independent of the external
interface of the component. In the current implementation however, the update()
function is executed at the wrong times.

What I would expect is that update() is only executed when it is triggered by
the activity of the TaskContext: in case of a PeriodicActivity update() is
executed periodically, in case of an event based activity update() is executed
every time an event is emitted. In the current implementation however,
update() is also called every time a command is invoked on the component, and
also when the component is started.

I see this as an important fix for the 1.2 release.

Wim

[Bug 354] update() of taskcontext executed too often

For more information about this bug, visit
A comment was added:
------- Comment #7 from peter [dot] soetens [..] ... 2007-03-11 22:07

(In reply to comment #5)
> The current implementation works indeed very well for periodic tasks, and the
> proposed changes do not affect the behavior of update in periodic tasks. Only
> for nonperiodic tasks the update function behaves in a strange way.
>
>
> > I think an asynchonious event is
> > paractically designed for what you want. Just create a new event, connect an
> > asynchronious callback to it and call this event explicitly.
>
> That is a solution that works. But then the question is: why would you even
> have an update function in a nonperiodic activity? And if you have one, how
> should it behave?

In my opinion, it is the task of update() to check if useful work needs to be
done, when it is called. You do this already when you process a command: the
command function is executed once, and update() takes over if further steps
need to be taken. This is an approach that works for periodic and non periodic
components.

So again in my opinion, it is your job to find out in update() if an event or a
command, or whatever happend and what actions to take. Read update() as: 'the
state of the component may have changed, do whatever necessary.'

Peter

[Bug 354] update() of taskcontext executed too often

For more information about this bug, visit
A comment was added:
------- Comment #6 from herman [dot] bruyninckx [..] ... 2007-03-08 13:58

(In reply to comment #5)

> The current implementation works indeed very well for periodic tasks, and the
> proposed changes do not affect the behavior of update in periodic tasks. Only
> for nonperiodic tasks the update function behaves in a strange way.
>
>
> > I think an asynchonious event is
> > paractically designed for what you want. Just create a new event, connect an
> > asynchronious callback to it and call this event explicitly.
>
> That is a solution that works. But then the question is: why would you even
> have an update function in a nonperiodic activity? And if you have one, how
> should it behave?
>

I think this is indeed the core of the current discussion: what we think is
necessary as a feature in RTT is already there in one particular way
(asynchronous event), so the question to be answered is as above: does update()
remain as a generically available part of any Activity, or is its semantics too
much linked with the PeriodicActivity so that it should only appear there?

I now tend to the latter "solution", but I cannot say well enough why...

wmeeusse's picture

[Bug 354] update() of taskcontext executed too often

For more information about this bug, visit
A comment was added:
------- Comment #5 from wim [dot] meeussen [..] ... 2007-03-08 12:51

> I'm verry happy with the current implementation. We generaly use the update
> method for periodically evaluating stuff in a component. So we realy don't
> want to 'call update explicitly'.

> Changing the behaviour of update will break the api and should not be done if
> there is no other (clean) way to do what you want.

The current implementation works indeed very well for periodic tasks, and the
proposed changes do not affect the behavior of update in periodic tasks. Only
for nonperiodic tasks the update function behaves in a strange way.

> I think an asynchonious event is
> paractically designed for what you want. Just create a new event, connect an
> asynchronious callback to it and call this event explicitly.

That is a solution that works. But then the question is: why would you even
have an update function in a nonperiodic activity? And if you have one, how
should it behave?

[Bug 354] update() of taskcontext executed too often

For more information about this bug, visit
A comment was added:
------- Comment #4 from sander [dot] vandenbroucke [..] ... 2007-03-08 11:52

(In reply to comment #2)
> I don't think this is the behaviour we want. We do not want to trigger the
> update() function when a command or event arrives. The update() function should
> only be executed when told so, not when a command or event arrives. So
> basically we want to listen to commands or events all the time, when one comes
> in, executed the proper piece of code but do not execute the update() function.
> Unless I explicitly call for it.
I'm verry happy with the current implementation. We generaly use the update
method for periodically evaluating stuff in a component. So we realy don't want
to 'call update explicitly'. I think an asynchonious event is paractically
designed for what you want. Just create a new event, connect an asynchronious
callback to it and call this event explicitly.

Changing the behaviour of update will break the api and should not be done if
there is no other (clean) way to do what you want.

Sander.

wmeeusse's picture

[Bug 354] update() of taskcontext executed too often

For more information about this bug, visit
A comment was added:
------- Comment #3 from wim [dot] meeussen [..] ... 2007-03-08 11:14

> I don't see a case where you start() a NonPeriodicActivity, but don't want
> update() to be called. You could then just invent a TaskContext method
> 'warmup()' and only call 'start()' if you want update to be called as well.
> But it seems to me that your need comes from a very specific component usage
> or implementations. Feel free to clarify your case.

Think about a component with a nonperiodic activity. The activity is triggered
by an external event, where the event for example tells the component that
there is data available on a port. Every time the event is fired, the update()
function is called, and reads this data from the port. At some point I want to
start my component, so it will start reacting on the external event (if the
component is not started, it will not react on the event). However, when I
start the component, there is no data available on the port, so the update
function should not be called yet. The start should just indicate that the
component is ready to receive events, but should not indicate that the
component should execute the code that is normally executed when an event is
fired.

Wim

Ruben Smits's picture

[Bug 354] update() of taskcontext executed too often

For more information about this bug, visit
A comment was added:
------- Comment #2 from ruben [dot] smits [..] ... 2007-03-08 09:55

(In reply to comment #1)
> (In reply to comment #0)
> ...
> > The
> > internal task execution of a component should be independent of the external
> > interface of the component. In the current implementation however, the update()
> > function is executed at the wrong times.
> >
> > What I would expect is that update() is only executed when it is triggered by
> > the activity of the TaskContext: in case of a PeriodicActivity update() is
> > executed periodically, in case of an event based activity update() is executed
> > every time an event is emitted. In the current implementation however,
> > update() is also called every time a command is invoked on the component, and
> > also when the component is started.
> >
> > I see this as an important fix for the 1.2 release.
>
> The only way to get new behaviour into the 1.x releases is by creating new
> classes or functions. Exceptions to this is when the behaviour is a bug or does
> not behave as specified, but that's not the case here. However, I understand
> that your needs come from day-to-day experiences with Orocos, which means
> something.
>
> What we can do is to configure the ExecutionEngine such that the user may
> decide if the EE 'triggers' the activity when an event or command arrives. It
> does now, but if you disable this behaviour, commands and events are only
> processed just before update() is called, and you as a user decide this by
> calling ActivityInterface::trigger(). In this case, the NonPeriodicActivity
> remains as-is.

I don't think this is the behaviour we want. We do not want to trigger the
update() function when a command or event arrives. The update() function should
only be executed when told so, not when a command or event arrives. So
basically we want to listen to commands or events all the time, when one comes
in, executed the proper piece of code but do not execute the update() function.
Unless I explicitly call for it.

> That doesn't handle your TaskContext::update() upon start() case yet. However,
> I don't see a case where you start() a NonPeriodicActivity, but don't want
> update() to be called.

We call start when we want to start listen for Commands or Events.

>You could then just invent a TaskContext method
> 'warmup()' and only call 'start()' if you want update to be called as well. But
> it seems to me that your need comes from a very specific component usage or
> implementations. Feel free to clarify your case.
>
> Peter
>

[Bug 354] update() of taskcontext executed too often

For more information about this bug, visit
A comment was added:
------- Comment #1 from peter [dot] soetens [..] ... 2007-03-08 09:40

(In reply to comment #0)
...
> The
> internal task execution of a component should be independent of the external
> interface of the component. In the current implementation however, the update()
> function is executed at the wrong times.
>
> What I would expect is that update() is only executed when it is triggered by
> the activity of the TaskContext: in case of a PeriodicActivity update() is
> executed periodically, in case of an event based activity update() is executed
> every time an event is emitted. In the current implementation however,
> update() is also called every time a command is invoked on the component, and
> also when the component is started.
>
> I see this as an important fix for the 1.2 release.

The only way to get new behaviour into the 1.x releases is by creating new
classes or functions. Exceptions to this is when the behaviour is a bug or does
not behave as specified, but that's not the case here. However, I understand
that your needs come from day-to-day experiences with Orocos, which means
something.

What we can do is to configure the ExecutionEngine such that the user may
decide if the EE 'triggers' the activity when an event or command arrives. It
does now, but if you disable this behaviour, commands and events are only
processed just before update() is called, and you as a user decide this by
calling ActivityInterface::trigger(). In this case, the NonPeriodicActivity
remains as-is.
That doesn't handle your TaskContext::update() upon start() case yet. However,
I don't see a case where you start() a NonPeriodicActivity, but don't want
update() to be called. You could then just invent a TaskContext method
'warmup()' and only call 'start()' if you want update to be called as well. But
it seems to me that your need comes from a very specific component usage or
implementations. Feel free to clarify your case.

Peter