Table of Contents

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

bInitRetains BOOL

if TRUE, the retain variables are initialized (warm start / cold start)

bInCopyCode BOOL

if TRUE, the instance afterwards gets moved into the copy code (online change)

bufferSize DINT := 0
logicBuffer POINTER TO DINT

must be an array in the form ARRAY[0..#Items]

pointBuffer POINTER TO LREAL

must be an array in the form ARRAY[0..#Items]

tangentBuffer POINTER TO LREAL

must be an array in the form ARRAY[0..#Items]

segmentBuffer POINTER TO LREAL

must be an array in the form ARRAY[0..#Items]

dofs INT

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

t LREAL

time variable

point POINTER TO LREAL

value of the point

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

t LREAL

time variable

x LREAL

value as x-coordinate

y LREAL

value as y-coordinate

z LREAL

value 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

t LREAL
p POINTER TO LREAL

(optional, may be 0) Pointer to an array with Degree-Of-Freedrom Elements, which holds the calculated position

v POINTER TO LREAL

(optional, may be 0) Pointer to an array with Degree-Of-Freedrom Elements, which holds the calculated velocity

a POINTER 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.