Support more than 180? rotations

We're interested in modifying KDL to support more than 180? rotations, and not have them wrap around. So from 0? to +270? is +270? travel, and not -90? travel.

I see two possible general approaches

1) modify some of the existing diff() type functions to add extra logic to deal with this. This changes existing behavior, but doesn't grow the API.

2) add new diff()-type functions to deal explicitly with long rotations. This won't break any existing code, but grows the API.

At this point we're only interested in preventing the +/-180? wrap around behaviour. Components like the OCL trajectory generators could then easily be changed (on a site-by-site basis if necessary) to use the new diff(), for robots that do support more than 360? of rotation.

Thoughts?
S

Support more than 180? rotations

On 06/25/2012 12:43 PM, S Roderick wrote:
> We're interested in modifying KDL to support more than 180? rotations,
> and not have them wrap around. So from 0? to +270? is +270? travel, and not -90? travel.
diff() deals with the angle between two poses ("Frame"s in KDL) (let's
call this "spacial angles", for now). This is different from
the joint angles you take about here. For joint angles, -90 is
different from +270.

The output of diff() will always result in an angle between 0 and 180.
>
> I see two possible general approaches
>
> 1) modify some of the existing diff() type functions to add extra logic to deal with this. This changes existing behavior, but doesn't grow the API.
For the reasons described above, this is not possible.
>
> 2) add new diff()-type functions to deal explicitly with long rotations. This won't break any existing code, but grows the API.
>
> At this point we're only interested in preventing the +/-180? wrap around behaviour. Components like the OCL trajectory generators could then easily be changed (on a site-by-site basis if necessary) to use the new diff(), for robots that do support more than 360? of rotation.
We're interested in this type of functionality, but, at least for me, it
is not yet completely clear how to handle this.
It is more then a littlle bit of extra logic, and it will have its
impact on the whole robot application.

Perhaps I first explain how this is solved in a typical industrial robot
controller:
1) Frame does not contain enough information to distinguish between
-90 and 270 degrees, since it describes nothing more than the pose.
2) Sometimes a robot has joints that have more then 360 degrees
travel for one or more joints.
3) People want to specify the motion in Cartesian space.
4) The difference between _joint angle_ -90 or 270 degrees is not
part of the Cartesian space specification, it is part of the description
of the robot state.
Pure Cartesian space specification is not sufficient.
5) Extend the description of a pose with some binary flags indicating
the "wind-up" state of each joint. ( mostly only for one or two joints)
6) In the trajectory generator, do some planning that takes into
account the "wind-up" state of the joints and the range of motion of the
joints
to determine the trajectory to be followed.
7) The wind-up state is passed at each sample time to the inverse
kinematics.

The conclusions I make from this:
- The wrapping problem is not a diff() problem, it is a trajectory
generator problem.
- The trajectory generator needs a lot of specific knowledge such
as joint limits,
wind-up state. This wind-up state needs to be passed to the
inverse position kinematics.
- I think it somewhere belongs in new class of type
Rotational_Interpolation. However, currently, the API of the traj. gen.
classes is
not sufficient to pass all this extra information.

So, the options are:
- avoid the problem in KDL ( and dump it on the application developer
:( ) by imposing angles < 180 degrees
(this is what currently is done in KDL).
- implement a scheme similar to the above.
- ...

Best regards,

Erwin

> Thoughts?
> S

Support more than 180? rotations

On Jun 25, 2012, at 08:00 , Erwin Aertbelien wrote:

> On 06/25/2012 12:43 PM, S Roderick wrote:
>> We're interested in modifying KDL to support more than 180? rotations,
>> and not have them wrap around. So from 0? to +270? is +270? travel, and not -90? travel.
> diff() deals with the angle between two poses ("Frame"s in KDL) (let's call this "spacial angles", for now). This is different from
> the joint angles you take about here. For joint angles, -90 is different from +270.
>
> The output of diff() will always result in an angle between 0 and 180.

Actually, you and Herman both assume this is a joint-space robot. It's a cartesian-space robot (stewart platform) capable of 720? of travel in one axes (around the vertical). Though the problem is fundamentally the same for each situation.

>> I see two possible general approaches
>>
>> 1) modify some of the existing diff() type functions to add extra logic to deal with this. This changes existing behavior, but doesn't grow the API.
> For the reasons described above, this is not possible.
>>
>> 2) add new diff()-type functions to deal explicitly with long rotations. This won't break any existing code, but grows the API.
>>
>> At this point we're only interested in preventing the +/-180? wrap around behaviour. Components like the OCL trajectory generators could then easily be changed (on a site-by-site basis if necessary) to use the new diff(), for robots that do support more than 360? of rotation.
> We're interested in this type of functionality, but, at least for me, it is not yet completely clear how to handle this.
> It is more then a littlle bit of extra logic, and it will have its impact on the whole robot application.

