FPSTalon

From Team 449 Wiki

FPSTalon (FPS stands for Feet Per Second, the unit used by this class) is the wrapper class that we use for controlling CANTalon motor controllers. The Talons have a ton of functionality, and, as such, FPSTalon is our most complex class. The JavaDocs for it are found here.

External Usage

Interfacing with FPSTalons from other classes is relatively simple. If you don't need to use the more complex features of the Talon, use the SimpleMotor interface instead.

Constructor

The constructor for FPSTalon has a ton of arguments, but in practice you'll only need to set a few, the defaults work fine for the rest. The only three parameters you need to have are the port number (which can be found on the roboRIO web interface), whether or not to invert the motor, and whether or not to use brake mode. Port number is self-explanatory, and brake mode controls whether, when PID is not being used, the motors should attempt to actively break when an input of 0 is given. Inversion seems like it should simply be which direction the motor should turn when given a positive input, but unfortunately, it's not.

Inversion

There are three different inversion parmameters, inverted, reverseOutput, and reverseSensor. For voltage control, only inverted matters, and you should set it so that a positive input to the Talon corresponds to moving forwards, spinning the flywheel in the correct direction, etc. For the PID modes, reverseOutput and reverseSensor both start mattering. Because the Talon SRX library is bad, inverted doesn't do anything in Motion Profile modes. As such, for both PID and motion profiling, you should set inverted to false and then manually switch it back if you need to use voltage mode again. You should set reverseSensor first, so that the sensor reads a positive velocity when turned in the forwards direction. Then set reverseOutput so that a positive input results in a positive sensor reading.

Limits

The Talon supports both physical limit switches and software limits. For the physical limit switches, if you want to enable using them, set fwdLimitSwitchNormallyOpen and revLimitSwitchNormallyOpen. For example, if you want the motor to shut off when either limit switch closes, set both to true, because they're "normally" open but close when you want to shut off the motor. If you want to limit the range of motion of a motor that has an encoder, but can't fit in limit switches, you can use software limits. Set fwdSoftLimit and redSoftLimit to turn on software limits. If the motor position is further forward than the forward switch, it won't go any more forward, and if it's further back than the reverse limit, it won't go any further back. Both are measured in feet from the position the motor was turned on in.

Output Modifiers

Four parameters affect how encoder data is read, written, and displayed. feedbackDevice is the type of encoder used, most likely QuadEncoder. encoderCPR is the number of counts per rotation of the encoder, which can be found on its part order page on VexPro, Andymark, etc. postEncoderGearing is the gearing ratio between where the encoder measures the motor output and the wheels. Most of the time the encoder will be on the wheels and you can just use the default value of 1. feetPerRotation specifies how many feet the wheel travels in one rotation, or the rolling circumference of the wheel in feet. You can leave it at the default value of 1 to use rotations per second, or try to measure the rolling rolling circumference of the wheel (note that this is often different from the actual circumference) by driving a certain distance with a motion profile.

Gear settings

perGearSettings is a list of gear-specific setting objects, and you should have one for every gear. A quick rundown:

  • gearNum and gear: The gear number or name, respectively, that these specific settings are for. If both are in the map, gear takes precedence. If there's only one gear for this motor, don't put either in the map, and it'll default to gear 0.
  • fwdPeakOutputVoltage and revPeakOutputVoltage: The maximum and minimum output voltages in closed-loop control modes, respectively. Defaults to 12 and -12 and there's rarely ever a reason to change that.
  • fwdNominalOutputVoltage and revNominalOutputVoltage: These are the minimum magnitude voltage outputs for closed-loop modes in the forwards and reverse directions. Unfortunately, the Talon library doesn't rescale the output so this voltage is the the Y-intercept of the input vs. output curve. Instead, it makes any output that would be less than the minimum the minimum. Nevertheless, this should be used for all drive motors. It's measured using the DetermineNominalVoltage command. The forwards limit defaults to 0 and the reverse defaults to the negative of the forward.
  • closedLoopRampRate is the voltage ramp rate for closed-loop control, in volts per second. What this does is make sure the voltage doesn't change any faster than this rate. This can help avoid using up too much battery voltage, especially for things like flywheels that don't need to accelerate or decelerate quickly.
  • maxSpeed is the measured max speed of the robot in this gear, in feet per second (or rotations per second if feetPerRotation is 1.) This is what controls whether PID is on or off for this gear- if it's not in the map, voltage mode is used, if it is, velocity PID is used.
  • kP, kI, and kD are the velocity closed-loop PID constants. See PID Tuning for more info, and don't put them in the map if you aren't using PID.
  • motionProfileP, motionProfileI, and motionProfileD are the motion profile PID constants. Again, see PID Tuning for more info, and don't bother putting them in the map if not using motion profiling in this gear.

In the main FPSTalon constructor, startingGearNum and startingGear are the starting gear's number or name, respectively. If both are in the map, startingGear is used. If neither is in the map, it defaults to the lowest-numbered (or only) gear.

Motion Profiling

