Stopping swerve wheels from resetting their position after every joystick input?

Hello there!

My team, 1305, has recently gotten a swerve drive train that we have been working on. We are using the Max Swerve modules from Rev. One thing I have noticed is that the wheels reset after joystick inputs, and I have trying a couple of ways to stop that, but none have worked so far, any ideas?

2 Likes

Thats almost certainly a code problem. Can you share a link to your code (preferably the whole project on github or similar)?

Also, did you use the REV starter template, or something else (e.g. YAGSL)?

2 Likes

It is hard to know without seeing some code, but I’ll take a guess. If you have followed the WPILib swervebot example (also any of the other code I’ve ever seen) then you will have a SwerveModule class with a SetDesiredState() function.

When there is no joystick input the state for each module will have zero speed, but will also have 0 angle (because it has to have some angle and that is what the maths will give you). In this case you want to set the driving motor to zero speed, but also you want to set the steering motor to zero speed, rather than driving to 0 angle.

I’m guessing that you are missing a check for zero speed and so you are driving the wheels to 0 angle when the joystick input stops. In my team’s software the relevent code looks like this. (C++ but hopefully you can get the idea).

void SwerveModule::SetDesiredState(const frc::SwerveModuleState& state, bool dry_steer_allowed) {
    // If speed is zero and we are not doing dry steering, set motor outputs to zero and do nothing else
    if (state.speed == 0.0_mps) {
        m_drive_controller.Set(ControlMode::PercentOutput, 0.0);
        if (!dry_steer_allowed) {
            m_steer_controller.Set(ControlMode::PercentOutput, 0.0);
            return;
        }
    }


Maintaining the current module angle when the desired chassis speeds are zero is built in to the SwerveDriveKinematics.toSwerveModuleStates method. I think you’ll need to do a little debugging.

My first thought is that you need a wider deadband on your controller, maybe when you’re “stopped” you’re still telling the wheels to move very slowly.

Here is our code: GitHub - team1305/2023_Offseason_Rev_Swerve_Project: 2023 offseason swerve project
you would want to go to the branch: Inuka-working-on-teleop-fixes
I’ve tried checking to see if the modules states.speed is equal to 0. I took that out since I didn’t really notice any affect and we had a ‘set wheels to X’ command that wasn’t working if the robot was still/

This line does handle the case when the speed is zero, so they will not snap back in that case.

I pulled the code and ran it in the simulator. What I saw was that the slew rates need to be adjusted. The class Constants.DriveConstants defines kDirectionSlewRate, kMagnitudeSlewRate and kRotationalSlewRate. The slew rate regulates the rate of change for the direction, speed, and rotation of the robot. When I move the left controller stick to the upper left corner and then let it snap back to zero, the slew rate on the angle lets its desired value reach zero before the speed reaches zero. In this case, the code tells the drivetrain to drive at a given speed in direction zero.

Most of the values of our code is just from the Rev example. Adjusting the slew rate values would make sense. for tuning the slew rate values, what would be the best way to tune? Also if you don’t mind me asking, what are you using for simulation?

For us, the slew rate limit is a negotiation between the build team and drive team. The goal is to make the robot as responsive as possible, but have reasonable limits to reduce stress on the drivetrain and prevent the driver from tipping the robot. In general, you can have faster slew rates for robots that are light and have a low center of gravity.

I just used the built in simulation. I added a couple values with SmartDashboard.putNumber() and ran your code.

I did not realize that I have not seen this simulation, this Definity would be helpful with autonomous. when adjusting values for the slew rates, we would want to decrease the value so that value doesn’t reach zero before the speed?

I’ll be able to get my hands on our base in a couple of days, so I’ll see if it ends up works and keep you posted!

A larger value allows a faster rate of change. For your specific problem, it’s a matter of making sure speed/magnitude reaches zero at the same time or before the direction and rotation values. You could increase the magnitude rate limit, or decrease direction. I didn’t try rotation, so you might have to look at that too.

I think I will have to fiddle with the rotation Slew rate too. Last time I tested the code, if I rotated the robot it wouldn’t reset the state of the wheels, but I could be wrong.

I just had a question about the simulator. for the SmartDashboard values, your putting the angle of the modules. I have a controller set up with the simulation but I am not sure how to actually go about testing code as I am not able to adjust the values using the joysticks?

I bit of a pivot here, but I wanted to mention that we used Max Swerve this season (6 comps including offseason) and decided to remove the slew rate for a couple of reasons:

  1. I was told that it was put there to counteract the damage done on the first version of the wheels to keep them on. We use tread rather than those wheels, so we don’t have to worry about the wheel coming apart.
  2. (main reason) We (at some point) had our rate limit set to a very high value (making it almost negligible) for all of our off-season events, and the robot was fine. The wheels did not see damage during that time. This made me decide that the slew rate limiting wasn’t strictly necessary for our bot anymore, as the limits were set so high that there wasn’t any slew anymore.
  3. It cluttered the code, making it look more confusing for newer programmers. This of course can be easily fixed by abstracting it to a method… but that’s not very relevant here.

(edit) If you choose to go down the route of removing the slew rate limits entirely, it would be an alternative solution to your issue as you will no longer have to worry about which slew zeros first. But of course, the option to tune the slews shouldn’t take long and will also work (and maybe be a bit safer for the robot).

(edit2) Here is our drive method if you want to take a look at how it works differently without slew: https://github.com/Patribots4738/ChargedUp2023/blob/2f997003d5e0f9eb81d13d348725346517bc7e5a/src/main/java/hardware/Swerve.java#L174
Please note that the discretize method that our speeds are being passed into is to prevent the robot from skewing as you drive in one direction and spin, it will be integrated into WPIlib 2024

We just used the rev sample code due to time constraint, and our code will change as we get into the next season. We were thinking about using tread on our wheels so I think that we could remove the limiters, but for now I think I will keep them in.

This is something I wanted to do next, as there is a slight change in heading even if I drive in a straight line. Will definitely have to reference this after I get this and autonomous fixed.

Did you add the “system joystick” to the “joysticks”? The simulator is about the least intuitive interface you’ll ever encounter.

I did add the system joysticks to the joysticks. I have SmartDashBoard outputting the angles for each swerve module and updating it in periodic. I was still unable to get any response from it. though I probably don’t have something turned on, and probably missed something.

Are you outputting the modules “actual” position, or the “desired” position setpoint? I was looking at the desired position. The actual position will not move in the simulator. You would need to write simulation code if you want to simulate mechanisms, REV’s example does not do that.

I was looking at the actual position. I am not exactly sure how to get the set up code for simulation and I am not sure if that will add a lot to the file. I am asking if I can get the base from my team sometime this week to go and test, so I can wait to test in person rather than use the simulation.

Would it help if any unmapped real joysticks were auto-mapped to the next open spot?

Yeah, automatically mapping the joysticks would be more like what DriverStation does.