reworking OCL / best practice examples

Dear List,

OCL (the OROCOS Component Library) was mentioned in the ongoing
discussions several times for documenting good ways to solve problems,
i.e. best practices.

As this is one of my course assignments, I'd like to start some
discussion on how this should be done.

What we want is some good examples which are well documented and show
how to solve some common problems. They should run without specific
hardware and involve the cartesian and naxes components.

The question is, should these example reside within OCL or be a new
higher-level subproject, e.g. BPL (best practices library?)

Suggestions are welcome

Markus

reworking OCL / best practice examples

> And why those values are removed from the HALs ? Because they are not generic
> enough. I.e. I always have the feeling that HALs are the interface of the less
> powerful devices and less powerful approaches out there. If you want anything
> more advanced, you have to use something different.
>

What I personally would do (actually, what I am going to do, to make
it available to the community) is an "union" instead of an
"intersection" of features.

The Abstract Device Interface (ADI) is a template which should cover
as many devices as possible.
Imagine it like this:

- device from manufacturer X has features A-B-C-D
- device from manufacturer Y has features B-C-D-E
- the ADI should have an interface A-B-C-D-E-F (the union of several
common devices)
- the user components needs features B-C-E. It will explore the
interface of the device component using RTT. It will work properly
with device Y and it will be able to work with device X only if
feature E is not mandatory.

The ADI makes people which develop device components and people which
use such components free to do "their best" to satisfy each other.
Remember: the device component is the one who provide an interface and
it has not dependency from other components, while the user component
is the one that explore an existing interface to see if its
requirements are satisfied (but which requirements are "plausible"?
Those indicated in the ADI).

The solution is back compatible. When a new feature is introducer in a
device, you add a new feature to the ADI, so the "old components" are
still working but they miss the new feature.

Davide

reworking OCL / best practice examples

On Mon, 4 May 2009, Davide Faconti wrote:

>> And why those values are removed from the HALs ? Because they are not generic
>> enough. I.e. I always have the feeling that HALs are the interface of the less
>> powerful devices and less powerful approaches out there. If you want anything
>> more advanced, you have to use something different.
>>
>
> What I personally would do (actually, what I am going to do, to make
> it available to the community) is an "union" instead of an
> "intersection" of features.
>
> The Abstract Device Interface (ADI) is a template which should cover
> as many devices as possible.
> Imagine it like this:
>
> - device from manufacturer X has features A-B-C-D
> - device from manufacturer Y has features B-C-D-E
> - the ADI should have an interface A-B-C-D-E-F (the union of several
> common devices)

I would not go this way! Interfaces should be as small as possible, and be
"aggregated" [1]in case more complex ones are needed. Making the "most
aggregated" version the default requires too many "not implemented" or "not
relevant" kind of reconfiguration...
[1] <http://en.wikipedia.org/wiki/Object_composition#Aggregation>

> - the user components needs features B-C-E. It will explore the
> interface of the device component using RTT. It will work properly
> with device Y and it will be able to work with device X only if
> feature E is not mandatory.

This is a good use case when you talk about "services", but I don't like it
for "components": there you want your components to be able to be used to
their full potential in the system you built.

> The ADI makes people which develop device components and people which
> use such components free to do "their best" to satisfy each other.
> Remember: the device component is the one who provide an interface and
> it has not dependency from other components, while the user component
> is the one that explore an existing interface to see if its
> requirements are satisfied (but which requirements are "plausible"?
> Those indicated in the ADI).
>
> The solution is back compatible. When a new feature is introducer in a
> device, you add a new feature to the ADI, so the "old components" are
> still working but they miss the new feature.

That's the reason why "aggregation" exists :-) Your suggestion requires a
new version of the "ADI standard"; my approach adds another (small) standard.

Herman

reworking OCL / best practice examples

