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
1 change: 1 addition & 0 deletions .remarkrc.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export default {
'https://www.conventionalcommits.org/en/v1.0.0/',
'https://vale.sh/',
'https://squoosh.app/',
'https://www.educational-animation.org/en/pid-controller/',
], // Add known flaky URL patterns here
},
]
Expand Down
2 changes: 1 addition & 1 deletion examples/stage1/stage1c/solutions/rev/simgui-ds.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,5 +52,5 @@
"buttonCount": 0,
"povCount": 0
}],
"robotJoysticks": [{"guid": "0300fa675e040000ff02000000007801"}]
"robotJoysticks": [{"guid": "Keyboard0"}]
}
Binary file added public/learning-course/stage1/stage1c/graph.webp
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.
Binary file added public/learning-course/stage1/stage1c/pid_d.webm
Binary file not shown.
Binary file added public/learning-course/stage1/stage1c/pid_i.webm
Binary file not shown.
Binary file added public/learning-course/stage1/stage1c/pid_p.webm
Binary file not shown.
4 changes: 4 additions & 0 deletions src/config/sidebarConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,10 @@ const learningCourse: SidebarTopic = {
label: 'Stage 1C Introduction',
slug: 'learning-course/stage1/stage1c/stage-overview',
},
{
label: 'Controls Intro',
slug: 'learning-course/stage1/stage1c/pid-intro',
},
],
},
],
Expand Down
2 changes: 1 addition & 1 deletion src/content/docs/educators-guide/introduction/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ Each section has a bit of explanation on the concepts or skills being introduced

<Aside type="note" title="Why Java?">
Java is the most popular language used in FRC by a significant margin
([source](https://community.firstinspires.org/more-reefscape-by-the-numbers-new-legal-devices
([source](https://www.firstinspires.org/community-blog/more-reefscape-by-the-numbers-new-legal-devices
"FRC Blog: More REEFSCAPE By The Numbers")). This means that there's an
abundance of public code to refer to and that it's the easiest language to
receive help for. Additionally, many students learn Java through AP Computer
Expand Down
1 change: 1 addition & 0 deletions src/content/docs/learning-course/index.mdx
Comment thread
Adrianamm marked this conversation as resolved.
Resolved
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ description: A guided curriculum for learning FRC Programming
import CourseSection from '@components/CourseSection.astro';

Welcome to FRCSoftware's learning course!

The purpose of this course is to help students learn how to program an FRC robot no matter their skill level.
The progression of the course moves from learning how to write Java to programming robots of increasing complexity.
We start with individual mechanisms of robots, using the FRC Kitbot, then move to more complex robots.
Expand Down
221 changes: 221 additions & 0 deletions src/content/docs/learning-course/stage1/stage1c/pid-intro.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
---
title: Controls Introduction
description: An overview of Feedback Controllers and PID
---

import ContentImage from '@components/ContentImage.astro';
import ContentRow from '@components/ContentRow.astro';
import ContentRowCaption from '@components/ContentRow.astro';

With FRC games, it's common for teams to have a mechanism move to a desired position or move the robot to a desired position or angle.
One example is auto aligning.
Robots auto align by turning a certain amount of degrees towards the goal then taking the steps needed to score the game piece.
Scoring with auto alignment is faster and more efficient than your driver lining up with the goal by hand.

In 2026, the kitbot might auto align to the goal by turning to a certain angle on the field.
Comment thread
Adrianamm marked this conversation as resolved.
Resolved
The kitbot can't turn too far to the left or too far to the right because then it might miss the goal.
It has to turn just the right amount.
How do teams make sure that happens?
This is done with PID.

## Feedback Controller

PID is a type of feedback controller.
A feedback controller uses sensors and equations to figure out what the mechanism is currently doing,
and controls the mechanism's output to make it do what we want it do.
The mechanism's current state is called the **output**.
We're able to get the current state through sensors.
One example of a sensor is an encoder.
Encoders are used to measure a motor's rotation.
In this stage, the Kitbot has encoders on its drivetrain.
We can take information from the encoders to figure out how far the kitbot has driven.

Code can be written to define the desired state, or where we want it to be.
This desired state is called the **setpoint**.

In the case of the kitbot's auto align, the **output** is the information from the sensor on what the robot's current angle is.
The **setpoint** is a target angle, perhaps pointing the kitbot towards the goal.

<Aside type="note">
We're able to get the kitbot's angle through Systemcore's built in IMU, or
Inertial Measurement Unit. This is a sensor that allows the robot to
accurately track its orientation in 3D space. One of the angles that it
returns is yaw, which is the robot's side to side movement on the vertical
axis. This is when the robot turns left and right.
</Aside>

Feedback controllers are also used outside of FRC.
One example is an air conditioner.
An air conditioner has a sensor that compares the current temperature with the desired temperature.
Then the air conditioner directs the airflow in a way which allows the air to get to the desired temperature.

A type of feedback controller is PID.
This stage will use PID to help the kitbot auto align and drive towards the goal.

## PID

PID is a type of feedback controller that uses three terms: proportional, integral, and derivative.
Together the three terms are P, I, and D, which is how PID gets its name.

PID works by constantly comparing the current output to the setpoint and changing the control effort, or in our case, the voltage, commanded to the motor.
The difference between the output to the setpoint is called the error.

- Proportional (P) is what gets you close to the setpoint.
- Integral (I) helps carefully creep the rest of the way to the setpoint.
- Derivative (D) is a braking force to stop or “dampen” any oscillations.
Comment thread
Adrianamm marked this conversation as resolved.
Resolved

In code, the three terms are commonly noted as `kp`, `ki`, and `kd`.
The k stands for constants.

### How does P, I, and D work together?

PID constantly compares where you are to where you want to be and adjusts.
This is possible because each term is working to help adjust.

Adjusting the three terms to get the desired output is called **tuning**.
To tune PID, the output and setpoint's information is put into a graph to help figure out how to tune each term.
When tuning PID, the output isn't always a clean line.
As the values are adjusted, the output line takes on different shapes which can help determine which value needs to be adjusted and how.

When the output passes the set point, this is called **overshoot**.
When the output goes up, then down, up again, and repeats, this is called **oscillating**.

<ContentRow>
<ContentFigure
src="/learning-course/stage1/stage1c/overshoot.webp"
alt="A graph where the output overshoots"
width="40%"
>
Overshoot
</ContentFigure>
<ContentFigure
src="/learning-course/stage1/stage1c/oscillating.webp"
alt="A graph where the output is oscillating"
width="30%"
>
Oscillating
</ContentFigure>
</ContentRow>

## PID Example

The example shows the three terms being tuned to work to get the output to match the setpoint.

First we start off with tuning P.
As P increases, the output gets closer to the setpoint.
However, it's not quite there yet.
The output starts to overshoot and then slightly oscillates.

<ContentFigure
width="550px"
alt="A graph where the P term increases"
src="/learning-course/stage1/stage1c/pid_p.webm"
>
Credit: Wikipedia
</ContentFigure>

P gets the output close to the setpoint but it's not there yet.
Therefore the example introduces I.
As I increases, the oscillations get bigger.

<Aside type="note">
Comment thread
Adrianamm marked this conversation as resolved.
Resolved
In FRC, using I is **not** recommended. Instead, it's recommended to use
another controller type called FeedForward. This will be covered in Stage 2
and is not needed for 1C. I is explained in this page for the purposes of
understanding PID.
</Aside>

<ContentFigure
width="550px"
alt="A graph where the I term increases"
src="/learning-course/stage1/stage1c/pid_i.webm"
>
Credit: Wikipedia
</ContentFigure>

P and I have both been added but the output doesn't match the setpoint.
However, there are still oscillations and the output still overshoots.
To solve this, the example introduces D.
As D increases, the oscillations smooth out and the output slowly stops overshooting.
Now the output matches up with the setpoint!

<ContentFigure
width="550px"
alt="A graph where the D term increases"
src="/learning-course/stage1/stage1c/pid_d.webm"
>
Credit: Wikipedia
</ContentFigure>

### Tuning PID

Tuning PID is necessary because every mechanism is different and behaves differently.
Even two theoretically identical robots may require different PID constants, as there may be small mechanical differences that impact how mechanisms behave.

<Aside type="tip">
When increasing PID values start small and increase carefully. Starting with
huge numbers or increasing in big jumps can make it difficult to get the
desired outcome.
</Aside>

When tuning PID, the first step is to set all three terms to 0.
The first value that you want to tune is P.
Increase P until the output is near the setpoint but it starts to oscillate.

If the output is close to the target but just misses it, I can be increased to push it towards the set point.
In FRC, this part is commonly skipped.

If there are any oscillations, D can be introduced.
Increasing D, can help smooth out the oscillations.
However, make sure that it isn't increased so much that it causes jittering.

Similar to the examples, graphs are used to tune PID.
By using a graph, we can see the mechanism's output, compare it to the setpoint, and adjust the different terms until
the output matches the setpoint.

### PID Exercise

In the simulation below, there is a water tank that is filling up with water.
The water tank has a fill line to show where the water should stop.
This is the setpoint.
The graph below shows the output (labeled "actual") and the setpoint.
To ensure that the water stops at the setpoint, PID can be used to adjust the flow of water into the tank.
Tune the P, I, and D values until the water stops at the water line.
The graph can be used to help!

<div style={{ position: 'relative', width: '100%', aspectRatio: '16/9' }}>
<iframe
src="https://www.educational-animation.org/web-animations/pid-controller/en/pid-controller.html"
title="Interactive Animation: PID Controller"
style={{
position: 'absolute',
inset: '0',
width: '100%',
height: '100%',
border: '0',
}}
allowFullScreen
loading="lazy"
/>
</div>
<p>
[Source: PID Controller –
educational-animation.org](https://www.educational-animation.org/en/pid-controller/)
</p>

<Aside type="answer">kp = 3.0, ki = 0.51, and kd = 0.31</Aside>

## PID and The Kitbot

Similar to the graph in the water tank example, FRC teams use AdvantageScope and its Line Graph tab to create graphs to help tune PID.
By reading the information from a sensor, a similar graph can be made that shows the setpoint and output.

<ContentFigure
width="650px"
alt="a screenshot of AdvantageScope and AdvantageScope has the graph tab open"
src="/learning-course/stage1/stage1c/graph.webp"
/>

To get to tuning the kitbot's PID, the PID controllers have set up in code to control the motors.
The rest of this section will explain
how to add the PID libraries and how to put the data into AdvantageScope so the PID can be tuned.
Loading