1#ifndef COPP_C_EXAMPLE_COMMON_H
2#define COPP_C_EXAMPLE_COMMON_H
38static int example_expect_ok(
enum CoppStatus status,
const char *call)
48static void example_fill_stations(
double *s,
size_t n)
50 for (
size_t j = 0; j < n; ++j)
52 s[j] = (double)j / (
double)(n - 1);
56static void example_eval_lissajous_sample(
double s,
62 const double pi = 3.14159265358979323846;
63 const double freq[
EXAMPLE_DIM] = {2.0 * pi, 3.0 * pi, 5.0 * pi};
68 const double w = freq[i];
69 const double x = s * w + phase[i];
70 const double sin_x = sin(x);
71 const double cos_x = cos(x);
72 const double w_sq = w * w;
76 ddq[i] = -sin_x * w_sq;
79 dddq[i] = (-cos_x * w_sq) * w;
84static enum CoppStatus example_evaluate_path_2nd(
void *user_data,
97 if (n > 0 && (s == NULL || q == NULL || dq == NULL || ddq == NULL))
102 for (
size_t j = 0; j < n; ++j)
107 example_eval_lissajous_sample(s[j], q_col, dq_col, ddq_col, NULL);
110 q[i + j * dim] = q_col[i];
111 dq[i + j * dim] = dq_col[i];
112 ddq[i + j * dim] = ddq_col[i];
119static enum CoppStatus example_evaluate_path_3rd(
void *user_data,
133 if (n > 0 && (s == NULL || q == NULL || dq == NULL || ddq == NULL || dddq == NULL))
138 for (
size_t j = 0; j < n; ++j)
144 example_eval_lissajous_sample(s[j], q_col, dq_col, ddq_col, dddq_col);
147 q[i + j * dim] = q_col[i];
148 dq[i + j * dim] = dq_col[i];
149 ddq[i + j * dim] = ddq_col[i];
150 dddq[i + j * dim] = dddq_col[i];
157static int example_create_analytic_path_2nd(
struct CoppPath **out_path)
164 example_evaluate_path_2nd,
167 return example_expect_ok(status,
"copp_path_from_evaluator_2nd");
170static int example_create_analytic_path_3rd(
struct CoppPath **out_path)
177 example_evaluate_path_2nd,
178 example_evaluate_path_3rd,
181 return example_expect_ok(status,
"copp_path_from_evaluator_3rd");
184static int example_add_second_order_limits(
struct CoppRobot *robot,
size_t n)
197 if (example_expect_ok(status,
"copp_add_axial_velocity_limits"))
208 return example_expect_ok(status,
"copp_add_axial_acceleration_limits");
211static int example_add_third_order_limits(
struct CoppRobot *robot,
size_t n)
216 if (example_add_second_order_limits(robot, n))
227 return example_expect_ok(status,
"copp_add_axial_jerk_limits");
230static int example_create_robot_2nd(
const struct CoppPath *path,
237 if (example_expect_ok(status,
"copp_robot_create"))
243 if (example_expect_ok(status,
"copp_robot_append_s"))
251 if (example_expect_ok(status,
"copp_robot_sample_path_2nd") ||
252 example_add_second_order_limits(*out_robot, n))
262static int example_create_robot_3rd(
const struct CoppPath *path,
269 if (example_expect_ok(status,
"copp_robot_create"))
275 if (example_expect_ok(status,
"copp_robot_append_s"))
283 if (example_expect_ok(status,
"copp_robot_sample_path_3rd") ||
284 example_add_third_order_limits(*out_robot, n))
294static int example_solve_topp2_seed(
struct CoppRobot *robot,
size_t n,
struct CoppVecF64 *out_a)
298 if (example_expect_ok(status,
"topp2_ra_default_options"))
304 status =
topp2_ra(problem, options, out_a);
305 if (example_expect_ok(status,
"topp2_ra"))
309 if (out_a->
data == NULL || out_a->
len != n)
311 fprintf(stderr,
"unexpected TOPP2 seed length\n");
317static int example_seed_third_order_problem(
struct CoppRobot *
robot,
321 if (example_solve_topp2_seed(
robot, n, out_a_seed))
328 return example_expect_ok(status,
"copp_robot_amax_substitute");
331static int example_time_from_second_order(
const double *s,
343 if (example_expect_ok(status,
"copp_s_to_t_2nd"))
347 if (!isfinite(*out_t_final) || *out_t_final <= 0.0 || *out_t_final >= DBL_MAX)
349 fprintf(stderr,
"invalid second-order time profile\n");
355static int example_time_from_third_order(
const double *s,
370 if (example_expect_ok(status,
"copp_s_to_t_3rd"))
374 if (!isfinite(*out_t_final) || *out_t_final <= 0.0 || *out_t_final >= DBL_MAX)
376 fprintf(stderr,
"invalid third-order time profile\n");
382static int example_interpolate_second_order(
const double *s,
396 return example_expect_ok(status,
"copp_t_to_s_uniform_2nd");
399static int example_interpolate_third_order(
const double *s,
416 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.