Skip to content

Commit

Permalink
Merge pull request #11 from RAR1741/sysid
Browse files Browse the repository at this point in the history
add SysId
  • Loading branch information
kryllyxofficial01 authored Feb 11, 2025
2 parents cceb794 + 6211af0 commit 3e21060
Show file tree
Hide file tree
Showing 3 changed files with 235 additions and 7 deletions.
43 changes: 36 additions & 7 deletions src/main/java/frc/robot/Robot.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,13 @@

import edu.wpi.first.math.geometry.Pose2d;
import edu.wpi.first.wpilibj.DataLogManager;
import edu.wpi.first.wpilibj.DriverStation;
import edu.wpi.first.wpilibj.GenericHID;
import edu.wpi.first.wpilibj2.command.CommandScheduler;
import edu.wpi.first.wpilibj2.command.sysid.SysIdRoutine;
import frc.robot.constants.RobotConstants;
import frc.robot.controls.controllers.DriverController;
import frc.robot.controls.controllers.FilteredController;
import edu.wpi.first.wpilibj.DriverStation;
import frc.robot.controls.controllers.OperatorController;
import frc.robot.controls.controllers.VirtualRobotController;
import frc.robot.subsystems.Elevator;
Expand All @@ -22,6 +26,7 @@
import frc.robot.subsystems.Subsystem;
import frc.robot.subsystems.drivetrain.RAROdometry;
import frc.robot.subsystems.drivetrain.SwerveDrive;
import frc.robot.subsystems.drivetrain.SwerveSysId;

