From 6273e58dbfe9dee7812dbaf971de7755ae3cbead Mon Sep 17 00:00:00 2001 From: Joel Truher Date: Sat, 27 Dec 2025 09:16:38 -0800 Subject: [PATCH] doc --- .../java/org/team100/lib/profile/README.md | 28 +++++++++++-------- .../org/team100/lib/profile/se2/README.md | 10 +++++++ .../org/team100/lib/profile/timed/README.md | 2 +- .../java/org/team100/lib/trajectory/README.md | 26 +++++++++++++---- .../org/team100/lib/visualization/README.md | 2 +- 5 files changed, 50 insertions(+), 18 deletions(-) create mode 100644 lib/src/main/java/org/team100/lib/profile/se2/README.md diff --git a/lib/src/main/java/org/team100/lib/profile/README.md b/lib/src/main/java/org/team100/lib/profile/README.md index ee0334ed..9fc22bdc 100644 --- a/lib/src/main/java/org/team100/lib/profile/README.md +++ b/lib/src/main/java/org/team100/lib/profile/README.md @@ -1,17 +1,23 @@ # lib.profile -This package supports "profiled" motion. +This package supports "profiled" motion, which means movement from +a specified starting state to an ending state, as fast as possible, +within some constraints on velocity and acceleration. -There are two types, "timed" and "incremental." +There are several subpackages: + +* `timed` profiles are like a trajectories: you precalculate the schedule +and then sample it. The main interface is `TimedProfile`. + +* `incremental` profiles have no state: you give one the current setpoint, +and it produces the next one. The main interface is `IncrementalProfile`. + +* `se2` provides multi-dimensional profiled motion in the SE(2) manifold +(x, y, theta), useful for navigation or planar motion. The main +interface is `ProfileSE2`. + +* `roadrunner` is a direct translation of the RoadRunner Kotlin classes, +which are used in the `timed` package. -A `TimedProfile` is like a trajectory: you precalculate the schedule -and then sample it. -An `IncrementalProfile` has no state: you give it the current setpoint, -and it produces the next one. There are also a few methods related to -coordinating multiple profiles so that they arrive at their goals -at the same time, e.g. for controlling multiple-DOF mechanisms, -or the drivetrain. -There is also `HolonomicProfile` which simply wraps (any) set of -three `IncrementalProfile`s and coordinates them. \ No newline at end of file diff --git a/lib/src/main/java/org/team100/lib/profile/se2/README.md b/lib/src/main/java/org/team100/lib/profile/se2/README.md new file mode 100644 index 00000000..f80f33e8 --- /dev/null +++ b/lib/src/main/java/org/team100/lib/profile/se2/README.md @@ -0,0 +1,10 @@ +# se2 + +Multi-dimensional profiled motion. + +The main interface is `ProfileSE2`. + +Implementations include + +* `HolonomicProfile` wraps any set of three `IncrementalProfile`s and coordinates them. +* `FreeRotationProfile` is similar but doesn't coordinate theta. \ No newline at end of file diff --git a/lib/src/main/java/org/team100/lib/profile/timed/README.md b/lib/src/main/java/org/team100/lib/profile/timed/README.md index 2f4a3235..00b50220 100644 --- a/lib/src/main/java/org/team100/lib/profile/timed/README.md +++ b/lib/src/main/java/org/team100/lib/profile/timed/README.md @@ -3,5 +3,5 @@ This package includes profiles that require significant precomputation, kinda like a trajectory. -At the moment, the only implementations are wrappers of roadrunner +At the moment, the only implementations are wrappers of `roadrunner` profiles. \ No newline at end of file diff --git a/lib/src/main/java/org/team100/lib/trajectory/README.md b/lib/src/main/java/org/team100/lib/trajectory/README.md index 3e83f7d7..c2941c93 100644 --- a/lib/src/main/java/org/team100/lib/trajectory/README.md +++ b/lib/src/main/java/org/team100/lib/trajectory/README.md @@ -7,14 +7,30 @@ i.e. handle course and heading separately, so they have four dimensions (x, y, h A good entry point to experiment with trajectories is `TrajectoryPlanner`. Try `restToRest()` between two poses. -The process of constructing a trajectory has three stages: +The process of constructing a trajectory has three stages. -1. Construct a list of splines. Each spline joins two points smoothly. The spline parameter has no physical meaning, it's just 0.0 on one end and 1.0 on the other. See the `lib.trajectory.path.spline` package. +1. First, make a list of `WaypointSE2`. These describe points in the SE(2) manifold that +you want to travel through. A waypoint includes -2. Construct a list of points along the spline, such that straight lines connecting the points ("secant lines") don't deviate too much from the true spline, and aren't too far apart from each other. (This uses recursive bisection.) These points will be close together where the curvature is high, and far apart along straighter sections of the spline. The list is created by `PathFactory`, producing `Path100`, which integrates along the list to find the distance. See the `lib.trajectory.path` package. + * a _translation_ in the (x,y) plane + * a _heading_ describing the orientation of the robot, i.e. where the front is facing. + * a _direction_ of motion. Note that "direction" in SE(2) has three dimensions. + * a _scale_ used for the next step. -3. Using a list of kinodynamic constraints (see `lib.trajectory.timing`), assign a time for each point. The resulting list of `TimedState`s is created by `TrajectoryFactory`, producing `Trajectory100`. +2. Construct a list of `HolonomicSpline`, with the waypoints above (called "knots") between them. +The "scale" parameter above determines the "straightness" of the curve at each knot. +In our implementation, the curvature at each knot is zero. -To use a trajectory, you `sample()` it, with time (in seconds) as the parameter. The resulting `TimedState` is interpolated between from the list above. +3. Construct a list of points (`Pose2dWithMotion`) along the splines, such that straight lines +connecting the points ("secant lines") don't deviate too much from the true spline, and aren't +too far apart from each other. (This uses recursive bisection.) These points will +be close together where the curvature is high, and far apart along straighter sections +of the spline. Each point is a `WaypointSE2` and also the spatial rate of heading and course +along the path. These steps are performed by `PathFactory`, producing `Path100`. + +4. Using a list of kinodynamic constraints (implementations of `TimingConstraint`), +assign a time for each point. The resulting list of `TimedState` is created by `TrajectoryFactory`, producing `Trajectory100`. + +To use a trajectory, you `sample()` it, with time (in seconds) as the parameter. The resulting `TimedState` is interpolated from the list of `TimedState` above. If you want to use these trajectories for non-holonomic (e.g. "tank") drivetrains, it will work well enough to set the course and heading to be the same at each waypoint. \ No newline at end of file diff --git a/lib/src/main/java/org/team100/lib/visualization/README.md b/lib/src/main/java/org/team100/lib/visualization/README.md index c9dfe749..352c858a 100644 --- a/lib/src/main/java/org/team100/lib/visualization/README.md +++ b/lib/src/main/java/org/team100/lib/visualization/README.md @@ -2,4 +2,4 @@ This package populates glass widgets. -There are more of these in studies/visualization if you're curious. \ No newline at end of file +There are more of these in studies/visualization. \ No newline at end of file