Bufferports with large buffer

Hello all,

I am using the orocos BufferPort class to do some sequential calculations for
trajectory generation.
Basically, I have three components:
- a path generator.
- a component which does some inverse kinematics and calculates a bunch of
dynamic quantities.
- a component which calculates a time-optimal trajectory along the path.

Each of these components uses information from the component one level up
and they pass data using bufferports. The reason for this is to allow a sort
of recursive approach is to do on-line trajectory generation with as little
delay as possible (I don't want to wait until the path is completely
generated, but start optimizing the trajectory based on the available data).

Now, I am using buffers which block on reading (if no data available there is
nothing meaningful the components can do anyway), but which do not block on
writing.

As a result, it seems I have to make the size of the buffers as large as the
maximum amount of data I plan to send through the buffers (usually about 2000
18-dimensional vectors of doubles).

However, in practice, "probably" the buffers will never be completely filled,
since the components add and remove the data
at a more or less similar speed.
Does anyone know how this is actually implemented in Orocos? How many
(internal) copies of the buffers does Orocos use? Does it copy the entire
buffer (even if not full) multiple times or only the filled part?
Is size an issue here (I am talking about about approximately 3 buffers with
2000 18-dimensional vectors of doubles)

Are there better ways to do this?

I have considered using buffers of size 1 and have them block on reading and
writing. However, this seems less efficient (e.g. if the inverse kinematics
takes a lot of time, there is no point in waiting with these calculations,
until the trajectory optimization starts processing).

Thanks!
Best regards,

Diederik

Bufferports with large buffer

Hi Diederik,

On Monday 23 June 2008 12:37:40 Diederik Verscheure wrote:
> As a result, it seems I have to make the size of the buffers as large as
> the maximum amount of data I plan to send through the buffers (usually
> about 2000 18-dimensional vectors of doubles).
>
> However, in practice, "probably" the buffers will never be completely
> filled, since the components add and remove the data
> at a more or less similar speed.
> Does anyone know how this is actually implemented in Orocos? How many
> (internal) copies of the buffers does Orocos use? Does it copy the entire
> buffer (even if not full) multiple times or only the filled part?

It only copies the 'used' part, but space is allocated for about 2*8*2000*18
doubles. That's over 2MB for each buffer. So in your case, you could use a
BufferLocked, which uses 1*2000*18 doubles (16 times less). Unfortunately, it
seems the BufferLocked is not supporting blocking reads or writes. That's a
missing feature... You could create your own blocking buffer class with
BufferLocked as a starting point and inspired by the BufferLockFree to do the
blocking part.

You can assign at any time a new buffer to a port or connection by writing in
your component

myport = new BufferLocked< std::vector >(2000);

Peter

Bufferports with large buffer

Hi Peter,

maybe one more question.
>
> You can assign at any time a new buffer to a port or connection by writing
> in your component
>
> myport = new BufferLocked< std::vector >(2000);
>

If I want to switch to a BufferLocked, do I need to carry out the above both
on the ReadBufferPort (which I use in one component) and the WriteBufferPort
(which I use in the other component, and which ends up being connected to the
ReadBufferPort)?
Thanks!

Diederik

> Peter
>
> --
> Peter Soetens -- FMTC --

Bufferports with large buffer

On Monday 23 June 2008 15:44:54 Diederik Verscheure wrote:
> Hi Peter,
>
> maybe one more question.
>
> > You can assign at any time a new buffer to a port or connection by
> > writing in your component
> >
> > myport = new BufferLocked< std::vector >(2000);
>
> If I want to switch to a BufferLocked, do I need to carry out the above
> both on the ReadBufferPort (which I use in one component) and the
> WriteBufferPort (which I use in the other component, and which ends up
> being connected to the ReadBufferPort)?

It does not matter. If both ports are already connected to each other, they
share the same, single connection, and the assignment can be done from either
port. It will force the connection to use the new object.
If they are not yet connected, the assignment may only be done to one port,
and the other port must be connected to this port. If done on both
unconnected ports, both would have a different connection and Orocos would
not find a way to 'merge' them. You can not connect two already connected
ports.

Peter

Bufferports with large buffer

Hi Peter,

It's good to know what is going on under the hood.
I guess if only the used part is copied, the overhead might not be that big
(time-wise, which I consider most important for this particular application),
and as long as there is no problem memory-wise (which I will find out soon) it
is OK.

Strictly speaking, I do not absolutely need a blocking buffer
(I could also do nothing when buffer.empty() == true).
But somehow, blocking seemed more elegant (and efficient?).

Anyway, thanks. I'll try out different things (lockfree and locking buffer,
with and without blocking) and see which works best for my case.

Best regards,
Diederik

On Monday 23 June 2008 14:29:51 Peter Soetens wrote:
> Hi Diederik,
>
> On Monday 23 June 2008 12:37:40 Diederik Verscheure wrote:
> > As a result, it seems I have to make the size of the buffers as large as
> > the maximum amount of data I plan to send through the buffers (usually
> > about 2000 18-dimensional vectors of doubles).
> >
> > However, in practice, "probably" the buffers will never be completely
> > filled, since the components add and remove the data
> > at a more or less similar speed.
> > Does anyone know how this is actually implemented in Orocos? How many
> > (internal) copies of the buffers does Orocos use? Does it copy the entire
> > buffer (even if not full) multiple times or only the filled part?
>
> It only copies the 'used' part, but space is allocated for about
> 2*8*2000*18 doubles. That's over 2MB for each buffer. So in your case, you
> could use a BufferLocked, which uses 1*2000*18 doubles (16 times less).
> Unfortunately, it seems the BufferLocked is not supporting blocking reads
> or writes. That's a missing feature... You could create your own blocking
> buffer class with BufferLocked as a starting point and inspired by the
> BufferLockFree to do the blocking part.
>
> You can assign at any time a new buffer to a port or connection by writing
> in your component
>
> myport = new BufferLocked< std::vector >(2000);
>
> Peter
>
> --
> Peter Soetens -- FMTC --

Met vriendelijke groeten,

Diederik