/**
* The methods in this class are called automatically corresponding to each
Expand All @@ -38,11 +43,15 @@ public class Robot extends LoggedRobot {
// private final EndEffector m_endAffector;
private final RAROdometry m_odometry;
private final PoseAligner m_poseAligner;
private final SignalManager m_signalManager = SignalManager.getInstance();

private final DriverController m_driverController;
private final OperatorController m_operatorController;

private final VirtualRobotController m_virtualRobotController;
private final SignalManager m_signalManager = SignalManager.getInstance();
private final GenericHID m_sysIdController;

private final SwerveSysId m_swerveSysId;

/**
* This function is run when the robot is first started up and should be used
Expand All @@ -61,6 +70,7 @@ public Robot() {
m_driverController = new DriverController(0, true, true, 0.5);
m_operatorController = new OperatorController(1, true, true, 0.5);
m_virtualRobotController = new VirtualRobotController(2);
m_sysIdController = new GenericHID(3);

// SCARY
DriverStation.silenceJoystickConnectionWarning(true);
Expand All @@ -79,17 +89,24 @@ public Robot() {
RobotTelemetry.print("Logging Initialized. Fard.");

m_signalManager.finalizeAll();

m_swerveSysId = new SwerveSysId(m_swerve.getSwerveModules(), "SwerveSysId");
}

@Override
public void robotPeriodic() {
m_virtualRobotController.updatePose();
if (this.isTestEnabled()) {
CommandScheduler.getInstance().run();
}
else {
m_virtualRobotController.updatePose();

m_subsystems.forEach(subsystem -> subsystem.periodic());
m_subsystems.forEach(subsystem -> subsystem.writePeriodicOutputs());
m_subsystems.forEach(subsystem -> subsystem.writeToLog());
m_subsystems.forEach(subsystem -> subsystem.periodic());
m_subsystems.forEach(subsystem -> subsystem.writePeriodicOutputs());
m_subsystems.forEach(subsystem -> subsystem.writeToLog());

m_signalManager.refresh();
m_signalManager.refresh();
}
}

@Override
Expand Down Expand Up @@ -179,10 +196,22 @@ public void disabledPeriodic() {

@Override
public void testInit() {
CommandScheduler.getInstance().cancelAll();
}

@Override
public void testPeriodic() {
if (m_sysIdController.getRawButtonPressed(FilteredController.Button.A)) {
m_swerveSysId.sysIdDriveQuasistatic(SysIdRoutine.Direction.kForward).schedule();
} else if (m_sysIdController.getRawButtonPressed(FilteredController.Button.B)) {
m_swerveSysId.sysIdDriveQuasistatic(SysIdRoutine.Direction.kReverse).schedule();
} else if (m_sysIdController.getRawButtonPressed(FilteredController.Button.X)) {
m_swerveSysId.sysIdDriveDynamic(SysIdRoutine.Direction.kForward).schedule();
} else if (m_sysIdController.getRawButtonPressed(FilteredController.Button.Y)) {
m_swerveSysId.sysIdDriveDynamic(SysIdRoutine.Direction.kReverse).schedule();
} else if (m_sysIdController.getRawButtonPressed(FilteredController.Button.START)) {
CommandScheduler.getInstance().cancelAll();
}
}

@Override
Expand Down
19 changes: 19 additions & 0 deletions src/main/java/frc/robot/subsystems/drivetrain/SwerveModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,25 @@ public SwerveModuleState getDesiredState() {
return m_periodicIO.desiredState;
}

// Pass voltage into drive motor and set turn motor to 0 deg
public void sysidDrive(double volts) {
// hold the turn motor in place
MotionMagicVoltage turnRequest = new MotionMagicVoltage(0).withSlot(0);
turnRequest.EnableFOC = true;
m_turnMotor.setControl(turnRequest);

m_driveMotor.setVoltage(volts);
}

// Pass voltage into turn motor and set drive motor to 0 volts⚡
public void sysidTurn(double volts) {
// hold the drive motor
VelocityVoltage driveRequest = new VelocityVoltage(0).withSlot(0);
m_driveMotor.setControl(driveRequest);

m_turnMotor.setVoltage(volts);
}

public void periodic() {
double driveVelocity = Helpers.MPSToRPS(getDriveTargetVelocity(),
RobotConstants.robotConfig.SwerveDrive.k_wheelCircumference);
Expand Down
180 changes: 180 additions & 0 deletions src/main/java/frc/robot/subsystems/drivetrain/SwerveSysId.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
package frc.robot.subsystems.drivetrain;

import edu.wpi.first.units.measure.MutDistance;
import edu.wpi.first.units.measure.MutLinearVelocity;
import edu.wpi.first.units.measure.MutVoltage;
import edu.wpi.first.units.measure.Voltage;

import static edu.wpi.first.units.Units.Meters;
import static edu.wpi.first.units.Units.MetersPerSecond;
import static edu.wpi.first.units.Units.Volts;

import edu.wpi.first.wpilibj.RobotController;
import edu.wpi.first.wpilibj2.command.Command;
import edu.wpi.first.wpilibj2.command.sysid.SysIdRoutine;
import frc.robot.subsystems.Subsystem;

public class SwerveSysId extends Subsystem {
private SwerveModule[] m_modules;

public SwerveSysId(SwerveModule[] modules, String baseSmartDashboardKey) {
super(baseSmartDashboardKey);

m_modules = modules;
}

public Command sysIdTurnQuasistatic(SysIdRoutine.Direction direction) {
return m_sysIdTurnRoutine.quasistatic(direction);
}

public Command sysIdTurnDynamic(SysIdRoutine.Direction direction) {
return m_sysIdTurnRoutine.dynamic(direction);
}

public Command sysIdDriveQuasistatic(SysIdRoutine.Direction direction) {
return m_sysIdDriveRoutine.quasistatic(direction);
}

public Command sysIdDriveDynamic(SysIdRoutine.Direction direction) {
return m_sysIdDriveRoutine.dynamic(direction);
}

// Mutable holder for unit-safe SysID values (to avoid reallocation)
private final MutVoltage m_appliedVoltage = Volts.of(0).mutableCopy();
private final MutDistance m_distance = Meters.of(0).mutableCopy();
private final MutLinearVelocity m_velocity = MetersPerSecond.of(0).mutableCopy();

private final SysIdRoutine m_sysIdDriveRoutine = new SysIdRoutine(
new SysIdRoutine.Config(),
new SysIdRoutine.Mechanism(
(Voltage volts) -> {
for (SwerveModule module : m_modules) {
module.sysidDrive(volts.in(Volts));
}
},
log -> {
log.motor("drive-frontleft").voltage(
m_appliedVoltage.mut_replace(
m_modules[SwerveDrive.Module.FRONT_LEFT].getDriveMotorVoltage()
* RobotController.getBatteryVoltage(),
Volts))
.linearPosition(
m_distance.mut_replace(
m_modules[SwerveDrive.Module.FRONT_LEFT].getDrivePositionMet(), Meters))
.linearVelocity(
m_velocity.mut_replace(
m_modules[SwerveDrive.Module.FRONT_LEFT].getDriveVelocity(), MetersPerSecond));

log.motor("drive-frontright").voltage(
m_appliedVoltage.mut_replace(
m_modules[SwerveDrive.Module.FRONT_RIGHT].getDriveMotorVoltage()
* RobotController.getBatteryVoltage(),
Volts))
.linearPosition(
m_distance.mut_replace(
m_modules[SwerveDrive.Module.FRONT_RIGHT].getDrivePositionMet(), Meters))
.linearVelocity(
m_velocity.mut_replace(
m_modules[SwerveDrive.Module.FRONT_RIGHT].getDriveVelocity(), MetersPerSecond));

log.motor("drive-backright").voltage(
m_appliedVoltage.mut_replace(
m_modules[SwerveDrive.Module.BACK_RIGHT].getDriveMotorVoltage()
* RobotController.getBatteryVoltage(),
Volts))
.linearPosition(
m_distance.mut_replace(
m_modules[SwerveDrive.Module.BACK_RIGHT].getDrivePositionMet(), Meters))
.linearVelocity(
m_velocity.mut_replace(
m_modules[SwerveDrive.Module.BACK_RIGHT].getDriveVelocity(), MetersPerSecond));

log.motor("drive-backleft").voltage(
m_appliedVoltage.mut_replace(
m_modules[SwerveDrive.Module.BACK_LEFT].getDriveMotorVoltage()
* RobotController.getBatteryVoltage(),
Volts))
.linearPosition(
m_distance.mut_replace(
m_modules[SwerveDrive.Module.BACK_LEFT].getDrivePositionMet(), Meters))
.linearVelocity(
m_velocity.mut_replace(
m_modules[SwerveDrive.Module.BACK_LEFT].getDriveVelocity(), MetersPerSecond));
},
this));

private final SysIdRoutine m_sysIdTurnRoutine = new SysIdRoutine(
new SysIdRoutine.Config(),
new SysIdRoutine.Mechanism(
(Voltage volts) -> {
for (SwerveModule module : m_modules) {
module.sysidTurn(volts.in(Volts));
}
},
log -> {
log.motor("turn-frontleft").voltage(
m_appliedVoltage.mut_replace(
m_modules[SwerveDrive.Module.FRONT_LEFT].getTurnMotorVoltage()
* RobotController.getBatteryVoltage(),
Volts))
.linearPosition(
m_distance.mut_replace(
m_modules[SwerveDrive.Module.FRONT_LEFT].getTurnPosition(), Meters))
.linearVelocity(
m_velocity.mut_replace(
m_modules[SwerveDrive.Module.FRONT_LEFT].getTurnVelocity(), MetersPerSecond));

log.motor("turn-frontright").voltage(
m_appliedVoltage.mut_replace(
m_modules[SwerveDrive.Module.FRONT_RIGHT].getTurnMotorVoltage()
* RobotController.getBatteryVoltage(),
Volts))
.linearPosition(
m_distance.mut_replace(
m_modules[SwerveDrive.Module.FRONT_RIGHT].getTurnPosition(), Meters))
.linearVelocity(
m_velocity.mut_replace(
m_modules[SwerveDrive.Module.FRONT_RIGHT].getTurnVelocity(), MetersPerSecond));

log.motor("turn-backright").voltage(
m_appliedVoltage.mut_replace(
m_modules[SwerveDrive.Module.BACK_RIGHT].getTurnMotorVoltage()
* RobotController.getBatteryVoltage(),
Volts))
.linearPosition(
m_distance.mut_replace(
m_modules[SwerveDrive.Module.BACK_RIGHT].getTurnPosition(), Meters))
.linearVelocity(
m_velocity.mut_replace(
m_modules[SwerveDrive.Module.BACK_RIGHT].getTurnVelocity(), MetersPerSecond));

log.motor("turn-backleft").voltage(
m_appliedVoltage.mut_replace(
m_modules[SwerveDrive.Module.BACK_LEFT].getTurnMotorVoltage()
* RobotController.getBatteryVoltage(),
Volts))
.linearPosition(
m_distance.mut_replace(
m_modules[SwerveDrive.Module.BACK_LEFT].getTurnPosition(), Meters))
.linearVelocity(
m_velocity.mut_replace(
m_modules[SwerveDrive.Module.BACK_LEFT].getTurnVelocity(), MetersPerSecond));
},
this));

@Override
public void reset() {
};

@Override
public void periodic() {
};

@Override
public void writePeriodicOutputs() {
};

@Override
public void stop() {
};
}

0 comments on commit 3e21060

Please sign in to comment.