Hello! My team has just about wrapped up our testing with our new swerve drive and everything has gone perfectly… ish. I have some questions about standard practices with swerve drive as well as motor selection going into the future.
I am wondering if it is common practice to use the absolute encoder solely for zeroing(We have mk4 modules) and then use motor encoders for everything else?
We have long been a fan of falcons because of their vast amounts of torque and high CPR encoders, but as the community has pointed out, maybe our luck with falcons and vex in general is abnormal. With this in mind, the next obvious choice is Neos but the CPR is only 42 or something similar like that. Is this ok for teams that have used Neos on a swerve drive? Or do you use something else entirely when trying to tune your turning PIDs? Can you connect a cancoder directly to the spark max and use it as a feedback device?
2.5 Side note, Falcon Integrated Pids refresh at 1ms, what do Spark Max Integrated Control loops refresh at?
Along that point, do most teams use integrated PIDs with inputs and outputs in motor ticks? Or is it standard to use WPI Pids. We tried to use WPI Pids but we believe, that because of the 20 ms response time, compared to the 1ms response time between roborio and talonFx integrated PIDs we couldn’t get the modules to turn as fast as desired which led to only ok performance when driving. Have other teams had success with WPI Pids? If so what did your tuning process look like?
3.5 With Control in mind, Wpi is so convenient with profiled pid controllers, regular pid controllers, trapezoidal motion profiles, etc., with features like enableContinuousInput. This feature is so helpful for teams as you don’t need to do the calculations on your end and it’s all taken care of for you. This was originally why we used Wpi pids, simply for ease. Is there any workaround for this that teams should be aware of? Or will vendors implement this into their code eventually?
Due to the lower CPR, yes, it is much harder to do onboard PID. Instead, use percent output or voltage for drive, and for turning use the WPILIB PIDController class, using the absolute encoder as feedback*.
For Falcons, onboard position (turning) and velocity (drive) is usually used. I’ve not really done WPI PID on Falcons, so I can’t speak for that.
On tuning with WPI: Straighten the wheels, get the output of the absolute encoders and set that as your offset.
* The “yes” only stands with Falcons, who do far better with onboard PID.
To overcome the lower performance or using wpi pids we tried to include feed forward by characterizing it using sysid with the can coder as our feedback device. The measured values were wildly incorrect I’m assuming due to the roll over of values. Is there anyway to configure this differently? Or should I characterize with respect to the motor and then convert the gains to be with respect to the can coder?
What I would do is characterize using the motor encoder as a feedback, making sure your CPR and gearing are correct (for example, MK2 is 18:1), and set your CPR such that it is in terms of degrees (I.e. dividing your calculated CPR by 360). This should get you correct values for your turning PID (using CANCoder as the feedback in code), I’ve never actually done this so I’m not certain. I just manually tuned mine. If you want the values I got feel free to ask.
Keep in mind these are values for MK2, but I imagine they should work decently well on newer modules. I got a P of 0.45 or 0.5 (I tuned two MK2 chasses and got different values), and a D of 0.3.
Funnily enough, I just checked and it turns out these are almost the exact same values I got for a MK4i chassis on Falcons.
I probably should have asked for input and output units. Our input units are radians and output is voltage. with our P at 6.25 right now I think I have some conversions to do.
Is there a reason your max velocity and acceleration are so high? Is that just what worked? I tried using feedforward and the response was so slow it was unusable and I’m looking for alternatives!
Max velocity was measured – command 100% power, and see what you get. The same for max acceleration, but here using the measured max was too aggressive and caused transient current faults from the motor controller. So, it was done by characterizing things and then rounding down and backing off the max acceleration.
The code linked above has test-mode routines which are used to do this, and to graph the related data. But in this case, it would have been OK to just guess and refine to get somewhere close. With these parameters, the I and D terms are zero (good), the P term is large enough so that things track the trapezoid pretty closely all through acceleration/flat/deceleration (good), and the trapezoidal parameters are such that the commanded position is achieved quite quickly.
The velocity is ~450 RPM and the acceleration is ~3333 RPM/s, so things quickly accelerate and decelerate, and the trapezoid actually does have a flat top on it for large turns.