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.
+ +