Introduction
This is the official documentation for FTC Team 23511, the Seattle Solvers.
Please note: while this mdBook is open-source, there is no guarantee that any pull requests/issues will be addressed or merged.
Odometry Testing
Environment:
- Latest FIRST Tech Challenge Field Soft Tiles
- Lightly used (1 season)
- Vacuumed before each new odometry system used
- No game elements (trusses, stage door, backdrop, etc.)
- Wood floor and tarp underneath field
Environment does not change or get moved between tests!
Hardware:
- Strafer® Chassis Kit V5 - goBILDA® - all parts lightly used for 1 season or less with no effects to performance
- Only modification of 435 RPM goBILDA® motors
- Same goBILDA® MOD 1.25 30 tooth gears as what come in the kit
- Added weights at the center of the robot until robot weighs 25 lbs
- All screws have red loctite applied to them to keep robot rigid between tests
- “New” Control Hub
- Both IMUs available and tested individually for 2 wheel testing
- Internal BHI260AP IMU
- External BNO055 IMU
- All tests done when battery is between 12-13v (measured via REV Driver Hub)
- All batteries are less than a year old
Only hardware changes between tests are changing the odometry module!
- CAD models for all odometry set-ups can be found here
Software:
-
Robot Library: RoadRunner V1.0 (Quickstart, 3 Dead Wheels)
-
Tuning steps: (each step should be ran 3 times, and the three values should be averaged to get the final constant)
-
ForwardPushTest
&LateralPushTest
: \( \frac{\frac{96}{24.5}}{384.5} = 0.010190812 \) -
ForwardRampLogger
: 5 Tiles (120 inches) -
LateralRampLogger
: ~5.5 seconds of runtime -
AngularRampLogger
: ~7 seconds of runtime -
ManualFeedforwardTuner
&ManualFeedbackTuner
: 4.5 Tiles (108 inches)
-
-
Testing Specifications:
-
- Moving in every 30° direction from 0° to 330° back and forth a distance of 2 Tiles (48 inches) in a straight line
- At the end, the change in position for each odometry wheel is returned
- There is no turning
- This will all be executed with
.strafeTo(new Vector2d(x, y))
, not.lineToX(x)
or.lineTo(x)
-
- A large variety of splines, turns, and turning while strafing in complex paths
- At the end, the change in position for each odometry wheel is returned
-
- A combination of Spline Test and Straight Test
- At the end, the change in position for each odometry wheel is returned
-
Straight Test
// Straight Test
.strafeTo(new Vector2d(0, 48))
.strafeTo(new Vector2d(0, 0))
.strafeTo(new Vector2d(24, 24 * Math.sqrt(3)))
.strafeTo(new Vector2d(0, 0))
.strafeTo(new Vector2d(24 * Math.sqrt(3), 24))
.strafeTo(new Vector2d(0, 0))
.strafeTo(new Vector2d(48, 0))
.strafeTo(new Vector2d(0, 0))
.strafeTo(new Vector2d(24 * Math.sqrt(3), -24))
.strafeTo(new Vector2d(0, 0))
.strafeTo(new Vector2d(24, -24 * Math.sqrt(3)))
.strafeTo(new Vector2d(0, 0))
.strafeTo(new Vector2d(0, -48))
.strafeTo(new Vector2d(0, 0))
.strafeTo(new Vector2d(-24, -24 * Math.sqrt(3)))
.strafeTo(new Vector2d(0, 0))
.strafeTo(new Vector2d(-24 * Math.sqrt(3), -24))
.strafeTo(new Vector2d(0, 0))
.strafeTo(new Vector2d(-48, 0))
.strafeTo(new Vector2d(0, 0))
.strafeTo(new Vector2d(-24 * Math.sqrt(3), 24))
.strafeTo(new Vector2d(0, 0))
.strafeTo(new Vector2d(-24, 24 * Math.sqrt(3)))
.strafeTo(new Vector2d(0, 0))
Spline Test
// Spline Test
.strafeToSplineHeading(new Vector2d(-48, -48), Math.toRadians(0))
.setTangent(0)
.splineToSplineHeading(new Pose2d(48, 48, Math.toRadians(90)), Math.PI / 2)
.setTangent(0)
.setReversed(true)
.splineTo(new Vector2d(24, 24), Math.PI / 2)
.setTangent(0)
.setReversed(false)
.splineToConstantHeading(new Vector2d(0, 36), Math.PI / 2)
.turnTo(Math.toRadians(180))
.splineTo(new Vector2d(-48, 48), Math.PI / 2)
.splineTo(new Vector2d(0, 0), Math.PI / 2)
.strafeToSplineHeading(new Vector2d(-48, -48), Math.toRadians(0))
.setTangent(0)
.splineToSplineHeading(new Pose2d(48, 48, Math.toRadians(90)), Math.PI / 2)
.setTangent(0)
.setReversed(true)
.splineTo(new Vector2d(24, 24), Math.PI / 2)
.setTangent(0)
.setReversed(false)
.splineToConstantHeading(new Vector2d(0, 36), Math.PI / 2)
.turnTo(Math.toRadians(180))
.splineTo(new Vector2d(-48, 48), Math.PI / 2)
.splineTo(new Vector2d(0, 0), Math.PI / 2)
.strafeToSplineHeading(new Vector2d(-48, -48), Math.toRadians(0))
.setTangent(0)
.splineToSplineHeading(new Pose2d(48, 48, Math.toRadians(90)), Math.PI / 2)
.setTangent(0)
.setReversed(true)
.splineTo(new Vector2d(24, 24), Math.PI / 2)
.setTangent(0)
.setReversed(false)
.splineToConstantHeading(new Vector2d(0, 36), Math.PI / 2)
.turnTo(Math.toRadians(180))
.splineTo(new Vector2d(-48, 48), Math.PI / 2)
.splineTo(new Vector2d(0, 0), Math.PI / 2)
.strafeToSplineHeading(new Vector2d(-48, -48), Math.toRadians(0))
.setTangent(0)
.splineToSplineHeading(new Pose2d(48, 48, Math.toRadians(90)), Math.PI / 2)
.setTangent(0)
.setReversed(true)
.splineTo(new Vector2d(24, 24), Math.PI / 2)
.setTangent(0)
.setReversed(false)
.splineToConstantHeading(new Vector2d(0, 36), Math.PI / 2)
.turnTo(Math.toRadians(180))
.splineTo(new Vector2d(-48, 48), Math.PI / 2)
.splineTo(new Vector2d(0, 0), Math.PI / 2)
Combined Test
// Combined Test
.strafeToSplineHeading(new Vector2d(-48, -48), Math.toRadians(0))
.strafeTo(new Vector2d(-24, 24 * Math.sqrt(3)))
.setTangent(0)
.splineToSplineHeading(new Pose2d(48, 48, Math.toRadians(90)), Math.PI / 2)
.strafeToSplineHeading(new Vector2d(-48, 48), Math.toRadians(270))
.turnTo(Math.toRadians(315))
.splineTo(new Vector2d(-48, 12), Math.PI / 6)
.splineToSplineHeading(new Pose2d(48, -6, Math.toRadians(215)), Math.PI / 3)
.setReversed(true)
.splineToSplineHeading(new Pose2d(6, -48, Math.toRadians(215)), Math.PI / 4)
.splineTo(new Vector2d(36, -18), Math.PI / 2)
.strafeToLinearHeading(new Vector2d(24, 24), Math.toRadians(0))
.turnTo(Math.toRadians(45))
.lineToX(0)
.turn(Math.toRadians(-45))
.strafeToSplineHeading(new Vector2d(-48, -48), Math.toRadians(0))
.strafeTo(new Vector2d(-24, 24 * Math.sqrt(3)))
.setTangent(0)
.splineToSplineHeading(new Pose2d(48, 48, Math.toRadians(90)), Math.PI / 2)
.strafeToSplineHeading(new Vector2d(-48, 48), Math.toRadians(270))
.turnTo(Math.toRadians(315))
.splineTo(new Vector2d(-48, 12), Math.PI / 6)
.splineToSplineHeading(new Pose2d(48, -6, Math.toRadians(215)), Math.PI / 3)
.setReversed(true)
.splineToSplineHeading(new Pose2d(6, -48, Math.toRadians(215)), Math.PI / 4)
.splineTo(new Vector2d(36, -18), Math.PI / 2)
.strafeToLinearHeading(new Vector2d(24, 24), Math.toRadians(0))
.turnTo(Math.toRadians(45))
.lineToX(0)
.turn(Math.toRadians(-45))
.strafeToSplineHeading(new Vector2d(-48, -48), Math.toRadians(0))
.strafeTo(new Vector2d(-24, 24 * Math.sqrt(3)))
.setTangent(0)
.splineToSplineHeading(new Pose2d(48, 48, Math.toRadians(90)), Math.PI / 2)
.strafeToSplineHeading(new Vector2d(-48, 48), Math.toRadians(270))
.turnTo(Math.toRadians(315))
.splineTo(new Vector2d(-48, 12), Math.PI / 6)
.splineToSplineHeading(new Pose2d(48, -6, Math.toRadians(215)), Math.PI / 3)
.setReversed(true)
.splineToSplineHeading(new Pose2d(6, -48, Math.toRadians(215)), Math.PI / 4)
.splineTo(new Vector2d(36, -18), Math.PI / 2)
.strafeToLinearHeading(new Vector2d(24, 24), Math.toRadians(0))
.turnTo(Math.toRadians(45))
.lineToX(0)
.turn(Math.toRadians(-45))
Contributors
Image above was made with contrib.rocks.