CatmullRomSpline
- Namespace
- ZCore
- Extends
- Inherited Methods
FUNCTION_BLOCK CatmullRomSpline EXTENDS ZCore.List
Implementation of a simple spline algorithm (Catmull-Rom). The function block holds a list of points that have time indices which can be populated by calling the Append method. The Interpolate method can be used to get an interpolated point for a specific time. This function block can be used to get a smooth line between a discrete series of points to eliminate sharp angles.
The Catmul-Rom splines are a specialization of the general Hermite spline. With a Hermite spline, you define the start and end point of the line, and 2 tangents, one at the start of the line and one at the end. The Catmull-Rom spline simplifies this by just asking you to define a series of points, and the tangents are created for you.
Constructor
FB_init
METHOD FB_init (
[input] bInitRetains : BOOL,
[input] bInCopyCode : BOOL,
[input] bufferSize : DINT,
[input] logicBuffer : POINTER TO DINT,
[input] pointBuffer : POINTER TO LREAL,
[input] tangentBuffer : POINTER TO LREAL,
[input] segmentBuffer : POINTER TO LREAL,
[input] dofs : INT)
The constructor is used to set up the spline. Since splines are very general objects all data buffers that it operates on are held externally and have to be given as pointers.
_logicBuffer : ARRAY[0..100] OF DINT;
_pointBuffer : ARRAY[0..100*<dof>] OF LREAL;
_tangentBuffer : ARRAY[0..100*<dof>] OF LREAL;
_segmentBuffer : ARRAY[0..100] OF LREAL;
_spline : List<Type>(100, ADR(_logicBuffer), ADR(_pointBuffer), ADR(_tangentBuffer), ADR(_segmentBuffer), <dof>);
Inputs
bInitRetainsBOOLif TRUE, the retain variables are initialized (warm start / cold start)
bInCopyCodeBOOLif TRUE, the instance afterwards gets moved into the copy code (online change)
bufferSizeDINT:= 0logicBufferPOINTER TO DINTmust be an array in the form ARRAY[0..#Items]
pointBufferPOINTER TO LREALmust be an array in the form ARRAY[0..#Items]
tangentBufferPOINTER TO LREALmust be an array in the form ARRAY[0..#Items]
segmentBufferPOINTER TO LREALmust be an array in the form ARRAY[0..#Items]
dofsINT
Methods
Append
METHOD Append (
[input] t : LREAL,
[input] point : POINTER TO LREAL) : DINT
This method is used to append a new point to the spline at the timestamp t.
Using the append method, the points of the spline have to be set up consecutively regarding to t,
points are not automatically sorted. Attempting to add a new point with a t that is smaller than the previous point,
this method will fail. Also, when trying to add more points to the spline than the buffer can handle, the method will fail.
When failing, the method returns -1 such that successful execution can be checked by the caller.
Using none-uniform distances for t between points, the "velocity" of the spline is changing.
For performance reasons this method only adds points to the spline, but doesn't recalculate the spline. The later is performed
automatically when calling Recalculate for the first time after appending a point.
Inputs
Returns
- DINT
Append3
METHOD Append3 (
[input] t : LREAL,
[input] x : LREAL,
[input] y : LREAL,
[input] z : LREAL) : DINT
This method is used to append a new point with 3 degrees of freedom to the spline. The method interally uses Append such that all specifics that are documented in this method apply to Append3 as well.
Note
If the Spline got initialized with dofs <> 3 this method will fail and return -1 (invalid insertion).
Inputs
tLREALtime variable
xLREALvalue as x-coordinate
yLREALvalue as y-coordinate
zLREALvalue as z-coordinate
Returns
- DINT
Clear
METHOD Clear ()
This method can be used to remove all points from the spline.
Interpolate
METHOD Interpolate (
[input] t : LREAL,
[input] p : POINTER TO LREAL,
[input] v : POINTER TO LREAL,
[input] a : POINTER TO LREAL)
Calculates the position p, velocity v and acceleration a for the spline that had been parametrized with t by calls to
Append or Append3, respectively.
If not needed, the pointers that are passed to this method can be 0. For instance, if one is only interested in the position p(t) the
parameters for velocity and acceleration can be set to 0.
When calling this method for the first time after setting up the spline the actual spline calculation is performed. This is why the first call to the method takes more CPU time then consecutive calls to it.
Inputs
tLREALpPOINTER TO LREAL(optional, may be 0) Pointer to an array with Degree-Of-Freedrom Elements, which holds the calculated position
vPOINTER TO LREAL(optional, may be 0) Pointer to an array with Degree-Of-Freedrom Elements, which holds the calculated velocity
aPOINTER TO LREAL(optional, may be 0) Pointer to an array with Degree-Of-Freedrom Elements, which holds the calculated acceleration
Recalculate
METHOD Recalculate ()
This method is called whenever the spline changed due to newly appended points by the first call to Interpolate. The spline is internally calculated with the Catmull-Rom approach. In this approach, the tangents of points of the spline do not have to be specified but are calculated automatically by the following equation:
tangent[i] = 0.5 * (point[i+1] - point[i-1])
The implementation also assumes that endpoint tangents are parallel and in line with the neighbour.