VingVing Robot LogoVingVing Robot

Documentation v0.0.3

VingVing Robot Docs

Sample RobotConfig

Complete, working examples of RobotConfig for different robot setups

About These Examples

These are real, tested configurations. Copy and modify for your robot's specific hardware. All PID values are starting points - you'll need to tune for your robot.

Example 1: Drive Encoder Localizer

Standard mecanum drive with drive encoder localization (no dead wheels).

RobotConfig.java
package org.firstinspires.ftc.teamcode;

import com.vingvingrobot.RobotConfig;
import com.vingvingrobot.robotconfiguration.*;

public class MyRobotConfig extends RobotConfig {
    // Mecanum drive constants
    public static MecanumConstants driveConstants = new MecanumConstants()
        .maxPower(1.0)
        // Motor hardware config names
        .leftFront("leftFront")
        .rightFront("rightFront")
        .leftBack("leftBack")
        .rightBack("rightBack")
        // Motor directions (adjust for your robot!)
        .leftFrontDirection(MotorDirection.FORWARD)
        .rightFrontDirection(MotorDirection.REVERSE)
        .leftBackDirection(MotorDirection.FORWARD)
        .rightBackDirection(MotorDirection.REVERSE)
        // Velocity from automatic tuners
        .xVelocity(52.3)
        .yVelocity(48.5);

    // Localizer configuration - using drive encoders
    public static LocalizerConstants localizerConstants = new LocalizerConstants()
        .localizerType(LocalizerType.DRIVE_ENCODER)
        // Drive encoder configuration
        .forwardEncoder("leftFront")
        .forwardEncoderDirection(ForwardEncoder.FORWARD)
        .strafeEncoder("rightFront")
        .strafeEncoderDirection(StrafeEncoder.FORWARD)
        .turnEncoder("rightBack")
        .turnEncoderDirection(TurnEncoder.REVERSE)
        // IMU for heading
        .imu("imu")
        .imuOrientation(IMUOrientation.LOGO_UP_USB_LEFT)
        // Track width (distance between left and right wheels)
        .trackWidth(14.5);

    // Path following constants
    public static FollowerConstants followerConstants = new FollowerConstants()
        .mass(10.0)
        // From automatic zero-power acceleration tuners
        .forwardZeroPowerAcceleration(-38.2)
        .lateralZeroPowerAcceleration(-42.1)
        // Translational PID (movement toward path)
        .translationalPID(new PIDFCoefficients(
            0.3,   // P
            0.0,   // I
            0.005, // D
            0.0    // F
        ))
        // Heading PID (rotation)
        .headingPID(new PIDFCoefficients(
            2.5,   // P
            0.0,   // I
            0.1,   // D
            0.0    // F
        ))
        // Drive PID (forward along path)
        .drivePID(new PIDFCoefficients(
            0.05,  // P
            0.0,   // I
            0.0,   // D
            0.0    // F
        ))
        // Centripetal PID (curve correction)
        .centripetalPID(new PIDFCoefficients(
            0.002, // P
            0.0,   // I
            0.0,   // D
            0.0    // F
        ))
        // Path completion tolerances
        .completionTolerances(2.0, 2.0, Math.toRadians(5));
}

Example 2: Three-Wheel Odometry

Mecanum drive with three dedicated odometry wheels for superior accuracy.

RobotConfig.java
public class ThreeWheelConfig extends RobotConfig {
    public static MecanumConstants driveConstants = new MecanumConstants()
        .maxPower(1.0)
        .leftFront("leftFront")
        .rightFront("rightFront")
        .leftBack("leftBack")
        .rightBack("rightBack")
        .leftFrontDirection(MotorDirection.FORWARD)
        .rightFrontDirection(MotorDirection.REVERSE)
        .leftBackDirection(MotorDirection.FORWARD)
        .rightBackDirection(MotorDirection.REVERSE)
        .xVelocity(55.0)
        .yVelocity(50.0);

    // Three-wheel odometry localizer
    public static LocalizerConstants localizerConstants = new LocalizerConstants()
        .localizerType(LocalizerType.THREE_WHEEL)
        // Odometry pods
        .forwardEncoder("odoParallel")
        .forwardEncoderDirection(ForwardEncoder.FORWARD)
        .strafeEncoder("odoPerpendicular")
        .strafeEncoderDirection(StrafeEncoder.REVERSE)
        .turnEncoder("odoTurn")
        .turnEncoderDirection(TurnEncoder.FORWARD)
        // Pod positions from robot center (inches)
        .centerWheelOffset(6.5)   // Perpendicular pod offset
        .lateralDistance(8.0)     // Parallel pod offset
        .trackWidth(14.5)         // Distance between turn and parallel pods
        // IMU
        .imu("imu")
        .imuOrientation(IMUOrientation.LOGO_UP_USB_FORWARD);

