Skip to content

Prototype board#9

Merged
SlushEE0 merged 2 commits intomainfrom
prototype-board
Jan 24, 2026
Merged

Prototype board#9
SlushEE0 merged 2 commits intomainfrom
prototype-board

Conversation

@SlushEE0
Copy link
Member

@SlushEE0 SlushEE0 commented Jan 24, 2026

Summary by CodeRabbit

  • New Features

    • Added intake motor control for operator interface
  • Improvements

    • Optimized gyro update timing for enhanced odometry accuracy
    • Increased encoder synchronization frequency for better performance
  • Configuration Updates

    • Updated swerve module encoder offsets and motor settings
    • Modified pilot and operator control bindings
    • Updated joystick hardware configuration

✏️ Tip: You can customize this high-level summary in your review settings.

Copilot AI review requested due to automatic review settings January 24, 2026 17:16
@SlushEE0 SlushEE0 merged commit a819f19 into main Jan 24, 2026
4 of 5 checks passed
@coderabbitai
Copy link

coderabbitai bot commented Jan 24, 2026

Caution

Review failed

The pull request is closed.

📝 Walkthrough

Walkthrough

Updates build metadata, adds intake motor subsystem with button-controlled voltage output, modifies swerve drive encoder offset calculations and motor inversion configuration, introduces AngularVelocity type for turn velocity measurement, and refactors button bindings to include gyro reset functionality.

Changes

Cohort / File(s) Summary
Build & Configuration
Template/simgui-ds.json, Template/src/main/java/frc/robot/BuildConstants.java
Updated joystick GUID identifier and refreshed build metadata constants (GIT_REVISION, GIT_SHA, GIT_DATE, GIT_BRANCH, BUILD_DATE, BUILD_UNIX_TIME) to reflect new build timestamp and branch.
Intake Motor System
Template/src/main/java/frc/robot/Robot.java
Added public static intakeMotor field of type OptixSpark initialized with device ID 36 in inverted configuration.
Motor Control Utilities
Template/src/main/java/frc/robot/utils/OptixSpark.java
Refactored wrapping logic to use MathUtil.inputModulus instead of custom modulus implementation; removed special-case handling when min equals max.
Input Bindings & Control
Template/src/main/java/frc/robot/config/ButtonBindings.java
Replaced pilot A binding (OnTheFly) with pilot start binding for gyro reset; added operator B binding to control intake motor voltage (7.5 when active, 0 when inactive); introduced new switchCommands(Runnable, Runnable) overload for Runnable-based actions.
Swerve Configuration
Template/src/main/java/frc/robot/config/SwerveConfig.java
Added TURN_INVERTED boolean array and expanded CANCODER_OFFSET array from three to four entries with updated offset values to support fourth module.
Swerve Core Logic
Template/src/main/java/frc/robot/subsystems/swerve/Swerve.java, Template/src/main/java/frc/robot/subsystems/swerve/SwerveModule.java
Reordered gyro update call before odometry update in periodic; lowered encoder synchronization threshold from 20.0 to 7.0 seconds; changed tuning parameter logging namespace from nested to flattened structure; toggled Offset Override default from false to true.
Swerve Type Safety
Template/src/main/java/frc/robot/subsystems/swerve/SwerveModuleIO.java
Changed turnVelocityRadPerSec field from double to AngularVelocity type with updated initialization using RadiansPerSecond.of().
Swerve Module Implementations
Template/src/main/java/frc/robot/subsystems/swerve/real/SwerveModuleSpark.java, Template/src/main/java/frc/robot/subsystems/swerve/sim/SwerveModuleSim.java
Consolidated data field initialization, added absoluteEncoderOffset field, implemented turn motor inversion and position wrapping; updated absolute encoder offset calculation; converted turn velocity to unit-aware AngularVelocity type throughout.
Utility Functions
Template/src/main/java/frc/robot/utils/MiscUtils.java
Added public static normalize(Rotation2d) utility method to normalize rotation values using MathUtil.angleModulus.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 Four wheels now spin with inverted grace,
New offsets guide each swerve's place,
Intake motors hum their voltage song,
Types grow stronger, safer, strong,
A prototype board finds its way! 🚀

✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR implements prototype board-specific configurations and refactoring for swerve drive modules. The changes include hardware calibration values, code quality improvements, and a prototype intake motor integration for testing.

Changes:

  • Refactored position wrapping logic in OptixSpark to use WPILib's MathUtil.inputModulus
  • Updated swerve module configuration with hardware-specific calibration offsets and motor inversions
  • Changed turnVelocityRadPerSec type from double to AngularVelocity for better type safety
  • Added prototype intake motor integration with button bindings for testing
  • Adjusted encoder sync interval and tunables path structure

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
OptixSpark.java Simplified position wrapping logic using MathUtil.inputModulus, removed min==max validation, added explicit this qualifiers
MiscUtils.java Added normalize() utility method for Rotation2d normalization
SwerveModuleSim.java Updated to use typed AngularVelocity for turn velocity instead of raw doubles
SwerveModuleSpark.java Added position wrapping configuration, turn motor inversion support, refactored encoder initialization, and type-safe velocity handling
SwerveModuleIO.java Changed turnVelocityRadPerSec from double to AngularVelocity type
SwerveModule.java Updated tunable parameter paths with leading slash, changed offset override default to true
Swerve.java Reordered periodic() method to call gyro update before odometry, reduced encoder sync interval to 7 seconds
SwerveConfig.java Updated CANCODER_OFFSET values for prototype hardware, added TURN_INVERTED configuration array
ButtonBindings.java Added intake motor control bindings and Runnable overload for switchCommands method
Robot.java Initialized prototype intake motor as static field for testing
BuildConstants.java Updated build metadata
simgui-ds.json Changed joystick GUID configuration
Comments suppressed due to low confidence (1)

