frc5024 / InfiniteRecharge

The source and tooling behind FRC team 5024's 2020 competition robot

Home Page:http://cs.5024.ca/InfiniteRecharge/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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