Perhaps ...

> Perhaps I first explain how this is solved in a typical industrial robot controller:
> 1) Frame does not contain enough information to distinguish between -90 and 270 degrees, since it describes nothing more than the pose.
> 2) Sometimes a robot has joints that have more then 360 degrees travel for one or more joints.

Even those with 190? of travel can have the same problem (say -95 to +95). Move from 0 to -95, ok. Then move to +95, bad - robot tries to go through hard stop.

> 3) People want to specify the motion in Cartesian space.
> 4) The difference between _joint angle_ -90 or 270 degrees is not part of the Cartesian space specification, it is part of the description of the robot state.
> Pure Cartesian space specification is not sufficient.
> 5) Extend the description of a pose with some binary flags indicating the "wind-up" state of each joint. ( mostly only for one or two joints)
> 6) In the trajectory generator, do some planning that takes into account the "wind-up" state of the joints and the range of motion of the joints
> to determine the trajectory to be followed.
> 7) The wind-up state is passed at each sample time to the inverse kinematics.

The above is definitely possible, and would be a more full-featured extension. And take a long time to implement, test and verify.

> The conclusions I make from this:
> - The wrapping problem is not a diff() problem, it is a trajectory generator problem.
> - The trajectory generator needs a lot of specific knowledge such as joint limits,
> wind-up state. This wind-up state needs to be passed to the inverse position kinematics.

IK is not part of our particular problem.

> - I think it somewhere belongs in new class of type Rotational_Interpolation. However, currently, the API of the traj. gen. classes is
> not sufficient to pass all this extra information.
>
> So, the options are:
> - avoid the problem in KDL ( and dump it on the application developer :( ) by imposing angles < 180 degrees
> (this is what currently is done in KDL).

It isn't possible for some of us to simply avoid this.

> - implement a scheme similar to the above.

Which I'm trying to approach incrementally, with a minimal of necessary change.
S

Support more than 180? rotations

On Mon, 25 Jun 2012, Stephen Roderick wrote:

> On Jun 25, 2012, at 08:00 , Erwin Aertbelien wrote:
>
>> On 06/25/2012 12:43 PM, S Roderick wrote:
>>> We're interested in modifying KDL to support more than 180? rotations,
>>> and not have them wrap around. So from 0? to +270? is +270? travel, and not -90? travel.
>> diff() deals with the angle between two poses ("Frame"s in KDL) (let's call this "spacial angles", for now). This is different from
>> the joint angles you take about here. For joint angles, -90 is different from +270.
>>
>> The output of diff() will always result in an angle between 0 and 180.
>
> Actually, you and Herman both assume this is a joint-space robot.

I have made _no assumptions at all_ about robots... I was just talking
about frames attached to "whatever". :-) And yes, I want to be able to have
'no wrap' "diff" representations, because it is indeed useful for many
things, including but not limited to, robot kinematics.

> It's a cartesian-space robot (stewart platform) capable of 720? of travel
> in one axes (around the vertical). Though the problem is fundamentally
> the same for each situation.
>
>>> I see two possible general approaches
>>>
>>> 1) modify some of the existing diff() type functions to add extra logic to deal with this. This changes existing behavior, but doesn't grow the API.
>> For the reasons described above, this is not possible.
>>>
>>> 2) add new diff()-type functions to deal explicitly with long rotations. This won't break any existing code, but grows the API.
>>>
>>> At this point we're only interested in preventing the +/-180? wrap around behaviour. Components like the OCL trajectory generators could then easily be changed (on a site-by-site basis if necessary) to use the new diff(), for robots that do support more than 360? of rotation.
>> We're interested in this type of functionality, but, at least for me, it
>> is not yet completely clear how to handle this.
>> It is more then a littlle bit of extra logic, and it will have its
>> impact on the whole robot application.

