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.
- 1 External Usage
- 2 Internal 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.
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.
There are three different inversion parmameters,
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,
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.
The Talon supports both physical limit switches and software limits. For the physical limit switches, if you want to enable using them, set
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
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.
Four parameters affect how encoder data is read, written, and displayed.
feedbackDevice is the type of encoder used, most likely
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.
perGearSettings is a list of gear-specific setting objects, and you should have one for every gear. A quick rundown:
gear: The gear number or name, respectively, that these specific settings are for. If both are in the map,
geartakes precedence. If there's only one gear for this motor, don't put either in the map, and it'll default to gear 0.
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.
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.
closedLoopRampRateis 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.
maxSpeedis the measured max speed of the robot in this gear, in feet per second (or rotations per second if
feetPerRotationis 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.
kDare 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.
motionProfileDare 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,
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.
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.
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.
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.
Setting Motor Speed
The two most commonly-used methods to set a Talon's speed are
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.
enableswitch 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.
resetPositionresets the position to 0. This is useful both to reset before a motion profile and for soft limits (discussed above).
setGearswitches 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.
All the output methods are called
getBlah() and do exactly what their name implies.
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 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.
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
encoderToFPS to convert velocities, 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:
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.
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.
setVelocityFPStakes a velocity in FPS, not -1 to 1, and sets it as the setpoint for velocity mode. Useful for scaling the input, like for
updateMotionProfileStatusupdates the private field
motionProfileStatuswith the Talon's current MP status. You should always use this method instead of directly calling
updateMotionProfileStatusdoes 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.
clearMPclears the motion profile buffers and resets everything motion-profile related.
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.