Source

papl / src / PaplQ.mli

Full commit
(*
  Copyright (c) 2012 Anders Lau Olsen.
  See LICENSE file for terms and conditions.
*)
(** Vector configurations

A configuration of type [PaplQ.t = float BatArray.t] is an array of floats.

Such configurations are useful for example for path planning for serial
manipulators.

For other types of planning and robots you may prefer other more structured
representations of the robot state. A simple example is {! PaplQTime.t} for
planning in time in a [PaplQ.t] configuration space.

It is your reponsibility not to mix configurations of different lengths.

*)

include module type of PaplVector.Array

(** {2 Imperative operators} *)

val ( *=:) : t -> float -> unit
(** Scale a vector. *)

val (/=:) : t -> float -> unit
(** Divide a vector. *)

val (+=:) : t -> t -> unit
(** Add a vector. *)

val (-=:) : t -> t -> unit
(** Subtract a vector. *)

(** {2 Metrics} *)

val dist_inf_box_normalized : box_t -> t PaplMetric.t
(** The metric [dist= dist_inf_box_normalized (a, b)] is the weighted infinity
    metric for which [dist a b == 1] (approximately).
*)

val dist2_box_normalized : box_t -> t PaplMetric.t
(** The metric [dist= dist_inf_box_normalized (a, b)] is the weighted Euclidean
    metric for which [dist a b == 1] (approximately).
*)

val dist2_sqr_box_normalized : box_t -> t PaplMetric.t
(** The metric [dist= dist_inf_box_normalized (a, b)] is the square of the
    weighted Euclidean metric for which [dist a b == 1] (approximately).
*)

(** {2 Boxes} *)

(** Box operations *)
module Box : sig
  val scale : float -> box_t -> box_t
(** Scaling of a box.

    [scale s (a, b) = (s *: a, s *: b)].
*)

  val translate : t -> box_t -> box_t
(** Translation of a box.

    [translate q (a, b) = (a +: q, b +: q)].
*)

  val intersect : box_t -> box_t -> box_t
(** The intersection of a pair of boxes. *)

  val center : box_t -> t -> box_t
(** Centering of a box at a configuration.

    [center box q] translates the corners of [box] such that [q] is at the
    center of the new box.
*)

  val within : box_t -> t -> bool
(** [within box (a, b)] is true iff
    [a.(i) <= q.(i) && q.(i) <= b.(i)] for all [i].
*)

  val within_by_eps : float -> box_t -> t -> bool
(** [within_by_eps eps box (a, b)] is true iff
    [a.(i) -. eps <= q.(i) && q.(i) <= b.(i) +. eps] for all [i].
*)

  val is_empty : box_t -> bool
(** A box [(a, b)] is empty if [ai > bi] for any coordinate [i].
*)
end

(** {2 Gram-Schmidt orthonormalization} *)

val gram_schmidt_by : dot_t -> int -> (unit -> t) -> t list
(**
   Gram-Schmidt orthonormalization.

   [gram_schmidt_by dot n make] creates an orthonormal basis of [n] elements on
   a space with inner product [dot], using vectors returned by [make ()].

   The [make] procedure will be called until [n] linearly independent vectors
   have been returned.

   The {{: http://en.wikipedia.org/wiki/Gram%E2%80%93Schmidt_process}modified
   Gram-Schmidt algorithm} is used.
*)

val gram_schmidt : int -> (unit -> t) -> t list
(**
   Gram-Schmidt orthonormalization.

   [gram_schmidt n make] is equivalent to [gram_schmidt_by dot n make].
*)

(** {2 Interpolation for circular joints} *)

val interpolate_circular : int -> int list -> t PaplInterpolate.t
(** Interpolation function for robots with circular joints.

    A circular joint is a revolute joint without any joint limits. The
    interpolation function for the circular joint always chooses the shortest
    rotation from one angle to the other.

    Suppose a robot has [n] joints and that joint [j0, ..., jN] are circular.
    Then [interpolate_circular n \[j0; ...; jN\]] is the interpolation for the
    robot.

    The joint numbers [j0, ..., jN] must be in the range [\[0, n)]. The joints
    that are not listed in [j0, ..., jN] are interpolated by the standard linear
    interpolation for floats.
*)