I guess this is specifically a post to 254, who I’m a huge fan of. Are there any plans to release the 2020/2021 version of Cheesy Drive?
Currently my team uses 4 falcon 500s and I am struggling to implement the drive algorithm properly. The Drive Function they used to calculate their signals is straight forward, my struggle is with ramp rates and the PID.
In the 2019 version, 254 uses Sparks (versus my team using TalonFXs) and command with some sort of Duty Cycle PID. My team was just using Percent Output to our talons for about a year now (still drives nice, but can be tippy…our 2020 robot had a high CG). I’m curious if there is a talon equivalent of that kDutyCycle, PID, control mode that the SparkMax is using.
I’ll flesh out (2) more. For a DC motor, \tau = K_t I where K_t is torque per amp and I is current draw. Also, V = \frac{\tau}{K_t} R + \frac{\omega}{K_v} where V is voltage, R is motor resistance, \omega is motor speed, and K_v is speed per volt.
You’d try applying a voltage, and if it produces too much torque, find a voltage that keeps it under the limit.
double voltage = -joystick.GetY() * 12.0;
var motor = DCMotor.getNEO(1);
double torque = motor.KtNMPerAmp * motor.getCurrent(encoderSpeed, voltage);
// Find voltage that limits torque
if (Math.abs(torque) > kMaxTorque) {
voltage = kMaxTorque * Math.signum(torque) / motor.KtNMPerAmp * motor.rOhms +
encoderSpeed / motor.KvRadPerSecPerVolt;
}
Now that I think about it, current limiting might also be an option since that’s proportional to torque, and that comes built in on CAN motor controllers.
on line 71 and onward they declare SparkMaxs, specifically a child class of it called “LazySparkMax”.
on line 174 where they start commanding them in open loop, they are using “kDutyCycle” which calls this function:
public void set(ControlType type, double setpoint) {
if (setpoint != mLastSet || type != mLastControlType) {
mLastSet = setpoint;
mLastControlType = type;
super.getPIDController().setReference(setpoint, type);
}
}
I guess my question was really two phased, as I am trying to figure out the equivalent of that duty cycle pid control with talons.
Thanks for these! Yeah it isn’t as simple as just adding a voltage ramp to the talon as that effects turning badly along with slowing down. Thanks for those… I’m gonna have to dive into them.
Duty cycle PID doesn’t make sense. The motor controller has direct control over the duty cycle, so there’s nothing for PID to do. If you look at the internals of CANSparkMax.set(), you’ll notice that it calls setpointCommand() with kDutyCycle, just like CANPIDController.
So calling setReference() like that is just a roundabout way of calling set() for open-loop duty cycle control.