# 2020/2021 Version of Cheesy Drive?

Hi Everyone,

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 don’t know what you mean. Could you point out where that is in https://github.com/Team254/FRC-2019-Public?

If your goal is to avoid tipping, you have to limit acceleration. Your options are:

1. Apply a voltage ramp (causes lots of input lag). You can either use the CAN motor controller support or use WPILib’s SlewRateLimiter.
2. Make an acceleration feedback controller that regulates acceleration using voltage
3. Use implicit model following to make the drivetrain behave like a heavier one. See IMF class, IMF model and declaration, and IMF usage.

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 +
}


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.

indent preformatted text by 4 spaces


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.

Ah. I guess I just looked to quickly and didn’t dive in. Is duty cycle essentailly percent output? I’m just not quite sure what that is

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.