1#ifndef COPP_C_EXAMPLE_COMMON_H
2#define COPP_C_EXAMPLE_COMMON_H
40static int example_expect_ok(
enum CoppStatus status,
const char *call)
50static void example_fill_stations(
double *s,
size_t n)
52 for (
size_t j = 0; j < n; ++j)
54 s[j] = (double)j / (
double)(n - 1);
58static void example_eval_lissajous_sample(
double s,
64 const double pi = 3.14159265358979323846;
65 const double freq[
EXAMPLE_DIM] = {2.0 * pi, 3.0 * pi, 5.0 * pi};
70 const double w = freq[i];
71 const double x = s * w + phase[i];
72 const double sin_x = sin(x);
73 const double cos_x = cos(x);
74 const double w_sq = w * w;
78 ddq[i] = -sin_x * w_sq;
81 dddq[i] = (-cos_x * w_sq) * w;
86static enum CoppStatus example_evaluate_path_2nd(
void *user_data,
99 if (n > 0 && (s == NULL || q == NULL || dq == NULL || ddq == NULL))
104 for (
size_t j = 0; j < n; ++j)
109 example_eval_lissajous_sample(s[j], q_col, dq_col, ddq_col, NULL);
112 q[i + j * dim] = q_col[i];
113 dq[i + j * dim] = dq_col[i];
114 ddq[i + j * dim] = ddq_col[i];
121static enum CoppStatus example_evaluate_path_3rd(
void *user_data,
135 if (n > 0 && (s == NULL || q == NULL || dq == NULL || ddq == NULL || dddq == NULL))
140 for (
size_t j = 0; j < n; ++j)
146 example_eval_lissajous_sample(s[j], q_col, dq_col, ddq_col, dddq_col);
149 q[i + j * dim] = q_col[i];
150 dq[i + j * dim] = dq_col[i];
151 ddq[i + j * dim] = ddq_col[i];
152 dddq[i + j * dim] = dddq_col[i];
159static int example_create_analytic_path_2nd(
struct CoppPath **out_path)
166 example_evaluate_path_2nd,
169 return example_expect_ok(status,
"copp_path_from_evaluator_2nd");
172static int example_create_analytic_path_3rd(
struct CoppPath **out_path)
179 example_evaluate_path_2nd,
180 example_evaluate_path_3rd,
183 return example_expect_ok(status,
"copp_path_from_evaluator_3rd");
186static int example_add_second_order_limits(
struct CoppRobot *robot,
size_t n)
199 if (example_expect_ok(status,
"copp_add_axial_velocity_limits"))
210 return example_expect_ok(status,
"copp_add_axial_acceleration_limits");
213static int example_add_third_order_limits(
struct CoppRobot *robot,
size_t n)
218 if (example_add_second_order_limits(robot, n))
229 return example_expect_ok(status,
"copp_add_axial_jerk_limits");
232static int example_create_robot_2nd(
const struct CoppPath *path,
239 if (example_expect_ok(status,
"copp_robot_create"))
245 if (example_expect_ok(status,
"copp_robot_append_s"))
253 if (example_expect_ok(status,
"copp_robot_sample_path_2nd") ||
254 example_add_second_order_limits(*out_robot, n))
264static int example_create_robot_3rd(
const struct CoppPath *path,
271 if (example_expect_ok(status,
"copp_robot_create"))
277 if (example_expect_ok(status,
"copp_robot_append_s"))
285 if (example_expect_ok(status,
"copp_robot_sample_path_3rd") ||
286 example_add_third_order_limits(*out_robot, n))
296static int example_solve_topp2_seed(
struct CoppRobot *robot,
size_t n,
struct CoppVecF64 *out_a)
300 if (example_expect_ok(status,
"topp2_ra_default_options"))
306 status =
topp2_ra(problem, options, out_a);
307 if (example_expect_ok(status,
"topp2_ra"))
311 if (out_a->
data == NULL || out_a->
len != n)
313 fprintf(stderr,
"unexpected TOPP2 seed length\n");
319static int example_seed_third_order_problem(
struct CoppRobot *
robot,
323 if (example_solve_topp2_seed(
robot, n, out_a_seed))
330 return example_expect_ok(status,
"copp_robot_amax_substitute");
333static int example_time_from_second_order(
const double *s,
345 if (example_expect_ok(status,
"copp_s_to_t_2nd"))
349 if (!isfinite(*out_t_final) || *out_t_final <= 0.0 || *out_t_final >= DBL_MAX)
351 fprintf(stderr,
"invalid second-order time profile\n");
357static int example_time_from_third_order(
const double *s,
372 if (example_expect_ok(status,
"copp_s_to_t_3rd"))
376 if (!isfinite(*out_t_final) || *out_t_final <= 0.0 || *out_t_final >= DBL_MAX)
378 fprintf(stderr,
"invalid third-order time profile\n");
384static int example_interpolate_second_order(
const double *s,
398 return example_expect_ok(status,
"copp_t_to_s_uniform_2nd");
401static int example_interpolate_third_order(
const double *s,
418 return example_expect_ok(status,
"copp_t_to_s_uniform_3rd");
const char * copp_status_message(enum CoppStatus status)
Return a short static message for a COPP status code.
CoppStatus
C ABI status code returned by COPP FFI functions.
@ COPP_STATUS_NULL_POINTER
A required pointer argument was null.
@ COPP_STATUS_INVALID_ARGUMENT
An unsupported enum value or option was provided through the C ABI.
@ COPP_STATUS_OK
Operation completed successfully.
enum CoppStatus copp_s_to_t_3rd(struct CoppSliceF64 s, struct CoppSliceF64 a, struct CoppSliceF64 b, size_t num_stationary_start, size_t num_stationary_end, double t0, double *out_t_final, struct CoppVecF64 *out_t_s)
Compute cumulative TOPP3/COPP3 time profile t(s) from node profiles a(s) = dot{s}^2 and b(s) = ddot{s...
enum CoppStatus copp_t_to_s_uniform_3rd(struct CoppSliceF64 s, struct CoppSliceF64 a, struct CoppSliceF64 b, size_t num_stationary_start, size_t num_stationary_end, struct CoppSliceF64 t_s, double t0, double dt, bool include_final, struct CoppVecF64 *out_s_t)
Interpolate s(t) from TOPP3/COPP3 profiles using a uniform time grid.
enum CoppStatus copp_t_to_s_uniform_2nd(struct CoppSliceF64 s, struct CoppSliceF64 a, struct CoppSliceF64 t_s, double t0, double dt, bool include_final, struct CoppVecF64 *out_s_t)
Interpolate s(t) from TOPP2 profiles using a uniform time grid.
enum CoppStatus copp_s_to_t_2nd(struct CoppSliceF64 s, struct CoppSliceF64 a, double t0, double *out_t_final, struct CoppVecF64 *out_t_s)
Compute cumulative TOPP2 time profile t(s) from node profile a(s).
struct CoppPath CoppPath
Opaque C handle for a library-owned Path.
enum CoppStatus copp_path_from_evaluator_2nd(size_t dim, double s_min, double s_max, CoppPathEvaluate2ndFn evaluate_2nd, void *user_data, struct CoppPath **out_path)
Build a path from a C callback that provides derivatives up to 2nd order.
enum CoppStatus copp_path_from_evaluator_3rd(size_t dim, double s_min, double s_max, CoppPathEvaluate2ndFn evaluate_2nd, CoppPathEvaluate3rdFn evaluate_3rd, void *user_data, struct CoppPath **out_path)
Build a path from C callbacks that provide derivatives up to 3rd order.
struct CoppRobot CoppRobot
Opaque C handle for a library-owned robot and constraint buffer.
void copp_robot_free(struct CoppRobot *robot)
Release a robot handle created by copp_robot_create.
enum CoppStatus copp_robot_amax_substitute(struct CoppRobot *robot, struct CoppSliceF64 amax, size_t idx_s)
Overwrite first-order bounds from a profile.
enum CoppStatus copp_add_axial_acceleration_limits(struct CoppRobot *robot, size_t start_idx_s, size_t len, struct CoppSliceF64 acceleration_max, struct CoppSliceF64 acceleration_min)
Add broadcast axial acceleration limits over an existing robot station interval.
enum CoppStatus copp_robot_append_s(struct CoppRobot *robot, struct CoppSliceF64 s)
Append strictly increasing station samples to a robot.
enum CoppStatus copp_robot_create(size_t dim, size_t capacity, struct CoppRobot **out_robot)
Create a library-owned robot handle for C callers.
enum CoppStatus copp_add_axial_velocity_limits(struct CoppRobot *robot, size_t start_idx_s, size_t len, struct CoppSliceF64 velocity_max, struct CoppSliceF64 velocity_min)
Add broadcast axial velocity limits over an existing robot station interval.
enum CoppStatus copp_add_axial_jerk_limits(struct CoppRobot *robot, size_t start_idx_s, size_t len, struct CoppSliceF64 jerk_max, struct CoppSliceF64 jerk_min)
Add broadcast axial jerk limits over an existing robot station interval.
enum CoppStatus copp_robot_sample_path_2nd(struct CoppRobot *robot, const struct CoppPath *path, size_t idx_s_from, size_t idx_s_to)
Sample a path over an existing robot station interval and store second-order derivatives.
enum CoppStatus copp_robot_sample_path_3rd(struct CoppRobot *robot, const struct CoppPath *path, size_t idx_s_from, size_t idx_s_to)
Sample a path over an existing robot station interval and store third-order derivatives.
enum CoppStatus topp2_ra_default_options(struct Topp2RaOptions *out_options)
Write default TOPP2-RA options into out_options.
enum CoppStatus topp2_ra(struct Topp2Problem problem, struct Topp2RaOptions options, struct CoppVecF64 *out_a)
Solve a TOPP2-RA problem.
Owned third-order profile returned by TOPP3/COPP3 C ABI solvers.
struct CoppVecF64 b
Node-based profile b[k] = ddot{s}_k.
size_t num_stationary_end
Effective stationary interval count at the end.
struct CoppVecF64 a
Node-based profile a[k] = dot{s}_k^2.
size_t num_stationary_start
Effective stationary interval count at the start.
Borrowed immutable f64 slice passed from C to COPP.
Library-owned f64 vector returned to C.
size_t len
Number of initialized elements.
double * data
Pointer to the first element, or null for an empty vector.
Borrowed value descriptor for a TOPP2 problem solved from C.
const struct CoppRobot * robot
Robot handle that owns the station-indexed constraint storage.
Options for TOPP2-RA reachability analysis.