minNumPointsInBottomBuffer controls how many points need to be loaded into the bottom-level motion profile buffer before a profile can start running. It defaults to 20, which is reasonable but you can generally get away with a lower number. updaterProcessPeriodSecs is the period, in seconds, of the thread that moves points from the API-level buffer to the bottom-level one. It should be about 10 times faster than the delta time for the motion profile.

Slaves

Each Talon has an optional list of slaves that it controls. Each Talon can have any number of slaves, and each slave only has two fields: port, the port the slave is on, and inverted, whether the slave is inverted compared to the master.

Other

currentLimit sets the maximum output current, in amps, for the Talon. You should almost always use this, especially on drives, and set the value to the same as the breaker on the Talon's PDP slot.

Input Methods

Setting Motor Speed

The two most commonly-used methods to set a Talon's speed are setVelocity and setGearScaledVelocity. setVelocity just takes a number from -1 to 1 and sets the output accordingly, with 1 being full throttle forwards and -1 being full backwards. It uses velocity PID if the max speed for the current gear is in the map, and voltage mode otherwise. setGearScaledVelocity does the same thing, but for velocity PID mode, instead of 1 setting the setpoint to the current gear's max speed, it sets the setpoint to the given gear's max speed. This should be used instead of setVelocity when the motor is being controlled by joystick input and autoshifting is being used, because it keeps the joysticks uniformly scaled to the high gear's velocity. Ihe less-used methods is setPercentVoltage, which again takes a -1 to 1 setpoint, but will use voltage mode even if there are PID constants in the map. This is pretty much only used for setting the motors to zero voltage output when you want them to stop but not in the active way that PID does.

Other

  • disable and enable switch the motor into and out of disabled mode. While disabled, the motor will give no output, even when commanded to. Be careful with calling this on a motor, as it will ignore all attempts to change its velocity until it's re-enabled.
  • resetPosition resets the position to 0. This is useful both to reset before a motion profile and for soft limits (discussed above).
  • setGear switches the talon to the given gear, fairly self-explanatory. Note that the Talon is only a motor, and does not control the shifter piston. All this method does is change the PID gains, etc., don't expect it to physically change anything.

Output Methods

All the output methods are called getBlah() and do exactly what their name implies.

Motion Profiling

The normal usage of the motion profiling methods is calling loadProfile to load in a profile to the talon, waiting until readyForMP returns true, then calling startRunningMP to actually start moving the motor. From there, wait until MPIsFinished returns true, then call holdPositionMP to have the Talon use PID to stay in its current location. Once you're done with MP for the match (normally at the start of Teleop), call stopMPProcesses to clean things up.

Internal Usage

Internal usage often involves interacting with CTRE's CANTalon class directly. This class is notoriously poorly documented, with the documentation being wrong in many places. However, it's still often useful, and you should read it. The javadocs are here, the software guide is here, and the other technical resources can be found here.

Units

We do everything in feet or feet per second. CTRE does everything in "native units" where one native unit is a quarter of a quadrature encode cycle (or one encoder tick), and native units per 100 milliseconds. That's obviously not a human-readable or usable unit. As a result, we have to convert in and out of native units to do everything. Use FPSToEncoder and encoderToFPS to convert velocities, and feetToEncoder and encoderToFeet to convert positions. "Feet" and "FPS" mean "movement of the final output wheel/flywheel/etc. in feet, or rotations if feetPerRotation is 1." "Encoder" means "native units as measured by the encoder," so all of these conversion methods account for native to sane unit conversion, post-encoder gearing, and wheel circumference. There are two other "pure" unit conversion methods that you'll probably never need to use: RPSToNative and nativeToRPS, which convert between native units and rotations per second. These are "pure" methods because they don't account for any of the physical aspects like post-encoder gearing and wheel circumference, and just convert between native units per 100 milliseconds and rotations per second.

Gears

All of the PID-related settings are stored in the gears. You should access anything stored in the gear settings via currentGearSettings.getBlah(). All gear settings are stored in perGearSettings, which maps the gear number to the settings.

Private Methods

  • setVelocityFPS takes a velocity in FPS, not -1 to 1, and sets it as the setpoint for velocity mode. Useful for scaling the input, like for setGearScaledVelocity.
  • updateMotionProfileStatus updates the private field motionProfileStatus with the Talon's current MP status. You should always use this method instead of directly calling canTalon.getMotionProfileStatus because updateMotionProfileStatus does nothing if called a second, third, etc. time during the same tic. We need to do this because getting the MP status is a lot of traffic for the CAN bus to handle, and calling it multiple times risks overloading the bus and having data get lost or corrupted.
  • clearMP clears the motion profile buffers and resets everything motion-profile related.

Information Hiding

In general, the other classes shouldn't know or care if the Talon is in voltage or velocity mode. As such, make sure that all public setters only take [-1, 1] values. We also need to contain the horrible mutated monster that is native units to this class, so make sure that all getters return either [-1, 1], feet, or feet per second. The details of how Motion Profiles work should also be contained to this class.