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-commands-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();
}
}

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 file in the mechanisms package named Feeder.java. Define a class named Feeder that implements Mechanism, then add the following:

  1. A private TalonFX motor controller object, named motor, with an ID of 5. It is connected to a systemcore CANBus with ID 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 A mechanism is defined as a class with the implements Mechanism keyword at the end.

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

Item 1, Hint 2 You can create a CANBus object via CANBus.systemcore(id).

Item 1, Hint 3 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");
public void periodic() {
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 an ID of 4. It is connected to a systemcore CANBus with ID 0.
  2. A shoot() command that waits 2 seconds, then sets the throttle of the motor to 0.9 forever.
  3. A intake() command that sets throttle to 0.8 forever.
  4. A outtake() command that sets throttle to -0.8 forever.
  5. A idle() command that sets throttle to 0 forever. Make this the default command.
  6. 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");
public void periodic() {
sim.periodic();
}

Change one thing, and copy-paste the code into IntakeLauncher.java.

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.intake.intake() and robot.feeder.intake() commands.
  2. While the xbox.rightBumper() trigger is active, run the robot.intake.shoot() and robot.feeder.feed() commands.
  3. While the xbox.a() trigger is active, run the robot.intake.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.intake.intake()).whileTrue(robot.feeder.intake());
// now fill in the rest...
}