Exercise - Kitbot Rewrite, Pt. 1
What You’ll Accomplish
Section titled “What You’ll Accomplish”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.
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.
Task 1: Setup
Section titled “Task 1: Setup”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-ctregit clone https://github.com/frcsoftware/Stage1-Template-REV stage1b-revThen, 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
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.Scheduler.getDefault().run() do?
Task 2: The Feeder Mechanism
Section titled “Task 2: The Feeder Mechanism”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:
- A private
TalonFXmotor controller object, namedmotor, with CAN ID 5 on Systemcore CANBus 0. - A
feed()command that sets the throttle of the motor to 0.75 forever. - An
intake()command that sets the throttle of the motor to -1 forever. - An
outtake()command that sets the throttle of the motor to 1 forever. - 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, aCANBus object can be created via
CANBus.systemcore(id).Item 1, Hint 2
Remember thatTalonFX 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.
- A private
SparkMaxmotor controller object, namedmotor, with CAN ID 5 on Systemcore CANBus 0. - A
feed()command that sets the throttle of the motor to 0.75 forever. - An
intake()command that sets the throttle of the motor to -1 forever. - An
outtake()command that sets the throttle of the motor to 1 forever. - 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
Remember thatSparkMax 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().
Task 3: The IntakeLauncher Mechanism
Section titled “Task 3: The IntakeLauncher Mechanism”Create a file named IntakeLauncher.java in the mechanisms package.
Define a class named IntakeLauncher that implements Mechanism; then, add the following:
- A private
TalonFXmotor controller object, namedmotor, with ID 4 on Systemcore bus 0.
- A private
SparkMaxmotor controller object, namedmotor, with ID 4 on Systemcore bus 0.
A
shoot()command that waits 2 seconds, then sets the throttle of the motor to 0.9 forever.- A
intake()command that sets throttle to 0.8 forever. - A
outtake()command that sets throttle to -0.8 forever. A
idle()command that sets throttle to 0 forever. Make this the default command.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.
Task 4: Finish the Robot class
Section titled “Task 4: Finish the Robot class”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?
Task 5: Finish the teleop OpMode
Section titled “Task 5: Finish the teleop OpMode”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:
- While the
xbox.leftBumper()trigger is active, run therobot.intakeLauncher.intake()androbot.feeder.intake()commands. - While the
xbox.rightBumper()trigger is active, run therobot.intakeLauncher.shoot()androbot.feeder.feed()commands. - While the
xbox.a()trigger is active, run therobot.intakeLauncher.outtake()androbot.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...}