diff --git a/lib/src/main/java/com/team2813/lib2813/control/DeviceInformation.java b/lib/src/main/java/com/team2813/lib2813/control/DeviceInformation.java index 8728b454..7351b382 100644 --- a/lib/src/main/java/com/team2813/lib2813/control/DeviceInformation.java +++ b/lib/src/main/java/com/team2813/lib2813/control/DeviceInformation.java @@ -15,20 +15,37 @@ */ package com.team2813.lib2813.control; +import com.ctre.phoenix6.CANBus; import com.team2813.lib2813.util.InputValidation; +import java.util.Objects; import java.util.Optional; public final class DeviceInformation { - private int id; - private Optional canbus; + private static final String DEFAULT_CANBUS_NAME = new CANBus().getName(); + private final int id; + private final CANBus canbus; /** - * Creates a DeviceInformation for a device on the RoboRIO can loop + * Creates a DeviceInformation for a device on the default CAN bus. * - * @param id the can ID + * @param deviceId the configured ID of the device */ - public DeviceInformation(int id) { - this(id, null); + public DeviceInformation(int deviceId) { + this.id = InputValidation.checkCanId(deviceId); + this.canbus = new CANBus(); + } + + /** + * Creates a DeviceInformation with a canbus. + * + * @param deviceId the configured ID of the device + * @param canbus the CAN bus the device is on + */ + public DeviceInformation(int deviceId, CANBus canbus) { + Objects.requireNonNull(canbus, "canbus"); + Objects.requireNonNull(canbus.getName(), "canbus name"); + this.id = InputValidation.checkCanId(deviceId); + this.canbus = canbus; } /** @@ -36,11 +53,14 @@ public DeviceInformation(int id) { * acts like {@link #DeviceInformation(int)} was called * * @param id the CAN id - * @param canbus the canbus string + * @param canbus the name of the CAN bus the device is on + * @deprecated Constructing {@code DeviceInformation} with a CAN bus string is deprecated for + * removal in the 2027 season. Construct instances using a {@link CANBus} instance instead. */ + @Deprecated(forRemoval = true) public DeviceInformation(int id, String canbus) { this.id = InputValidation.checkCanId(id); - this.canbus = Optional.ofNullable(canbus); + this.canbus = canbus == null ? new CANBus() : new CANBus(canbus); } /** @@ -57,20 +77,36 @@ public int id() { * can loop * * @return the canbus that the device is on + * @deprecated use {@link #canBus()}} */ + @Deprecated(forRemoval = true) public Optional canbus() { + String canbusName = canbus.getName(); + if (canbusName.equals(DEFAULT_CANBUS_NAME)) { + return Optional.empty(); + } + return Optional.of(canbusName); + } + + /** + * Returns the canbus that this device is on. + * + * @return the canbus that the device is on + */ + public CANBus canBus() { return canbus; } @Override - public boolean equals(Object o) { - if (!(o instanceof DeviceInformation)) return false; - DeviceInformation other = (DeviceInformation) o; - return other.id == id && other.canbus.equals(canbus); + public boolean equals(Object obj) { + if (obj instanceof DeviceInformation other) { + return other.id == id && other.canbus.getName().equals(canbus.getName()); + } + return false; } @Override public int hashCode() { - return id * 31 + canbus.hashCode(); + return id * 31 + canbus.getName().hashCode(); } } diff --git a/lib/src/main/java/com/team2813/lib2813/control/encoders/CancoderWrapper.java b/lib/src/main/java/com/team2813/lib2813/control/encoders/CancoderWrapper.java index e62cf3d4..4c70372e 100644 --- a/lib/src/main/java/com/team2813/lib2813/control/encoders/CancoderWrapper.java +++ b/lib/src/main/java/com/team2813/lib2813/control/encoders/CancoderWrapper.java @@ -15,6 +15,7 @@ */ package com.team2813.lib2813.control.encoders; +import com.ctre.phoenix6.CANBus; import com.ctre.phoenix6.hardware.CANcoder; import com.team2813.lib2813.control.DeviceInformation; import com.team2813.lib2813.control.Encoder; @@ -23,18 +24,51 @@ import edu.wpi.first.units.measure.Angle; import edu.wpi.first.units.measure.AngularVelocity; +/** + * A wrapper for {@link CANcoder} that implements {@link Encoder}. + * + *

Represents a CAN-based magnetic encoder that provides absolute and relative position along + * with filtered velocity. + */ public class CancoderWrapper implements Encoder { - private CANcoder cancoder; - private DeviceInformation info; + private final CANcoder cancoder; + private final DeviceInformation info; - public CancoderWrapper(int id, String canbus) { - cancoder = new CANcoder(id, canbus); - info = new DeviceInformation(id, canbus); + /** + * Creates an instance for a CANcoder on the specified CAN bus. + * + * @param deviceId the configured ID of the CANcoder + * @param canbus the CAN bus the device is on + */ + public CancoderWrapper(int deviceId, CANBus canbus) { + info = new DeviceInformation(deviceId, canbus); + cancoder = new CANcoder(deviceId, canbus); } - public CancoderWrapper(int id) { - cancoder = new CANcoder(id); - info = new DeviceInformation(id); + /** + * Creates an instance for a CANcoder on the specified CAN bus name. + * + * @param deviceId the configured ID of the CANcoder + * @param canbusName the name of the CAN bus the device is on + * @deprecated Constructing {@code CancoderWrapper} with a CAN bus string is deprecated for + * removal in the 2027 season. Construct instances using a {@link CANBus} instance instead. + */ + @Deprecated(forRemoval = true) + public CancoderWrapper(int deviceId, String canbusName) { + @SuppressWarnings("removal") + DeviceInformation deviceInformation = new DeviceInformation(deviceId, canbusName); + info = deviceInformation; + cancoder = new CANcoder(deviceId, info.canBus()); + } + + /** + * Creates an instance for a CANcoder on the default CAN bus. + * + * @param deviceId the configured ID of the CANcoder + */ + public CancoderWrapper(int deviceId) { + cancoder = new CANcoder(deviceId); + info = new DeviceInformation(deviceId, cancoder.getNetwork()); } @Override @@ -58,8 +92,9 @@ public AngularVelocity getVelocityMeasure() { @Override public boolean equals(Object obj) { - if (!(obj instanceof CancoderWrapper)) return false; - CancoderWrapper other = (CancoderWrapper) obj; - return info.equals(other.info); + if (obj instanceof CancoderWrapper other) { + return info.equals(other.info); + } + return false; } } diff --git a/lib/src/main/java/com/team2813/lib2813/control/imu/Pigeon2Wrapper.java b/lib/src/main/java/com/team2813/lib2813/control/imu/Pigeon2Wrapper.java index 59da20db..89154abe 100644 --- a/lib/src/main/java/com/team2813/lib2813/control/imu/Pigeon2Wrapper.java +++ b/lib/src/main/java/com/team2813/lib2813/control/imu/Pigeon2Wrapper.java @@ -15,37 +15,54 @@ */ package com.team2813.lib2813.control.imu; +import com.ctre.phoenix6.CANBus; import com.ctre.phoenix6.hardware.Pigeon2; import com.team2813.lib2813.control.DeviceInformation; import com.team2813.lib2813.util.ConfigUtils; public class Pigeon2Wrapper { - - private Pigeon2 pigeon; + private final Pigeon2 pigeon; + private final DeviceInformation info; private double currentHeading = 0; - private DeviceInformation info; /** - * Constructor + * Creates an instance for a Pigeon 2 IMU sensor on the specified CAN bus. * - * @param deviceNumber [0,62] + * @param deviceId [0,62] * @param canbus Name of the CANbus; can be a SocketCAN interface (on Linux), or a CANivore device * name or serial number */ - public Pigeon2Wrapper(int deviceNumber, String canbus) { - info = new DeviceInformation(deviceNumber, canbus); - pigeon = new Pigeon2(deviceNumber, canbus); + public Pigeon2Wrapper(int deviceId, CANBus canbus) { + info = new DeviceInformation(deviceId, canbus); + pigeon = new Pigeon2(deviceId, canbus); + } + + /** + * Constructor + * + * @param deviceId [0,62] + * @param canbusName the name of the CAN bus the device is on; can be a SocketCAN interface (on + * Linux), or a CANivore device name or serial number + * @deprecated Constructing {@code CancoderWrapper} with a CAN bus string is deprecated for + * removal in the 2027 season. Construct instances using a {@link CANBus} instance instead. + */ + @Deprecated(forRemoval = true) + public Pigeon2Wrapper(int deviceId, String canbusName) { + @SuppressWarnings("removal") + DeviceInformation deviceInformation = new DeviceInformation(deviceId, canbusName); + info = deviceInformation; + pigeon = new Pigeon2(deviceId, info.canBus()); } /** * Constructor * - * @param deviceNumber [0,62] + * @param deviceId [0,62] */ - public Pigeon2Wrapper(int deviceNumber) { - info = new DeviceInformation(deviceNumber); - pigeon = new Pigeon2(deviceNumber); + public Pigeon2Wrapper(int deviceId) { + pigeon = new Pigeon2(deviceId); + info = new DeviceInformation(deviceId, pigeon.getNetwork()); } public Pigeon2 getPigeon() { @@ -77,11 +94,10 @@ public int hashCode() { return info.hashCode(); } - public boolean equals(Object other) { - if (!(other instanceof Pigeon2Wrapper)) { - return false; + public boolean equals(Object obj) { + if (obj instanceof Pigeon2Wrapper other) { + return info.equals(other.info); } - Pigeon2Wrapper o = (Pigeon2Wrapper) other; - return o.info.equals(info); + return false; } } diff --git a/lib/src/main/java/com/team2813/lib2813/control/motors/SparkMaxWrapper.java b/lib/src/main/java/com/team2813/lib2813/control/motors/SparkMaxWrapper.java index 2f9f8c74..b5dd12ca 100644 --- a/lib/src/main/java/com/team2813/lib2813/control/motors/SparkMaxWrapper.java +++ b/lib/src/main/java/com/team2813/lib2813/control/motors/SparkMaxWrapper.java @@ -113,7 +113,9 @@ public void configPIDF(int slot, double p, double i, double d, double f) { throw new RuntimeException("Invalid slot!"); } ClosedLoopSlot cSlot = slots[slot]; - config.apply(new ClosedLoopConfig().pidf(p, i, d, f, cSlot)); + ClosedLoopConfig closedLoopConfig = new ClosedLoopConfig().pid(p, i, d, cSlot); + closedLoopConfig.feedForward.kV(f, cSlot); + config.apply(closedLoopConfig); ConfigUtils.revConfig(() -> motor.configure(config, resetMode, persistMode)); } diff --git a/lib/src/main/java/com/team2813/lib2813/control/motors/TalonFXWrapper.java b/lib/src/main/java/com/team2813/lib2813/control/motors/TalonFXWrapper.java index 6d1163d9..3c6d860c 100644 --- a/lib/src/main/java/com/team2813/lib2813/control/motors/TalonFXWrapper.java +++ b/lib/src/main/java/com/team2813/lib2813/control/motors/TalonFXWrapper.java @@ -51,7 +51,7 @@ public class TalonFXWrapper implements PIDMotor { private final DeviceInformation information; /** - * Create a TalonFXWrapper on the specified canbus + * Create a TalonFXWrapper on the specified canbus. * * @param canID [0, 62] the can ID of the motor * @param canbus the canbus that the motor is on @@ -62,7 +62,7 @@ public class TalonFXWrapper implements PIDMotor { * InvertType} that is for following motors * @throws InvalidCanIdException if the CAN id is invalid */ - public TalonFXWrapper(int canID, String canbus, InvertType invertType) { + public TalonFXWrapper(int canID, CANBus canbus, InvertType invertType) { Objects.requireNonNull(invertType, "invertType should not be null"); Objects.requireNonNull(canbus, "canbus should not be null"); if (!InvertType.rotationValues.contains(invertType)) { @@ -83,6 +83,28 @@ public TalonFXWrapper(int canID, String canbus, InvertType invertType) { information = new DeviceInformation(canID, canbus); } + /** + * Create a TalonFXWrapper on the specified canbus name. + * + * @param canID [0, 62] the can ID of the motor + * @param canbusName the canbus that the motor is on + * @param invertType the invert type + * @throws NullPointerException if either {@code invertType} or {@code canbus} are null + * @throws IllegalArgumentException if {@code invertType} is not in {@link + * InvertType#rotationValues}. In other words, this exception is thrown when passed an {@link + * InvertType} that is for following motors + * @throws InvalidCanIdException if the CAN id is invalid + * @deprecated Constructing {@code DeviceInformation} with a CAN bus string is deprecated for + * removal in the 2027 season. Construct instances using a {@link CANBus} instance instead. + */ + @Deprecated(forRemoval = true) + public TalonFXWrapper(int canID, String canbusName, InvertType invertType) { + this( + canID, + new CANBus(Objects.requireNonNull(canbusName, "canbus should not be null")), + invertType); + } + /** * Create a TalonFXWrapper on the RoboRIO's canbus * diff --git a/lib/src/test/java/com/team2813/lib2813/util/ControlUtilsTest.java b/lib/src/test/java/com/team2813/lib2813/util/ControlUtilsTest.java index b4389369..168cb726 100644 --- a/lib/src/test/java/com/team2813/lib2813/util/ControlUtilsTest.java +++ b/lib/src/test/java/com/team2813/lib2813/util/ControlUtilsTest.java @@ -21,6 +21,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.function.Executable; +@SuppressWarnings("removal") public class ControlUtilsTest { @Test public void deadbandValuesWithinDeadbandAreZeroed() {