Indeed. That's why I think it is a "trajectory" issue, and not a "Frame"
issue...

> Perhaps ...
>
>> Perhaps I first explain how this is solved in a typical industrial robot controller:
>> 1) Frame does not contain enough information to distinguish between -90 and 270 degrees, since it describes nothing more than the pose.
>> 2) Sometimes a robot has joints that have more then 360 degrees travel for one or more joints.
>
> Even those with 190? of travel can have the same problem (say -95 to +95). Move from 0 to -95, ok. Then move to +95, bad - robot tries to go through hard stop.
>
>> 3) People want to specify the motion in Cartesian space.
>> 4) The difference between _joint angle_ -90 or 270 degrees is not part of the Cartesian space specification, it is part of the description of the robot state.
>> Pure Cartesian space specification is not sufficient.
>> 5) Extend the description of a pose with some binary flags indicating the "wind-up" state of each joint. ( mostly only for one or two joints)

That "wind up" logic is (probably) a key element in the data structure representation...
Both to _describe_ the properties of a "frame diff", to _specify_ the
desired behaviour in a specific application, and to _monitor_ the actual
behaviour when executing the desired behaviour in the specific application.

(This is not very different from the semantics of "controllers": also there
one has to foresee different "versions" of the same data structure.)

>> 6) In the trajectory generator, do some planning that takes into account the "wind-up" state of the joints and the range of motion of the joints
>> to determine the trajectory to be followed.
>> 7) The wind-up state is passed at each sample time to the inverse kinematics.
>
> The above is definitely possible, and would be a more full-featured
> extension. And take a long time to implement, test and verify.
>
>> The conclusions I make from this:
>> - The wrapping problem is not a diff() problem, it is a trajectory generator problem.
>> - The trajectory generator needs a lot of specific knowledge such as joint limits,
>> wind-up state. This wind-up state needs to be passed to the inverse position kinematics.
>
> IK is not part of our particular problem.
>
>> - I think it somewhere belongs in new class of type
>> Rotational_Interpolation. However, currently, the API of the traj.
>> gen. classes is not sufficient to pass all this extra information.

I like the semantics of "Interpolation", since it is different from
"trajectory generation", and fills its own semantic gap in the current KDL
"ontology"...

