diff --git a/examples/stage1/stage1b/snippets/src/main/java/sources/CommandBasedKitbot.java b/examples/stage1/stage1b/snippets/src/main/java/sources/CommandBasedKitbot.java index f98703d0..196a2c4f 100644 --- a/examples/stage1/stage1b/snippets/src/main/java/sources/CommandBasedKitbot.java +++ b/examples/stage1/stage1b/snippets/src/main/java/sources/CommandBasedKitbot.java @@ -45,9 +45,9 @@ public MyTeleop(Robot robot) { private final ExampleMotor motor = new ExampleMotor(); // [feederSim] - private final SingleFlywheelSim sim = new SingleFlywheelSim(motor, "Feeder"); + private final SingleFlywheelSim sim = new SingleFlywheelSim(motor, "Feeder"); // Create a flywheel simulation - public void periodic() { + public void periodic() { // Update the simulation sim.periodic(); } // [/feederSim] diff --git a/src/content/docs/learning-course/stage1/stage1b/command-based-kitbot-pt2.mdx b/src/content/docs/learning-course/stage1/stage1b/command-based-kitbot-pt2.mdx index 9ee6afc3..f8eedf95 100644 --- a/src/content/docs/learning-course/stage1/stage1b/command-based-kitbot-pt2.mdx +++ b/src/content/docs/learning-course/stage1/stage1b/command-based-kitbot-pt2.mdx @@ -13,7 +13,7 @@ import Aside from '@components/Aside.astro'; In this second part of the kitbot rewrite, you will: -1. Create a `Drivetrain` mechanism class. +1. Create a `Drivetrain` mechanism class to allow for control of the drivetrain. 2. Define an `arcadeDrive` command that dynamically reads controller inputs using `DoubleSupplier`s. 3. Bind the default drivetrain command in your teleop OpMode to enable driving. 4. Define some basic autonomous modes. @@ -68,6 +68,8 @@ To do that, write the following: ### Task 3: Using the Drivetrain +Now that we have a `Drivetrain` class, we need to set it up to be used in our robot code. + 1. Create a `Drivetrain` instance in `Robot.java` named `drivetrain`. It should be a public instead of private. 2. Call `drivetrain.periodic();` in the `robotPeriodic` method. @@ -101,7 +103,9 @@ To do that, write the following: ### Task 4: Create Auto Mode Files -Create 2 java files in the `opmode` package, named `DriveStraightAutoMode.java` and `TurnInPlaceAutoMode.java`, +We need to create two new files to define our autonomous OpModes. + +Create 2 Java files in the `opmode` package, named `DriveStraightAutoMode.java` and `TurnInPlaceAutoMode.java`, before deleting the `MyAuto.java` file. Copy-paste the following code in each file, while replacing `MyOpModeName` with the correct name for each opmode: @@ -112,6 +116,8 @@ while replacing `MyOpModeName` with the correct name for each opmode: ### Task 5: Drive Straight Autonomous +This auto will drive the robot straight forwards for 4 seconds. + In the `start()` method of `DriveStraightAutoMode.java`, schedule an `arcadeDrive` command with a timeout of 4 seconds. Then, do the following: @@ -143,6 +149,8 @@ Then, do the following: ### Task 6: Rotate in Place Command +This command will rotate the robot a certain number of degrees. + Create a new `Command` in `Drivetrain.java`, called `rotateInPlace`, with the parameters `double angleDegrees` and `DoubleSupplier rotationThrottle`. It should execute these actions, in order: diff --git a/src/content/docs/learning-course/stage1/stage1b/command-based-kitbot.mdx b/src/content/docs/learning-course/stage1/stage1b/command-based-kitbot.mdx index c7a52718..db832232 100644 --- a/src/content/docs/learning-course/stage1/stage1b/command-based-kitbot.mdx +++ b/src/content/docs/learning-course/stage1/stage1b/command-based-kitbot.mdx @@ -56,52 +56,90 @@ the robot class' `robotPeriodic()` method. ``` +
+ 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. +
+ ### 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 file in the `mechanisms` package named `Feeder.java`. -Define a class named `Feeder` that implements `Mechanism`, then add the following: +Remember that packages are folders that contain java files. +The `mechanisms` package will contain the code for our feeder and intake launcher mechanisms. -1. A private `TalonFX` or `SparkMax` 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. +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`.
- Item 1, Hint 1 + Hint A mechanism is defined as a class with the `implements Mechanism` keyword at the end. ```java #feederDef ```
-
- Item 1, Hint 2 (CTRE only) - For CTRE devices, a `CANBus` object can be created via `CANBus.systemcore(id)`. -
-{/* prettier-ignore */} -
- Item 1, Hint 3 - Remember that `TalonFX` and `SparkMax` are classes, and that creating objects within another - class is done like so:
- {/* rli:ignore */} - ```java - 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. -
+ +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)`. +
+ {/* prettier-ignore */} +
+ Item 1, Hint 2 + Remember that `TalonFX` is a class, and that creating objects within another + class is done like so:
+ {/* rli:ignore */} + ```java + 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. +
+
+ + 1. A private `SparkMax` 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 + Remember that `SparkMax` is a class, and that creating objects within another + class is done like so:
+ {/* rli:ignore */} + ```java + 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" @@ -121,22 +159,40 @@ to allow for simulation to work: ``` +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 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` or `SparkMax` 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? + + + 1. A private `TalonFX` motor controller object, named `motor`, with ID 4 + on Systemcore bus 0. + + + 1. A private `SparkMax` 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. +
  3. A `intake()` command that sets throttle to 0.8 forever.
  4. +
  5. A `outtake()` command that sets throttle to -0.8 forever.
  6. +
  7. + A `idle()` command that sets throttle to 0 forever. Make this the + default command. +
  8. +
  9. + 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? +
  10. +
Item 2 Hint @@ -148,15 +204,16 @@ Define a class named `IntakeLauncher` that implements `Mechanism`; then, add the ```java #feederSim ``` - Change one thing, and copy-paste the code into `IntakeLauncher.java`. + Copy-paste the code into `IntakeLauncher.java`, and change one thing.
### Task 4: Finish the `Robot` class -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. +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();` @@ -170,10 +227,10 @@ Which method should it be? ### Task 5: Finish the teleop OpMode -In the constructor of the teleop opmode (it should be in `MyTeleop.java`), +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: +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. diff --git a/src/content/docs/learning-course/stage1/stage1b/spot-the-error.mdx b/src/content/docs/learning-course/stage1/stage1b/spot-the-error.mdx index abc4eb6f..9ecfc247 100644 --- a/src/content/docs/learning-course/stage1/stage1b/spot-the-error.mdx +++ b/src/content/docs/learning-course/stage1/stage1b/spot-the-error.mdx @@ -70,6 +70,9 @@ Can you spot the error? ### Exercise 3 +This fails to compile, with the error shown in the comment. +It also has a logic error. + {/* rli:ignore */} ```java