Skip to content

Exercise - Kitbot Rewrite, Pt. 1

You will rewrite the code for a kitbot’s intake launcher and feeder mechanisms. In part 2 of this exercise, you’ll rewrite the drivetrain code in command-based, and add some basic auto modes.

Note

Your code will only work completely after you complete part 2. However, feel free to check your work with the solution code(currently TBD) after completing part 1.

Use git to clone stage 1 template code. Because both stage 1A and stage 1B use the same template, use the following terminal command to create a new project:

git clone https://github.com/frcsoftware/Stage1-Template-CTRE stage1b-ctre

Then, navigate to the Robot class under src/main/java/first/robot. For commands to function, you must call Scheduler.getDefault().run() in the robot class’ robotPeriodic() method.

class Robot extends OpModeRobot {
@Override
public void robotPeriodic() {
Scheduler.getDefault().run();
}
}

What does Scheduler.getDefault().run() do? The command scheduler is in charge of running all the commands that are active, and handling any mechanism requirements that those commands may have. Calling this method runs the scheduler, and therefore all active commands, for one iteration.

Create a new package named mechanisms under the robot package. Remember that packages are folders that contain java files. The mechanisms package will contain the code for our feeder and intake launcher mechanisms.

Then, create a new Java class in the mechanisms package named Feeder.java, which will be used to control the feeder. The Feeder class should implement Mechanism.

Hint A mechanism is defined as a class with the implements Mechanism keyword at the end.

public class Feeder implements Mechanism {
// your code here...
}

Then, add the following:

  1. A private TalonFX motor controller object, named motor, with CAN ID 5 on Systemcore CANBus 0.
  2. A feed() command that sets the throttle of the motor to 0.75 forever.
  3. An intake() command that sets the throttle of the motor to -1 forever.
  4. An outtake() command that sets the throttle of the motor to 1 forever.
  5. An idle() command that sets the throttle of the motor to 0 forever. Make this the default command.

The feed(), intake(), outtake() and idle() commands should be returned from methods.

Item 1, Hint 1 For CTRE devices, a CANBus object can be created via CANBus.systemcore(id).

Item 1, Hint 2 Remember that TalonFX is a class, and that creating objects within another class is done like so:

private TypeOfClass myMotor = new TypeOfClass();

First, figure out what to replace TypeOfClass with. Next, add the appropriate constructor parameters by hovering over the red squiggly line.

Items 2-4, Hint 1 Re-read the “Defining Commands” and “Combining Commands and Mechanisms” subsections of the “Commands and Mechanisms, Pt. 1” supersection (it should be visible from the left sidebar).

Item 5, Hint 1 To set a mechanism’s default command, call setDefaultCommand(Command) inside of the constructor.

After completing all of that, copy-paste the following code into the Feeder class to allow for simulation to work:

private final SingleFlywheelSim sim = new SingleFlywheelSim(motor, "Feeder"); // Create a flywheel simulation
public void periodic() { // Update the simulation
sim.periodic();
}

This code creates a SingleFlywheelSim object named sim that simulates the feeder by representing it as a single spinning flywheel, then updates the simulation in sim.periodic().

Create a file named IntakeLauncher.java in the mechanisms package. Define a class named IntakeLauncher that implements Mechanism; then, add the following:

  1. A private TalonFX motor controller object, named motor, with ID 4 on Systemcore bus 0.
  1. A shoot() command that waits 2 seconds, then sets the throttle of the motor to 0.9 forever.

  2. A intake() command that sets throttle to 0.8 forever.
  3. A outtake() command that sets throttle to -0.8 forever.
  4. A idle() command that sets throttle to 0 forever. Make this the default command.

  5. The code needed for simulating the intake launcher. You haven’t officially learned how to do this, but task 2’s final section gives a hint. Can you figure it out?

Item 2 Hint Call coroutine.wait(Seconds.of(2)) to wait 2 seconds within a Command.

Item 6 Hint In task 2, you were told to copy-paste the following code to simulate the feeder:

private final SingleFlywheelSim sim = new SingleFlywheelSim(motor, "Feeder"); // Create a flywheel simulation
public void periodic() { // Update the simulation
sim.periodic();
}

Copy-paste the code into IntakeLauncher.java, and change one thing.

Now that we have the mechanism classes created, we need to instantiate them in the Robot class.

Go to the Robot class and create new instances of the IntakeLauncher and Feeder classes. They should be public properties of the Robot class, so that they are accessible from OpModes. Name them intakeLauncher and feeder, respectively.

You also need to call intakeLauncher.periodic(); and feeder.periodic(); within a method of the Robot class. Which method should it be?

Hint What method in the Robot class has the word periodic in it?

In the constructor of the teleop OpMode (it should be in MyTeleop.java), create a private CommandXboxController instance named xbox.

In your OpMode constructor, define the following behavior:

  1. While the xbox.leftBumper() trigger is active, run the robot.intakeLauncher.intake() and robot.feeder.intake() commands.
  2. While the xbox.rightBumper() trigger is active, run the robot.intakeLauncher.shoot() and robot.feeder.feed() commands.
  3. While the xbox.a() trigger is active, run the robot.intakeLauncher.outtake() and robot.feeder.outtake() commands.

Hint Can you think of why we should use whileTrue() instead of onTrue() here?

public MyTeleop(Robot robot) {
xbox.leftBumper().whileTrue(robot.intakeLauncher.intake()).whileTrue(robot.feeder.intake());
// now fill in the rest...
}