Interpolation helpers convert path-domain profiles into time-domain schedules. Solvers usually return profiles over station samples s[k]; controllers often need cumulative time t(s) or samples of the inverse map s(t).
Include
or:
TOPP2 Profile
TOPP2/COPP2 solvers return a node profile:
\[a_k = a(s_k) = \dot{s}(s_k)^2.
\]
The segment profile is:
\[b_k = \frac{a_{k+1} - a_k}{2(s_{k+1} - s_k)}.
\]
std::vector<double> s{0.0, 0.5, 1.0};
std::vector<double> a{1.0, 1.0, 1.0};
s,
a,
time.t_s,
0.1);
std::vector<double> t_query{0.0, 0.25, 0.5, 1.0};
s,
a,
time.t_s,
t_query);
COPP_API std::vector< double > t_to_s_topp2_uniform(Span< const double > s, Span< const double > a, Span< const double > t_s, double dt, TimeGridOptions options={})
Sample the inverse TOPP2 mapping s(t) on a uniform time grid.
COPP_API std::vector< double > a_to_b_topp2(Span< const double > s, Span< const double > a)
Compute segment profile b from node profile a.
COPP_API TimeProfile s_to_t_topp2(Span< const double > s, Span< const double > a, double t0=0.0)
Convert a second-order path profile a(s) = ds/dt squared to t(s).
COPP_API std::vector< double > t_to_s_topp2_samples(Span< const double > s, Span< const double > a, Span< const double > t_s, Span< const double > t_sample)
Sample the inverse TOPP2 mapping s(t) at explicit query times.
Input requirements:
- s.size() >= 2
- a.size() == s.size()
- s is strictly increasing
- all values are finite
- every segment has a positive finite speed denominator
TOPP3 Profile
TOPP3/COPP3 use node-based a and b arrays:
\[a_k = \dot{s}(s_k)^2, \qquad b_k = \ddot{s}(s_k).
\]
copp::Profile3rd owns those arrays:
std::vector<double> s{0.0, 0.5, 1.0};
{1.0, 1.0, 1.0},
{0.0, 0.0, 0.0},
};
s,
profile,
time.t_s,
0.1);
COPP_API TimeProfile s_to_t_topp3(Span< const double > s, const Profile3rd &profile, double t0=0.0)
Convert a third-order profile to cumulative time t(s).
COPP_API std::vector< double > t_to_s_topp3_uniform(Span< const double > s, const Profile3rd &profile, Span< const double > t_s, double dt, TimeGridOptions options={})
Sample the inverse TOPP3 mapping s(t) on a uniform time grid.
Owned third-order TOPP/COPP profile.
copp::Profile3rdRef is the zero-copy borrowed view. It is useful for external storage and for interpolating only part of a profile:
auto part = profile.
slice(10, 40);
Non-owning view of a contiguous one-dimensional array.
Profile3rdRef slice(std::size_t idx_s_start, std::size_t idx_s_final) const
Borrow a closed station subrange idx_s_start..=idx_s_final.
Stationary counts are clipped to the local slice. A slice must still contain at least one non-stationary segment after that adjustment.
Uniform Versus Explicit Time Grids
Uniform sampling is convenient for controllers:
s,
a,
time.t_s,
0.001,
grid);
Options for generating a uniform s(t) sampling grid.
Explicit samples are better for diagnostics, plotting, or synchronizing with an external time base:
std::vector<double> t_sample{0.0, 0.02, 0.05, time.t_final};
s,
profile,
time.t_s,
t_sample);
COPP_API std::vector< double > t_to_s_topp3_samples(Span< const double > s, const Profile3rd &profile, Span< const double > t_s, Span< const double > t_sample)
Sample the inverse TOPP3 mapping s(t) at explicit query times.
Out-of-range query times are returned as NaN, matching Rust/Python.
Tutorial Sources
- bindings/cpp/tests/test_topp2_interpolation.cpp
- bindings/cpp/tests/test_topp3_interpolation.cpp