Add DriveTrain and control stubs, and fill in abstract DriveTrain code
ewpratten opened this issue · comments
One of the first things we need to do, is get the robot's drivebase moving. This issue plays a key part in the process.
This issue is written a bit like a tutorial, just to make sure everyone knows what they are doing. Future issues will be less hand-hold-y
Outline
Here is a quick outline of all that needs to get done:
- Fill out method stub for controlling the robot with driver inputs
- Make the DriveTrain stateful
- Add Open-Loop controller
- Add Closed-Loop voltage controller & overload to accept WPILib's inputs
- Add a stub for ramp-rate control
- Add a "safety stop" method
- Stub out state-handling logic
Getting started
This is just a reminder to make, and switch to a new branch of the project before starting work. If you do not know how to do this, ask a returning team member.
All of the work outlined in this issue is to be done in the DriveTrain class located at src/main/java/frc/robot/subsystems/DriveTrain.java
. We will need a RobotLogger instance for the DriveTrain (I forgot to add it when setting up the project). Just create a public static object of RobotLogger
at the top of the DriveTrain source. It should look something like this:
public class DriveTrain extends SubsystemBase {
private RobotLogger logger = RobotLogger.getInstance();
...
Making the DriveTrain stateful
We will talk about autonomous control a little later (probably week 2), it will require the DriveTrain to behave a little differently than when the drivers are controlling the robot. Because of this, we will have to give the DriveTrain a way to know which "mode" it is running in. We can do this with a simple enum.
For now, I think well only need to define 2 modes:
- Open-Loop
- Used to control the robot with "percent output". This is basically telling the robot to do things like "move at 50% speed forward".
- This is how we will control the robot from Xbox controller inputs
- Voltage control
- As the name suggests, this will be a method of controlling the robot by specifying how much voltage to send to each motor.
These modes can be defined with the following enum. Remember to comment the code (please). For the new members, this should be defined above the class constructor (private DriveTrain()
)
/**
* Drive control modes
*/
public enum DriveMode {
OPEN_LOOP, // Open loop control (percent output control)
VOLTAGE // Voltage control
}
We will also want a private variable just to keep track of the current mode
// Keep track of the current DriveMode
private DriveMode m_currentDriveMode = DriveMode.OPEN_LOOP;
Open-Loop & Voltage controllers
Before starting, we will need another private variable to keep track of the current DriveSignal. Name it m_currentSignal
.
We need a method to actually specify our inputs. We'll start with the Open-Loop input. Voltage control is very similar. The idea of these methods is,
- Check if the DriveTrain is currently running in a diffrent mode
- If so, do anything needed to safely switch mode, and log the mode change
- Set the "desired output"
Ill write the Open-Loop controller as an example
/**
* Set the Open loop control signal. The values of this signal should be in the
* rage of [-1.0-1.0]
*
* @param signal Open loop signal
*/
public void setOpenLoop(DriveSignal signal) {
// Force-set the mode if not already set
if (m_currentDriveMode != DriveMode.OPEN_LOOP) {
// Enable motor brakes
setBrakes(true);
// Log the state change
logger.log("DriveTrain", String.format("Set control mode to OPEN_LOOP with signal: %s", signal.toString()));
// Set the new state
m_currentDriveMode = DriveMode.OPEN_LOOP;
}
// Set the current DriveTrain signal
m_currentSignal = signal;
}
Make sure to also add a method called setVoltage
. It should be similar, except all references to OPEN_LOOP
should be changed to VOLTAGE
, and the brakes value should be false
.
Make sure to update the javadoc at the top. The setVoltage
method will take values from -12.0
to 12.0
.
WPILib also requires a slightly different method. Just overload setVoltage
(create another method with the exact same name) and make it take in two double
values. called "left" and "right". With these values, create a DriveSignal
object, and pass it into the other setVoltage method. This can be done in one line with
setVoltage(new DriveSignal(left, right));
Remember: Comment, and add a javadoc to each method
Ramp Rate
We need a method stub for ramp rate control. Just call it setRampRate
, and make it take a double
. Also, add a comment that says something like TODO: Method stub
. We will fill this out once we have sorted out our motor controllers.
Safety Stop
Add a method called stop
, and make it call setOpenLoop
with a DriveSignal of zero (new DriveSignal(0,0)
)
Call this in Robot.java
in the disabledInit
method near the bottom. Just call m_driveTrain.stop();
(and add a comment describing why it's there).
Controlling the bot
We need a way to let the drivers control the bot. I have already stubbed out a drive
method. Just add the following logic for me:
// Square inputs
speed = InputUtils.scale(speed, ScalingMode.SQUARED);
rotation = InputUtils.scale(rotation, ScalingMode.SQUARED);
// Compute a DriveSignal from inputs
DriveSignal signal = DifferentialDriveCalculation.semiConstCurve(speed, rotation);
// Set the signal
setOpenLoop(signal);
This will square the inputs, then calculate, and set a DriveSignal.
Stubbing state handling
We have no logic to do for each state yet, so just add this statement to the periodic
method:
// Handle motor outputs for each mode
switch (m_currentDriveMode) {
case OPEN_LOOP:
// Set Open loop outputs for motors
// TODO: Set outputs here (reading from m_currentSignal)
break;
case VOLTAGE:
// Set Voltage outputs for motors
// TODO: Set outputs here (reading from m_currentSignal)
break;
default:
// This code should never run, but if it does, we set the mode to OPEN_LOOP, and
// the outputs to 0
setOpenLoop(new DriveSignal(0, 0));
}
Once finished
Once this is finished, make sure it builds, then open a Pull Request on GitHub from your branch into master. Ill review it, then merge it.
This is finished, and waiting on #34 to be merged