sun167
November 1, 2024, 7:42pm
1
We’re using YAGSL to make our swerve code. Usually, the drivebase follows the joystick inputs. We encountered an error where the modules stop following these inputs. It happens when we change module angle from one point to another angle around its 90 degrees counterpart.
Here is our code: MainRepository_AlphaLab_8067 - Google Drive
Here is a video of our issue: Enregistrement de l'écran 2024-11-01 151432.mp4 - Google Drive
The problem occurs at 0:07, 0:13 and 0:16
We can also notice that when we ask it to go to a position it stops a bit before reaching it and then gets to it only after we stop giving any input (maybe not related but still a problem we would like to solve)
Note At no point did we give any rotation comand so the robot should technically be only translating . we also noticed that in some cases the diference between the wanted position and the returned position is pretty big and it only solves itself once no input is given like mentionned previously.
What swerve module type are you using?
sun167
November 1, 2024, 7:50pm
3
SDS MK4i NEO using L2 gear ratios and CANcoder
Where did you get your conversion factors from?
You should use the format from the docs.
https://yagsl.gitbook.io/yagsl/configuring-yagsl/standard-conversion-factors?origin=serp_auto#swerve-drive-specialties-sds
Also could you upload your code to github, it makes it easier for us to view.
sun167
November 1, 2024, 8:24pm
5
We already had the good gear ratios (acording to the docs) in our json files, however it was not the case in our subsystem at line 75 (it was set 12.8). We changed it so it matches with the json files. The problem is still there.
also here is the github : GitHub - ALPHALAB8067/MainRepository_AlphaLab_8067: Main Repository pour tout les fichiers en général d'AlphaLab
1 Like
Yeah these aren’t right, please change
to
"conversionFactors": {
"angle": {"gearRatio": 21.4285714286},
"drive": {"gearRatio": 6.75, "diameter": 4}
}
These values you supplied here are given as a reference to help you.
// Angle conversion factor is 360 / (GEAR RATIO * ENCODER RESOLUTION)
// In this case the gear ratio is 12.8 motor revolutions per wheel rotation.
// The encoder resolution per motor revolution is 1 per motor revolution.
double angleConversionFactor = SwerveMath.calculateDegreesPerSteeringRotation(21.4285714286);
// Motor conversion factor is (PI * WHEEL DIAMETER IN METERS) / (GEAR RATIO * ENCODER RESOLUTION).
// In this case the wheel diameter is 4 inches, which must be converted to meters to get meters/second.
// The gear ratio is 6.75 motor revolutions per wheel rotation.
// The encoder resolution per motor revolution is 1 per motor revolution.
double driveConversionFactor = SwerveMath.calculateMetersPerRotation(Units.inchesToMeters(4), 6.75);
System.out.println("\"conversionFactors\": {");
System.out.println("\t\"angle\": {\"factor\": " + angleConversionFactor + " },");
System.out.println("\t\"drive\": {\"factor\": " + driveConversionFactor + " }");
System.out.println("}");
which you could supply here if it was uncommented (for now; i am going to require it given through the JSONs soon).
System.out.println("}");
// Configure the Telemetry before creating the SwerveDrive to avoid unnecessary objects being created.
SwerveDriveTelemetry.verbosity = TelemetryVerbosity.HIGH;
try
{
swerveDrive = new SwerveParser(directory).createSwerveDrive(Constants.MAX_SPEED);
//swerveDrive.setCosineCompensator(true);
swerveDrive.setAutoCenteringModules(false);
//swerveDrive.setMaximumSpeeds(0.5,0.5,0.5); // Alternative method if you don't want to supply the conversion factor via JSON files.
// swerveDrive = new SwerveParser(directory).createSwerveDrive(maximumSpeed, angleConversionFactor, driveConversionFactor);
} catch (Exception e)
{
throw new RuntimeException(e);
}
swerveDrive.setHeadingCorrection(false); // Heading correction should only be used while controlling the robot via angle.
swerveDrive.setCosineCompensator(false);//!SwerveDriveTelemetry.isSimulation); // Disables cosine compensation for simulations since it causes discrepancies not seen in real life.
if (visionDriveTest)
{
setupPhotonVision();
// Stop the odometry thread if we are using vision that way we can synchronize updates better.
however you don’t supply it and use the constructor here.
double driveConversionFactor = SwerveMath.calculateMetersPerRotation(Units.inchesToMeters(4), 6.75);
System.out.println("\"conversionFactors\": {");
System.out.println("\t\"angle\": {\"factor\": " + angleConversionFactor + " },");
System.out.println("\t\"drive\": {\"factor\": " + driveConversionFactor + " }");
System.out.println("}");
// Configure the Telemetry before creating the SwerveDrive to avoid unnecessary objects being created.
SwerveDriveTelemetry.verbosity = TelemetryVerbosity.HIGH;
try
{
swerveDrive = new SwerveParser(directory).createSwerveDrive(Constants.MAX_SPEED);
//swerveDrive.setCosineCompensator(true);
swerveDrive.setAutoCenteringModules(false);
//swerveDrive.setMaximumSpeeds(0.5,0.5,0.5); // Alternative method if you don't want to supply the conversion factor via JSON files.
// swerveDrive = new SwerveParser(directory).createSwerveDrive(maximumSpeed, angleConversionFactor, driveConversionFactor);
} catch (Exception e)
{
throw new RuntimeException(e);
}
swerveDrive.setHeadingCorrection(false); // Heading correction should only be used while controlling the robot via angle.
swerveDrive.setCosineCompensator(false);//!SwerveDriveTelemetry.isSimulation); // Disables cosine compensation for simulations since it causes discrepancies not seen in real life.
Ontop of the conversion factor changes, this seems to be uninverted while the rest are, is this intentional?
"type": "sparkmax",
"id": 12,
"canbus": null
},
"encoder": {
"type": "cancoder",
"id": 1,
"canbus": null
},
"inverted": {
"drive": false,
"angle": true
},
"absoluteEncoderOffset": 330 ,
"location": {
"front": 12,
"left": 12
}
}
sun167
November 1, 2024, 9:07pm
8
Yes it is intentional and the problem is now fixed Thank you so much although i am curious as to why the second observation was previously happening (im referring to the one where the angle motor would not go to the corect position with something that looked like a small offset and he would then snap to the corect position but only after no input is given and we know for a fact that it is not auto centering ) anyway thank you so much once again.
1 Like
It was a side-effect of the invalid conversion factors, if the given is so close to 0 that it doesn’t mean anything then the motor will not turn.
* onto the swerve module.
*/
public void setDesiredState(SwerveModuleState desiredState, boolean isOpenLoop, boolean force)
{
desiredState = SwerveModuleState.optimize(desiredState, Rotation2d.fromDegrees(getAbsolutePosition()));
// If we are forcing the angle
if (!force && antiJitterEnabled)
{
// Prevents module rotation if speed is less than 1%
SwerveMath.antiJitter(desiredState, lastState, Math.min(maxSpeed, 4));
}
// Cosine compensation.
double velocity = configuration.useCosineCompensator
? getCosineCompensatedVelocity(desiredState)
: desiredState.speedMetersPerSecond;
if (isOpenLoop)
{
double percentOutput = desiredState.speedMetersPerSecond / maxSpeed;
/**
* Perform anti-jitter within modules if the speed requested is too low.
*
* @param moduleState Current {@link SwerveModuleState} requested.
* @param lastModuleState Previous {@link SwerveModuleState} used.
* @param maxSpeed Maximum speed of the modules.
*/
public static void antiJitter(SwerveModuleState moduleState, SwerveModuleState lastModuleState, double maxSpeed)
{
if (Math.abs(moduleState.speedMetersPerSecond) <= (maxSpeed * 0.01))
{
moduleState.angle = lastModuleState.angle;
}
}
/**
* Cube the {@link Translation2d} magnitude given in Polar coordinates.
*
* @param translation {@link Translation2d} to manipulate.
* @return Cubed magnitude from {@link Translation2d}.
sun167
November 1, 2024, 9:46pm
10
ok but why did it snap back to the correct position after no input ?
this is not important its just out of curiosity.
nstrike
November 1, 2024, 9:52pm
11
Honestly I am not sure I suspect a disconnect where the last state is not updated correctly in that condition but idk.
{
angleMotor.setPosition(absoluteEncoderPosition);
}
angleMotor.setReference(desiredState.angle.getDegrees(), 0, absoluteEncoderPosition);
synchronizeEncoderQueued = false;
} else
{
angleMotor.setReference(desiredState.angle.getDegrees(), 0);
}
lastState = desiredState;
if (SwerveDriveTelemetry.isSimulation)
{
simModule.updateStateAndPosition(desiredState);
}
if (SwerveDriveTelemetry.verbosity.ordinal() >= TelemetryVerbosity.INFO.ordinal())
{
SwerveDriveTelemetry.desiredStates[moduleNumber * 2] = desiredState.angle.getDegrees();
SwerveDriveTelemetry.desiredStates[(moduleNumber * 2) + 1] = velocity;