    public static FollowerConstants followerConstants = new FollowerConstants()
        .mass(12.0)
        .forwardZeroPowerAcceleration(-40.5)
        .lateralZeroPowerAcceleration(-45.0)
        .translationalPID(new PIDFCoefficients(0.35, 0.0, 0.008, 0.0))
        .headingPID(new PIDFCoefficients(3.0, 0.0, 0.15, 0.0))
        .drivePID(new PIDFCoefficients(0.06, 0.0, 0.0, 0.0))
        .centripetalPID(new PIDFCoefficients(0.003, 0.0, 0.0, 0.0))
        .completionTolerances(1.5, 1.5, Math.toRadians(3));
}

Example 3: GoBilda Pinpoint

Using GoBilda Pinpoint odometry computer for simplified wiring.

RobotConfig.java
public class PinpointConfig extends RobotConfig {
    public static MecanumConstants driveConstants = new MecanumConstants()
        .maxPower(1.0)
        .leftFront("leftFront")
        .rightFront("rightFront")
        .leftBack("leftBack")
        .rightBack("rightBack")
        .leftFrontDirection(MotorDirection.FORWARD)
        .rightFrontDirection(MotorDirection.REVERSE)
        .leftBackDirection(MotorDirection.FORWARD)
        .rightBackDirection(MotorDirection.REVERSE)
        .xVelocity(58.0)
        .yVelocity(53.0);

    // Pinpoint localizer
    public static LocalizerConstants localizerConstants = new LocalizerConstants()
        .localizerType(LocalizerType.PINPOINT)
        // Pinpoint device name
        .pinpoint("pinpoint")
        // Pod offsets from robot center
        .xOffset(2.5)    // Forward offset
        .yOffset(-3.0)   // Lateral offset (left is positive)
        // Encoder directions
        .forwardEncoderDirection(ForwardEncoder.FORWARD)
        .strafeEncoderDirection(StrafeEncoder.REVERSE);

    public static FollowerConstants followerConstants = new FollowerConstants()
        .mass(11.0)
        .forwardZeroPowerAcceleration(-42.0)
        .lateralZeroPowerAcceleration(-48.0)
        .translationalPID(new PIDFCoefficients(0.4, 0.0, 0.01, 0.0))
        .headingPID(new PIDFCoefficients(3.5, 0.0, 0.2, 0.0))
        .drivePID(new PIDFCoefficients(0.07, 0.0, 0.0, 0.0))
        .centripetalPID(new PIDFCoefficients(0.0025, 0.0, 0.0, 0.0))
        .completionTolerances(1.0, 1.0, Math.toRadians(2));
}

Example 4: SparkFun OTOS

Optical tracking odometry sensor for accurate position tracking.

RobotConfig.java
public class OTOSConfig extends RobotConfig {
    public static MecanumConstants driveConstants = new MecanumConstants()
        .maxPower(1.0)
        .leftFront("leftFront")
        .rightFront("rightFront")
        .leftBack("leftBack")
        .rightBack("rightBack")
        .leftFrontDirection(MotorDirection.FORWARD)
        .rightFrontDirection(MotorDirection.REVERSE)
        .leftBackDirection(MotorDirection.FORWARD)
        .rightBackDirection(MotorDirection.REVERSE)
        .xVelocity(60.0)
        .yVelocity(55.0);

    // OTOS localizer
    public static LocalizerConstants localizerConstants = new LocalizerConstants()
        .localizerType(LocalizerType.OTOS)
        // OTOS sensor name
        .otos("sensor_otos")
        // Sensor offset from robot center
        .xOffset(0.0)    // Centered
        .yOffset(0.0)    // Centered
        // Sensor orientation
        .otosOrientation(OTOSOrientation.STANDARD);

    public static FollowerConstants followerConstants = new FollowerConstants()
        .mass(9.5)
        .forwardZeroPowerAcceleration(-35.0)
        .lateralZeroPowerAcceleration(-38.0)
        .translationalPID(new PIDFCoefficients(0.45, 0.0, 0.012, 0.0))
        .headingPID(new PIDFCoefficients(4.0, 0.0, 0.25, 0.0))
        .drivePID(new PIDFCoefficients(0.08, 0.0, 0.0, 0.0))
        .centripetalPID(new PIDFCoefficients(0.003, 0.0, 0.0, 0.0))
        .completionTolerances(0.8, 0.8, Math.toRadians(2));
}

Configuration Tips

💡 Start with These Values

Use the example closest to your hardware as a starting point. Then run automatic tuners for velocity and zero-power acceleration. Finally, tune PID values.

💡 Verify Motor Directions

Motor directions depend on physical mounting. Test each motor individually to ensure FORWARD makes the robot move forward, not backward or sideways.

💡 Document Your Config

Add comments explaining your robot's specific values. Future you (or teammates) will appreciate knowing why particular PID values were chosen.

Next: See Config in Action

Now that you have a complete RobotConfig, see how to use it in autonomous and TeleOp.