Skip to content

Commit f033e8d

Browse files
authored
Merge pull request #93 from strykeforce/swerve-module-rotation
Add get/set Rotation2d to SwerveModule
2 parents 0b73116 + ee34484 commit f033e8d

File tree

4 files changed

+42
-10
lines changed

4 files changed

+42
-10
lines changed

build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@ plugins {
66
id "maven-publish"
77
id "org.jetbrains.kotlin.jvm" version "1.6.10"
88
id "org.jetbrains.kotlin.kapt" version "1.6.10"
9-
id "edu.wpi.first.GradleRIO" version "2022.1.1"
9+
id "edu.wpi.first.GradleRIO" version "2022.3.1"
1010
id 'com.diffplug.spotless' version '6.2.0'
1111
}
1212

1313
group = "org.strykeforce"
14-
version = "22.0.1"
14+
version = "22.1.0"
1515

1616
sourceCompatibility = JavaVersion.VERSION_11
1717
targetCompatibility = JavaVersion.VERSION_11

src/main/java/org/strykeforce/swerve/SwerveModule.java

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package org.strykeforce.swerve;
22

3+
import edu.wpi.first.math.geometry.Rotation2d;
34
import edu.wpi.first.math.geometry.Translation2d;
45
import edu.wpi.first.math.kinematics.SwerveModuleState;
56
import org.strykeforce.telemetry.Registrable;
@@ -32,7 +33,7 @@ public interface SwerveModule extends Registrable {
3233
* Command the swerve module motors to the desired state.
3334
*
3435
* @param desiredState the desired swerve module speed and angle
35-
* @param isDriveOpenLoop true if drive should set speed using closed-loop velocity control
36+
* @param isDriveOpenLoop false if drive should set speed using closed-loop velocity control
3637
*/
3738
void setDesiredState(SwerveModuleState desiredState, boolean isDriveOpenLoop);
3839

@@ -45,6 +46,23 @@ default void setDesiredState(SwerveModuleState desiredState) {
4546
this.setDesiredState(desiredState, false);
4647
}
4748

49+
/**
50+
* Command the swerve module azimuth rotation to the desired angle with a drive speed of zero. If
51+
* setting the module to an angle with a non-zero drive speed, use {@link
52+
* SwerveModule#setDesiredState(SwerveModuleState)} or {@link
53+
* SwerveModule#setDesiredState(SwerveModuleState, boolean)}.
54+
*
55+
* @param rotation the desired absolute azimuth angle
56+
*/
57+
void setAzimuthRotation2d(Rotation2d rotation);
58+
59+
/**
60+
* Get the angle of the swerve drive azimuth.
61+
*
62+
* @return the angle of the azimuth rotation.
63+
*/
64+
Rotation2d getAzimuthRotation2d();
65+
4866
/** Resets the drive encoders to currently read a position of 0. */
4967
void resetDriveEncoder();
5068

src/main/java/org/strykeforce/swerve/TalonSwerveModule.java

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -91,11 +91,9 @@ public void setDesiredState(SwerveModuleState desiredState, boolean isDriveOpenL
9191
if (desiredState.speedMetersPerSecond < driveDeadbandMetersPerSecond) {
9292
desiredState = new SwerveModuleState(0.0, previousAngle);
9393
}
94-
previousAngle = desiredState.angle;
9594

96-
Rotation2d currentAngle = getAzimuthRotation2d();
97-
SwerveModuleState optimizedState = SwerveModuleState.optimize(desiredState, currentAngle);
98-
setAzimuthRotation2d(optimizedState.angle);
95+
SwerveModuleState optimizedState = setAzimuthOptimizedState(desiredState);
96+
9997
if (isDriveOpenLoop) {
10098
setDriveOpenLoopMetersPerSecond(optimizedState.speedMetersPerSecond);
10199
} else {
@@ -155,17 +153,35 @@ private int getAzimuthAbsoluteEncoderCounts() {
155153
return azimuthTalon.getSensorCollection().getPulseWidthPosition() & 0xFFF;
156154
}
157155

156+
@Override
158157
public Rotation2d getAzimuthRotation2d() {
159158
double azimuthCounts = azimuthTalon.getSelectedSensorPosition();
160159
double radians = 2.0 * Math.PI * azimuthCounts / azimuthCountsPerRev;
161160
return new Rotation2d(radians);
162161
}
163162

163+
@Override
164164
public void setAzimuthRotation2d(Rotation2d angle) {
165+
setAzimuthOptimizedState(new SwerveModuleState(0.0, angle));
166+
logger.info("azimuth {}: set rotation to: {}", azimuthTalon.getDeviceID(), angle);
167+
}
168+
169+
@NotNull
170+
private SwerveModuleState setAzimuthOptimizedState(SwerveModuleState desiredState) {
171+
// minimize change in heading by potentially reversing the drive direction
172+
Rotation2d currentAngle = getAzimuthRotation2d();
173+
SwerveModuleState optimizedState = SwerveModuleState.optimize(desiredState, currentAngle);
174+
175+
// set the azimuth wheel position
165176
double countsBefore = azimuthTalon.getSelectedSensorPosition();
166-
double countsFromAngle = angle.getRadians() / (2.0 * Math.PI) * azimuthCountsPerRev;
177+
double countsFromAngle =
178+
optimizedState.angle.getRadians() / (2.0 * Math.PI) * azimuthCountsPerRev;
167179
double countsDelta = Math.IEEEremainder(countsFromAngle - countsBefore, azimuthCountsPerRev);
168180
azimuthTalon.set(MotionMagic, countsBefore + countsDelta);
181+
182+
// save previous angle for use if inside deadband in setDesiredState()
183+
previousAngle = optimizedState.angle;
184+
return optimizedState;
169185
}
170186

171187
private double getDriveMetersPerSecond() {

src/test/java/org/strykeforce/swerve/TalonSwerveModuleTest.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import static org.assertj.core.api.Assertions.assertThat;
44
import static org.junit.jupiter.api.Assertions.assertEquals;
55
import static org.junit.jupiter.api.Assertions.assertThrows;
6-
import static org.mockito.ArgumentMatchers.anyDouble;
76
import static org.mockito.ArgumentMatchers.anyInt;
87
import static org.mockito.Mockito.eq;
98
import static org.mockito.Mockito.mock;
@@ -165,7 +164,6 @@ void shouldSetAzimuthZero(int absoluteEncoderPosition, int zeroReference, double
165164
module.loadAndSetAzimuthZeroReference();
166165
verify(azimuthTalon).setSelectedSensorPosition(setpoint, 0, 10);
167166
}
168-
169167
}
170168

171169
/*

0 commit comments

Comments
 (0)