>> So, the options are:
>> - avoid the problem in KDL ( and dump it on the application developer :( ) by imposing angles < 180 degrees
>> (this is what currently is done in KDL).
>
> It isn't possible for some of us to simply avoid this.
>
>> - implement a scheme similar to the above.
>
> Which I'm trying to approach incrementally, with a minimal of necessary change.

I agree with this goal... Maybe the first step is to find appropriate
extensions to the Frame data structure that allow to represent the "no
wrap" behaviour?

> S

Herman

Support more than 180? rotations

On 06/25/2012 03:06 PM, Herman Bruyninckx wrote:
> On Mon, 25 Jun 2012, Stephen Roderick wrote:
>
>> On Jun 25, 2012, at 08:00 , Erwin Aertbelien wrote:
>>
>>> On 06/25/2012 12:43 PM, S Roderick wrote:
>>>> We're interested in modifying KDL to support more than 180? rotations,
>>>> and not have them wrap around. So from 0? to +270? is +270? travel,
>>>> and not -90? travel.
>>> diff() deals with the angle between two poses ("Frame"s in KDL)
>>> (let's call this "spacial angles", for now). This is different from
>>> the joint angles you take about here. For joint angles, -90 is
>>> different from +270.
>>>
>>> The output of diff() will always result in an angle between 0 and 180.
>>
>> Actually, you and Herman both assume this is a joint-space robot.
The point was: you'll need some robot-specific information ( wind-up
state, joint range of motion, ...) to
determine the direction and amount of rotational motion.

>
> I have made _no assumptions at all_ about robots... I was just talking
> about frames attached to "whatever". :-) And yes, I want to be able to
> have
> 'no wrap' "diff" representations, because it is indeed useful for many
> things, including but not limited to, robot kinematics.
>
>> It's a cartesian-space robot (stewart platform) capable of 720? of
>> travel
>> in one axes (around the vertical). Though the problem is fundamentally
>> the same for each situation.
>>
>>>> I see two possible general approaches
>>>>
>>>> 1) modify some of the existing diff() type functions to add extra
>>>> logic to deal with this. This changes existing behavior, but
>>>> doesn't grow the API.
>>> For the reasons described above, this is not possible.
>>>>
>>>> 2) add new diff()-type functions to deal explicitly with long
>>>> rotations. This won't break any existing code, but grows the API.
>>>>
>>>> At this point we're only interested in preventing the +/-180? wrap
>>>> around behaviour. Components like the OCL trajectory generators
>>>> could then easily be changed (on a site-by-site basis if necessary)
>>>> to use the new diff(), for robots that do support more than 360? of
>>>> rotation.
>>> We're interested in this type of functionality, but, at least for
>>> me, it
>>> is not yet completely clear how to handle this.
>>> It is more then a littlle bit of extra logic, and it will have its
>>> impact on the whole robot application.
>
> Indeed. That's why I think it is a "trajectory" issue, and not a "Frame"
> issue...
>
>> Perhaps ...
>>
>>> Perhaps I first explain how this is solved in a typical industrial
>>> robot controller:
>>> 1) Frame does not contain enough information to distinguish between
>>> -90 and 270 degrees, since it describes nothing more than the pose.
>>> 2) Sometimes a robot has joints that have more then 360 degrees
>>> travel for one or more joints.
>>
>> Even those with 190? of travel can have the same problem (say -95 to
>> +95). Move from 0 to -95, ok. Then move to +95, bad - robot tries to
>> go through hard stop.
>>
>>> 3) People want to specify the motion in Cartesian space.
>>> 4) The difference between _joint angle_ -90 or 270 degrees is not
>>> part of the Cartesian space specification, it is part of the
>>> description of the robot state.
>>> Pure Cartesian space specification is not sufficient.
>>> 5) Extend the description of a pose with some binary flags
>>> indicating the "wind-up" state of each joint. ( mostly only for one
>>> or two joints)
>
> That "wind up" logic is (probably) a key element in the data structure
> representation...
> Both to _describe_ the properties of a "frame diff", to _specify_ the
> desired behaviour in a specific application, and to _monitor_ the actual
> behaviour when executing the desired behaviour in the specific
> application.
>
> (This is not very different from the semantics of "controllers": also
> there
> one has to foresee different "versions" of the same data structure.)
>
>>> 6) In the trajectory generator, do some planning that takes into
>>> account the "wind-up" state of the joints and the range of motion of
>>> the joints
>>> to determine the trajectory to be followed.
>>> 7) The wind-up state is passed at each sample time to the inverse
>>> kinematics.
>>
>> The above is definitely possible, and would be a more full-featured
>> extension. And take a long time to implement, test and verify.
>>
>>> The conclusions I make from this:
>>> - The wrapping problem is not a diff() problem, it is a
>>> trajectory generator problem.
>>> - The trajectory generator needs a lot of specific knowledge such
>>> as joint limits,
>>> wind-up state. This wind-up state needs to be passed to the
>>> inverse position kinematics.
>>
>> IK is not part of our particular problem.
>>
>>> - I think it somewhere belongs in new class of type
>>> Rotational_Interpolation. However, currently, the API of the traj.
>>> gen. classes is not sufficient to pass all this extra information.
>
> I like the semantics of "Interpolation", since it is different from
> "trajectory generation", and fills its own semantic gap in the current
> KDL
> "ontology"...
Just to be clear, this is what I wanted to say:
- there exists a KDL class Rotational_Interpolation, the subclass
Rotational_Interpolation_sa ( sa is a short for "single-axis")
interpolates the rotations around a single rotation axis along the
shortest angle. It is given to the Trajectory* classes.
- A new class of this type can be created that has more knowledge
about allowable angles and wind-up state and
can choose in a correct way how to perform the motion.
- But then it will need more information (e.g. wind-up for the joints...)