>> - device from manufacturer X has features A-B-C-D
>> - device from manufacturer Y has features   B-C-D-E
>> - the ADI should have an interface A-B-C-D-E-F (the union of several
>> common devices)
>
> I would not go this way! Interfaces should be as small as possible, and be
> "aggregated" [1]in case more complex ones are needed. Making the "most
> aggregated" version the default requires too many "not implemented" or "not
> relevant" kind of reconfiguration...
> [1] <http://en.wikipedia.org/wiki/Object_composition#Aggregation>
>

Aggregation seems to be an interesting pattern. I have to better look at it.

>> - the user components needs  features B-C-E. It will explore the
>> interface of the device component using RTT. It will work properly
>> with device Y and it will be able to work with device X only if
>> feature E is not mandatory.
>
> This is a good use case when you talk about "services", but I don't like it
> for "components": there you want your components to be able to be used to
> their full potential in the system you built.

I see what you mean but, as you said few days ago, we need the
components to know as little as possible about each other (I hope I
understood correctly what you meant! ).

If a certain component MISS a feature (recommended in the ADI), it is
because we can't do nothing about it (try to limit the motor current
on a driver that does not support such feature)!
The user of that interface should see what is provided and which are
its own requirement to be functional (the kinematic controller might
want to limit the current, but can still give a path if such feature
is not present).
You will always try to provide as many services as possible and, on
the other side, to use has many as given.

I guess that the difference between "service" and "component" is that
a service (like an HAL of a sensor), provides an almost 1-way
communication. Of course, the user can set some parameters or need to
do some initialization, but conceptually 1 is the producer of the data
and the other the user.
I guess that component has a 2-way interface. Can you give me an
example of what is for you a component and what is a service?

reworking OCL / best practice examples

On Mon, 4 May 2009, Davide Faconti wrote:

>>> - device from manufacturer X has features A-B-C-D
>>> - device from manufacturer Y has features   B-C-D-E
>>> - the ADI should have an interface A-B-C-D-E-F (the union of several
>>> common devices)
>>
>> I would not go this way! Interfaces should be as small as possible, and be
>> "aggregated" [1]in case more complex ones are needed. Making the "most
>> aggregated" version the default requires too many "not implemented" or "not
>> relevant" kind of reconfiguration...
>> [1] <http://en.wikipedia.org/wiki/Object_composition#Aggregation>
>>
>
> Aggregation seems to be an interesting pattern. I have to better look at it.
>
>>> - the user components needs  features B-C-E. It will explore the
>>> interface of the device component using RTT. It will work properly
>>> with device Y and it will be able to work with device X only if
>>> feature E is not mandatory.
>>
>> This is a good use case when you talk about "services", but I don't like it
>> for "components": there you want your components to be able to be used to
>> their full potential in the system you built.
>
> I see what you mean but, as you said few days ago, we need the
> components to know as little as possible about each other (I hope I
> understood correctly what you meant! ).
>
You did! :-)

But there is a difference between "not knowing about each other but knowing
which interface to use" and "not knowing about each other and not even
knowing what interface to use". This "interface discovery" is typically the
difference between component-based and service-oriented systems. The third
category, object-oriented systems, assume you know both the interface and
the communication partner".

All three levels are relevant, but Orocos wants to provide the middle
level only (for the time being).

> If a certain component MISS a feature (recommended in the ADI), it is
> because we can't do nothing about it (try to limit the motor current
> on a driver that does not support such feature)!
> The user of that interface should see what is provided and which are
> its own requirement to be functional (the kinematic controller might
> want to limit the current, but can still give a path if such feature
> is not present).

That is not the way you build _systems_ that you want to fully and
deterministically control: I am quite sure you are quite sure what hardware
your humanoids have... :-)

> You will always try to provide as many services as possible and, on
> the other side, to use has many as given.
That's again a _policy_, which is not at all a given in all use cases...

> I guess that the difference between "service" and "component" is that
> a service (like an HAL of a sensor), provides an almost 1-way
> communication.
Not really. I'm talking about services in the sense of "Corba 3.0", and
"service oriented architectures" on the Web.

> Of course, the user can set some parameters or need to
> do some initialization, but conceptually 1 is the producer of the data
> and the other the user.
That's what _all_ three levels have in common; the difference is about how
to connect producer and user.

