Extrapolating a trajectory using splines

81 views Asked by At

I am currently working on a simulation/collision avoidance system for autonomous sailing agents based on telemetry data. The aim is to extrapolate the courses of other agents in order to predict possible collisions.

At the moment I'm working with cubic Hermite splines for extrapolation, but I'm getting results that I can't understand. For example, the extrapolated course is travelling in a direction that makes no sense to me.

I have read several times that splines are not suitable for extrapolations and that polynomials are preferable. However, I can't find a concrete source for this. In general, I can hardly find any useful sources regarding the extrapolation of splines or polynomials. But maybe I'm just blind.

Below I have attached my current code and the data I am using. Other methods for extrapolation are ruled out because the task requires splines or polynomials.

Maybe someone has a suggestion for me.

The data:

# scenario 1
w1 = np.array([[0, 0], [0, 1], [2, 2], [3, 2]])
t1 = np.array([[0, 1], [0, 1], [1, 0], [1, 0]])

# scenario 2
w2 = np.array([[0, 0], [0, 1], [.5, 1.5], [1, 1]])
t2 = np.array([[0, 1], [0, 1], [1, 0], [0, -1]])

The code:

t = np.linspace(0, len(waypoints) - 1, 100)
ex = np.linspace(len(waypoints)-1, len(waypoints), 10)

chs = CubicHermiteSpline(np.arange(0, len(waypoints)), waypoints, tangents)

poly = chs(t)
extrapolated = chs(ex)

ax.plot(poly[:, 0], poly[:, 1], '-', label='cubic hermite spline')
ax.plot(waypoints[:, 0], waypoints[:, 1], 'o', label='waypoints')
ax.plot(extrapolated[:, 0], extrapolated[:, 1], 'o', label='extrapolated')

ax.quiver(waypoints[:, 0], waypoints[:, 1], tangents[:, 0], tangents[:, 1], color='green', label='direction', angles='xy', scale_units='xy', scale=1, alpha=.25)

ax.legend()
1

There are 1 answers

0
joeday On

TL;DR -- these are expected paths for this spline. At the time of the latest way point for scenario 2, the spline's path is actively changing and so we should not expect it to extrapolate straight out. If we had an additional waypoint at [1,0], the spline would behave as you expect.

Let's start with Scenario 1

Here's what I see (using your provided code) for the plot of scenario 1:

Scenario 1 Provided By the Questioner

This actually makes sense to me. The piecewise trajectory from our waypoint at [2,0] to our next waypoint at [3,0] is straight to the right. To be thorough though, we can utilize the derivative method of our CubicHermiteSpline object to see the first order derivative at our last waypoint:

chs.derivative(nu=1)(3)

Which yields array([1., 0.]), as we expect (this is the tangent we provided for this latest waypoint). We can check the second order derivative at our last waypoint like so:

chs.derivative(nu=2)(3)

which yields array([0., 0.]), as we expect. Together, these two values paint the picture of a line going straight to the right.

Scenario 2 is maybe where things get sticky.

Scenario 2 Provided by the Questioner

Now when we check the first order derivative at our last waypoint, now we get chs.derivative(nu=1)(3) = array([0., -1.]). This matches the tangent we provided for that waypoint.

Unlike before though, when we check the second order derivative at our last waypoint, we get chs.derivative(nu=2)(3) = array([-1., -1.]). So at our last waypoint, the fit line's slope is actively changing. This means that our spline, if we were to extrapolate it beyond our last waypoint, would not continue in a straight line down from the last waypoint (as suggested by the green quiver).

Instead, we should expect the slope to continue to change. In an xy-plane, this looks like a increase in both negative x and y directions at equal rates. That's exactly what we see happening with our extrapolated values, starting from our last waypoint.

Our third-order derivative is chs.derivative(nu=3)(3) = array([0., 0.]) (worth checking for a cubic!).