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
  • “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:

    1. Straight Test:

      • 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)


    2. Spline Test:

      • 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


    3. Combined Test:



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.