copp::Path represents the geometric path q = q(s). Solvers do not optimize geometry; they optimize how quickly this already-defined path is traversed.
Include
or:
Output Shapes
Every batch evaluation uses a station vector s of length N and returns column-major matrices with shape (dim x N):
std::vector<double> samples{0.0, 0.5, 1.0};
auto out = path.evaluate_up_to_2nd(samples);
double q_axis0_at_mid = out.q(0, 1);
double dq_axis0_at_mid = out.dq.value()(0, 1);
double ddq_axis0_at_mid = out.ddq.value()(0, 1);
Waypoint Splines
Waypoint paths are the easiest entry point. Each inner initializer-list is one waypoint vector. Path::from_waypoints_interpolating builds a spline that passes through every waypoint; Path::from_waypoints is an equivalent alias:
{0.0, 0.0},
{0.5, 0.25},
{1.0, 1.0},
});
auto dim = path.dim();
static Path from_waypoints_interpolating(MatrixView waypoints, SplineConfig config={})
Build a spline path that interpolates every waypoint.
std::pair< double, double > s_range() const
Return the valid path-parameter interval (s_min, s_max).
If you already have a matrix, use the native COPP shape (dim x n_points):
{0.0, 0.0},
{0.5, 0.25},
{1.0, 1.0},
});
static Matrix from_columns(std::initializer_list< std::initializer_list< double > > columns)
Build a matrix from column-major initializer-list notation.
The default spline configuration follows Rust/Python:
- order 5
- range [0, 1]
- out-of-range behavior: error
- zero boundary derivative states
Custom range and clamping:
@ Clamp
Clamp out-of-range query samples to the nearest endpoint.
Configuration for waypoint spline construction.
OutOfRangeMode out_of_range
Interpolating Versus Fitting Waypoint Paths
Path::from_waypoints_interpolating constrains the path to pass through every waypoint at its assigned parameter. Choose it when each waypoint is a position or event that must be retained.
Path::from_waypoints_fitting instead treats adjacent columns as a reference polyline under one common parameter and builds an adaptive nonuniform C4 quintic B-spline. The fitted curve does not pass through interior waypoints: selected axes may deviate from the polyline within their absolute tolerances (input units, same parameter), and that error is numerically audited over every complete reference interval. Endpoint positions are retained. Unselected axes keep C4 quintic interpolation through all waypoints.
config.axes = std::vector<std::size_t>{0, 1};
config.tolerance_per_axis = {1.0e-3, 1.0e-2};
config.parameters = std::vector<double>{0.0, 0.3, 1.0};
if (auto report = fitted.smoothing_report()) {
}
static Path from_waypoints_fitting(MatrixView waypoints, SmoothingConfig config={})
Build a tolerance-bounded fitted path from waypoint positions.
Configuration for tolerance-bounded waypoint fitting.
SmoothingConfig defaults to a uniform tolerance of 1e-3 on every row, uniform parameters on [0, 1], 20 refinement passes, 20000 selected-axis spans, and out-of-range errors. An empty tolerance_per_axis uses tolerance for every selected axis. Invalid configurations, or tolerances that cannot be met within the budgets, throw copp::Error (or return an error from the copp::no_throw overloads). smoothing_report() returns std::nullopt for interpolated, parametric, and evaluator paths.
Fitting is geometric preprocessing, not time parameterization: evaluated derivatives are still derivatives with respect to s.
- Warning
- Both waypoint constructor families (from_waypoints_interpolating / from_waypoints and from_waypoints_fitting) are currently unstable. Their names, signatures, and configuration types may change as more algorithms are added.
Scalar Parametric Paths
Path::from_parametric uses copp::Jet3 automatic differentiation. The callback receives a seeded scalar s; ordinary arithmetic and COPP math helpers propagate derivatives up to third order.
return std::vector<copp::Jet3>{
};
},
0.0,
1.0);
std::vector<double> samples{0.0, 0.5, 1.0};
static Path from_parametric(PathParametric parametric, double s_min, double s_max)
Build a path from a scalar-parametric formula.
PathDerivatives evaluate_up_to_3rd(Span< const double > s) const
Evaluate position, first derivative, second derivative, and third derivative.
Jet3 sin(Jet3 x) noexcept
Jet3 cos(Jet3 x) noexcept
Third-order forward-mode automatic-differentiation scalar.
For tighter loops, avoid allocating a vector inside every callback invocation by using the writer overload:
2,
0.0,
1.0,
});
Non-owning view of a contiguous one-dimensional array.
Jet3 powi(Jet3 x, int n) noexcept
Supported helpers include sin, cos, exp, log/ln, sqrt, and powi.
Batch Evaluator Paths
Use evaluator paths when the path comes from an external model or when you already know analytic derivatives. The callback is batch-oriented to avoid crossing the C++/Rust bridge once per station.
2,
0.0,
1.0,
for (std::size_t j = 0; j < s.
size(); ++j) {
const double x = s[j];
q(0, j) = x;
dq(0, j) = 1.0;
ddq(0, j) = 0.0;
q(1, j) = x * x;
dq(1, j) = 2.0 * x;
ddq(1, j) = 2.0;
}
});
Mutable column-major matrix view used by callback APIs.
static Path from_evaluator_2nd(std::size_t dim, double s_min, double s_max, PathEvaluator2nd evaluator)
Build a path from a batch evaluator with explicit derivatives up to second order.
constexpr std::size_t size() const noexcept
Third-order evaluators add dddq:
1,
0.0,
1.0,
for (std::size_t j = 0; j < s.
size(); ++j) {
const double x = s[j];
q(0, j) = x * x * x;
dq(0, j) = 3.0 * x * x;
ddq(0, j) = 6.0 * x;
dddq(0, j) = 6.0;
}
});
static Path from_evaluator_3rd(std::size_t dim, double s_min, double s_max, PathEvaluator3rd evaluator)
Build a path from a batch evaluator with explicit derivatives up to third order.
The path owns the callback object. Throw copp::Error or another std::exception from the callback to report evaluator failure.
Tutorial Sources