This code has been available on GitHub for some time now, but I want to share it here as well, now that I finished writing comments. Read the Readme to get an idea of the purpose of our classes.
https://github.com/Team4256/4256-17-Rockefeller
Though I am the programming leader for 4256, I only began coding last year. Therefore, this is functional swerve code that everyone should be able to understand. Hopefully its helpful.
When you write your methods, is there a reason why you have final parameters? I honestly don’t think it is necessary.
Necessary, no, but it’s a good practice. Generally it’s bad form to alter parameters inside a method, making them explicitly final does help to detect the anti-pattern.
Since I created this thread, it has gotten nearly 400 views on Chief Delphi and yet only 5 unique visitors on Github. Therefore, I would like to expand on what we did here and make it easier to find the appropriate files in our source code.
The most important thing to consider when designing swerve is how your code is going to know the heading of each wheel. When our drive team first told us we would have absolute encoders (Versaplanetary), we thought the problem was solved. However, that is only true if you have a 1 to 1 gear ratio between the encoder’s shaft and the wheel’s shaft. We did not. At first we thought we could just scale up the values according to the gear ratio, but because the encoder tares itself at the nearest whole number count upon power cycling, that value could not be trusted. For example, the measured shaft could turn once (encoder value: 1) to produce a 90 degree change in heading, but upon power cycling the encoder would return 0 while the heading remained at 90 degrees. This was further complicated by a non-whole number gear ratio. To fix this, we installed Hall Effect sensors that got triggered whenever the heading was 0 degrees. Then we ran an alignment procedure to figure out what encoder value was actually 0 degrees. The only issue with this is precision (magnets can’t be installed perfectly), so we added an offset angle for each swerve module.
alignment stuff
setting offset angles (see beginning of teleop periodic)
Another thing that took us a while to get right was a function that we called “decapitateAngle”. Maybe we were overcomplicating it, but basically it makes sure that the wheel doesn’t turn more than it has to to reach a desired heading. For example, if you want to go from 0 degrees to 180 degrees, it won’t actually adjust the heading. Instead, it will reverse the direction of the traction motors. You can check out that code in the file with the alignment stuff.
Lastly, we combined all 4 modules together with the holonomic function in here. The parameters are an overall robot heading (direction) in degrees, a speed from -1 to 1, and a spin from -1 to 1. For autonomous we added code that adjusts spin based on a PID loop such that the robot’s front rotates to a desired heading. Please note that holonomic is based on this paper from chief delphi.