> I guess that component has a 2-way interface. Can you give me an
> example of what is for you a component and what is a service?

Components = Orocos TaskContext
Service = Google

Herman

reworking OCL / best practice examples

Actually, now that I thought of it, my point of view for that problem was the
following:

- in the way I worked at LAAS (and still view the functional layer), the only
interaction between modules is the data flow. This has the important
property that "as long as I can plug one output port to one input port, I
have two compatible components". No need for complex modelling in the C++
side (still, it is nice to have modeling tools on the deployment side).
- I developed (and still use) a supervision system that has the flexibility to
allow me to easily wrap incompatible components so that they appear the
same way from the supervision point of view without the need of having the
components themselves do it. Of course, this flexibility has a price (in my
case, RT-ness).

I personally think that the solution you talk about is an over-complex one.

Could you explain the rationale of why you think you need something that
complex ?

reworking OCL / best practice examples

On Mon, 4 May 2009, Sylvain Joyeux wrote:

> Actually, now that I thought of it, my point of view for that problem was the
> following:
>
> - in the way I worked at LAAS (and still view the functional layer), the only
> interaction between modules is the data flow.

Strange... no need for 'events' of any kind? Albeit only for
reconfiguration or error state communication...

Herman

> This has the important
> property that "as long as I can plug one output port to one input port, I
> have two compatible components". No need for complex modelling in the C++
> side (still, it is nice to have modeling tools on the deployment side).
> - I developed (and still use) a supervision system that has the flexibility to
> allow me to easily wrap incompatible components so that they appear the
> same way from the supervision point of view without the need of having the
> components themselves do it. Of course, this flexibility has a price (in my
> case, RT-ness).
>
> I personally think that the solution you talk about is an over-complex one.
>
> Could you explain the rationale of why you think you need something that
> complex ?

reworking OCL / best practice examples

> > - in the way I worked at LAAS (and still view the functional layer), the
> > only interaction between modules is the data flow.
>
> Strange... no need for 'events' of any kind? Albeit only for
> reconfiguration or error state communication...
Nope. That's taken care of by the supervision system. Of course, the
supervision system *does* have other means of communication with the modules
(events, "requests" (i.e. commands)).

reworking OCL / best practice examples

On May 4, 2009, at 08:38 , Davide Faconti wrote:

>>
>> What we want is some good examples which are well documented and show
>> how to solve some common problems. They should run without specific
>> hardware and involve the cartesian and naxes components.
>>
>
> Well, I would not be so restrictive about it.
> For example, we can contribute with a "design pattern" that we use
> very often of Hardware Abstract Layer for sensors (laser, gyroscopes,
> force sensors, etc).
> And it is not related to motion control (directly)
>
>> The question is, should these example reside within OCL or be a new
>> higher-level subproject, e.g. BPL (best practices library?)
>>
>
> Personally, I think that we need something very common in other
> framework such as Player or Orca2, which is a Abstract Device
> Interface.
>
> robotics.stanford.edu/~gerkey/research/final_papers/iros03-
> abstraction.pdf
>
> Forgetting about names (OCL,BFL,HDNAYCBSO, ..) what we might need is:
>
> 1) The Abstract Device Interface definition.
> 2) Design Pattern (or best practice if you prefer) repository. Just
> example with didactic purpose.
> 3) Ready to run reusable components, some of them Hardware dependent
> (it MUST use section 1) as dependency and be "inspired" bu section 2)
> ).
> 4) a set of tools to make the life of the Orocos user easier. They
> will be hardware and application __independent__ (Deployment,
> Reporting, TaskBrowser, Viewer, etc).
>
> Right now, the OCL includes groups 3 and 4.
>
> What do you think?

I'm not sure about the Abstract Device bit (haven't read the
referenced paper), but I think I agree with Davide in general. Keep
the useful tools in OCL, and then do a different section that contains
"better practics" or "design patterns" or whatever. Prevents us
accidentally coupling them together.
S