>
>>> So, the options are:
>>> - avoid the problem in KDL ( and dump it on the application
>>> developer :( ) by imposing angles < 180 degrees
>>> (this is what currently is done in KDL).
>>
>> It isn't possible for some of us to simply avoid this.
>>
>>> - implement a scheme similar to the above.
>>
>> Which I'm trying to approach incrementally, with a minimal of
>> necessary change.
>
Stephen, In what way can it be solved incrementally ? What do you have
exactly in mind ?

> I agree with this goal... Maybe the first step is to find appropriate
> extensions to the Frame data structure that allow to represent the "no
> wrap" behaviour?
>
There is even a step before this:
- deciding on how you specify your motion, e.g. for lin. motion:
- by start and end frame ( extended with add. data) ?
- by initial pose (with add. data) , a rotation axis and an
angle ?
( this pushes again the problem to the application
developer,
but is simple to understand and results in easily
predictable motion).

>> S
>
> Herman

Support more than 180? rotations

On Jun 25, 2012, at 09:40 , Erwin Aertbelien wrote:

> On 06/25/2012 03:06 PM, Herman Bruyninckx wrote:
>> On Mon, 25 Jun 2012, Stephen Roderick wrote:
>>
>>> On Jun 25, 2012, at 08:00 , Erwin Aertbelien wrote:
>>>
>>>> On 06/25/2012 12:43 PM, S Roderick wrote:
>>>>> We're interested in modifying KDL to support more than 180? rotations,
>>>>> and not have them wrap around. So from 0? to +270? is +270? travel, and not -90? travel.
>>>> diff() deals with the angle between two poses ("Frame"s in KDL) (let's call this "spacial angles", for now). This is different from
>>>> the joint angles you take about here. For joint angles, -90 is different from +270.
>>>>
>>>> The output of diff() will always result in an angle between 0 and 180.
>>>
>>> Actually, you and Herman both assume this is a joint-space robot.
> The point was: you'll need some robot-specific information ( wind-up state, joint range of motion, ...) to
> determine the direction and amount of rotational motion.

For joint-space motion, you actually don't. I added to our unit tests of the OCL::JointGeneratorPos (from v1, with some minor mod's), and it does the correct thing for large angles. Underneath it is bascially doing a (b-a) calculation, so there is no wrap around.

I still think that the only place we face issues with in the current implementation, for joint- or cartesian-space position motions, is with representing cartesian displacements. But I'll add to our unit tests of the OCL::CartesianGeneratorPos to (dis)prove my theory. How we go about fixing this is still open for discussion ... :-)

Cheers
S

Support more than 180? rotations

On Mon, 25 Jun 2012, S Roderick wrote:

> We're interested in modifying KDL to support more than 180? rotations, and not have them wrap around. So from 0? to +270? is +270? travel, and not -90? travel.
>
> I see two possible general approaches
>
> 1) modify some of the existing diff() type functions to add extra logic to deal with this. This changes existing behavior, but doesn't grow the API.
>
> 2) add new diff()-type functions to deal explicitly with long rotations. This won't break any existing code, but grows the API.
>
> At this point we're only interested in preventing the +/-180? wrap around behaviour. Components like the OCL trajectory generators could then easily be changed (on a site-by-site basis if necessary) to use the new diff(), for robots that do support more than 360? of rotation.
>
> Thoughts?

First of all: this is a relevant feature to have!

Secondly: I am not sure whether the feature belongs to the "diff" part of
KDL (that is, when dealing with just rotations as parameters), or to the
"trajectory generator" part of KDL (that is, when it matters _how_ the diff
is traversed). Because I think you _have_ to give some extra "trajectory"
information to the "diff" to differentiate between the two outcomes. Don't
you?

My (for the time being not so motivated) suggestion is to put it unner the
"trajectory generator" part.
(And to separate that part from the pure "frame geometry" part, as well as
from the "kinematic chain" part. But that is another thread/story/...)

> S

Herman