We are programming a Thrifty swerve as an off season project. We are using a neo 550 for steering, and of course the ctre can coder for absolute azimuth angle.
What strategy are people using to pid this? We could use the internal motor sensor on the neo550, but that travels through a planetary gearbox and steering ring, and ends up with backlash. But you can do the pid all internal to the spark max.
The cancoder has zero backlash, however I seem to remember a problem with using a secondary sensor to pid the spark max onboard, so I’m not sure if using the cancoder would mean the steering pid would happen on the Rio, which would negatively affect the pid response.
The Spark Max didn’t initially support a secondary encoder for PID. However, that was a quadrature encoder wired directly to the Spark Max. I haven’t heard anything about the Rev Spark Max supporting a CTRE CANCoder which would require Rev to decode the CTRE CAN frames…
How sure are you of this, given typical delays in a FRC signal chain? I really haven’t seen any evidence that the RIO isn’t fast enough to easily handle steering control on a swerve.
Adding 3630s anecdotal evidence. We experienced no problem running the 6 concurrent PID loops (4 of which were operating our swerve wheel angles) on the RIO with no problems.
Oh - I have no doubt the Rio is fast enough. Back before on-speed-controller pid we ran all of our pids on the Rio - heck, on the cRio.
I’m not up to speed on all the timings involved though, and swerve is a new animal to us. I’m just wondering how much time to target will change if we do direct PID on the spark max compared to cancoder-Rio-spark max. I’ve seen swerve teams talk about the amount of time it takes to get their modules on target, so it’s something I’m rattling around in my head.
With a CAN-based sensor, there are really two possible sources of latency. The first is how often the sensor sends a message updating it’s position data. The second is how often the periodic routines run on the RIO. These two are asynchronous, so it is possible that the periodic routine runs just before a new update. So, in the worse case, these latencies are additive.
We are using SRX Mag Encoders, since we are using SPARK MAX and running PID on the RIO – I second the recommendation to use ProfiledPIDController, BTW. But, I imagine using CANcoders would be fine also.
Out of curiosity, I understand the point of a motion profile on a large mechanism, but on something like a steering module is there any real benefit to that rather than brute force PID? I’d have to port it to Labview assuming Jsimso hasn’t already.
This write up seems to cover things, based on a quick search and skim. Empirically speaking, it was an easy conversion with WPILib and noticably improved things. There’s also some explanation here.
I am wondering what is the best approach to do the steering control. The strykeforce library seems to only support Talons for the steering but not the NEOs. Currently my approach is using the cancoder position at initialization to set the angle of the SparkMax internal encoder, and then simply using the internal PID to set the angle of the modules from there onwards. However, it may be better to just use the cancoder for the feedback instead along with a ProfiledPIDController for each module due to the backlash mentioned previously. The cancoder appears to be noisy though and jumps a few counts every few seconds. How are other teams approaching this problem?
Both approaches work well. My preference would be to run the control loops in the motor controller using motor integrated encoders, because of the snappy response times of the module. 5-10ms latency could lead to significant control loop tuning changes when you want to rotate to a position in < 100ms.
Last year we used the strykeforce library with neo 550 for the steering control and it worked well using can coders. This year we went closed loop with Talson SRX in closed loop with mag encoders. Both are valid approaches. We made our decision based on our existing motor conroller inventory and our comfort with closed loop.