🤖 A collection of tools to help with FRC/FTC autonomous for Kotlin robots
MIT License
Here are some use cases where ezAuton would and wouldn't be a good idea to use
The following example is all that is needed for a simulation running pure pursuit that is recorded. Note this is very similar for any trajectory algorithm, I am aware pure pursuit is inferior to other methods like ramsete.
suspend fun run() {
// (1) a straight line trajectory starting at (0,0) going to (0,20) with a max speed of 3 m/s.
val trajectory = trajectory(samplePeriod = 5.ms) {
point(0.m, 0.m, speed = 0.mps, acceleration = 13.0.mps / s, deceleration = 12.0.mps / s)
point(0.m, 10.m, speed = 3.mps, acceleration = 13.0.mps / s, deceleration = 12.0.mps / s)
point(0.m, 20.m, speed = 0.mps, acceleration = 13.0.mps / s, deceleration = 12.0.mps / s)
}
// (2) a simulated robot
val robot = SimulatedTankRobot.create(lateralWheelDistance = 1.m, maxAccel = 14.0.mpss, minVel = 0.3.mps, maxVel = 16.0.mps)
// (3) a lookahead that scales with the velocity of the robot
val lookahead = ScalingLookahead(distanceRange = 1.0.m..5.0.m, speedRange = 2.0.mps..10.0.mps, velocityEstimator = robot)
// (4) pure pursuit
val purePursuit = robot.purePursuit(period = 10.ms, trajectory, lookahead)
// (4) the action we will actually be running
val action = action {
// (5) record everything inside this
val recording = recording {
// (6) include data about the path
include(trajectory.path.simpleRepr)
// (7) run pure pursuit in parallel
parallel(purePursuit)
// (8) every 10ms sample data from the robot (like location) and include in recording
sample(10.ms, robot)
}
// (9) save the recording to ~/.ezauton/test.json
recording.save("test.json")
}
action.run()
}
Create a trajectory.
.m, .mps, .mps/s = .mpss
. The library uses.ft
and likewise for other units.Create a simulated robot.
A simulated robot implements a lot of interfaces. This is useful because this library is built around interface and not implementation. Trajectory algorithms and other functions almost always accept an interface, so the library is flexible to any implementation.
Notice that some of the interfaces are oddly named. Generally, abbreviations are used at a minimum, but to avoid extraordinarily long names, a few are used. For example
Create a lookahead that scales with the speed of the robot
robot
implements TankRobotVelEst
, an interface which inVelocityEst
, so it can be passed into velocity estimatorCreate a pure pursuit action.
This uses a useful extension function to allow for less boilerplate.
The extension function depends on any classes which implement both
TransLocEst
and TransLocDrivable
. This means that the robot can estimate
its translational location and drive towards any given translational location.
The tank robot implementation of TransLocDrivable
implements this by driving in arcs.
If there is no common interface, it is easy to use the regular non-extension version
Record anything inside the scope into a Recording object which can be saved
Include the data of the path. Currently, only a simple representation of the path which is just a list of points can be serialized. This is because paths can contain any type of path segments---including weird shapes such as curves, which might be hard to serialize and even harder to display in a visualizer
Run pure pursuit in parallel (so we can sample and run pure pursuit at the same time).
Sample data (such as location) every 10 milliseconds.
Sampler<Data.TankRobotState>
, so it can be sampledSave the data to a json file located in test.json