Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion src/content/docs/learning-course/stage1/stage-overview.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ next: stage-1a/stage-overview

Congratulations!
Whether you already know Java, have programmed an FRC robot before,
or are a complete beginner, you should have a good grasp of the basic syntax of the Java language by now.
or are a complete beginner, you should have a good grasp of the Java language by now.
In Stage 1, we'll be moving on to the exciting part: actually writing code for a robot!
It might seem daunting at first, but the best way to think through it is to focus on understanding
how each individual component of the code works, instead of trying to tackle it all at once.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { REV_CTRE_CHOOSER_KEY } from '@data/tabsSyncKeys.ts';
It's common to write code without having immediate access to a physical robot to test changes.
Luckily, your computer can also run robot code allowing it to be tested without a robot.
While there are some things that can be tested by simulating pure robot code, there are no physical motors to move and respond with new positions.
Instead we use simulation classes that use physics to take the desired input voltage to the motors and estimate how the physical mechanism would respond and update our motor controller instances to match.
Instead, we use simulation classes that use physics to take the desired input voltage to the motors and model how the physical mechanism would respond.
For this stage custom classes have been provided that abstract away much of this logic.
You can find these files under the `simulation` folder if you would like to read the implementation.
You can also read the [WPILib docs on simulation](https://docs.wpilib.org/en/stable/docs/software/wpilib-tools/robot-simulation/index.html) if you would like to learn more about simulation.
Expand All @@ -27,6 +27,7 @@ To simulate the drivetrain another class needs to instantiated in `Robot.java`.
Create an instance of the `DrivetrainSim` class under the `DifferentialDrive` instance using the left and right Leader motors as inputs.
This class will read the voltage commanded to the motors and, using its physics sim, update the motor controllers with new positions.
The class will then publish the new drivetrain position and additional motor data so it can be viewed in AdvantageScope.
AdvantageScope is a program that is bundled with WPILib, and is used to visualize data sent by the robot.

<Tabs syncKey={REV_CTRE_CHOOSER_KEY}>
<TabItem label="CTRE">
Expand Down Expand Up @@ -110,11 +111,11 @@ After adding the simulation code your `Robot.java` file should now look like thi
When simulating code there are two main windows to control and visualize what the code is doing.

The first important window is the Sim GUI.
The Sim GUI is automatically opened when simulating code and acts as both a Driver Station and shows information about simulated devices such as position and velocity.
The Sim GUI is automatically opened when simulating code.
It acts as a Driver Station and shows information about simulated devices such as position and velocity.
More information about the Sim GUI can be found in [WPILib's documentation](https://docs.wpilib.org/en/stable/docs/software/wpilib-tools/robot-simulation/simulation-gui.html).

The other important window is a program called AdvantageScope.
AdvantageScope is bundled with WPILib and is used to visualize data sent by the robot.
The main tabs used in AdvantageScope are **Line Graph**, used to graph numeric data such as a motors current position, and **2D Field** used to visualize positions on the field.
AdvantageScope can also be used to assist in debugging by visualizing logs generated by the robot during a match.
More information about using AdvantageScope can be found at [their docs](https://docs.advantagescope.org/).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ by the same basic components.
</FileTree>

You'll notice that we're skipping a lot of files here, because you don't have to edit those.
What's great about using a framework like WPILib is that it automatically generates these files when you create a new project, so you can get started coding quicker.
What's great about using a framework like WPILib is that it automatically generates these files when you create a new project, so you can get started coding faster.
The other folders, like `src/main/deploy/` for example, will come in handy as your robot code becomes more advanced.
Thus, the only files shown in the structure tree are the ones directly responsible for controlling what our kitbot will do.

Expand All @@ -91,7 +91,8 @@ Thus, the only files shown in the structure tree are the ones directly responsib
### `Main.java`

The first file to take note of is the `Main.java` file; this is the entrypoint for any Java project in real life.
Its contents are pretty short and sweet (comments and package declaration removed for brevity):
Its contents are pretty short and sweet.
Comments and package declaration removed for brevity so your `Main.java` will look different.

```java stage1/snippets/Main.java#main

Expand All @@ -118,7 +119,7 @@ RobotBase.startRobot(first.robot.Robot::new);
It seems to be "starting" an instance of the `first.robot.Robot` class, and if we go to that class file, we end up at `Robot.java`.
This is the core of your robot code, where:

- your subsystems are defined
- your mechanisms are defined
- shared behavior is defined
- your debugging data is logged (telemetry).

Expand All @@ -136,7 +137,7 @@ An OpMode is a class that controls the behavior of your robot during a specific
You can have multiple OpModes per robot mode, and they are selected on the Driver Station to tell the robot which one to run.
This allows you to have different autonomous routines for different situations,
or multiple teleop routines for different drivers.
OpModes use the `Robot` class to access the robot's subsystems and other shared behavior.
OpModes use the `Robot` class to access the robot's mechanisms and other shared behavior.

<Aside type="note">
Prior FRC programmers may have used `SendableChooser` to register different
Expand All @@ -146,5 +147,5 @@ OpModes use the `Robot` class to access the robot's subsystems and other shared

### `simulation/`

These are the files that control simulation of the robot, allowing you to test code without actually having a physical robot in front of you.
These are the files that control simulating the robot, allowing you to test code without actually having a physical robot in front of you.
We've set this up for you already; you'll just have to set up the simulation software yourself, which we'll cover at the end of Stage 1A.
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,61 @@ import ContentImage from '@components/ContentImage.astro';
src="/learning-course/stage1/stage1a/kitbotDrivetrain.webp"
/>

The kitbot uses a four motor tank drive meaning the left and right sides are driven independently by two motors each.
This allows
the robot to move similar to a tank by driving the left and right sides at different speeds.
The kitbot uses a four motor tank drive.
A tank drive is a type of drive train where left and right sides are driven independently by two motors each.
This allows the robot to move similar to a tank by driving the left and right sides at different speeds.
For this stage, the four drivetrain motors will be referred to as `leftLeader`, `leftFollower`, `rightLeader`, `rightFollower`.

# Systemcore

Systemcore is the main processor for robot code.
It can be thought of as the "brain" of the robot.
Motor controllers connect to the Systemcore through the CAN ports.

<ContentFigure
width="300px"
alt="Drivetrain"
src="/learning-course/stage1/stage1a/systemcore.webp"
/>

# Motor Controllers

Motors can not be controlled directly.
Instead, Systemcore talks to a motor controller and the motor controller then drives the motors.
FRCSoftware covers two types of motor controllers: REV's SparkMAX and CTRE's TalonFX

export const codeRepo = [
{
title: 'SparkMAX',
image: '/learning-course/stage1/stage1a/sparkmax.webp',
imageAlt: 'A photo of a SPARKMax. Photo Credit: REV',
},
{
title: 'TalonFX',
image: '/learning-course/stage1/stage1a/kraken.webp',
imageAlt: 'A photo of a kraken motor. Photo Credit: CTRE',
},
];

<section class="mechanism-section">
<div class="section-heading"> </div>

<div class="featured-grid">
{codeRepo.map((example) => (
<article class="featured-card">
{example.image && (
<div class="featured-image">
<img src={example.image} alt={example.imageAlt} loading="lazy" />
</div>
)}
<div class="featured-body">
<h3>{example.title}</h3>
</div>
</article>
))}
</div>
</section>

Vendors, such as REV or CTRE, provide classes that can be used to both control and get sensor data, such as position, velocity, and temperature, from their motor controllers.
While each individual type of motor controller has its own class, motor controllers from the same vendor are
mostly interacted with in the same way so this stage will only use the `SparkMax` for REV code and the `TalonFX` for CTRE code.
Expand All @@ -45,9 +91,16 @@ mostly interacted with in the same way so this stage will only use the `SparkMax
`TalonFX` and `SparkMax` look like `import
com.ctre.phoenix6.hardware.TalonFX;` and `import
com.revrobotics.spark.SparkMax;` respectively.

<ContentFigure
width="500px"
alt="Opening AdvantageScope"
src="/learning-course/stage1/stage1a/import.webm"
/>

</Aside>

When creating a motor controller object, the physical motor controller's CAN ID and the CAN Bus ID are given.
When creating a motor controller object, the physical motor controller's CAN ID and the CAN Bus must be provided in the constructor.
CAN Bus refers to which of the 5 Systemcore CAN ports, or which CANivore, the device is plugged into.
CAN ID is an integer that each CAN device is configured to have.
All devices on a given CAN Bus must have a unique ID.
Expand Down Expand Up @@ -108,7 +161,7 @@ Now try creating the right motor controllers on your own.

# Motor Controller Configuration

Motor Controllers have many settings that can be changed such as IDs, motor
Motor controllers have many settings that can be changed such as IDs, motor
types, and limits.
Vendors provide
software, such as REV's [REV Hardware Client 2](https://docs.revrobotics.com/rev-hardware-client-2) and CTRE's [Phoenix Tuner X](https://v6.docs.ctr-electronics.com/en/stable/docs/tuner/index.html), to run
Expand Down Expand Up @@ -157,11 +210,11 @@ This object stores the configuration so it can be changed and shared across diff

</Tabs>

Next, settings can be changed from their default by calling various functions on the configuration object with their new values.
Next, the motor controller’s settings can be changed from their default by calling various functions on the configuration object with their new values.
For the left motors, the invert setting will be `true` for REV code and `Clockwise_Positive` for CTRE code.
This will cause the motors to spin in a direction that would drive the robot forward when a positive input is given.
Since the motors on the right side of the drivetrain are facing the opposite direction they would cause the wheels try and drive the robot backwards when given a positive input if they were configured the same way.
Instead they should be configured with an invert setting of `false` or `CounterClockwise_Positive` so they also drive the robot forward when given a positive input.
Since the motors on the right side of the drivetrain are facing the opposite direction, they would cause the wheels to try and drive the robot backwards when given a positive input if they were configured the same way.
Therefore, the left motor needs to be configured with an invert setting of `false` or `CounterClockwise_Positive` so they also drive the robot forward when given a positive input.

<Tabs syncKey={REV_CTRE_CHOOSER_KEY}>
<TabItem label="CTRE">
Expand Down Expand Up @@ -240,7 +293,7 @@ While there are several ways to control a tank drive, this stage will be using a
Arcade drive uses the y-axis of a joystick to control how fast the robot drives forward or backward while the x-axis controls how fast the robot rotates clockwise or counter clockwise.
WPILib provides a class to convert joystick inputs into commands for the motors to follow called `DifferentialDrive`.

An instance of `DifferentialDrive` should be created under where the motor controllers were declared.
An instance of `DifferentialDrive` should be created under where the motor controllers were first declared.

<Tabs syncKey={REV_CTRE_CHOOSER_KEY}>
<TabItem label="CTRE">
Expand Down Expand Up @@ -338,12 +391,13 @@ By extending `PeriodicOpMode` these classes gain a few useful functions that are
- `periodic()` is called repeatedly when the robot is enabled.
- `end()` is called once when the robot transitions from enabled to disabled.
- `disabledPeriodic()` is called repeatedly when the robot is disabled.
Further information about OpModes can be found in [this blog post](https://zharel.me/blog/opmodes/) if you would like to learn more.

Further information about OpModes can be found in [this blog post](https://zharel.me/blog/opmodes/) if you would like to learn more.

Two blank `PeriodicOpMode`s, `MyTeleop.java` and `MyAuto.java` are provided under the `opmode` folder.

To control the robot with joysticks a Teleop OpMode needs to be created that periodically gives the `DifferentialDrive` instance new values from the controller.
First an instance of `XboxController` needs to be created.
In `MyTeleop.java`, an instance of `XboxController` needs to be created.
This class has functions that provide the state of different buttons on the controller.
Multiple controllers can be used at once so the Driver Station gives each a slot.
The index provided in the constructor tells the `XboxController` which slot to listen to.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,13 @@ Inside the `MyAuto` class, construct a `Timer` instance.

</Tabs>

<Aside type="note">
When adding in `Timer`, there will be an error. This error is an import
error and can be fixed through quick fix. When using quickfix, there will
usually be many options. For `Timer`, select `import
org.wpilib.system.Timer;`
</Aside>

With the code as it is now, this timer will keep track of the time since the autonomous was selected in the driver station.
However, the timer needs to keep track of the time since the robot is enabled.
This can be accomplished using the timer's `restart()` function, which resets the timer to zero, inside of the OpMode's `start()` function.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,14 @@ import YouTube from '@components/YouTube.astro';

Welcome to Stage 1A!
This stage will use your Java knowledge to write code to control a robot.
What robot?
What robot you may ask?
Well, the answer is the 2026 FIRST Robotics Competition kitbot, the best starting point
for new FRC teams, as well as the simplest robot to get fully working.
You can watch the below video to learn more about what functionalities the kitbot has.
If you're a bit confused after watching that video, don't worry.
We'll explain the kitbot more in depth in the next section.

<YouTube url="https://www.youtube.com/watch?v=nTmZXOgHntM" />

## Stage 1a Goals
## Stage 1A Goals

At the end of Stage 1A, you will have wrote your first robot code and see Kitbot drive using simulation.
Your code will control the robot's driving, and scoring mechanisms as well run an autonomous routine.
Expand Down
Loading