Template/src/main/java/frc/robot/utils/OptixSpark.java:352

  • The removal of the min==max check creates a potential issue. If min and max are equal, this will set wrapMin and wrapMax to the same value, which could cause division by zero or incorrect behavior in the positionError method (line 478) where errorBound is calculated as (wrapMax - wrapMin) / 2.0. Consider adding validation to handle or reject the case where min equals max.
        double a = Math.min(min, max);
        double b = Math.max(min, max);
        this.wrapEnabled = true;
        this.wrapMin = a;
        this.wrapMax = b;

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

setModuleStates(desiredStates);

if (getIsStopped() && (Timer.getTimestamp() - lastEncoderSyncTime) > 20.0) {
if (getIsStopped() && (Timer.getTimestamp() - lastEncoderSyncTime) > 7.0) {
Copy link

Copilot AI Jan 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The encoder sync interval was reduced from 20.0 seconds to 7.0 seconds. While this will cause more frequent encoder syncing, ensure this frequency is appropriate and won't cause performance issues or wear on hardware. Document the rationale for this specific timeout value.

Copilot uses AI. Check for mistakes.
Comment on lines +83 to +85
intakeMotor = OptixSpark.ofSparkMax(36);
intakeMotor.setInverted(true);
intakeMotor.apply();
Copy link

Copilot AI Jan 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The intakeMotor is initialized as a public static field but is not managed as a proper subsystem. This bypasses WPILib's command-based framework benefits like proper requirements management and lifecycle hooks. Consider creating a proper IntakeSubsystem that extends SubsystemBase, or at minimum, ensure the motor is properly stopped in appropriate lifecycle methods (e.g., disabledInit, autonomousExit).

Copilot uses AI. Check for mistakes.
Rotation2d.fromRadians(2.746),
Rotation2d.fromRadians(-1.161),
Rotation2d.fromRadians(0),
Rotation2d.fromRadians(-9.779+Math.PI),
Copy link

Copilot AI Jan 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The CANCODER_OFFSET value for module 0 uses the expression (-9.779+Math.PI) which evaluates to approximately -6.6374. Consider replacing this with the computed value or adding a comment explaining why this specific mathematical expression is used. Having the expression inline makes it less clear what the intended offset value is.

Suggested change
Rotation2d.fromRadians(-9.779+Math.PI),
// Module 0 offset: (-9.779 + Math.PI) rad ≈ -6.6374 rad
Rotation2d.fromRadians(-6.6374),

Copilot uses AI. Check for mistakes.
Comment on lines +54 to +58
Bind.button(ctl.b()).switchCommands(() -> {
Robot.intakeMotor.setVoltage(7.5);
}, () -> {
Robot.intakeMotor.setVoltage(0);
});
Copy link

Copilot AI Jan 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The switchCommands binding implementation has a logic issue. The Commands.either() will evaluate the condition when the button is pressed, and the switchState toggle happens immediately, so the command will alternate each press. However, using runOnce() means each command only runs once when the button is pressed, not continuously. This is likely not the intended behavior for motor control. Consider using Commands.run() for continuous execution while the motor should be on, or implement a proper toggle that maintains state between button presses.

Suggested change
Bind.button(ctl.b()).switchCommands(() -> {
Robot.intakeMotor.setVoltage(7.5);
}, () -> {
Robot.intakeMotor.setVoltage(0);
});
ctl.b().toggleOnTrue(
Commands.startEnd(
() -> Robot.intakeMotor.setVoltage(7.5),
() -> Robot.intakeMotor.setVoltage(0)));

Copilot uses AI. Check for mistakes.
import frc.robot.config.RobotConfig.Input;
import frc.robot.config.RobotConfig.RobotType;
import frc.robot.utils.MiscUtils;
import frc.robot.utils.OptixSpark;
Copy link

Copilot AI Jan 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The import for OptixSpark is added but never used in this file. The only reference to OptixSpark is through Robot.intakeMotor, which doesn't require the import. Consider removing this unused import.

Suggested change
import frc.robot.utils.OptixSpark;

Copilot uses AI. Check for mistakes.
Comment on lines +93 to +97
public static Rotation2d normalize(Rotation2d rotation) {
double currentRads = rotation.getRadians();
return Rotation2d.fromRadians(MathUtil.angleModulus(currentRads));
}

Copy link

Copilot AI Jan 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new normalize method is added but never used in this PR. The method applies angleModulus to normalize a Rotation2d to the range [-π, π]. This appears to be dead code unless there's a planned future use. Consider removing it if it's not needed, or adding usage if it is intended to be used.

Suggested change
public static Rotation2d normalize(Rotation2d rotation) {
double currentRads = rotation.getRadians();
return Rotation2d.fromRadians(MathUtil.angleModulus(currentRads));
}

Copilot uses AI. Check for mistakes.
tunableTurnKI = new LoggedNetworkNumber("/Tuning/Swerve/Module " + name + "/Turn/kI", turnConfig.kI);
tunableTurnKD = new LoggedNetworkNumber("/Tuning/Swerve/Module " + name + "/Turn/kD", turnConfig.kD);

tunableOffsetOverride = new LoggedNetworkBoolean("/Tuning/Swerve/Module " + name + "/Offset Override", true);
Copy link

Copilot AI Jan 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The tunableOffsetOverride default value changed from false to true. This means offset override will be enabled by default, which could affect the behavior on robot startup. Ensure this change is intentional and that it won't cause unexpected behavior when the robot is initialized.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants