Control Theory Basics

-

2024 October 22/23

+

2024 October 22/23 (2.5 hours)

Slideshow (Control theory basics)

Introduction

@@ -308,17 +308,49 @@

The Problem

Open-Loop vs. Closed-Loop

-

Control theory is a field of applied mathematics regarding optimizing control systems for accuracy and response time. There are two types of control: open-loop (feedforward) and closed-loop (feedback). As the names suggest, open-loop control utilizes inputs to determine an output without considering the output. Closed-loop control utilizes output back into the system, hence its second name “feedback”. An example of an open-loop system is timed water boiling. The boiling of the water does not depend on its temperature, so there is no feedback loop in-between. Temperature regulating air conditioners and HVAC systems are an example of a closed-loop system: the temperature is fed back into the control system to determine the new output, eventually adjusting the room to the desired temperature.

-

There are many systems that depend on closed-loop control to function. Reliably controlling DC motors to be at certain rotational speed is not possible without taking into account its rotational output measured by an encoder. The motor controller would use this value to compute a close-enough voltage to feed into the motor. The accuracy of this system is not as meaningful because it is self-adjusting.

+

Control theory is a field of applied mathematics regarding optimizing control systems for accuracy and response time. There are two types of control: open-loop (feedforward) and closed-loop (feedback). As the names suggest, open-loop control utilizes inputs to determine an output without considering the output. Closed-loop control utilizes output back into the system, hence its second name “feedback”. An example of an open-loop system is boiling water on a gas stove for a certain time. The gas stove only cares about the volume of gas that the user selects, and does not care about whether or not the water is boiling or what the temperature of the water is. Temperature-regulating air conditioners and HVAC systems are an example of a closed-loop system: the temperature is fed back into the control system to determine the new output, eventually adjusting the room to the desired temperature.

+

There are many systems that depend on closed-loop control to function. Reliably controlling DC motors to be at certain rotational speed is not possible without taking into account its rotational output measured by an encoder. The motor controller uses this value to compute a close-enough voltage to feed into the motor.

+
-

PID Controllers

-

PID (proportional–integral–derivative) controllers are the most common form of an adjustable closed-loop controller. It allows you to tweak three constant coefficients (as stated by its name) to increase efficiency and response while lowering undesirable effects like undershooting or overshooting. There is a PID controller implemented in every Falcon 500 motor. WPILib includes a PIDController class implementation for general use. Any PID controller will have two variable inputs: your target output and your current output. See an interactive example here that shows a circle attempting to position itself under the cursor. Here is another interesting website that shows a simulation of a cart balancing an arm using PID. There are many strategies for tuning PID, but this is the one I have bookmarked and use for FRC. Try to tune the PID constants of the first example for optimal behavior.

-

Every output on the robot—this being the swerve drivebase wheels and rotators, the arm, the elevator, etc—should ideally go through a PID controller with correctly tuned PID constants. The math behind it isn’t necessary to learn to use one, but this article on the WPILib documentation explains it well.

+

PID Controllers

+

PID (proportional–integral–derivative) controllers are the most common form of adjustable closed-loop controllers. It allows you to tweak three constant coefficients (as stated by its name) to increase efficiency and response while lowering undesirable effects like undershooting or overshooting.

+

Imagine you are trying to drive a car to a location on a straight but slippery and poorly constructed road. Call your destination’s location $r(t)$ (also called the setpoint). At time $t$, you know that your car is located at $y(t)$. These are the two variable inputs to the PID controller. The process variable, $e(t) = r(t) - y(t)$, is the difference between the destination and the car’s current position.

+

The constant inputs to the PID controller are $K_p$, $K_i$, and $K_d$, three coefficients that go into the equation $u(t) = K_p e(t) + K_i \int_0^t e(\tau),d\tau + K_d \frac{de(t)}{dt}$, where $u(t)$ is the distance that we tell the car to go at time $t$. (It isn’t too important to understand this math.) We send $u(t)$ to the motor, and wait until we figure out where the car is after we tried to drive $u(t)$. Then we repeat this process.

+
+../../_images/PID_en.svg
+

The basic idea of a PID controller

+
+
+
+

The effect of changing $K_p$, $K_i$, and $K_d$

+

Say we want to drive our car to the campground 1 mile down the road. We use a PID controller to control the acceleration of the car, but we don’t know the optimal $K_p$, $K_i$, and $K_d$, so we try driving our car using the PID controller a few times.

+

This is what happens when we change $K_p$:

+
+../../_images/PID_varyingP.jpg +
+

This is what happens when we change $K_i$:

+
+../../_images/Change_with_Ki.png +
+

This is what happens when we change $K_d$:

+
+../../_images/Change_with_Kd.png +
+

In general, we usually set $K_i = 0$, and we manually tune $K_p$ and $K_d$. None of these constants should usually be significantly more than 1.0, as that tends to cause drastic overshooting.

NOTE: Another less-regarded factor in PID loops is data frequency. Since it’s a discrete model, lower delta time results in better calculations.

+
+

Using the PID controller on the robot

+

There is a PID controller implemented in every Falcon 500 motor. Every output on the robot—this being the swerve drivebase wheels and rotators, the arm, the elevator, etc—should ideally go through a PID controller with correctly tuned PID constants. The math behind it isn’t necessary to learn to use one, but this article on the WPILib documentation explains it well. WPILib includes a PIDController class implementation for general use.

+
+
+

Exercise 1 - Tuning a PID controller

+

See an interactive example here that shows a circle attempting to position itself under the cursor. Here is another interesting website that shows a simulation of a cart balancing an arm by changing its velocity using PID. There are many strategies for tuning PID, but this is the one I have bookmarked and use for FRC.

+

Exercise 1: Try to tune the PID constants of the first example for optimal behavior.

+

PID with feedforward

Sometimes it is beneficial to add a feedforward component to a PID control system to compensate for variables in specific circumstances. We utilized PIDf in our old swerve subsystem code to account for friction. In practice, the implementation is incredibly simple. Add the desired amount of feedforward output multiplied by a coefficient to the PID output. This WPILib article shows PIDf in practice.

@@ -335,7 +367,7 @@

The Problem: In Practice

What Typically Happens

-

On the software side, the raw encoder output can (and often is already by your library) be filtered through various methods to separate the desired signal from the noise. We will cover some of these methods later. But ultimately, it is also important to direct robot output in such a way that accounts for physical aspects without the need to model unpredictable complexity. When you create a plan on how to program a rotating arm, the first instinct of us is to recreate a geometric model of the arm from the motor output. We are used to drawing diagrams and solving problems through simulations in physics and math classes at IMSA and previously. But the real world is too complex for inverse kinematics based on torque equations to be accurate enough. Some of these equations weren’t even defined for ranges of values appearing in production. Although it is important to consider that theoretical models are still very applicable in FRC, but require more consideration regarding their utility. Combining those models with control theory methods of reducing impact of noise (such as adding a PID controller as the last step) leads to great results.

+

On the software side, the raw encoder output can (and often is already by your library) be filtered through various methods to separate the desired signal from the noise. We will cover some of these methods later. But ultimately, it is also important to direct robot output in such a way that accounts for physical aspects without the need to model unpredictable complexity. When you create a plan on how to program a rotating arm, the first instinct of us is to recreate a geometric model of the arm from the motor output. We are used to drawing diagrams and solving problems through simulations in physics and math classes at IMSA and previously. But the real world is too complex for inverse kinematics based on torque equations to be accurate enough. Some of these equations weren’t even defined for ranges of values appearing in production. Although theoretical models are still very applicable in FRC, many systems used in FRC are hard to describe using these theoretical models, or have so much potential for error that the theoretical model won’t accurately predict how the system will be have in the real world. Combining those models with control theory methods for reducing the impact of noise (such as adding a PID controller as the last step) leads to great results.

Design Decisions First

@@ -343,14 +375,23 @@

Design Decisions First

Implications of Complexity

-

Although, sometimes you might have to be stuck with programming a rotating arm. In which case, you can predetermine the necessary motor values beforehand. Create a table for the arm to be static at a certain angle and also that angle but with a weighted object. Seems simple in theory, but once you realize that the battery voltage affects motor output, the problem gets exponentially more difficult. Now imagine if you still decided to stick with your old inverse kinematics equation. Your equation would now have to consider battery strain, on top of drivebase movement and other factors. And now, consider this but with the typical occurrence: you only have two hours a week to test it and competition is coming up. What about other subsystems? You have code for them too and you need to test it (your drivebase code should be consistent over the years for this reason). Well, what if the member who singlehandedly wrote the arm subsystem and every command for it gets sick? It is far simpler to debug a close-enough estimation of the real world than complex equations that model it.

-

But this section is an exaggeration: most FRC teams do not encounter every possible negative outcome in one season. Simply, it is to state that robot design and programming should account for unforeseen challenges. The pandemic has taken a toll on this team as significant amount of knowledge and connections have been lost. But with each season, there are improvements. The arm example is a retelling of the events that occurred during the 2022-2023 FRC season when our knowledge regarding creating reliable designs and writing reliable code was limited. I encourage reading ChiefDelphi posts for the purpose fo regaining these skills. What separates consistently well-performing teams and everyone else is proper documentation and long-term connections.

+

Although, sometimes you might have to be stuck with programming a rotating arm. In which case, you can predetermine the necessary motor values beforehand. Create a table for the arm to be static at a certain angle and also that angle but with a weighted object. It seems simple in theory, but once you realize that the battery voltage affects motor output, the problem gets exponentially more difficult. Now imagine if you still decided to stick with your old inverse kinematics equation. Your equation would now have to consider battery strain, on top of drivebase movement and other factors. And now, consider this but with the typical occurrence: you only have two hours a week to test it and competition is coming up. What about other subsystems? You have code for them too and you need to test it (your drivebase code should be consistent over the years for this reason). Well, what if the member who singlehandedly wrote the arm subsystem and every command for it gets sick? It is far simpler to debug a close-enough estimation of the real world than complex equations that model it.

+

But this section is an exaggeration: most FRC teams do not encounter every possible negative outcome in one season. Simply, it is to state that robot design and programming should account for unforeseen challenges. The pandemic has taken a toll on this team as significant amount of knowledge and connections have been lost. But with each season, there are improvements. The arm example is a retelling of the events that occurred during the 2022-2023 FRC season when our knowledge regarding creating reliable designs and writing reliable code was limited. I encourage reading ChiefDelphi posts for the purpose of regaining these skills. What separates consistently well-performing teams and everyone else is proper documentation and long-term connections.

Further Reading

I strongly recommend reading at least some chapters of this FRC-specific book on control theory for more information. This manual contains the essential knowledge of classical control theory, specific examples of modeling many mechanisms present in FRC, inverse kinematics, calculus and linear algebra prerequisites needed to learn about Kalman Filters (BC sequence + MVC + LinAlg level math), different types of Kalman Filters, and much more. Reading the book in its entirety would set your control theory and mathematical knowledge above majority of FRC programmers, even on top performing teams.

This particular repository about Kalman Filters is another great source to learn about Kalman Filters. This repo provided the knowledge to implement the Extended Kalman Filter used in Titan Processing.

+
+

Image credits

+
    +
  • https://commons.wikimedia.org/wiki/File:PID_en.svg by Arturo Urquizo

  • +
  • https://commons.wikimedia.org/wiki/File:PID_varyingP.jpg by User:TimmmyK

  • +
  • https://commons.wikimedia.org/wiki/File:Change_with_Ki.png by User:Skorkmaz

  • +
  • https://commons.wikimedia.org/wiki/File:Change_with_Kd.png by User:Skorkmaz

  • +
+
@@ -416,7 +457,12 @@

Further ReadingWhat is Control Theory + +
  • PID Controllers
  • @@ -427,7 +473,10 @@

    Further ReadingImplications of Complexity -
  • Further Reading
  • +
  • Further Reading +
  • diff --git a/dev/_images/Change_with_Kd.png b/dev/_images/Change_with_Kd.png new file mode 100644 index 0000000000000000000000000000000000000000..950335a8e718914344686faf8f165551273bfc40 GIT binary patch literal 7565 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 literal 0 HcmV?d00001 diff --git a/dev/_images/Change_with_Ki.png b/dev/_images/Change_with_Ki.png new file mode 100644 index 0000000000000000000000000000000000000000..5f3b2b6d5d39d5c3c53d75f4f02ab60053cb3cf4 GIT binary patch literal 7763 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 + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Plant /Process + + + + + + + + + + + + + + diff --git a/dev/_images/PID_varyingP.jpg b/dev/_images/PID_varyingP.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a4ea65ef0c7b464a7b0517762af3ab173a604d25 GIT binary patch literal 35407 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 literal 0 HcmV?d00001 diff --git a/dev/_sources/PreseasonTraining/ControlTheoryBasics/index.md.txt b/dev/_sources/PreseasonTraining/ControlTheoryBasics/index.md.txt index 372f473..b6e91fe 100644 --- a/dev/_sources/PreseasonTraining/ControlTheoryBasics/index.md.txt +++ b/dev/_sources/PreseasonTraining/ControlTheoryBasics/index.md.txt @@ -1,6 +1,6 @@ # Control Theory Basics -2024 October 22/23 +2024 October 22/23 (2.5 hours) [Slideshow (Control theory basics)]() @@ -16,18 +16,56 @@ The biggest obstacle in robotics, which prevents us from completely solving ever ### Open-Loop vs. Closed-Loop -Control theory is a field of applied mathematics regarding optimizing control systems for accuracy and response time. There are two types of control: open-loop (feedforward) and closed-loop (feedback). As the names suggest, open-loop control utilizes inputs to determine an output without considering the output. Closed-loop control utilizes output back into the system, hence its second name "feedback". An example of an open-loop system is timed water boiling. The boiling of the water does not depend on its temperature, so there is no feedback loop in-between. Temperature regulating air conditioners and HVAC systems are an example of a closed-loop system: the temperature is fed back into the control system to determine the new output, eventually adjusting the room to the desired temperature. +Control theory is a field of applied mathematics regarding optimizing control systems for accuracy and response time. There are two types of control: open-loop (feedforward) and closed-loop (feedback). As the names suggest, open-loop control utilizes inputs to determine an output without considering the output. Closed-loop control utilizes output back into the system, hence its second name "feedback". An example of an open-loop system is boiling water on a gas stove for a certain time. The gas stove only cares about the volume of gas that the user selects, and does not care about whether or not the water is boiling or what the temperature of the water is. Temperature-regulating air conditioners and HVAC systems are an example of a closed-loop system: the temperature is fed back into the control system to determine the new output, eventually adjusting the room to the desired temperature. -There are many systems that depend on closed-loop control to function. Reliably controlling DC motors to be at certain rotational speed is not possible without taking into account its rotational output measured by an encoder. The motor controller would use this value to compute a close-enough voltage to feed into the motor. The accuracy of this system is not as meaningful because it is self-adjusting. +There are many systems that depend on closed-loop control to function. Reliably controlling DC motors to be at certain rotational speed is not possible without taking into account its rotational output measured by an encoder. The motor controller uses this value to compute a close-enough voltage to feed into the motor. -### PID Controllers +## PID Controllers -PID (proportional–integral–derivative) controllers are the most common form of an adjustable closed-loop controller. It allows you to tweak three constant coefficients (as stated by its name) to increase efficiency and response while lowering undesirable effects like undershooting or overshooting. There is a PID controller implemented in every Falcon 500 motor. WPILib includes a `PIDController` [class implementation](https://docs.wpilib.org/en/stable/docs/software/advanced-controls/controllers/pidcontroller.html) for general use. Any PID controller will have two variable inputs: your target output and your current output. See an [interactive example here](https://eliottwiener.github.io/pidcontroldemo/) that shows a circle attempting to position itself under the cursor. Here is another [interesting website](https://sparshg.dev/pid-balancer/) that shows a simulation of a cart balancing an arm using PID. There are many strategies for tuning PID, but [this](https://robotics.stackexchange.com/questions/167/what-are-good-strategies-for-tuning-pid-loops) is the one I have bookmarked and use for FRC. Try to tune the PID constants of the first example for optimal behavior. +PID (proportional–integral–derivative) controllers are the most common form of adjustable closed-loop controllers. It allows you to tweak three constant coefficients (as stated by its name) to increase efficiency and response while lowering undesirable effects like undershooting or overshooting. -Every output on the robot---this being the swerve drivebase wheels and rotators, the arm, the elevator, etc---should ideally go through a PID controller with correctly tuned PID constants. The math behind it isn't necessary to learn to use one, but [this article](https://docs.wpilib.org/en/stable/docs/software/advanced-controls/introduction/introduction-to-pid.html) on the WPILib documentation explains it well. +Imagine you are trying to drive a car to a location on a straight but slippery and poorly constructed road. Call your destination's location $r(t)$ (also called the **setpoint**). At time $t$, you know that your car is located at $y(t)$. These are the two variable inputs to the PID controller. The **process variable**, $e(t) = r(t) - y(t)$, is the difference between the destination and the car's current position. + +The constant inputs to the PID controller are $K_p$, $K_i$, and $K_d$, three coefficients that go into the equation $u(t) = K_p e(t) + K_i \int_0^t e(\tau)\,d\tau + K_d \frac{de(t)}{dt}$, where $u(t)$ is the distance that we tell the car to go at time $t$. (It isn't too important to understand this math.) We send $u(t)$ to the motor, and wait until we figure out where the car is after we tried to drive $u(t)$. Then we repeat this process. + +```{figure} PID_en.svg + +The basic idea of a PID controller +``` + +### The effect of changing $K_p$, $K_i$, and $K_d$ + +Say we want to drive our car to the campground 1 mile down the road. We use a PID controller to control the acceleration of the car, but we don't know the optimal $K_p$, $K_i$, and $K_d$, so we try driving our car using the PID controller a few times. + +This is what happens when we change $K_p$: + +```{figure} PID_varyingP.jpg +``` + +This is what happens when we change $K_i$: + +```{figure} Change_with_Ki.png +``` + +This is what happens when we change $K_d$: + +```{figure} Change_with_Kd.png +``` + +In general, we usually set $K_i = 0$, and we manually tune $K_p$ and $K_d$. None of these constants should usually be significantly more than 1.0, as that tends to cause drastic overshooting. > NOTE: Another less-regarded factor in PID loops is data frequency. Since it's a discrete model, lower delta time results in better calculations. +### Using the PID controller on the robot + +There is a PID controller implemented in every Falcon 500 motor. Every output on the robot---this being the swerve drivebase wheels and rotators, the arm, the elevator, etc---should ideally go through a PID controller with correctly tuned PID constants. The math behind it isn't necessary to learn to use one, but [this article](https://docs.wpilib.org/en/stable/docs/software/advanced-controls/introduction/introduction-to-pid.html) on the WPILib documentation explains it well. WPILib includes a `PIDController` [class implementation](https://docs.wpilib.org/en/stable/docs/software/advanced-controls/controllers/pidcontroller.html) for general use. + +### Exercise 1 - Tuning a PID controller + +See an [interactive example here](https://eliottwiener.github.io/pidcontroldemo/) that shows a circle attempting to position itself under the cursor. Here is another [interesting website](https://sparshg.dev/pid-balancer/) that shows a simulation of a cart balancing an arm by changing its velocity using PID. There are many strategies for tuning PID, but [this](https://robotics.stackexchange.com/questions/167/what-are-good-strategies-for-tuning-pid-loops) is the one I have bookmarked and use for FRC. + +**Exercise 1:** Try to tune the PID constants of [the first example]((https://eliottwiener.github.io/pidcontroldemo/)) for optimal behavior. + ### PID with feedforward Sometimes it is beneficial to add a feedforward component to a PID control system to compensate for variables in specific circumstances. We utilized PIDf in our old swerve subsystem code to account for friction. In practice, the implementation is incredibly simple. Add the desired amount of feedforward output multiplied by a coefficient to the PID output. [This WPILib article](https://docs.wpilib.org/en/stable/docs/software/advanced-controls/controllers/combining-feedforward-feedback.html) shows PIDf in practice. @@ -42,7 +80,7 @@ A common example of affected software input is when you introduce an encoder to ### What Typically Happens -On the software side, the raw encoder output can (and often is already by your library) be filtered through various methods to separate the desired signal from the noise. We will cover some of these methods later. But ultimately, it is also important to direct robot output in such a way that accounts for physical aspects without the need to model unpredictable complexity. When you create a plan on how to program a rotating arm, the first instinct of us is to recreate a geometric model of the arm from the motor output. We are used to drawing diagrams and solving problems through simulations in physics and math classes at IMSA and previously. But the real world is too complex for inverse kinematics based on torque equations to be accurate enough. Some of these equations weren't even defined for ranges of values appearing in production. Although it is important to consider that theoretical models are still very applicable in FRC, but require more consideration regarding their utility. Combining those models with control theory methods of reducing impact of noise (such as adding a PID controller as the last step) leads to great results. +On the software side, the raw encoder output can (and often is already by your library) be filtered through various methods to separate the desired signal from the noise. We will cover some of these methods later. But ultimately, it is also important to direct robot output in such a way that accounts for physical aspects without the need to model unpredictable complexity. When you create a plan on how to program a rotating arm, the first instinct of us is to recreate a geometric model of the arm from the motor output. We are used to drawing diagrams and solving problems through simulations in physics and math classes at IMSA and previously. But the real world is too complex for inverse kinematics based on torque equations to be accurate enough. Some of these equations weren't even defined for ranges of values appearing in production. Although theoretical models are still very applicable in FRC, many systems used in FRC are hard to describe using these theoretical models, or have so much potential for error that the theoretical model won't accurately predict how the system will be have in the real world. Combining those models with control theory methods for reducing the impact of noise (such as adding a PID controller as the last step) leads to great results. ### Design Decisions First @@ -50,12 +88,19 @@ More often than not, the simplest solutions are also the best, most reliable. Go ### Implications of Complexity -Although, sometimes you might have to be stuck with programming a rotating arm. In which case, you can predetermine the necessary motor values beforehand. Create a table for the arm to be static at a certain angle and also that angle but with a weighted object. Seems simple in theory, but once you realize that the battery voltage affects motor output, the problem gets exponentially more difficult. Now imagine if you still decided to stick with your old inverse kinematics equation. Your equation would now have to consider battery strain, on top of drivebase movement and other factors. And now, consider this but with the typical occurrence: you only have two hours a week to test it and competition is coming up. What about other subsystems? You have code for them too and you need to test it (your drivebase code should be consistent over the years for this reason). Well, what if the member who singlehandedly wrote the arm subsystem and every command for it gets sick? It is far simpler to debug a close-enough estimation of the real world than complex equations that model it. +Although, sometimes you might have to be stuck with programming a rotating arm. In which case, you can predetermine the necessary motor values beforehand. Create a table for the arm to be static at a certain angle and also that angle but with a weighted object. It seems simple in theory, but once you realize that the battery voltage affects motor output, the problem gets exponentially more difficult. Now imagine if you still decided to stick with your old inverse kinematics equation. Your equation would now have to consider battery strain, on top of drivebase movement and other factors. And now, consider this but with the typical occurrence: you only have two hours a week to test it and competition is coming up. What about other subsystems? You have code for them too and you need to test it (your drivebase code should be consistent over the years for this reason). Well, what if the member who singlehandedly wrote the arm subsystem and every command for it gets sick? It is far simpler to debug a close-enough estimation of the real world than complex equations that model it. -But this section is an exaggeration: most FRC teams do not encounter every possible negative outcome in one season. Simply, it is to state that robot design and programming should account for unforeseen challenges. The pandemic has taken a toll on this team as significant amount of knowledge and connections have been lost. But with each season, there are improvements. The arm example is a retelling of the events that occurred during the 2022-2023 FRC season when our knowledge regarding creating reliable designs and writing reliable code was limited. I encourage reading ChiefDelphi posts for the purpose fo regaining these skills. What separates consistently well-performing teams and everyone else is proper documentation and long-term connections. +But this section is an exaggeration: most FRC teams do not encounter every possible negative outcome in one season. Simply, it is to state that robot design and programming should account for unforeseen challenges. The pandemic has taken a toll on this team as significant amount of knowledge and connections have been lost. But with each season, there are improvements. The arm example is a retelling of the events that occurred during the 2022-2023 FRC season when our knowledge regarding creating reliable designs and writing reliable code was limited. I encourage reading ChiefDelphi posts for the purpose of regaining these skills. What separates consistently well-performing teams and everyone else is proper documentation and long-term connections. ## Further Reading I strongly recommend reading at least some chapters of this [FRC-specific book on control theory](https://file.tavsys.net/control/controls-engineering-in-frc.pdf) for more information. This manual contains the essential knowledge of classical control theory, specific examples of modeling many mechanisms present in FRC, inverse kinematics, calculus and linear algebra prerequisites needed to learn about Kalman Filters (BC sequence + MVC + LinAlg level math), different types of Kalman Filters, and much more. Reading the book in its entirety would set your control theory and mathematical knowledge above majority of FRC programmers, even on top performing teams. -[This particular repository about Kalman Filters](https://github.com/rlabbe/Kalman-and-Bayesian-Filters-in-Python) is another great source to learn about Kalman Filters. This repo provided the knowledge to implement the Extended Kalman Filter used in [Titan Processing](https://github.com/titan2022/Titan-Processing). \ No newline at end of file +[This particular repository about Kalman Filters](https://github.com/rlabbe/Kalman-and-Bayesian-Filters-in-Python) is another great source to learn about Kalman Filters. This repo provided the knowledge to implement the Extended Kalman Filter used in [Titan Processing](https://github.com/titan2022/Titan-Processing). + +### Image credits + +* https://commons.wikimedia.org/wiki/File:PID_en.svg by Arturo Urquizo +* https://commons.wikimedia.org/wiki/File:PID_varyingP.jpg by User:TimmmyK +* https://commons.wikimedia.org/wiki/File:Change_with_Ki.png by User:Skorkmaz +* https://commons.wikimedia.org/wiki/File:Change_with_Kd.png by User:Skorkmaz diff --git a/dev/searchindex.js b/dev/searchindex.js index ce9cdc9..48606f6 100644 --- a/dev/searchindex.js +++ b/dev/searchindex.js @@ -1 +1 @@ -Search.setIndex({"docnames": ["PreseasonTraining/2024CodeOverview/index", "PreseasonTraining/ControlTheoryBasics/index", "PreseasonTraining/ElectricalOverview/index", "PreseasonTraining/JavaBasics/BrainfInterpreter", "PreseasonTraining/JavaBasics/InventoryManager", "PreseasonTraining/JavaBasics/OldNotes", "PreseasonTraining/JavaBasics/WordleClone", "PreseasonTraining/JavaBasics/index", "PreseasonTraining/LEDProgramming/index", "PreseasonTraining/LinuxInstallation/index", "PreseasonTraining/OpenCV_ColorSegmentation/index", "PreseasonTraining/Overview/index", "PreseasonTraining/TankAutonomous/index", "PreseasonTraining/TankDriveSimulation/index", "PreseasonTraining/index", "Resources/Applications/git", "Resources/Applications/index", "Resources/Coprocessors/index", "Resources/CppProgramming/index", "Resources/JavaProgramming/index", "Resources/JavaProgramming/installation", "Resources/Linux/index", "Resources/RobotDesign/index", "Resources/StyleGuide", "Resources/index", "TeamHistory/index", "TitanAlgorithms/index", "TitanDashboard/index", "TitanProcessing/AprilTags/index", "TitanProcessing/Calibration/index", "TitanProcessing/Installation/index", "TitanProcessing/Localization/index", "TitanProcessing/Networking/index", "TitanProcessing/index", "index"], "filenames": ["PreseasonTraining/2024CodeOverview/index.md", "PreseasonTraining/ControlTheoryBasics/index.md", "PreseasonTraining/ElectricalOverview/index.md", "PreseasonTraining/JavaBasics/BrainfInterpreter.md", "PreseasonTraining/JavaBasics/InventoryManager.md", "PreseasonTraining/JavaBasics/OldNotes.md", "PreseasonTraining/JavaBasics/WordleClone.md", "PreseasonTraining/JavaBasics/index.md", "PreseasonTraining/LEDProgramming/index.md", "PreseasonTraining/LinuxInstallation/index.md", "PreseasonTraining/OpenCV_ColorSegmentation/index.md", "PreseasonTraining/Overview/index.md", "PreseasonTraining/TankAutonomous/index.md", "PreseasonTraining/TankDriveSimulation/index.md", "PreseasonTraining/index.md", "Resources/Applications/git.md", "Resources/Applications/index.md", "Resources/Coprocessors/index.md", "Resources/CppProgramming/index.md", "Resources/JavaProgramming/index.md", "Resources/JavaProgramming/installation.md", "Resources/Linux/index.md", "Resources/RobotDesign/index.md", "Resources/StyleGuide.md", "Resources/index.md", "TeamHistory/index.md", "TitanAlgorithms/index.md", "TitanDashboard/index.md", "TitanProcessing/AprilTags/index.md", "TitanProcessing/Calibration/index.md", "TitanProcessing/Installation/index.md", "TitanProcessing/Localization/index.md", "TitanProcessing/Networking/index.md", "TitanProcessing/index.md", "index.md"], "titles": ["2024 Code overview", "Control Theory Basics", "Electrical overview", "3 - Brainf interpreter", "1 - Inventory Manager", "Old notes from 2023", "2 - Wordle Clone", "Java Basics", "LED Programming", "Linux installation", "Color-based segmentation in OpenCV Python", "Programming Subteam Overview", "Tank Autonomous", "Tank Drive Simulation", "Preseason Training", "Git", "Applications", "3 - Coprocessors", "2 - C++ Programming", "Java / roboRIO Programming", "Installation", "4 - Linux", "5 - Robot design", "Style guide", "Resources", "Team #2022 History", "Titan Algorithms", "Titan Dashboard", "AprilTag Detection", "Calibration", "Installation", "Localization", "Networking", "Titan Processing", "Titan Robotics #2022 Documentation"], "terms": {"last": [0, 1, 10], "year": [0, 1], "everi": [0, 1, 5, 8, 10, 13, 15], "command": [0, 1, 3, 4, 5, 12, 19, 20, 23, 30], "subsystem": [0, 1, 23], "vision": [0, 10, 11, 13, 33], "qna": 0, "watch": 0, "old": [0, 1, 7, 14, 34], "match": [0, 13, 29, 30], "strategi": [0, 1, 34], "inspir": 0, "2024": [1, 2, 3, 4, 6, 8, 9, 10, 12, 13, 14, 20, 32, 33, 34], "octob": [1, 9, 10, 14], "22": [1, 32], "23": 1, "slideshow": [1, 2, 3, 4, 6, 9, 10, 13], "probabl": 1, "most": [1, 8, 9, 10, 11, 13, 19, 20, 33], "import": [1, 3, 5, 6, 11, 23, 32], "subject": 1, "frc": [1, 5, 11, 14, 19, 24, 32, 34], "program": [1, 2, 5, 10, 14, 15, 20, 24, 34], "one": [1, 8, 9, 10, 13, 15, 20, 23, 32], "you": [1, 5, 6, 8, 9, 10, 12, 13, 15, 19, 20, 32, 33, 34], "should": [1, 9, 10, 11, 12, 13, 20, 29, 30], "consid": [1, 30], "top": [1, 9, 10, 23, 32], "prioriti": 1, "It": [1, 5, 9, 13, 20, 29, 33], "separ": [1, 10, 15], "well": 1, "perform": [1, 11, 32], "from": [1, 2, 7, 8, 9, 10, 14, 15, 20, 24, 30, 32, 34], "those": 1, "fail": 1, "earli": 1, "contrari": 1, "mani": [1, 20], "peopl": [1, 3, 5, 6], "assum": [1, 20], "aim": [1, 23], "optim": [1, 11], "reliabl": [1, 32], "instead": [1, 8, 15], "speed": [1, 13], "function": [1, 5, 8, 10, 13, 32], "At": [1, 13], "titan": [1, 5, 30, 32], "our": [1, 2, 5, 8, 10, 13, 20, 23, 30, 34], "curs": 1, "overengin": 1, "solut": [1, 30, 32], "do": [1, 8, 9, 10, 11, 13, 15, 19, 20], "than": [1, 5, 10], "we": [1, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14], "can": [1, 5, 8, 9, 10, 11, 12, 13, 15, 20, 32, 33, 34], "reason": [1, 10, 33], "achiev": [1, 10, 32], "lead": 1, "bare": 1, "ani": [1, 9, 13, 15, 20, 32], "time": [1, 5, 8, 9, 11, 12, 13, 15, 24, 32], "electr": [1, 14, 34], "test": [1, 23, 30, 32], "befor": [1, 15, 32], "competit": 1, "caus": [1, 9], "unforeseen": 1, "mechan": [1, 13], "issu": [1, 9, 30], "product": [1, 15, 30, 33], "yearli": 1, "present": 1, "team": [1, 3, 6, 11, 13, 23, 24, 34], "1678": 1, "citru": 1, "circuit": 1, "consist": [1, 5, 13, 23], "advis": 1, "other": [1, 5, 9, 10, 13, 15, 20, 29, 34], "stick": [1, 9], "even": [1, 24], "mean": [1, 10, 12, 33], "miss": 1, "out": [1, 3, 5, 6, 9, 10, 13, 20, 32], "strateg": 1, "advantag": 1, "thei": [1, 10, 13, 32], "often": [1, 10, 33], "illustr": 1, "thi": [1, 3, 4, 5, 8, 9, 10, 11, 12, 13, 15, 20, 23, 29, 32, 33], "discourag": 1, "us": [1, 5, 8, 9, 10, 11, 12, 13, 15, 20, 24, 29, 30, 32, 33], "swerv": 1, "drive": [1, 5, 9, 11, 12, 14, 23, 34], "without": [1, 8, 12, 15, 28, 30], "long": [1, 9], "term": 1, "experi": [1, 11, 15], "all": [1, 5, 8, 10, 11, 12, 13, 15, 20, 29, 30, 32, 34], "share": 1, "same": [1, 5, 10, 15, 32], "goal": [1, 10], "maxim": 1, "And": [1, 5], "so": [1, 8, 10, 12, 13, 20, 23, 30, 33], "side": [1, 13], "how": [1, 9, 11, 12, 20], "done": [1, 5, 12, 13], "biggest": [1, 10], "obstacl": 1, "which": [1, 5, 8, 9, 10, 12, 13, 15, 20, 28, 32], "prevent": [1, 9], "u": [1, 11], "complet": [1, 10, 12, 20], "solv": [1, 32], "nois": 1, "system": [1, 2, 3, 5, 6, 9, 30, 32], "have": [1, 5, 10, 11, 12, 13, 15, 19, 20, 32], "variabl": [1, 5, 8, 10, 13, 20, 23], "amount": [1, 11, 19], "bend": 1, "twist": 1, "slack": 1, "unwant": 1, "form": [1, 10], "temporari": [1, 32], "deform": 1, "rigid": 1, "object": [1, 5, 13, 28, 32], "also": [1, 5, 8, 9, 10, 12, 13, 20, 29, 34], "uniqu": [1, 10], "aspect": 1, "when": [1, 5, 8, 10, 12, 13, 20, 30], "compar": 1, "high": 1, "school": 1, "level": [1, 23, 32], "materi": 1, "properti": [1, 10], "start": [1, 9, 10, 12, 13, 15, 20, 29], "show": [1, 8, 32], "significantli": 1, "length": [1, 3], "mass": 1, "size": [1, 5, 6, 10, 29, 30], "unlik": [1, 10, 33], "compact": 1, "ftc": 1, "vex": 1, "simpl": [1, 4, 12], "contrapt": 1, "like": [1, 5, 10, 11, 12, 13, 30], "measur": 1, "tape": [1, 10], "2020": 1, "would": [1, 10, 13], "work": [1, 3, 6, 10, 11, 13, 15, 28], "becaus": [1, 33], "criteria": [1, 13], "scale": 1, "want": [1, 8, 9, 10, 12, 15, 20], "manuev": 1, "while": [1, 5, 6, 8, 10, 11, 29], "adapt": 1, "undesir": 1, "physic": [1, 10, 13], "chang": [1, 12, 13, 15, 29], "field": [1, 10, 30], "appli": [1, 9], "mathemat": 1, "regard": [1, 19], "accuraci": 1, "respons": 1, "There": [1, 5, 12, 20, 30, 34], "ar": [1, 5, 8, 10, 13, 15, 20, 24, 29, 30, 32, 34], "two": [1, 3, 6, 8, 10, 11, 13, 14, 32], "type": [1, 5, 10, 20, 30, 32], "feedback": 1, "As": 1, "name": [1, 5, 10, 20, 30], "suggest": 1, "util": [1, 5, 6, 8, 10, 12, 13, 23, 29, 32], "input": [1, 5, 10, 15], "determin": [1, 29, 33], "an": [1, 2, 4, 5, 8, 10, 13, 14, 15, 20, 28, 33], "output": [1, 10, 12, 13], "back": [1, 15, 20, 32], "henc": 1, "its": [1, 10, 13, 20, 32], "second": [1, 8, 10, 11, 12, 13, 15, 28, 32], "exampl": [1, 5, 12, 13, 20, 28, 30, 32], "water": 1, "boil": 1, "doe": [1, 10, 11, 32], "depend": 1, "temperatur": 1, "between": [1, 13, 32], "regul": 1, "air": 1, "condition": 1, "hvac": 1, "fed": 1, "new": [1, 3, 5, 6, 8, 12, 13, 32], "eventu": 1, "adjust": 1, "room": 1, "desir": 1, "dc": 1, "motor": [1, 5, 11, 12, 20], "certain": [1, 5, 13], "rotat": [1, 12, 30, 32], "possibl": [1, 23, 33], "take": [1, 10, 30], "account": [1, 9, 20, 32], "encod": 1, "valu": [1, 8, 10, 13, 29, 30, 32], "comput": [1, 9, 10, 11, 13], "enough": [1, 8, 13, 32], "voltag": 1, "feed": [1, 10, 28], "meaning": 1, "self": 1, "proport": 1, "integr": 1, "deriv": 1, "common": [1, 10], "allow": [1, 13, 15, 30, 32], "tweak": 1, "three": [1, 10, 12], "constant": [1, 10, 23, 32], "coeffici": [1, 10, 29, 30], "state": [1, 8], "increas": 1, "effici": 1, "lower": [1, 5], "effect": 1, "undershoot": 1, "overshoot": 1, "implement": 1, "falcon": [1, 13, 20], "500": [1, 13, 20], "wpilib": [1, 5, 11, 19, 20, 23, 32], "includ": [1, 5, 10, 13, 15, 20, 23, 30, 32, 33], "pidcontrol": 1, "class": [1, 3, 5, 6, 13, 23, 28, 32], "gener": [1, 30], "your": [1, 8, 9, 10, 12, 13, 15, 20, 30, 32, 33], "target": [1, 5, 9, 33], "current": [1, 9, 20, 30, 32], "see": [1, 5, 8, 10, 12, 20, 32], "interact": [1, 10], "here": [1, 8, 10, 11, 13, 15, 30, 34], "circl": [1, 10], "attempt": [1, 6, 10], "posit": [1, 10, 30, 32], "itself": [1, 13], "under": [1, 8, 20], "cursor": 1, "anoth": [1, 8, 9, 10, 32], "interest": [1, 8], "websit": [1, 20], "simul": [1, 14, 34], "cart": 1, "balanc": [1, 13], "arm": [1, 13, 23], "tune": 1, "bookmark": 1, "try": [1, 3, 6, 10, 13, 15, 20, 30, 33], "behavior": 1, "being": [1, 8, 10], "drivebas": [1, 12], "wheel": [1, 13], "elev": 1, "etc": [1, 5, 9], "ideal": [1, 10], "go": [1, 8, 15], "through": [1, 4, 8, 11, 12, 13, 19, 28, 33], "correctli": 1, "math": [1, 8, 10], "behind": 1, "isn": [1, 20], "t": [1, 9, 10, 11, 12, 13, 15, 20], "necessari": [1, 8, 10, 20, 29, 30, 33], "learn": [1, 15, 24], "articl": [1, 10], "document": [1, 19, 23, 29, 32], "explain": 1, "note": [1, 7, 10, 14, 32, 34], "less": [1, 32], "factor": 1, "data": [1, 10, 32], "frequenc": 1, "sinc": [1, 8, 9, 10, 12, 13, 23, 32, 33], "": [1, 5, 8, 9, 10, 11, 12, 13, 15, 20, 23, 30], "discret": 1, "model": [1, 33], "delta": 1, "result": [1, 5, 6, 8, 13, 20], "better": 1, "calcul": [1, 8], "sometim": [1, 9], "benefici": 1, "add": [1, 5, 6, 12, 13, 20], "compon": [1, 13, 19], "compens": 1, "specif": [1, 8, 10, 15, 20, 33], "circumst": 1, "pidf": 1, "code": [1, 5, 8, 10, 11, 14, 15, 20, 23, 30, 33, 34], "friction": 1, "incredibli": 1, "multipli": [1, 8], "cw": 1, "yapathon": 1, "ahead": [1, 19], "A": [1, 5, 13, 15], "affect": 1, "softwar": [1, 10, 11, 13, 20, 34], "introduc": [1, 4], "axi": [1, 13], "sever": [1, 8, 10], "impact": 1, "belt": 1, "slippag": 1, "gearbox": 1, "misalign": 1, "sensor": [1, 5], "Then": [1, 5, 9, 10, 32], "signal": [1, 8, 32], "deal": 1, "graviti": 1, "weight": 1, "torqu": 1, "These": [1, 20, 24], "cannot": [1, 13], "imposs": 1, "make": [1, 4, 5, 8, 9, 10, 11, 12, 15, 20, 29, 30, 32], "perfect": [1, 10], "best": [1, 10, 11, 30], "minim": 1, "dure": [1, 4, 11, 13], "process": [1, 13, 20, 28, 29, 30, 32, 34], "them": [1, 8, 9, 10, 13, 15], "If": [1, 5, 8, 9, 15, 20], "contain": [1, 5, 6, 10, 12, 13, 15, 19], "place": [1, 13], "closest": 1, "gear": 1, "don": [1, 9, 10, 12, 13, 15, 20], "requir": [1, 10, 13, 15, 30, 33], "toler": 1, "repres": [1, 10], "raw": [1, 20, 30], "alreadi": [1, 12, 15, 20], "librari": [1, 5, 8, 10, 20, 28, 30, 32, 33], "filter": [1, 33], "variou": [1, 10], "method": [1, 5, 8, 10, 12, 13, 23, 28, 32], "cover": [1, 10, 12, 13], "some": [1, 8, 9, 10, 13, 19, 20, 34], "later": [1, 10, 20], "But": [1, 8], "ultim": 1, "direct": [1, 13], "wai": [1, 10, 12, 20, 30, 32], "need": [1, 9, 10, 11, 12, 13, 15, 20], "unpredict": 1, "creat": [1, 5, 8, 10, 12, 13, 15, 20, 32, 33], "plan": [1, 30], "instinct": 1, "recreat": 1, "geometr": 1, "draw": [1, 10], "diagram": 1, "imsa": [1, 5], "previous": 1, "real": [1, 8, 13], "world": 1, "too": [1, 9, 28], "invers": 1, "kinemat": [1, 19], "base": [1, 12, 13, 14, 19, 20, 34], "equat": [1, 8], "accur": [1, 29], "weren": 1, "defin": [1, 8], "rang": [1, 8, 10], "appear": 1, "although": [1, 10, 32], "theoret": 1, "still": 1, "veri": 1, "applic": [1, 10, 24, 34], "consider": 1, "combin": 1, "reduc": [1, 11], "ad": [1, 5, 20], "step": [1, 15], "great": [1, 20], "simplest": [1, 10], "constraint": 1, "remov": [1, 9, 15], "unnecessari": [1, 10], "approach": 1, "move": [1, 13], "degre": [1, 10, 12, 30], "freedom": 1, "precis": 1, "hold": [1, 29], "heavi": 1, "much": [1, 10, 11, 13, 23], "acceler": 1, "perhap": 1, "mai": [1, 29], "onli": [1, 5, 8, 10, 11, 12, 13, 15, 30, 32], "total": 1, "throughout": 1, "entir": [1, 19], "game": [1, 11, 13, 32], "mayb": 1, "actual": [1, 8, 13], "suitabl": 1, "ha": [1, 5, 8, 9, 10, 11, 13, 15, 19, 32], "higher": [1, 20], "pullei": 1, "easier": [1, 13], "energi": 1, "won": 1, "counter": [1, 13], "power": [1, 9], "usag": [1, 15, 30], "faster": 1, "case": [1, 3, 5, 8, 23], "action": [1, 10, 15], "run": [1, 5, 8, 9, 12, 13, 20, 30], "nearest": 1, "member": [1, 5, 15, 20, 23], "ruin": 1, "dream": 1, "attach": 1, "custom": [1, 11], "5": [1, 3, 6, 13, 24, 32, 34], "might": [1, 9, 10, 20, 24], "stuck": 1, "predetermin": 1, "beforehand": 1, "tabl": [1, 32], "static": [1, 3, 5, 6, 8], "angl": [1, 10, 30], "seem": 1, "onc": [1, 8, 13, 15], "realiz": 1, "batteri": 1, "get": [1, 5, 6, 10, 20, 32], "exponenti": 1, "difficult": [1, 10], "now": [1, 8, 12, 20], "imagin": [1, 13], "decid": 1, "strain": 1, "movement": 1, "occurr": 1, "hour": [1, 2, 3, 4, 6, 8], "week": 1, "come": [1, 9], "up": [1, 3, 5, 6, 8, 9, 10, 13, 14], "about": [1, 8, 10, 13, 24], "over": [1, 10, 28], "who": [1, 3, 6], "singlehandedli": 1, "wrote": [1, 23], "sick": 1, "far": [1, 13], "simpler": 1, "debug": [1, 13, 20, 30], "estim": [1, 29], "section": 1, "exagger": 1, "encount": 1, "neg": 1, "outcom": 1, "season": [1, 10, 13, 33], "simpli": [1, 13, 24], "challeng": 1, "pandem": 1, "taken": [1, 4], "toll": 1, "signific": 1, "knowledg": 1, "connect": [1, 8, 10, 20], "been": [1, 9], "lost": [1, 12, 32], "each": [1, 5, 8, 10, 12, 13, 15, 29, 32], "improv": 1, "retel": 1, "event": 1, "occur": [1, 10], "2022": [1, 20], "2023": [1, 7, 14, 33, 34], "write": [1, 9, 10, 13, 15], "wa": [1, 20, 32], "limit": [1, 20], "encourag": 1, "chiefdelphi": 1, "post": 1, "purpos": [1, 8, 10, 13], "fo": 1, "regain": 1, "skill": 1, "everyon": [1, 4, 13, 15], "els": [1, 5, 6, 8, 23, 30], "proper": 1, "strongli": 1, "recommend": [1, 10, 20, 24], "least": [1, 9], "chapter": 1, "book": 1, "inform": [1, 10, 12, 13], "manual": [1, 9, 30, 32], "essenti": 1, "classic": 1, "calculu": 1, "linear": 1, "algebra": 1, "prerequisit": 1, "kalman": [1, 33], "bc": 1, "sequenc": 1, "mvc": 1, "linalg": 1, "differ": [1, 10, 15], "entireti": 1, "set": [1, 8, 10, 12, 13, 19, 20], "abov": [1, 4, 30], "major": [1, 19], "programm": [1, 11, 19], "particular": 1, "repositori": [1, 12, 13, 15], "sourc": [1, 9, 15, 24], "repo": [1, 15, 20, 30], "provid": [1, 8, 28, 29], "extend": [1, 10, 13, 33], "septemb": [2, 3, 4, 6, 8, 12, 13, 14], "25": [2, 14], "2": [2, 5, 7, 8, 9, 10, 13, 14, 24, 30, 34], "introduct": [2, 14], "robot": [2, 11, 12, 13, 20, 24, 32, 33], "perspect": [2, 10], "11": [3, 6, 14, 20], "1": [3, 5, 6, 7, 8, 9, 10, 13, 14, 20, 30, 34], "split": [3, 5, 6, 14], "group": [3, 6, 10, 12, 13, 14, 23], "The": [3, 5, 6, 8, 19, 20, 23, 28, 29, 32, 33], "were": [3, 6], "java": [3, 4, 5, 6, 10, 11, 12, 13, 14, 24, 30, 34], "wordl": [3, 7, 14, 34], "clone": [3, 7, 12, 13, 14, 34], "more": [3, 5, 6, 10, 12, 13, 20, 24, 32], "familiar": [3, 6], "main": [3, 5, 6, 9, 10, 13, 15, 20, 30, 33], "public": [3, 5, 6, 12, 13, 23], "void": [3, 5, 6, 8, 13], "string": [3, 5, 6, 13, 28], "arg": [3, 5, 6], "brainfuckread": 3, "reader": [3, 6], "getcod": 3, "brainfuckinterpret": 3, "io": [3, 6], "file": [3, 9, 10, 11, 12, 13, 15, 20, 23, 29, 30, 32], "nio": 3, "filenam": 3, "return": [3, 6, 8, 10, 13, 20, 32], "readstr": 3, "topath": 3, "catch": [3, 6], "except": [3, 6], "err": [3, 6], "println": [3, 5, 6, 32], "char": [3, 6], "memori": 3, "3000": 3, "int": [3, 5, 6, 8, 28, 32], "posrightbracketforleftbracket": 3, "datapoint": 3, "0": [3, 5, 6, 8, 9, 10, 13, 20, 29, 32], "posleftbracket": 3, "i": [3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 15, 20, 23, 28, 30, 32, 33], "charat": [3, 6], "switch": [3, 13], "break": [3, 6, 10, 15], "default": [3, 9, 20, 28, 32], "print": [3, 5, 10, 29, 30], "10": [4, 5, 10, 14, 20, 30, 32], "project": [4, 8, 11, 13, 15, 20, 28, 30, 32, 34], "consol": [4, 10], "follow": [4, 9, 10, 13, 20, 23, 24, 30, 32], "along": 4, "meet": 4, "first": [4, 8, 9, 10, 12, 13, 15, 19, 20, 28, 29, 32], "led": [4, 14, 34], "what": [5, 9, 11], "jit": 5, "compil": [5, 20, 33], "just": [5, 8, 10, 12, 13], "In": [5, 8, 9, 10, 13], "languag": [5, 8], "bytecod": 5, "translat": [5, 10], "machin": 5, "platform": [5, 13, 15, 30], "cross": [5, 30], "c": [5, 13, 24, 30, 34], "directli": 5, "e": [5, 6, 20, 23], "g": [5, 20, 23], "integ": [5, 6, 8, 10], "number": [5, 8, 13], "doubl": [5, 12, 32], "decim": [5, 8], "text": [5, 6], "primit": 5, "basic": [5, 14, 19, 29, 34], "upper": 5, "complex": 5, "next": [5, 12, 15, 20], "orient": [5, 13], "everyth": [5, 12, 30], "constructor": [5, 13, 28], "modifi": [5, 13], "privat": [5, 6, 13, 23], "readonli": 5, "thing": [5, 8, 10, 15], "access": [5, 8, 10, 11, 13, 23], "insid": [5, 10, 12, 13, 15, 30], "instanc": [5, 8, 13], "cant": 5, "after": [5, 8, 9, 10, 11, 15, 24], "creation": 5, "btw": 5, "attribut": 5, "python": [5, 8, 14, 29, 30, 34], "car": 5, "engin": 5, "float": [5, 8], "fuel": 5, "unit": 5, "gallon": 5, "mileag": 5, "mile": 5, "x": [5, 8, 9, 10, 11, 12, 13, 29, 30], "drivecar": 5, "33": 5, "per": [5, 30], "addfuel": 5, "hondaciv": 5, "brand": 5, "zero": [5, 10], "0f": 5, "fill": 5, "30": 5, "drove": 5, "typic": [5, 10, 13, 15], "written": [5, 33], "standard": [5, 8, 10, 32], "stuff": 5, "gyroscop": 5, "manufactur": 5, "own": [5, 30, 33], "reusabl": 5, "algorithm": [5, 33, 34], "walkthrough": 5, "practic": 5, "inventori": [5, 7, 14, 34], "manag": [5, 7, 9, 11, 14, 20, 34], "item": 5, "quantiti": 5, "arraylist": [5, 6], "additem": 5, "search": [5, 9, 10, 20], "queri": 5, "ye": 5, "n": [5, 30], "r": 5, "window": [5, 9, 10, 20, 28, 30], "special": [5, 13], "charact": 5, "line": [5, 10, 12], "scanner": [5, 6], "automat": [5, 10, 15], "vscode": [5, 11, 15, 20], "inventorymanag": 5, "welcom": [5, 34], "No": 5, "space": [5, 9, 10, 11, 30], "find": [5, 9, 34], "exit": [5, 10], "leav": [5, 32], "record": 5, "user": 5, "inputscann": [5, 6], "loop": [5, 8, 10], "condit": [5, 8, 10, 12], "true": [5, 6, 13, 20, 32], "boolean": [5, 6], "isrun": [5, 6], "userinput": [5, 6], "nextlin": [5, 6], "splittedcommand": 5, "arrai": [5, 8, 32], "word": [5, 6], "startswith": 5, "fals": [5, 6, 8, 10, 13, 32], "count": 5, "convert": [5, 8, 32], "newitem": 5, "parseint": 5, "unknown": 5, "brainf": [6, 7, 14, 34], "interpret": [6, 7, 14, 34], "word_length": 6, "3": [6, 7, 10, 13, 14, 24, 30, 34], "max_attempt": 6, "9999999": 6, "wordleread": 6, "secretword": 6, "getrandomword": 6, "equal": 6, "congrat": 6, "guess": 6, "matchingindec": 6, "letter": [6, 20, 29], "turngreen": 6, "indexof": 6, "turnyellow": 6, "random": 6, "randgen": 6, "currenttimemilli": 6, "fileinputstream": 6, "fstream": 6, "txt": 6, "datainputstream": 6, "bufferedread": 6, "br": 6, "inputstreamread": 6, "strline": 6, "readlin": 6, "null": [6, 9, 32], "close": [6, 10, 13, 29], "nextint": 6, "tolowercas": 6, "wordexist": 6, "42m": 6, "0m": 6, "43m": 6, "4": [8, 14, 24, 30, 34], "lesson": [8, 10], "strip": 8, "microcontrol": 8, "arduino": 8, "uno": 8, "wokwi": 8, "onlin": [8, 9, 10, 15, 20], "emul": 8, "substitut": [8, 11], "board": [8, 30], "turn": [8, 12], "repeat": 8, "infinit": 8, "For": [8, 10, 13, 20, 30], "100": [8, 9], "light": [8, 9, 11], "displai": [8, 13, 20, 29], "open": [8, 9, 10, 15, 20, 28], "tab": [8, 15], "fastl": 8, "control": [8, 11, 12, 14, 15, 20, 34], "clear": 8, "pixel": [8, 10, 29], "empti": [8, 13], "send": [8, 13, 20, 28], "earlier": 8, "call": [8, 9, 12, 13, 15, 28, 32], "bracket": 8, "oper": [8, 9, 33], "chsv": 8, "hue": [8, 10], "satur": [8, 10], "crgb": 8, "red": [8, 10], "green": [8, 10, 11, 15], "blue": [8, 10, 15], "color": [8, 14, 29, 34], "rgb": [8, 10], "both": [8, 20, 30], "255": [8, 10], "8": [8, 10, 14, 20, 30], "byte": [8, 10], "blank": [8, 32], "updat": [8, 9, 10, 15, 24, 32], "num_l": 8, "th": 8, "iter": 8, "divis": 8, "divid": 8, "progress": [8, 12], "To": [8, 10, 13, 15, 20, 30, 33], "delai": [8, 32], "millisecond": 8, "similar": [8, 20], "sleep": [8, 9], "fast": 8, "list": [8, 9, 15, 20], "notabl": 8, "featur": [8, 10, 15], "until": [8, 13], "forev": [8, 12], "statement": [8, 12, 32], "thing1": 8, "thing2": 8, "funciton": 8, "1000": 8, "wait": [8, 9], "modulo": 8, "number0": 8, "remaind": 8, "sin": 8, "co": 8, "tan": 8, "pow": 8, "y": [8, 10, 13, 20, 29], "sqrt": 8, "log": [8, 20], "natur": 8, "log10": 8, "hsv": [8, 10], "support": [8, 9, 19, 20, 32], "download": [8, 9, 10, 11, 15, 20], "desktop": [8, 9], "version": [8, 9, 13, 20, 33], "id": [8, 9, 13, 20, 30, 32], "select": [8, 9, 15, 20, 30], "usb": [8, 9, 11], "port": [8, 20, 30, 32], "tool": [8, 29], "click": [8, 15, 20], "upload": [8, 15], "intro": 9, "kde": 9, "live": 9, "iso": 9, "http": [9, 15, 20, 30], "cdimag": 9, "org": 9, "cd": [9, 30], "amd64": [9, 20], "hybrid": 9, "12": [9, 10, 20, 30], "7": 9, "read": [9, 10, 19], "flash": 9, "onto": 9, "On": [9, 10, 13, 20], "instruct": [9, 20], "rufu": 9, "app": [9, 20], "free": [9, 10, 13, 15, 20, 30], "disk": 9, "menu": [9, 15], "ll": 9, "50": [9, 13], "gb": 9, "200": 9, "prefer": [9, 20], "disabl": [9, 11], "bitlock": 9, "guid": [9, 10, 15, 24, 30, 34], "sure": [9, 10, 12, 20, 29], "know": [9, 10, 11, 20], "microsoft": [9, 10, 20], "password": 9, "associ": 9, "down": [9, 13], "recoveri": 9, "kei": [9, 10, 13], "paper": [9, 29], "plug": [9, 11], "imag": 9, "reboot": 9, "spam": [9, 20], "appropri": [9, 10], "hotkei": 9, "bio": 9, "soon": 9, "laptop": [9, 20], "esc": [9, 10], "f2": 9, "f10": 9, "boot": 9, "secur": 9, "technic": 9, "o": [9, 20], "approv": 9, "someon": [9, 23], "sold": 9, "sign": [9, 11], "save": [9, 15, 29], "ask": [9, 10, 11, 13, 20], "session": [9, 20], "enter": [9, 11, 13, 15, 20], "left": [9, 13, 29], "calamar": 9, "termin": [9, 12, 13, 20], "prompt": 9, "goe": 9, "usernam": [9, 12, 13, 20], "arrow": [9, 13], "screen": [9, 13], "sudo": [9, 20, 30], "nano": 9, "edit": [9, 13, 30], "ctrl": 9, "order": [9, 12], "merg": [9, 12, 33], "configur": [9, 13, 20], "bootload": 9, "hardwar": [9, 11], "recent": 9, "nonfre": 9, "amd": [9, 20], "graphic": [9, 10], "misc": 9, "intel": [9, 20, 30], "nvidia": 9, "mediatek": 9, "packag": [9, 30], "buster": 9, "backport": 9, "devic": [9, 20], "shell": [9, 20], "l": [9, 20], "dev": [9, 28], "figur": [9, 10, 13], "got": 9, "sda": 9, "care": 9, "right": [9, 13], "usbstick": 9, "mkdir": [9, 30], "p": 9, "mnt": 9, "mount": 9, "apt": [9, 20, 30], "deb": [9, 30], "tee": 9, "d": 9, "eof": 9, "bookworm": 9, "9": [10, 14, 32], "store": [10, 11, 20], "linux": [10, 11, 14, 20, 24, 30, 34], "preinstal": 10, "ping": [10, 12], "georgi": [10, 20], "ethan": [10, 20], "help": [10, 12, 13, 30], "pip": 10, "contrib": [10, 30], "partit": 10, "entiti": 10, "background": 10, "detect": [10, 33, 34], "format": 10, "convini": 10, "monitor": [10, 11], "human": 10, "represent": 10, "largest": 10, "extens": [10, 20], "alwai": [10, 11, 15, 24], "multipl": [10, 30], "someth": 10, "commonli": 10, "Its": 10, "modul": [10, 23, 30, 33], "re": [10, 20], "hidden": 10, "impli": 10, "initi": [10, 12, 28, 32, 33], "ones": 10, "specifi": [10, 12, 28, 29, 32], "pre": 10, "train": [10, 34], "design": [10, 11, 13, 24, 34], "explicit": [10, 33], "syntax": 10, "look": [10, 12, 20], "w3school": 10, "visual": [10, 30], "studio": [10, 30], "button": [10, 13, 15], "shortcut": 10, "structur": [10, 11, 32], "info": 10, "outlin": [10, 23], "accross": 10, "choos": [10, 20], "bright": 10, "pacakg": 10, "keyword": [10, 30], "shorten": 10, "readibl": 10, "np": 10, "cv2": 10, "cv": 10, "webcam": 10, "claim": 10, "captur": 10, "argument": [10, 13, 28, 32], "index": [10, 28], "unless": [10, 20], "almost": [10, 13], "templat": [10, 12, 13], "cap": 10, "videocaptur": 10, "isopen": 10, "_": 10, "todo": 10, "quit": 10, "q": 10, "press": [10, 11, 13, 15, 20], "otherwis": [10, 15, 20], "kill": 10, "extern": [10, 13, 19], "waitkei": 10, "ord": 10, "error": 10, "releas": [10, 20, 33], "destroyallwindow": 10, "imshow": 10, "correspond": 10, "titl": 10, "keep": [10, 23], "bgr": 10, "properli": 10, "your_fram": 10, "arr": 10, "np_arr": 10, "pretti": [10, 13], "page": [10, 20, 32, 34], "new_fram": 10, "cvtcolor": 10, "color_bgr2rgb": 10, "color_bgr2grai": 10, "grayscal": 10, "color_bgr2hsv": 10, "hide": 10, "part": [10, 11], "sens": 10, "unsign": 10, "inclus": 10, "inrang": 10, "lower_threshold": 10, "upper_threshold": 10, "where": 10, "white": 10, "full": [10, 13, 15, 23, 30], "exclud": 10, "black": 10, "exist": [10, 12, 20], "imaag": 10, "countour": 10, "origin": [10, 15], "drawcontour": 10, "respect": [10, 33], "fourth": 10, "width": [10, 30], "findcontour": 10, "retr_extern": 10, "chain_approx_simpl": 10, "lens": 10, "individu": 10, "view": [10, 15], "avail": [10, 20, 32, 34], "script": [10, 20, 29, 30], "scan": 10, "aruco": [10, 30], "chessboard": 10, "known": 10, "diment": [10, 29], "matrix": [10, 30], "distort": [10, 29, 30], "flat": [10, 29], "surfac": [10, 29], "pictur": [10, 30], "approxim": 10, "20": [10, 30, 32], "copi": [10, 12, 15, 20, 32], "feel": [10, 13, 15, 20, 30], "expand": 10, "locat": 10, "obtain": 10, "2d": 10, "vertic": 10, "point": [10, 11, 13], "given": 10, "sphere": 10, "radiu": 10, "trigonometri": 10, "depth": 10, "3d": [10, 32], "wikipedia": 10, "resourc": [10, 34], "smoothest": 11, "driver": [11, 13], "think": 11, "wast": 11, "autom": 11, "task": [11, 14], "score": 11, "autonom": [11, 13, 14, 34], "15": [11, 13], "period": [11, 13], "good": [11, 32], "bad": 11, "github": [11, 15, 30], "bild": 11, "coprocessor": [11, 24, 32, 33, 34], "roborio": [11, 13, 24, 32, 34], "ethernet": 11, "wifi": 11, "station": [11, 13], "emerg": 11, "stop": [11, 12, 20], "restart": 11, "enabl": 11, "again": [11, 12], "phoenix": [11, 13, 19], "tuner": 11, "non": 11, "rememb": [11, 15], "fly": 11, "hard": 11, "di": 11, "pleas": [11, 15, 20, 23], "link": [11, 15, 30], "cheatsheet": [11, 15], "rev": 11, "client": 11, "git": [11, 16, 24, 33, 34], "homework": 11, "titan2022": [12, 13], "training2024": [12, 13], "haven": 12, "previou": 12, "afterward": [12, 13, 20], "branch": [12, 13, 32, 33], "auton": 12, "tankdrivesubsystem": [12, 13], "driveleft": 12, "driveright": 12, "18": [12, 14], "tankcontrolcommand": [12, 13], "movecommand": 12, "teleop": [12, 13], "four": [12, 13, 29], "end": 12, "timeout": 12, "withtimeout": 12, "sequentialcommandgroup": 12, "pass": [12, 13, 28, 32], "schedul": [12, 13], "finish": [12, 13], "autonomousinit": [12, 13], "routin": [12, 14, 23], "element": 12, "found": [12, 13, 15, 30], "discard": 12, "off": 12, "mb": 12, "90": 12, "fine": [12, 20], "me": [12, 13], "squar": [12, 29], "17": [13, 14, 20], "sim": 13, "folder": [13, 15, 23, 32], "worri": 13, "entri": [13, 20], "src": 13, "mimic": 13, "serv": 13, "shooter": 13, "shoot": 13, "intak": 13, "pick": 13, "piec": 13, "local": [13, 15, 20, 23, 28, 33, 34], "oop": 13, "pattern": [13, 29], "timedrobot": 13, "overrid": 13, "robotinit": 13, "robotperiod": 13, "autonomousperiod": 13, "teleopinit": 13, "teleopperiod": 13, "disabledinit": 13, "player": 13, "rest": 13, "teleoper": 13, "mode": 13, "init": [13, 20], "20m": 13, "todai": 13, "tomorrow": 13, "assign": 13, "subsystembas": 13, "tankdriv": 13, "alongsid": 13, "One": 13, "wasd": 13, "joystick": 13, "keyboard": 13, "xboxcontrol": 13, "mycommand": 13, "getleftx": 13, "getlefti": 13, "getrightx": 13, "getrighti": 13, "getxbutton": 13, "getxbuttonpress": 13, "getxbuttonreleas": 13, "talon": 13, "fx": 13, "wpi_talonfx": 13, "differenti": 13, "ctre": [13, 19, 20], "api": 13, "6": [13, 19, 20], "motor0": 13, "controlmod": 13, "percentoutput": 13, "max": [13, 20], "veloc": 13, "m": 13, "setinvert": 13, "clockwis": 13, "slow": 13, "life": 13, "never": [13, 20], "anywher": 13, "percentag": 13, "smartdashboard": 13, "dashboard": [13, 34], "putnumb": 13, "putbooleam": 13, "putstr": 13, "style": [13, 24, 34], "six": 13, "togeth": [13, 15], "ident": 13, "around": 13, "plai": 13, "content": 13, "subteam": [14, 34], "overview": [14, 34], "tank": [14, 34], "instal": [14, 19, 24, 33, 34], "segment": [14, 34], "opencv": [14, 30, 34], "theori": [14, 34], "easi": 14, "harder": 14, "24": 14, "short": [15, 24], "cli": 15, "host": 15, "master": [15, 20, 30], "messag": [15, 33], "fetch": 15, "option": 15, "dublic": 15, "independ": 15, "past": [15, 20], "descript": 15, "readi": 15, "sync": 15, "addit": 15, "check": [15, 20, 24, 29], "bar": 15, "addion": 15, "checkout": 15, "notifi": 15, "avoid": 15, "conflict": 15, "particularli": 15, "big": 15, "request": [15, 33], "offici": [19, 20, 30, 32, 33, 34], "wiki": 19, "navx2": 19, "odometri": 19, "pathplann": [19, 23], "edu": 19, "wpi": 19, "com": [19, 20, 30], "phoenix6": 19, "pathplannerlib": 19, "lib": 19, "revlib": 19, "revrobot": 19, "troubl": 20, "reach": 20, "veteran": 20, "discord": 20, "64": 20, "bit": 20, "cpu": 20, "panel": 20, "box": 20, "sai": 20, "either": 20, "32": 20, "arm64": 20, "distribut": 20, "glibc": 20, "popular": 20, "distro": 20, "debian": [20, 30], "ubuntu": 20, "mint": 20, "arch": 20, "elementari": 20, "fedora": 20, "enterpris": 20, "suse": 20, "maco": [20, 30], "mac": 20, "appl": 20, "silicon": 20, "choic": 20, "standalon": 20, "homebrew": 20, "brew": 20, "macport": 20, "doesn": 20, "matter": 20, "thread": [20, 30], "organ": 20, "my": 20, "powershel": 20, "bash": 20, "gh": 20, "auth": 20, "web": 20, "browser": 20, "jdk": 20, "develop": 20, "kit": 20, "temurin": 20, "lt": 20, "msi": 20, "bashrc": 20, "export": 20, "path": [20, 28, 29, 30], "home": 20, "bin": 20, "java_hom": 20, "bash_profil": 20, "zprofil": 20, "suit": 20, "doc": 20, "trial": 20, "realiti": 20, "winrar": 20, "shouldn": 20, "interfer": 20, "must": 20, "x11": [20, 28], "wayland": 20, "network": [20, 30, 33, 34], "curl": [20, 30], "githubusercont": 20, "ethanc8": [20, 30], "frclinuxdevkit": 20, "sh": 20, "vscodium": 20, "environ": 20, "fldk_install_ext_destin": 20, "launch": 20, "binari": [20, 30], "oss": 20, "yourself": 20, "codium": 20, "super": 20, "experiment": 20, "tell": 20, "abl": 20, "diagnost": 20, "kind": 20, "involv": 20, "peripher": 20, "android": 20, "rootf": 20, "userspac": 20, "ca": 20, "certif": 20, "waydro": 20, "waydroid": 20, "prop": 20, "persist": 20, "multi_window": 20, "wget": 20, "someblob": 20, "x_2024": 20, "0_apkcombo": 20, "apk": 20, "phoenix_tun": 20, "unfortun": 20, "spark": 20, "experienc": 20, "wish": 20, "contribut": 20, "titanalgorithm": 20, "especi": 23, "lot": 23, "refer": [23, 32, 33], "pascalcas": 23, "macro_cas": 23, "m_camelcas": 23, "camelcas": 23, "enum": 23, "pascalcasetest": 23, "pascalcasesubsystem": 23, "abstract": 23, "pascalcasecommand": 23, "cpp": 23, "hpp": 23, "test_camelcas": 23, "cmake": [23, 30], "projecct": 23, "subfold": 23, "relat": [23, 24, 34], "auto": 23, "reus": 23, "topic": 24, "writ": 24, "irrelev": 24, "configread": 28, "readfromfil": 28, "std": 28, "directori": [28, 30, 32], "config": [28, 29, 30], "load": 28, "rel": 28, "root": 28, "absolut": 28, "titanprocess": 28, "apriltagdetector": 28, "stream": [28, 30, 32], "pose": [28, 29, 32, 33], "packet": [28, 32], "udp": [28, 30, 32], "networkingcli": [28, 32], "posefilt": 28, "video": [28, 32], "bool": 28, "whether": 28, "marker": 29, "cm": 29, "type_calibr": 29, "py": [29, 30, 32], "TO": [29, 30], "cfg": 29, "front": 29, "camera": [29, 30], "recogn": 29, "overlai": 29, "logic": 29, "focal": 29, "resolut": 29, "optic": 29, "center": 29, "apriltag": [29, 30, 33, 34], "aarch64": 30, "x86_64": 30, "msvc": 30, "mingw": 30, "clang": 30, "calibr": [30, 33, 34], "submodul": 30, "realsens": 30, "sdk": 30, "googletest": 30, "framework": 30, "json": 30, "modern": 30, "vcpkg": 30, "scratch": 30, "execut": 30, "ol": 30, "titanian": 30, "pool": 30, "v": 30, "vcpkg_2023": 30, "titan2022_amd64": 30, "nlohmann": 30, "makefil": 30, "ninja": 30, "toolchain": 30, "altern": 30, "b": 30, "dcmake_toolchain_fil": 30, "buildsystem": 30, "dbuild_exampl": 30, "forc": 30, "clangd": 30, "dcmake_export_compile_command": 30, "dcmake_build_typ": 30, "relwithdebinfo": 30, "gninja": 30, "j": 30, "dno_realsens": 30, "compat": 30, "ip": [30, 32], "server": 30, "quaddecim": 30, "quadsigma": 30, "decodesharpen": 30, "height": 30, "fp": 30, "exposur": 30, "paramet": 30, "camset": 30, "meter": 30, "quick": 30, "charuco": 30, "photo": 30, "impliment": [30, 32], "offer": 32, "commun": 32, "tri": 32, "mitig": 32, "reconnect": 32, "problem": 32, "socket": 32, "lowest": 32, "protocol": 32, "futur": 32, "idea": 32, "tcp": 32, "h": 32, "header": 32, "5800": 32, "label": 32, "vector": 32, "vector3d": 32, "vec": 32, "send_vector": 32, "vector_nam": 32, "pose_nam": 32, "tag": 32, "position2": 32, "rotation2": 32, "send_tag": 32, "tag_nam": 32, "due": 32, "reutil": 32, "outsid": 32, "bind": 32, "replac": 32, "intend": 32, "trbnetworkingclientref": 32, "trbnetworkingclientcr": 32, "trbvector3d": 32, "trbvector3dmak": 32, "returnvec": 32, "trbnetworkingclientsendvector": 32, "trbnetworkingclientsendpos": 32, "trbnetworkingclientsendtag": 32, "trbnetwork": 32, "sendvector": 32, "sendtag": 32, "explicitli": 32, "numer": 32, "midwest": 32, "networkingserv": 32, "5801": 32, "observ": 32, "subscrib": 32, "lambda": 32, "translation3d": 32, "respond": 32, "networkingcal": 32, "tostr": 32, "networkingpos": 32, "networkingtag": 32, "capabl": 33, "roll": 33, "frequent": 33, "bug": 33, "fix": 33, "modif": 33, "rebuild": 33, "commit": 33, "fork": 33, "pull": 33, "preseason": 34, "histori": 34}, "objects": {}, "objtypes": {}, "objnames": {}, "titleterms": {"2024": 0, "code": [0, 3, 6, 12, 13], "overview": [0, 2, 11], "agenda": [0, 5, 11], "control": [1, 13], "theori": 1, "basic": [1, 7], "introduct": [1, 19, 33], "The": [1, 10, 12, 13], "problem": [1, 10], "what": [1, 29], "i": 1, "open": 1, "loop": 1, "v": 1, "close": 1, "pid": 1, "feedforward": 1, "more": [1, 8], "On": 1, "robot": [1, 22, 34], "In": 1, "practic": 1, "typic": 1, "happen": 1, "design": [1, 22], "decis": 1, "first": 1, "implic": 1, "complex": 1, "further": 1, "read": [1, 28], "electr": 2, "3": [3, 17], "brainf": 3, "interpret": 3, "final": [3, 6, 12, 13], "1": 4, "inventori": 4, "manag": 4, "old": 5, "note": 5, "from": [5, 12, 13], "2023": 5, "2": [6, 18], "wordl": 6, "clone": [6, 15], "java": [7, 19, 20, 23, 32], "content": [7, 14, 16, 19, 24, 33, 34], "led": 8, "program": [8, 11, 13, 18, 19], "setup": [8, 28, 32], "exampl": 8, "anim": 8, "rainbow": 8, "sine": 8, "wave": 8, "deploi": 8, "linux": [9, 21], "instal": [9, 10, 20, 30], "debian": 9, "chang": 9, "grub": 9, "set": 9, "newer": 9, "kernel": 9, "firmwar": 9, "color": 10, "base": 10, "segment": 10, "opencv": 10, "python": [10, 32], "overivew": 10, "numpi": 10, "instruct": [10, 30], "import": 10, "packag": 10, "camera": 10, "stream": 10, "show": 10, "imag": 10, "arrai": 10, "convert": 10, "frame": 10, "mask": 10, "contour": 10, "calibr": [10, 29], "intro": 10, "run": [10, 29], "challeng": 10, "find": 10, "center": 10, "calcul": 10, "object": 10, "distanc": 10, "subteam": 11, "tank": [12, 13], "autonom": 12, "get": [12, 13], "structur": [12, 13, 15, 23], "after": [12, 13], "lesson": [12, 13], "task": [12, 13], "drive": 13, "simul": 13, "frc": [13, 20], "subsystem": 13, "command": 13, "initi": 13, "execut": 13, "end": 13, "boolean": 13, "interrupt": 13, "isfinish": 13, "xbox": 13, "motor": 13, "extra": 13, "preseason": 14, "train": 14, "index": 14, "date": 14, "git": [15, 20], "commit": 15, "push": 15, "pull": 15, "switch": 15, "branch": 15, "merg": 15, "applic": 16, "coprocessor": 17, "c": [18, 23, 32], "roborio": 19, "librari": 19, "guid": [19, 23], "api": 19, "refer": 19, "oper": 20, "system": 20, "github": 20, "cli": 20, "login": 20, "onli": 20, "pre": 20, "season": 20, "game": 20, "tool": [20, 30], "phoenix": 20, "tuner": 20, "x": 20, "rev": 20, "hardwar": 20, "client": [20, 32], "option": [20, 30], "apach": 20, "maven": 20, "4": 21, "5": 22, "style": 23, "name": 23, "resourc": 24, "document": [24, 34], "other": [24, 30], "websit": 24, "team": 25, "2022": [25, 34], "histori": 25, "titan": [26, 27, 33, 34], "algorithm": 26, "dashboard": 27, "apriltag": 28, "detect": 28, "configur": [28, 30], "multithread": 28, "how": 29, "doe": 29, "o": 30, "support": 30, "build": 30, "local": 31, "network": 32, "why": 32, "limit": 32, "send": 32, "inform": 32, "With": 32, "repli": 32, "server": 32, "receiv": 32, "process": 33, "contribut": 33}, "envversion": {"sphinx.domains.c": 3, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 9, "sphinx.domains.index": 1, "sphinx.domains.javascript": 3, "sphinx.domains.math": 2, "sphinx.domains.python": 4, "sphinx.domains.rst": 2, "sphinx.domains.std": 2, "sphinx": 58}, "alltitles": {"2024 Code overview": [[0, "code-overview"]], "Agenda": [[0, "agenda"], [5, "agenda"], [11, "agenda"]], "Control Theory Basics": [[1, "control-theory-basics"]], "Introduction": [[1, "introduction"], [19, "introduction"], [33, "introduction"]], "The Problem": [[1, "the-problem"]], "What is Control Theory": [[1, "what-is-control-theory"]], "Open-Loop vs. Closed-Loop": [[1, "open-loop-vs-closed-loop"]], "PID Controllers": [[1, "pid-controllers"]], "PID with feedforward": [[1, "pid-with-feedforward"]], "More On Robot Control": [[1, "more-on-robot-control"]], "The Problem: In Practice": [[1, "the-problem-in-practice"]], "What Typically Happens": [[1, "what-typically-happens"]], "Design Decisions First": [[1, "design-decisions-first"]], "Implications of Complexity": [[1, "implications-of-complexity"]], "Further Reading": [[1, "further-reading"]], "Electrical overview": [[2, "electrical-overview"]], "3 - Brainf interpreter": [[3, "brainf-interpreter"]], "Final code": [[3, "final-code"], [6, "final-code"]], "1 - Inventory Manager": [[4, "inventory-manager"]], "Old notes from 2023": [[5, "old-notes-from-2023"]], "2 - Wordle Clone": [[6, "wordle-clone"]], "Java Basics": [[7, "java-basics"]], "Contents": [[7, null], [14, null], [16, null], [19, null], [24, null], [33, null], [34, null]], "LED Programming": [[8, "led-programming"]], "Setup": [[8, "setup"], [28, "setup"], [32, "setup"], [32, "id2"], [32, "id5"]], "More examples": [[8, "more-examples"]], "Animated Rainbow": [[8, "animated-rainbow"]], "Sine Wave": [[8, "sine-wave"]], "Deploying": [[8, "deploying"]], "Linux installation": [[9, "linux-installation"]], "Installing Debian": [[9, "installing-debian"]], "Changing GRUB settings": [[9, "changing-grub-settings"]], "Installing a newer kernel/firmware": [[9, "installing-a-newer-kernel-firmware"]], "Color-based segmentation in OpenCV Python": [[10, "color-based-segmentation-in-opencv-python"]], "Installation": [[10, "installation"], [20, "installation"], [30, "installation"]], "Overivew": [[10, "overivew"]], "Segmentation": [[10, "segmentation"]], "OpenCV": [[10, "opencv"]], "NumPy": [[10, "numpy"]], "Python": [[10, "python"]], "The problem": [[10, "the-problem"]], "Instructions": [[10, "instructions"], [30, "instructions"]], "Importing packages": [[10, "importing-packages"]], "Camera stream": [[10, "camera-stream"]], "Showing image": [[10, "showing-image"]], "NumPy arrays": [[10, "numpy-arrays"]], "Converting frames": [[10, "converting-frames"]], "Masking": [[10, "masking"]], "Contours": [[10, "contours"]], "Calibration": [[10, "calibration"], [29, "calibration"]], "Intro": [[10, "intro"]], "Running": [[10, "running"]], "Challenges": [[10, "challenges"]], "Finding the center": [[10, "finding-the-center"]], "Calculating object distance": [[10, "calculating-object-distance"]], "Programming Subteam Overview": [[11, "programming-subteam-overview"]], "Tank Autonomous": [[12, "tank-autonomous"]], "Getting code": [[12, "getting-code"], [13, "getting-code"]], "Structure": [[12, "structure"], [13, "structure"], [15, "structure"], [23, "structure"]], "Final code (from after the lesson)": [[12, "final-code-from-after-the-lesson"], [13, "final-code-from-after-the-lesson"]], "The Task": [[12, "the-task"], [13, "the-task"]], "Tank Drive Simulation": [[13, "tank-drive-simulation"]], "FRC Programming": [[13, "frc-programming"]], "Subsystems": [[13, "subsystems"]], "Commands": [[13, "commands"]], "initialize()": [[13, "initialize"]], "execute()": [[13, "execute"]], "end(boolean interrupted)": [[13, "end-boolean-interrupted"]], "isFinished()": [[13, "isfinished"]], "Xbox Controls": [[13, "xbox-controls"]], "Motors": [[13, "motors"]], "Extra": [[13, "extra"]], "Preseason Training": [[14, "preseason-training"]], "Index by date": [[14, "index-by-date"]], "Git": [[15, "git"], [20, "git"]], "Cloning": [[15, "cloning"]], "Committing": [[15, "committing"]], "Pushing & Pulling": [[15, "pushing-pulling"]], "Switching branches": [[15, "switching-branches"]], "Merging": [[15, "merging"]], "Applications": [[16, "applications"]], "3 - Coprocessors": [[17, "coprocessors"]], "2 - C++ Programming": [[18, "c-programming"]], "Java / roboRIO Programming": [[19, "java-roborio-programming"]], "Library guides": [[19, "library-guides"]], "API references": [[19, "api-references"]], "Operating system": [[20, "operating-system"]], "GitHub CLI": [[20, "github-cli"]], "Git login": [[20, "git-login"]], "(Only for pre-season) Java": [[20, "only-for-pre-season-java"]], "FRC Game Tools": [[20, "frc-game-tools"]], "Phoenix Tuner X": [[20, "phoenix-tuner-x"]], "REV Hardware Client": [[20, "rev-hardware-client"]], "(Optional) Apache Maven": [[20, "optional-apache-maven"]], "4 - Linux": [[21, "linux"]], "5 - Robot design": [[22, "robot-design"]], "Style guide": [[23, "style-guide"]], "Naming": [[23, "naming"]], "Java": [[23, "java"]], "C++": [[23, "c"]], "Resources": [[24, "resources"]], "Documentation and other websites": [[24, "documentation-and-other-websites"]], "Team #2022 History": [[25, "team-2022-history"]], "Titan Algorithms": [[26, "titan-algorithms"]], "Titan Dashboard": [[27, "titan-dashboard"]], "AprilTag Detection": [[28, "apriltag-detection"]], "Reading Configuration": [[28, "reading-configuration"]], "Detection": [[28, "detection"]], "Multithreading": [[28, "multithreading"]], "How to run": [[29, "how-to-run"]], "What it does": [[29, "what-it-does"]], "OS Support": [[30, "os-support"]], "Building": [[30, "building"]], "Build Options": [[30, "build-options"]], "Configuration": [[30, "configuration"]], "Other Tools": [[30, "other-tools"]], "Localization": [[31, "localization"]], "Networking": [[32, "networking"]], "Why?": [[32, "why"]], "Limitations": [[32, "limitations"]], "C++ Client": [[32, "c-client"]], "Sending Information": [[32, "sending-information"], [32, "id3"]], "Sending Information (With Reply)": [[32, "sending-information-with-reply"], [32, "id4"]], "C Client": [[32, "id1"]], "Python Client": [[32, "python-client"]], "Java Server": [[32, "java-server"]], "Receiving Information": [[32, "receiving-information"]], "Titan Processing": [[33, "titan-processing"]], "Contributing": [[33, "contributing"]], "Titan Robotics #2022 Documentation": [[34, "titan-robotics-2022-documentation"]]}, "indexentries": {}}) \ No newline at end of file +Search.setIndex({"docnames": ["PreseasonTraining/2024CodeOverview/index", "PreseasonTraining/ControlTheoryBasics/index", "PreseasonTraining/ElectricalOverview/index", "PreseasonTraining/JavaBasics/BrainfInterpreter", "PreseasonTraining/JavaBasics/InventoryManager", "PreseasonTraining/JavaBasics/OldNotes", "PreseasonTraining/JavaBasics/WordleClone", "PreseasonTraining/JavaBasics/index", "PreseasonTraining/LEDProgramming/index", "PreseasonTraining/LinuxInstallation/index", "PreseasonTraining/OpenCV_ColorSegmentation/index", "PreseasonTraining/Overview/index", "PreseasonTraining/TankAutonomous/index", "PreseasonTraining/TankDriveSimulation/index", "PreseasonTraining/index", "Resources/Applications/git", "Resources/Applications/index", "Resources/Coprocessors/index", "Resources/CppProgramming/index", "Resources/JavaProgramming/index", "Resources/JavaProgramming/installation", "Resources/Linux/index", "Resources/RobotDesign/index", "Resources/StyleGuide", "Resources/index", "TeamHistory/index", "TitanAlgorithms/index", "TitanDashboard/index", "TitanProcessing/AprilTags/index", "TitanProcessing/Calibration/index", "TitanProcessing/Installation/index", "TitanProcessing/Localization/index", "TitanProcessing/Networking/index", "TitanProcessing/index", "index"], "filenames": ["PreseasonTraining/2024CodeOverview/index.md", "PreseasonTraining/ControlTheoryBasics/index.md", "PreseasonTraining/ElectricalOverview/index.md", "PreseasonTraining/JavaBasics/BrainfInterpreter.md", "PreseasonTraining/JavaBasics/InventoryManager.md", "PreseasonTraining/JavaBasics/OldNotes.md", "PreseasonTraining/JavaBasics/WordleClone.md", "PreseasonTraining/JavaBasics/index.md", "PreseasonTraining/LEDProgramming/index.md", "PreseasonTraining/LinuxInstallation/index.md", "PreseasonTraining/OpenCV_ColorSegmentation/index.md", "PreseasonTraining/Overview/index.md", "PreseasonTraining/TankAutonomous/index.md", "PreseasonTraining/TankDriveSimulation/index.md", "PreseasonTraining/index.md", "Resources/Applications/git.md", "Resources/Applications/index.md", "Resources/Coprocessors/index.md", "Resources/CppProgramming/index.md", "Resources/JavaProgramming/index.md", "Resources/JavaProgramming/installation.md", "Resources/Linux/index.md", "Resources/RobotDesign/index.md", "Resources/StyleGuide.md", "Resources/index.md", "TeamHistory/index.md", "TitanAlgorithms/index.md", "TitanDashboard/index.md", "TitanProcessing/AprilTags/index.md", "TitanProcessing/Calibration/index.md", "TitanProcessing/Installation/index.md", "TitanProcessing/Localization/index.md", "TitanProcessing/Networking/index.md", "TitanProcessing/index.md", "index.md"], "titles": ["2024 Code overview", "Control Theory Basics", "Electrical overview", "3 - Brainf interpreter", "1 - Inventory Manager", "Old notes from 2023", "2 - Wordle Clone", "Java Basics", "LED Programming", "Linux installation", "Color-based segmentation in OpenCV Python", "Programming Subteam Overview", "Tank Autonomous", "Tank Drive Simulation", "Preseason Training", "Git", "Applications", "3 - Coprocessors", "2 - C++ Programming", "Java / roboRIO Programming", "Installation", "4 - Linux", "5 - Robot design", "Style guide", "Resources", "Team #2022 History", "Titan Algorithms", "Titan Dashboard", "AprilTag Detection", "Calibration", "Installation", "Localization", "Networking", "Titan Processing", "Titan Robotics #2022 Documentation"], "terms": {"last": [0, 1, 10], "year": [0, 1], "everi": [0, 1, 5, 8, 10, 13, 15], "command": [0, 1, 3, 4, 5, 12, 19, 20, 23, 30], "subsystem": [0, 1, 23], "vision": [0, 10, 11, 13, 33], "qna": 0, "watch": 0, "old": [0, 1, 7, 14, 34], "match": [0, 13, 29, 30], "strategi": [0, 1, 34], "inspir": 0, "2024": [1, 2, 3, 4, 6, 8, 9, 10, 12, 13, 14, 20, 32, 33, 34], "octob": [1, 9, 10, 14], "22": [1, 32], "23": 1, "2": [1, 2, 5, 7, 8, 9, 10, 13, 14, 24, 30, 34], "5": [1, 3, 6, 13, 24, 32, 34], "hour": [1, 2, 3, 4, 6, 8], "slideshow": [1, 2, 3, 4, 6, 9, 10, 13], "probabl": 1, "most": [1, 8, 9, 10, 11, 13, 19, 20, 33], "import": [1, 3, 5, 6, 11, 23, 32], "subject": 1, "frc": [1, 5, 11, 14, 19, 24, 32, 34], "program": [1, 2, 5, 10, 14, 15, 20, 24, 34], "one": [1, 8, 9, 10, 13, 15, 20, 23, 32], "you": [1, 5, 6, 8, 9, 10, 12, 13, 15, 19, 20, 32, 33, 34], "should": [1, 9, 10, 11, 12, 13, 20, 29, 30], "consid": [1, 30], "top": [1, 9, 10, 23, 32], "prioriti": 1, "It": [1, 5, 9, 13, 20, 29, 33], "separ": [1, 10, 15], "well": 1, "perform": [1, 11, 32], "from": [1, 2, 7, 8, 9, 10, 14, 15, 20, 24, 30, 32, 34], "those": 1, "fail": 1, "earli": 1, "contrari": 1, "mani": [1, 20], "peopl": [1, 3, 5, 6], "assum": [1, 20], "aim": [1, 23], "optim": [1, 11], "reliabl": [1, 32], "instead": [1, 8, 15], "speed": [1, 13], "function": [1, 5, 8, 10, 13, 32], "At": [1, 13], "titan": [1, 5, 30, 32], "our": [1, 2, 5, 8, 10, 13, 20, 23, 30, 34], "curs": 1, "overengin": 1, "solut": [1, 30, 32], "do": [1, 8, 9, 10, 11, 13, 15, 19, 20], "than": [1, 5, 10], "we": [1, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14], "can": [1, 5, 8, 9, 10, 11, 12, 13, 15, 20, 32, 33, 34], "reason": [1, 10, 33], "achiev": [1, 10, 32], "lead": 1, "bare": 1, "ani": [1, 9, 13, 15, 20, 32], "time": [1, 5, 8, 9, 11, 12, 13, 15, 24, 32], "electr": [1, 14, 34], "test": [1, 23, 30, 32], "befor": [1, 15, 32], "competit": 1, "caus": [1, 9], "unforeseen": 1, "mechan": [1, 13], "issu": [1, 9, 30], "product": [1, 15, 30, 33], "yearli": 1, "present": 1, "team": [1, 3, 6, 11, 13, 23, 24, 34], "1678": 1, "citru": 1, "circuit": 1, "consist": [1, 5, 13, 23], "advis": 1, "other": [1, 5, 9, 10, 13, 15, 20, 29, 34], "stick": [1, 9], "even": [1, 24], "mean": [1, 10, 12, 33], "miss": 1, "out": [1, 3, 5, 6, 9, 10, 13, 20, 32], "strateg": 1, "advantag": 1, "thei": [1, 10, 13, 32], "often": [1, 10, 33], "illustr": 1, "thi": [1, 3, 4, 5, 8, 9, 10, 11, 12, 13, 15, 20, 23, 29, 32, 33], "discourag": 1, "swerv": 1, "drive": [1, 5, 9, 11, 12, 14, 23, 34], "without": [1, 8, 12, 15, 28, 30], "long": [1, 9], "term": 1, "experi": [1, 11, 15], "all": [1, 5, 8, 10, 11, 12, 13, 15, 20, 29, 30, 32, 34], "share": 1, "same": [1, 5, 10, 15, 32], "goal": [1, 10], "maxim": 1, "And": [1, 5], "so": [1, 8, 10, 12, 13, 20, 23, 30, 33], "side": [1, 13], "how": [1, 9, 11, 12, 20], "done": [1, 5, 12, 13], "biggest": [1, 10], "obstacl": 1, "which": [1, 5, 8, 9, 10, 12, 13, 15, 20, 28, 32], "prevent": [1, 9], "u": [1, 11], "complet": [1, 10, 12, 20], "solv": [1, 32], "nois": 1, "system": [1, 2, 3, 5, 6, 9, 30, 32], "have": [1, 5, 10, 11, 12, 13, 15, 19, 20, 32], "variabl": [1, 5, 8, 10, 13, 20, 23], "amount": [1, 11, 19], "bend": 1, "twist": 1, "slack": 1, "unwant": 1, "form": [1, 10], "temporari": [1, 32], "deform": 1, "rigid": 1, "object": [1, 5, 13, 28, 32], "also": [1, 5, 8, 9, 10, 12, 13, 20, 29, 34], "uniqu": [1, 10], "aspect": 1, "when": [1, 5, 8, 10, 12, 13, 20, 30], "compar": 1, "high": 1, "school": 1, "level": [1, 23, 32], "materi": 1, "properti": [1, 10], "start": [1, 9, 10, 12, 13, 15, 20, 29], "show": [1, 8, 32], "significantli": 1, "length": [1, 3], "mass": 1, "size": [1, 5, 6, 10, 29, 30], "unlik": [1, 10, 33], "compact": 1, "ftc": 1, "vex": 1, "simpl": [1, 4, 12], "contrapt": 1, "like": [1, 5, 10, 11, 12, 13, 30], "measur": 1, "tape": [1, 10], "2020": 1, "would": [1, 10, 13], "work": [1, 3, 6, 10, 11, 13, 15, 28], "becaus": [1, 33], "criteria": [1, 13], "scale": 1, "want": [1, 8, 9, 10, 12, 15, 20], "manuev": 1, "while": [1, 5, 6, 8, 10, 11, 29], "adapt": 1, "undesir": 1, "physic": [1, 10, 13], "field": [1, 10, 30], "appli": [1, 9], "mathemat": 1, "regard": [1, 19], "accuraci": 1, "respons": 1, "There": [1, 5, 12, 20, 30, 34], "ar": [1, 5, 8, 10, 13, 15, 20, 24, 29, 30, 32, 34], "two": [1, 3, 6, 8, 10, 11, 13, 14, 32], "type": [1, 5, 10, 20, 30, 32], "feedback": 1, "As": 1, "name": [1, 5, 10, 20, 30], "suggest": 1, "util": [1, 5, 6, 8, 10, 12, 13, 23, 29, 32], "input": [1, 5, 10, 15], "determin": [1, 29, 33], "an": [1, 2, 4, 5, 8, 10, 13, 14, 15, 20, 28, 33], "output": [1, 10, 12, 13], "back": [1, 15, 20, 32], "henc": 1, "its": [1, 10, 13, 20, 32], "second": [1, 8, 10, 11, 12, 13, 15, 28, 32], "exampl": [1, 5, 12, 13, 20, 28, 30, 32], "boil": 1, "water": 1, "ga": 1, "stove": 1, "certain": [1, 5, 13], "onli": [1, 5, 8, 10, 11, 12, 13, 15, 30, 32], "care": [1, 9], "about": [1, 8, 10, 13, 24], "volum": 1, "user": [1, 5], "select": [1, 8, 9, 15, 20, 30], "doe": [1, 10, 11, 32], "whether": [1, 28], "temperatur": 1, "regul": 1, "air": 1, "condition": 1, "hvac": 1, "fed": 1, "new": [1, 3, 5, 6, 8, 12, 13, 32], "eventu": 1, "adjust": 1, "room": 1, "desir": 1, "depend": 1, "dc": 1, "motor": [1, 5, 11, 12, 20], "rotat": [1, 12, 30, 32], "possibl": [1, 23, 33], "take": [1, 10, 30], "account": [1, 9, 20, 32], "encod": 1, "valu": [1, 8, 10, 13, 29, 30, 32], "comput": [1, 9, 10, 11, 13], "enough": [1, 8, 13, 32], "voltag": 1, "feed": [1, 10, 28], "proport": 1, "integr": 1, "deriv": 1, "common": [1, 10], "allow": [1, 13, 15, 30, 32], "tweak": 1, "three": [1, 10, 12], "constant": [1, 10, 23, 32], "coeffici": [1, 10, 29, 30], "state": [1, 8], "increas": 1, "effici": 1, "lower": [1, 5], "undershoot": 1, "overshoot": 1, "imagin": [1, 13], "try": [1, 3, 6, 10, 13, 15, 20, 30, 33], "car": [1, 5], "locat": [1, 10], "straight": 1, "slipperi": 1, "poorli": 1, "construct": 1, "road": 1, "call": [1, 8, 9, 12, 13, 15, 28, 32], "your": [1, 8, 9, 10, 12, 13, 15, 20, 30, 32, 33], "destin": 1, "": [1, 5, 8, 9, 10, 11, 12, 13, 15, 20, 23, 30], "r": [1, 5], "t": [1, 9, 10, 11, 12, 13, 15, 20], "setpoint": 1, "know": [1, 9, 10, 11, 20], "y": [1, 8, 10, 13, 20, 29], "These": [1, 20, 24], "process": [1, 13, 20, 28, 29, 30, 32, 34], "e": [1, 5, 6, 20, 23], "differ": [1, 10, 15], "between": [1, 13, 32], "current": [1, 9, 20, 30, 32], "posit": [1, 10, 30, 32], "go": [1, 8, 15], "equat": [1, 8], "int_0": 1, "tau": 1, "d": [1, 9], "frac": 1, "de": 1, "dt": 1, "where": [1, 10], "distanc": 1, "tell": [1, 20], "isn": [1, 20], "too": [1, 9, 28], "understand": 1, "math": [1, 8, 10], "send": [1, 8, 13, 20, 28], "wait": [1, 8, 9], "until": [1, 8, 13], "figur": [1, 9, 10, 13], "after": [1, 5, 8, 9, 10, 11, 15, 24], "tri": [1, 32], "Then": [1, 5, 9, 10, 32], "repeat": [1, 8], "idea": [1, 32], "sai": [1, 20], "campground": 1, "mile": [1, 5], "down": [1, 9, 13], "acceler": 1, "don": [1, 9, 10, 12, 13, 15, 20], "few": 1, "gener": [1, 30], "usual": 1, "set": [1, 8, 10, 12, 13, 19, 20], "0": [1, 3, 5, 6, 8, 9, 10, 13, 20, 29, 32], "manual": [1, 9, 30, 32], "none": 1, "tend": 1, "drastic": 1, "note": [1, 7, 10, 14, 32, 34], "anoth": [1, 8, 9, 10, 32], "less": [1, 32], "factor": 1, "data": [1, 10, 32], "frequenc": 1, "sinc": [1, 8, 9, 10, 12, 13, 23, 32, 33], "discret": 1, "model": [1, 33], "delta": 1, "result": [1, 5, 6, 8, 13, 20], "better": 1, "calcul": [1, 8], "implement": 1, "falcon": [1, 13, 20], "500": [1, 13, 20], "being": [1, 8, 10], "drivebas": [1, 12], "wheel": [1, 13], "arm": [1, 13, 23], "elev": 1, "etc": [1, 5, 9], "ideal": [1, 10], "through": [1, 4, 8, 11, 12, 13, 19, 28, 33], "correctli": 1, "behind": 1, "necessari": [1, 8, 10, 20, 29, 30, 33], "learn": [1, 15, 24], "articl": [1, 10], "wpilib": [1, 5, 11, 19, 20, 23, 32], "document": [1, 19, 23, 29, 32], "explain": 1, "includ": [1, 5, 10, 13, 15, 20, 23, 30, 32, 33], "pidcontrol": 1, "class": [1, 3, 5, 6, 13, 23, 28, 32], "see": [1, 5, 8, 10, 12, 20, 32], "interact": [1, 10], "here": [1, 8, 10, 11, 13, 15, 30, 34], "circl": [1, 10], "attempt": [1, 6, 10], "itself": [1, 13], "under": [1, 8, 20], "cursor": 1, "interest": [1, 8], "websit": [1, 20], "simul": [1, 14, 34], "cart": 1, "balanc": [1, 13], "veloc": [1, 13], "bookmark": 1, "behavior": 1, "sometim": [1, 9], "benefici": 1, "add": [1, 5, 6, 12, 13, 20], "compon": [1, 13, 19], "compens": 1, "specif": [1, 8, 10, 15, 20, 33], "circumst": 1, "pidf": 1, "code": [1, 5, 8, 10, 11, 14, 15, 20, 23, 30, 33, 34], "friction": 1, "incredibli": 1, "multipli": [1, 8], "cw": 1, "yapathon": 1, "ahead": [1, 19], "A": [1, 5, 13, 15], "affect": 1, "softwar": [1, 10, 11, 13, 20, 34], "introduc": [1, 4], "axi": [1, 13], "sever": [1, 8, 10], "impact": 1, "belt": 1, "slippag": 1, "gearbox": 1, "misalign": 1, "sensor": [1, 5], "signal": [1, 8, 32], "deal": 1, "graviti": 1, "weight": 1, "torqu": 1, "cannot": [1, 13], "imposs": 1, "make": [1, 4, 5, 8, 9, 10, 11, 12, 15, 20, 29, 30, 32], "perfect": [1, 10], "best": [1, 10, 11, 30], "minim": 1, "dure": [1, 4, 11, 13], "them": [1, 8, 9, 10, 13, 15], "If": [1, 5, 8, 9, 15, 20], "contain": [1, 5, 6, 10, 12, 13, 15, 19], "place": [1, 13], "closest": 1, "gear": 1, "requir": [1, 10, 13, 15, 30, 33], "toler": 1, "repres": [1, 10], "raw": [1, 20, 30], "alreadi": [1, 12, 15, 20], "librari": [1, 5, 8, 10, 20, 28, 30, 32, 33], "filter": [1, 33], "variou": [1, 10], "method": [1, 5, 8, 10, 12, 13, 23, 28, 32], "cover": [1, 10, 12, 13], "some": [1, 8, 9, 10, 13, 19, 20, 34], "later": [1, 10, 20], "But": [1, 8], "ultim": 1, "direct": [1, 13], "wai": [1, 10, 12, 20, 30, 32], "need": [1, 9, 10, 11, 12, 13, 15, 20], "unpredict": 1, "creat": [1, 5, 8, 10, 12, 13, 15, 20, 32, 33], "plan": [1, 30], "instinct": 1, "recreat": 1, "geometr": 1, "draw": [1, 10], "diagram": 1, "imsa": [1, 5], "previous": 1, "real": [1, 8, 13], "world": 1, "invers": 1, "kinemat": [1, 19], "base": [1, 12, 13, 14, 19, 20, 34], "accur": [1, 29], "weren": 1, "defin": [1, 8], "rang": [1, 8, 10], "appear": 1, "although": [1, 10, 32], "theoret": 1, "still": 1, "veri": 1, "applic": [1, 10, 24, 34], "hard": [1, 11], "describ": 1, "much": [1, 10, 11, 13, 23], "potenti": 1, "error": [1, 10], "won": 1, "predict": 1, "combin": 1, "reduc": [1, 11], "ad": [1, 5, 20], "step": [1, 15], "great": [1, 20], "simplest": [1, 10], "constraint": 1, "remov": [1, 9, 15], "unnecessari": [1, 10], "approach": 1, "move": [1, 13], "degre": [1, 10, 12, 30], "freedom": 1, "precis": 1, "hold": [1, 29], "heavi": 1, "perhap": 1, "mai": [1, 29], "total": 1, "throughout": 1, "entir": [1, 19], "game": [1, 11, 13, 32], "mayb": 1, "actual": [1, 8, 13], "suitabl": 1, "ha": [1, 5, 8, 9, 10, 11, 13, 15, 19, 32], "higher": [1, 20], "pullei": 1, "easier": [1, 13], "energi": 1, "counter": [1, 13], "consider": 1, "power": [1, 9], "usag": [1, 15, 30], "faster": 1, "case": [1, 3, 5, 8, 23], "action": [1, 10, 15], "run": [1, 5, 8, 9, 12, 13, 20, 30], "nearest": 1, "member": [1, 5, 15, 20, 23], "ruin": 1, "dream": 1, "attach": 1, "custom": [1, 11], "might": [1, 9, 10, 20, 24], "stuck": 1, "predetermin": 1, "beforehand": 1, "tabl": [1, 32], "static": [1, 3, 5, 6, 8], "angl": [1, 10, 30], "seem": 1, "onc": [1, 8, 13, 15], "realiz": 1, "batteri": 1, "get": [1, 5, 6, 10, 20, 32], "exponenti": 1, "difficult": [1, 10], "now": [1, 8, 12, 20], "decid": 1, "strain": 1, "movement": 1, "occurr": 1, "week": 1, "come": [1, 9], "up": [1, 3, 5, 6, 8, 9, 10, 13, 14], "over": [1, 10, 28], "who": [1, 3, 6], "singlehandedli": 1, "wrote": [1, 23], "sick": 1, "far": [1, 13], "simpler": 1, "debug": [1, 13, 20, 30], "estim": [1, 29], "section": 1, "exagger": 1, "encount": 1, "neg": 1, "outcom": 1, "season": [1, 10, 13, 33], "simpli": [1, 13, 24], "challeng": 1, "pandem": 1, "taken": [1, 4], "toll": 1, "signific": 1, "knowledg": 1, "connect": [1, 8, 10, 20], "been": [1, 9], "lost": [1, 12, 32], "each": [1, 5, 8, 10, 12, 13, 15, 29, 32], "improv": 1, "retel": 1, "event": 1, "occur": [1, 10], "2022": [1, 20], "2023": [1, 7, 14, 33, 34], "write": [1, 9, 10, 13, 15], "wa": [1, 20, 32], "limit": [1, 20], "encourag": 1, "chiefdelphi": 1, "post": 1, "purpos": [1, 8, 10, 13], "regain": 1, "skill": 1, "everyon": [1, 4, 13, 15], "els": [1, 5, 6, 8, 23, 30], "proper": 1, "strongli": 1, "recommend": [1, 10, 20, 24], "least": [1, 9], "chapter": 1, "book": 1, "inform": [1, 10, 12, 13], "essenti": 1, "classic": 1, "calculu": 1, "linear": 1, "algebra": 1, "prerequisit": 1, "kalman": [1, 33], "bc": 1, "sequenc": 1, "mvc": 1, "linalg": 1, "entireti": 1, "abov": [1, 4, 30], "major": [1, 19], "programm": [1, 11, 19], "particular": 1, "repositori": [1, 12, 13, 15], "sourc": [1, 9, 15, 24], "repo": [1, 15, 20, 30], "provid": [1, 8, 28, 29], "extend": [1, 10, 13, 33], "http": [1, 9, 15, 20, 30], "wikimedia": 1, "org": [1, 9], "wiki": [1, 19], "file": [1, 3, 9, 10, 11, 12, 13, 15, 20, 23, 29, 30, 32], "pid_en": 1, "svg": 1, "arturo": 1, "urquizo": 1, "pid_varyingp": 1, "jpg": 1, "timmmyk": 1, "change_with_ki": 1, "png": 1, "skorkmaz": 1, "change_with_kd": 1, "septemb": [2, 3, 4, 6, 8, 12, 13, 14], "25": [2, 14], "introduct": [2, 14], "robot": [2, 11, 12, 13, 20, 24, 32, 33], "perspect": [2, 10], "11": [3, 6, 14, 20], "1": [3, 5, 6, 7, 8, 9, 10, 13, 14, 20, 30, 34], "split": [3, 5, 6, 14], "group": [3, 6, 10, 12, 13, 14, 23], "The": [3, 5, 6, 8, 19, 20, 23, 28, 29, 32, 33], "were": [3, 6], "java": [3, 4, 5, 6, 10, 11, 12, 13, 14, 24, 30, 34], "wordl": [3, 7, 14, 34], "clone": [3, 7, 12, 13, 14, 34], "more": [3, 5, 6, 10, 12, 13, 20, 24, 32], "familiar": [3, 6], "main": [3, 5, 6, 9, 10, 13, 15, 20, 30, 33], "public": [3, 5, 6, 12, 13, 23], "void": [3, 5, 6, 8, 13], "string": [3, 5, 6, 13, 28], "arg": [3, 5, 6], "brainfuckread": 3, "reader": [3, 6], "getcod": 3, "brainfuckinterpret": 3, "io": [3, 6], "nio": 3, "filenam": 3, "return": [3, 6, 8, 10, 13, 20, 32], "readstr": 3, "topath": 3, "catch": [3, 6], "except": [3, 6], "err": [3, 6], "println": [3, 5, 6, 32], "char": [3, 6], "memori": 3, "3000": 3, "int": [3, 5, 6, 8, 28, 32], "posrightbracketforleftbracket": 3, "datapoint": 3, "posleftbracket": 3, "i": [3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 15, 20, 23, 28, 30, 32, 33], "charat": [3, 6], "switch": [3, 13], "break": [3, 6, 10, 15], "default": [3, 9, 20, 28, 32], "print": [3, 5, 10, 29, 30], "10": [4, 5, 10, 14, 20, 30, 32], "project": [4, 8, 11, 13, 15, 20, 28, 30, 32, 34], "consol": [4, 10], "follow": [4, 9, 10, 13, 20, 23, 24, 30, 32], "along": 4, "meet": 4, "first": [4, 8, 9, 10, 12, 13, 15, 19, 20, 28, 29, 32], "led": [4, 14, 34], "what": [5, 9, 11], "jit": 5, "compil": [5, 20, 33], "just": [5, 8, 10, 12, 13], "In": [5, 8, 9, 10, 13], "languag": [5, 8], "bytecod": 5, "translat": [5, 10], "machin": 5, "target": [5, 9, 33], "platform": [5, 13, 15, 30], "cross": [5, 30], "c": [5, 13, 24, 30, 34], "directli": 5, "g": [5, 20, 23], "integ": [5, 6, 8, 10], "number": [5, 8, 13], "doubl": [5, 12, 32], "decim": [5, 8], "text": [5, 6], "primit": 5, "basic": [5, 14, 19, 29, 34], "upper": 5, "complex": 5, "next": [5, 12, 15, 20], "orient": [5, 13], "everyth": [5, 12, 30], "constructor": [5, 13, 28], "modifi": [5, 13], "privat": [5, 6, 13, 23], "readonli": 5, "thing": [5, 8, 10, 15], "access": [5, 8, 10, 11, 13, 23], "insid": [5, 10, 12, 13, 15, 30], "instanc": [5, 8, 13], "cant": 5, "creation": 5, "btw": 5, "attribut": 5, "python": [5, 8, 14, 29, 30, 34], "engin": 5, "float": [5, 8], "fuel": 5, "unit": 5, "gallon": 5, "mileag": 5, "x": [5, 8, 9, 10, 11, 12, 13, 29, 30], "drivecar": 5, "33": 5, "per": [5, 30], "addfuel": 5, "hondaciv": 5, "brand": 5, "zero": [5, 10], "0f": 5, "fill": 5, "30": 5, "drove": 5, "typic": [5, 10, 13, 15], "written": [5, 33], "standard": [5, 8, 10, 32], "us": [5, 8, 9, 10, 11, 12, 13, 15, 20, 24, 29, 30, 32, 33], "stuff": 5, "gyroscop": 5, "manufactur": 5, "own": [5, 30, 33], "reusabl": 5, "algorithm": [5, 33, 34], "walkthrough": 5, "practic": 5, "inventori": [5, 7, 14, 34], "manag": [5, 7, 9, 11, 14, 20, 34], "item": 5, "quantiti": 5, "arraylist": [5, 6], "additem": 5, "search": [5, 9, 10, 20], "queri": 5, "ye": 5, "n": [5, 30], "window": [5, 9, 10, 20, 28, 30], "special": [5, 13], "charact": 5, "line": [5, 10, 12], "scanner": [5, 6], "automat": [5, 10, 15], "vscode": [5, 11, 15, 20], "inventorymanag": 5, "welcom": [5, 34], "No": 5, "space": [5, 9, 10, 11, 30], "find": [5, 9, 34], "exit": [5, 10], "leav": [5, 32], "record": 5, "inputscann": [5, 6], "loop": [5, 8, 10], "condit": [5, 8, 10, 12], "true": [5, 6, 13, 20, 32], "boolean": [5, 6], "isrun": [5, 6], "userinput": [5, 6], "nextlin": [5, 6], "splittedcommand": 5, "arrai": [5, 8, 32], "word": [5, 6], "startswith": 5, "fals": [5, 6, 8, 10, 13, 32], "count": 5, "convert": [5, 8, 32], "newitem": 5, "parseint": 5, "unknown": 5, "brainf": [6, 7, 14, 34], "interpret": [6, 7, 14, 34], "word_length": 6, "3": [6, 7, 10, 13, 14, 24, 30, 34], "max_attempt": 6, "9999999": 6, "wordleread": 6, "secretword": 6, "getrandomword": 6, "equal": 6, "congrat": 6, "guess": 6, "matchingindec": 6, "letter": [6, 20, 29], "turngreen": 6, "indexof": 6, "turnyellow": 6, "random": 6, "randgen": 6, "currenttimemilli": 6, "fileinputstream": 6, "fstream": 6, "txt": 6, "datainputstream": 6, "bufferedread": 6, "br": 6, "inputstreamread": 6, "strline": 6, "readlin": 6, "null": [6, 9, 32], "close": [6, 10, 13, 29], "nextint": 6, "tolowercas": 6, "wordexist": 6, "42m": 6, "0m": 6, "43m": 6, "4": [8, 14, 24, 30, 34], "lesson": [8, 10], "strip": 8, "microcontrol": 8, "arduino": 8, "uno": 8, "wokwi": 8, "onlin": [8, 9, 10, 15, 20], "emul": 8, "substitut": [8, 11], "board": [8, 30], "turn": [8, 12], "infinit": 8, "For": [8, 10, 13, 20, 30], "100": [8, 9], "light": [8, 9, 11], "displai": [8, 13, 20, 29], "open": [8, 9, 10, 15, 20, 28], "tab": [8, 15], "fastl": 8, "control": [8, 11, 12, 14, 15, 20, 34], "clear": 8, "pixel": [8, 10, 29], "empti": [8, 13], "earlier": 8, "bracket": 8, "oper": [8, 9, 33], "chsv": 8, "hue": [8, 10], "satur": [8, 10], "crgb": 8, "red": [8, 10], "green": [8, 10, 11, 15], "blue": [8, 10, 15], "color": [8, 14, 29, 34], "rgb": [8, 10], "both": [8, 20, 30], "255": [8, 10], "8": [8, 10, 14, 20, 30], "byte": [8, 10], "blank": [8, 32], "updat": [8, 9, 10, 15, 24, 32], "num_l": 8, "th": 8, "iter": 8, "divis": 8, "divid": 8, "progress": [8, 12], "To": [8, 10, 13, 15, 20, 30, 33], "delai": [8, 32], "millisecond": 8, "similar": [8, 20], "sleep": [8, 9], "fast": 8, "list": [8, 9, 15, 20], "notabl": 8, "featur": [8, 10, 15], "forev": [8, 12], "statement": [8, 12, 32], "thing1": 8, "thing2": 8, "funciton": 8, "1000": 8, "modulo": 8, "number0": 8, "remaind": 8, "sin": 8, "co": 8, "tan": 8, "pow": 8, "sqrt": 8, "log": [8, 20], "natur": 8, "log10": 8, "hsv": [8, 10], "support": [8, 9, 19, 20, 32], "download": [8, 9, 10, 11, 15, 20], "desktop": [8, 9], "version": [8, 9, 13, 20, 33], "id": [8, 9, 13, 20, 30, 32], "usb": [8, 9, 11], "port": [8, 20, 30, 32], "tool": [8, 29], "click": [8, 15, 20], "upload": [8, 15], "intro": 9, "kde": 9, "live": 9, "iso": 9, "cdimag": 9, "cd": [9, 30], "amd64": [9, 20], "hybrid": 9, "12": [9, 10, 20, 30], "7": 9, "read": [9, 10, 19], "flash": 9, "onto": 9, "On": [9, 10, 13, 20], "instruct": [9, 20], "rufu": 9, "app": [9, 20], "free": [9, 10, 13, 15, 20, 30], "disk": 9, "menu": [9, 15], "ll": 9, "50": [9, 13], "gb": 9, "200": 9, "prefer": [9, 20], "disabl": [9, 11], "bitlock": 9, "guid": [9, 10, 15, 24, 30, 34], "sure": [9, 10, 12, 20, 29], "microsoft": [9, 10, 20], "password": 9, "associ": 9, "recoveri": 9, "kei": [9, 10, 13], "paper": [9, 29], "plug": [9, 11], "imag": 9, "reboot": 9, "spam": [9, 20], "appropri": [9, 10], "hotkei": 9, "bio": 9, "soon": 9, "laptop": [9, 20], "esc": [9, 10], "f2": 9, "f10": 9, "boot": 9, "secur": 9, "technic": 9, "o": [9, 20], "approv": 9, "someon": [9, 23], "sold": 9, "sign": [9, 11], "save": [9, 15, 29], "ask": [9, 10, 11, 13, 20], "session": [9, 20], "enter": [9, 11, 13, 15, 20], "left": [9, 13, 29], "calamar": 9, "termin": [9, 12, 13, 20], "prompt": 9, "goe": 9, "usernam": [9, 12, 13, 20], "arrow": [9, 13], "screen": [9, 13], "sudo": [9, 20, 30], "nano": 9, "edit": [9, 13, 30], "ctrl": 9, "order": [9, 12], "merg": [9, 12, 33], "configur": [9, 13, 20], "bootload": 9, "hardwar": [9, 11], "recent": 9, "nonfre": 9, "amd": [9, 20], "graphic": [9, 10], "misc": 9, "intel": [9, 20, 30], "nvidia": 9, "mediatek": 9, "packag": [9, 30], "buster": 9, "backport": 9, "devic": [9, 20], "shell": [9, 20], "l": [9, 20], "dev": [9, 28], "got": 9, "sda": 9, "right": [9, 13], "usbstick": 9, "mkdir": [9, 30], "p": 9, "mnt": 9, "mount": 9, "apt": [9, 20, 30], "deb": [9, 30], "tee": 9, "eof": 9, "bookworm": 9, "9": [10, 14, 32], "store": [10, 11, 20], "linux": [10, 11, 14, 20, 24, 30, 34], "preinstal": 10, "ping": [10, 12], "georgi": [10, 20], "ethan": [10, 20], "help": [10, 12, 13, 30], "pip": 10, "contrib": [10, 30], "partit": 10, "entiti": 10, "background": 10, "detect": [10, 33, 34], "format": 10, "convini": 10, "monitor": [10, 11], "human": 10, "represent": 10, "largest": 10, "extens": [10, 20], "alwai": [10, 11, 15, 24], "multipl": [10, 30], "someth": 10, "commonli": 10, "Its": 10, "modul": [10, 23, 30, 33], "re": [10, 20], "hidden": 10, "impli": 10, "initi": [10, 12, 28, 32, 33], "ones": 10, "specifi": [10, 12, 28, 29, 32], "pre": 10, "train": [10, 34], "design": [10, 11, 13, 24, 34], "explicit": [10, 33], "syntax": 10, "look": [10, 12, 20], "w3school": 10, "visual": [10, 30], "studio": [10, 30], "button": [10, 13, 15], "shortcut": 10, "structur": [10, 11, 32], "info": 10, "outlin": [10, 23], "accross": 10, "choos": [10, 20], "bright": 10, "pacakg": 10, "keyword": [10, 30], "shorten": 10, "readibl": 10, "np": 10, "cv2": 10, "cv": 10, "webcam": 10, "claim": 10, "captur": 10, "argument": [10, 13, 28, 32], "index": [10, 28], "unless": [10, 20], "almost": [10, 13], "templat": [10, 12, 13], "cap": 10, "videocaptur": 10, "isopen": 10, "_": 10, "todo": 10, "quit": 10, "q": 10, "press": [10, 11, 13, 15, 20], "otherwis": [10, 15, 20], "kill": 10, "extern": [10, 13, 19], "waitkei": 10, "ord": 10, "releas": [10, 20, 33], "destroyallwindow": 10, "imshow": 10, "correspond": 10, "titl": 10, "keep": [10, 23], "bgr": 10, "properli": 10, "your_fram": 10, "arr": 10, "np_arr": 10, "pretti": [10, 13], "page": [10, 20, 32, 34], "new_fram": 10, "cvtcolor": 10, "color_bgr2rgb": 10, "color_bgr2grai": 10, "grayscal": 10, "color_bgr2hsv": 10, "hide": 10, "part": [10, 11], "sens": 10, "unsign": 10, "inclus": 10, "inrang": 10, "lower_threshold": 10, "upper_threshold": 10, "white": 10, "full": [10, 13, 15, 23, 30], "exclud": 10, "black": 10, "exist": [10, 12, 20], "imaag": 10, "countour": 10, "origin": [10, 15], "drawcontour": 10, "respect": [10, 33], "fourth": 10, "width": [10, 30], "findcontour": 10, "retr_extern": 10, "chain_approx_simpl": 10, "lens": 10, "individu": 10, "view": [10, 15], "avail": [10, 20, 32, 34], "script": [10, 20, 29, 30], "scan": 10, "aruco": [10, 30], "chessboard": 10, "known": 10, "diment": [10, 29], "matrix": [10, 30], "distort": [10, 29, 30], "flat": [10, 29], "surfac": [10, 29], "pictur": [10, 30], "approxim": 10, "20": [10, 30, 32], "copi": [10, 12, 15, 20, 32], "feel": [10, 13, 15, 20, 30], "expand": 10, "obtain": 10, "2d": 10, "vertic": 10, "point": [10, 11, 13], "given": 10, "sphere": 10, "radiu": 10, "trigonometri": 10, "depth": 10, "3d": [10, 32], "wikipedia": 10, "resourc": [10, 34], "smoothest": 11, "driver": [11, 13], "think": 11, "wast": 11, "autom": 11, "task": [11, 14], "score": 11, "autonom": [11, 13, 14, 34], "15": [11, 13], "period": [11, 13], "good": [11, 32], "bad": 11, "github": [11, 15, 30], "bild": 11, "coprocessor": [11, 24, 32, 33, 34], "roborio": [11, 13, 24, 32, 34], "ethernet": 11, "wifi": 11, "station": [11, 13], "emerg": 11, "stop": [11, 12, 20], "restart": 11, "enabl": 11, "again": [11, 12], "phoenix": [11, 13, 19], "tuner": 11, "non": 11, "rememb": [11, 15], "fly": 11, "di": 11, "pleas": [11, 15, 20, 23], "link": [11, 15, 30], "cheatsheet": [11, 15], "rev": 11, "client": 11, "git": [11, 16, 24, 33, 34], "homework": 11, "titan2022": [12, 13], "training2024": [12, 13], "haven": 12, "previou": 12, "afterward": [12, 13, 20], "branch": [12, 13, 32, 33], "auton": 12, "tankdrivesubsystem": [12, 13], "driveleft": 12, "driveright": 12, "18": [12, 14], "tankcontrolcommand": [12, 13], "movecommand": 12, "teleop": [12, 13], "four": [12, 13, 29], "end": 12, "timeout": 12, "withtimeout": 12, "sequentialcommandgroup": 12, "pass": [12, 13, 28, 32], "schedul": [12, 13], "finish": [12, 13], "autonomousinit": [12, 13], "routin": [12, 14, 23], "element": 12, "found": [12, 13, 15, 30], "discard": 12, "chang": [12, 13, 15, 29], "off": 12, "mb": 12, "90": 12, "fine": [12, 20], "me": [12, 13], "squar": [12, 29], "17": [13, 14, 20], "sim": 13, "folder": [13, 15, 23, 32], "worri": 13, "entri": [13, 20], "src": 13, "mimic": 13, "serv": 13, "shooter": 13, "shoot": 13, "intak": 13, "pick": 13, "piec": 13, "local": [13, 15, 20, 23, 28, 33, 34], "oop": 13, "pattern": [13, 29], "timedrobot": 13, "overrid": 13, "robotinit": 13, "robotperiod": 13, "autonomousperiod": 13, "teleopinit": 13, "teleopperiod": 13, "disabledinit": 13, "player": 13, "rest": 13, "teleoper": 13, "mode": 13, "init": [13, 20], "20m": 13, "todai": 13, "tomorrow": 13, "assign": 13, "subsystembas": 13, "tankdriv": 13, "alongsid": 13, "One": 13, "wasd": 13, "joystick": 13, "keyboard": 13, "xboxcontrol": 13, "mycommand": 13, "getleftx": 13, "getlefti": 13, "getrightx": 13, "getrighti": 13, "getxbutton": 13, "getxbuttonpress": 13, "getxbuttonreleas": 13, "talon": 13, "fx": 13, "wpi_talonfx": 13, "differenti": 13, "ctre": [13, 19, 20], "api": 13, "6": [13, 19, 20], "motor0": 13, "controlmod": 13, "percentoutput": 13, "max": [13, 20], "m": 13, "setinvert": 13, "clockwis": 13, "slow": 13, "life": 13, "never": [13, 20], "anywher": 13, "percentag": 13, "smartdashboard": 13, "dashboard": [13, 34], "putnumb": 13, "putbooleam": 13, "putstr": 13, "style": [13, 24, 34], "six": 13, "togeth": [13, 15], "ident": 13, "around": 13, "plai": 13, "content": 13, "subteam": [14, 34], "overview": [14, 34], "tank": [14, 34], "instal": [14, 19, 24, 33, 34], "segment": [14, 34], "opencv": [14, 30, 34], "theori": [14, 34], "easi": 14, "harder": 14, "24": 14, "short": [15, 24], "cli": 15, "host": 15, "master": [15, 20, 30], "messag": [15, 33], "fetch": 15, "option": 15, "dublic": 15, "independ": 15, "past": [15, 20], "descript": 15, "readi": 15, "sync": 15, "addit": 15, "check": [15, 20, 24, 29], "bar": 15, "addion": 15, "checkout": 15, "notifi": 15, "avoid": 15, "conflict": 15, "particularli": 15, "big": 15, "request": [15, 33], "offici": [19, 20, 30, 32, 33, 34], "navx2": 19, "odometri": 19, "pathplann": [19, 23], "edu": 19, "wpi": 19, "com": [19, 20, 30], "phoenix6": 19, "pathplannerlib": 19, "lib": 19, "revlib": 19, "revrobot": 19, "troubl": 20, "reach": 20, "veteran": 20, "discord": 20, "64": 20, "bit": 20, "cpu": 20, "panel": 20, "box": 20, "either": 20, "32": 20, "arm64": 20, "distribut": 20, "glibc": 20, "popular": 20, "distro": 20, "debian": [20, 30], "ubuntu": 20, "mint": 20, "arch": 20, "elementari": 20, "fedora": 20, "enterpris": 20, "suse": 20, "maco": [20, 30], "mac": 20, "appl": 20, "silicon": 20, "choic": 20, "standalon": 20, "homebrew": 20, "brew": 20, "macport": 20, "doesn": 20, "matter": 20, "thread": [20, 30], "organ": 20, "my": 20, "powershel": 20, "bash": 20, "gh": 20, "auth": 20, "web": 20, "browser": 20, "jdk": 20, "develop": 20, "kit": 20, "temurin": 20, "lt": 20, "msi": 20, "bashrc": 20, "export": 20, "path": [20, 28, 29, 30], "home": 20, "bin": 20, "java_hom": 20, "bash_profil": 20, "zprofil": 20, "suit": 20, "doc": 20, "trial": 20, "realiti": 20, "winrar": 20, "shouldn": 20, "interfer": 20, "must": 20, "x11": [20, 28], "wayland": 20, "network": [20, 30, 33, 34], "curl": [20, 30], "githubusercont": 20, "ethanc8": [20, 30], "frclinuxdevkit": 20, "sh": 20, "vscodium": 20, "environ": 20, "fldk_install_ext_destin": 20, "launch": 20, "binari": [20, 30], "oss": 20, "yourself": 20, "codium": 20, "super": 20, "experiment": 20, "abl": 20, "diagnost": 20, "kind": 20, "involv": 20, "peripher": 20, "android": 20, "rootf": 20, "userspac": 20, "ca": 20, "certif": 20, "waydro": 20, "waydroid": 20, "prop": 20, "persist": 20, "multi_window": 20, "wget": 20, "someblob": 20, "x_2024": 20, "0_apkcombo": 20, "apk": 20, "phoenix_tun": 20, "unfortun": 20, "spark": 20, "experienc": 20, "wish": 20, "contribut": 20, "titanalgorithm": 20, "especi": 23, "lot": 23, "refer": [23, 32, 33], "pascalcas": 23, "macro_cas": 23, "m_camelcas": 23, "camelcas": 23, "enum": 23, "pascalcasetest": 23, "pascalcasesubsystem": 23, "abstract": 23, "pascalcasecommand": 23, "cpp": 23, "hpp": 23, "test_camelcas": 23, "cmake": [23, 30], "projecct": 23, "subfold": 23, "relat": [23, 24, 34], "auto": 23, "reus": 23, "topic": 24, "writ": 24, "irrelev": 24, "configread": 28, "readfromfil": 28, "std": 28, "directori": [28, 30, 32], "config": [28, 29, 30], "load": 28, "rel": 28, "root": 28, "absolut": 28, "titanprocess": 28, "apriltagdetector": 28, "stream": [28, 30, 32], "pose": [28, 29, 32, 33], "packet": [28, 32], "udp": [28, 30, 32], "networkingcli": [28, 32], "posefilt": 28, "video": [28, 32], "bool": 28, "marker": 29, "cm": 29, "type_calibr": 29, "py": [29, 30, 32], "TO": [29, 30], "cfg": 29, "front": 29, "camera": [29, 30], "recogn": 29, "overlai": 29, "logic": 29, "focal": 29, "resolut": 29, "optic": 29, "center": 29, "apriltag": [29, 30, 33, 34], "aarch64": 30, "x86_64": 30, "msvc": 30, "mingw": 30, "clang": 30, "calibr": [30, 33, 34], "submodul": 30, "realsens": 30, "sdk": 30, "googletest": 30, "framework": 30, "json": 30, "modern": 30, "vcpkg": 30, "scratch": 30, "execut": 30, "ol": 30, "titanian": 30, "pool": 30, "v": 30, "vcpkg_2023": 30, "titan2022_amd64": 30, "nlohmann": 30, "makefil": 30, "ninja": 30, "toolchain": 30, "altern": 30, "b": 30, "dcmake_toolchain_fil": 30, "buildsystem": 30, "dbuild_exampl": 30, "forc": 30, "clangd": 30, "dcmake_export_compile_command": 30, "dcmake_build_typ": 30, "relwithdebinfo": 30, "gninja": 30, "j": 30, "dno_realsens": 30, "compat": 30, "ip": [30, 32], "server": 30, "quaddecim": 30, "quadsigma": 30, "decodesharpen": 30, "height": 30, "fp": 30, "exposur": 30, "paramet": 30, "camset": 30, "meter": 30, "quick": 30, "charuco": 30, "photo": 30, "impliment": [30, 32], "offer": 32, "commun": 32, "mitig": 32, "reconnect": 32, "problem": 32, "socket": 32, "lowest": 32, "protocol": 32, "futur": 32, "tcp": 32, "h": 32, "header": 32, "5800": 32, "label": 32, "vector": 32, "vector3d": 32, "vec": 32, "send_vector": 32, "vector_nam": 32, "pose_nam": 32, "tag": 32, "position2": 32, "rotation2": 32, "send_tag": 32, "tag_nam": 32, "due": 32, "reutil": 32, "outsid": 32, "bind": 32, "replac": 32, "intend": 32, "trbnetworkingclientref": 32, "trbnetworkingclientcr": 32, "trbvector3d": 32, "trbvector3dmak": 32, "returnvec": 32, "trbnetworkingclientsendvector": 32, "trbnetworkingclientsendpos": 32, "trbnetworkingclientsendtag": 32, "trbnetwork": 32, "sendvector": 32, "sendtag": 32, "explicitli": 32, "numer": 32, "midwest": 32, "networkingserv": 32, "5801": 32, "observ": 32, "subscrib": 32, "lambda": 32, "translation3d": 32, "respond": 32, "networkingcal": 32, "tostr": 32, "networkingpos": 32, "networkingtag": 32, "capabl": 33, "roll": 33, "frequent": 33, "bug": 33, "fix": 33, "modif": 33, "rebuild": 33, "commit": 33, "fork": 33, "pull": 33, "preseason": 34, "histori": 34}, "objects": {}, "objtypes": {}, "objnames": {}, "titleterms": {"2024": 0, "code": [0, 3, 6, 12, 13], "overview": [0, 2, 11], "agenda": [0, 5, 11], "control": [1, 13], "theori": 1, "basic": [1, 7], "introduct": [1, 19, 33], "The": [1, 10, 12, 13], "problem": [1, 10], "what": [1, 29], "i": 1, "open": 1, "loop": 1, "v": 1, "close": 1, "pid": 1, "effect": 1, "chang": [1, 9], "k_p": 1, "k_i": 1, "k_d": 1, "us": 1, "robot": [1, 22, 34], "exercis": 1, "1": [1, 4], "tune": 1, "feedforward": 1, "more": [1, 8], "On": 1, "In": 1, "practic": 1, "typic": 1, "happen": 1, "design": [1, 22], "decis": 1, "first": 1, "implic": 1, "complex": 1, "further": 1, "read": [1, 28], "imag": [1, 10], "credit": 1, "electr": 2, "3": [3, 17], "brainf": 3, "interpret": 3, "final": [3, 6, 12, 13], "inventori": 4, "manag": 4, "old": 5, "note": 5, "from": [5, 12, 13], "2023": 5, "2": [6, 18], "wordl": 6, "clone": [6, 15], "java": [7, 19, 20, 23, 32], "content": [7, 14, 16, 19, 24, 33, 34], "led": 8, "program": [8, 11, 13, 18, 19], "setup": [8, 28, 32], "exampl": 8, "anim": 8, "rainbow": 8, "sine": 8, "wave": 8, "deploi": 8, "linux": [9, 21], "instal": [9, 10, 20, 30], "debian": 9, "grub": 9, "set": 9, "newer": 9, "kernel": 9, "firmwar": 9, "color": 10, "base": 10, "segment": 10, "opencv": 10, "python": [10, 32], "overivew": 10, "numpi": 10, "instruct": [10, 30], "import": 10, "packag": 10, "camera": 10, "stream": 10, "show": 10, "arrai": 10, "convert": 10, "frame": 10, "mask": 10, "contour": 10, "calibr": [10, 29], "intro": 10, "run": [10, 29], "challeng": 10, "find": 10, "center": 10, "calcul": 10, "object": 10, "distanc": 10, "subteam": 11, "tank": [12, 13], "autonom": 12, "get": [12, 13], "structur": [12, 13, 15, 23], "after": [12, 13], "lesson": [12, 13], "task": [12, 13], "drive": 13, "simul": 13, "frc": [13, 20], "subsystem": 13, "command": 13, "initi": 13, "execut": 13, "end": 13, "boolean": 13, "interrupt": 13, "isfinish": 13, "xbox": 13, "motor": 13, "extra": 13, "preseason": 14, "train": 14, "index": 14, "date": 14, "git": [15, 20], "commit": 15, "push": 15, "pull": 15, "switch": 15, "branch": 15, "merg": 15, "applic": 16, "coprocessor": 17, "c": [18, 23, 32], "roborio": 19, "librari": 19, "guid": [19, 23], "api": 19, "refer": 19, "oper": 20, "system": 20, "github": 20, "cli": 20, "login": 20, "onli": 20, "pre": 20, "season": 20, "game": 20, "tool": [20, 30], "phoenix": 20, "tuner": 20, "x": 20, "rev": 20, "hardwar": 20, "client": [20, 32], "option": [20, 30], "apach": 20, "maven": 20, "4": 21, "5": 22, "style": 23, "name": 23, "resourc": 24, "document": [24, 34], "other": [24, 30], "websit": 24, "team": 25, "2022": [25, 34], "histori": 25, "titan": [26, 27, 33, 34], "algorithm": 26, "dashboard": 27, "apriltag": 28, "detect": 28, "configur": [28, 30], "multithread": 28, "how": 29, "doe": 29, "o": 30, "support": 30, "build": 30, "local": 31, "network": 32, "why": 32, "limit": 32, "send": 32, "inform": 32, "With": 32, "repli": 32, "server": 32, "receiv": 32, "process": 33, "contribut": 33}, "envversion": {"sphinx.domains.c": 3, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 9, "sphinx.domains.index": 1, "sphinx.domains.javascript": 3, "sphinx.domains.math": 2, "sphinx.domains.python": 4, "sphinx.domains.rst": 2, "sphinx.domains.std": 2, "sphinx": 58}, "alltitles": {"2024 Code overview": [[0, "code-overview"]], "Agenda": [[0, "agenda"], [5, "agenda"], [11, "agenda"]], "Control Theory Basics": [[1, "control-theory-basics"]], "Introduction": [[1, "introduction"], [19, "introduction"], [33, "introduction"]], "The Problem": [[1, "the-problem"]], "What is Control Theory": [[1, "what-is-control-theory"]], "Open-Loop vs. Closed-Loop": [[1, "open-loop-vs-closed-loop"]], "PID Controllers": [[1, "pid-controllers"]], "The effect of changing $K_p$, $K_i$, and $K_d$": [[1, "the-effect-of-changing-k-p-k-i-and-k-d"]], "Using the PID controller on the robot": [[1, "using-the-pid-controller-on-the-robot"]], "Exercise 1 - Tuning a PID controller": [[1, "exercise-1-tuning-a-pid-controller"]], "PID with feedforward": [[1, "pid-with-feedforward"]], "More On Robot Control": [[1, "more-on-robot-control"]], "The Problem: In Practice": [[1, "the-problem-in-practice"]], "What Typically Happens": [[1, "what-typically-happens"]], "Design Decisions First": [[1, "design-decisions-first"]], "Implications of Complexity": [[1, "implications-of-complexity"]], "Further Reading": [[1, "further-reading"]], "Image credits": [[1, "image-credits"]], "Electrical overview": [[2, "electrical-overview"]], "3 - Brainf interpreter": [[3, "brainf-interpreter"]], "Final code": [[3, "final-code"], [6, "final-code"]], "1 - Inventory Manager": [[4, "inventory-manager"]], "Old notes from 2023": [[5, "old-notes-from-2023"]], "2 - Wordle Clone": [[6, "wordle-clone"]], "Java Basics": [[7, "java-basics"]], "Contents": [[7, null], [14, null], [16, null], [19, null], [24, null], [33, null], [34, null]], "LED Programming": [[8, "led-programming"]], "Setup": [[8, "setup"], [28, "setup"], [32, "setup"], [32, "id2"], [32, "id5"]], "More examples": [[8, "more-examples"]], "Animated Rainbow": [[8, "animated-rainbow"]], "Sine Wave": [[8, "sine-wave"]], "Deploying": [[8, "deploying"]], "Linux installation": [[9, "linux-installation"]], "Installing Debian": [[9, "installing-debian"]], "Changing GRUB settings": [[9, "changing-grub-settings"]], "Installing a newer kernel/firmware": [[9, "installing-a-newer-kernel-firmware"]], "Color-based segmentation in OpenCV Python": [[10, "color-based-segmentation-in-opencv-python"]], "Installation": [[10, "installation"], [20, "installation"], [30, "installation"]], "Overivew": [[10, "overivew"]], "Segmentation": [[10, "segmentation"]], "OpenCV": [[10, "opencv"]], "NumPy": [[10, "numpy"]], "Python": [[10, "python"]], "The problem": [[10, "the-problem"]], "Instructions": [[10, "instructions"], [30, "instructions"]], "Importing packages": [[10, "importing-packages"]], "Camera stream": [[10, "camera-stream"]], "Showing image": [[10, "showing-image"]], "NumPy arrays": [[10, "numpy-arrays"]], "Converting frames": [[10, "converting-frames"]], "Masking": [[10, "masking"]], "Contours": [[10, "contours"]], "Calibration": [[10, "calibration"], [29, "calibration"]], "Intro": [[10, "intro"]], "Running": [[10, "running"]], "Challenges": [[10, "challenges"]], "Finding the center": [[10, "finding-the-center"]], "Calculating object distance": [[10, "calculating-object-distance"]], "Programming Subteam Overview": [[11, "programming-subteam-overview"]], "Tank Autonomous": [[12, "tank-autonomous"]], "Getting code": [[12, "getting-code"], [13, "getting-code"]], "Structure": [[12, "structure"], [13, "structure"], [15, "structure"], [23, "structure"]], "Final code (from after the lesson)": [[12, "final-code-from-after-the-lesson"], [13, "final-code-from-after-the-lesson"]], "The Task": [[12, "the-task"], [13, "the-task"]], "Tank Drive Simulation": [[13, "tank-drive-simulation"]], "FRC Programming": [[13, "frc-programming"]], "Subsystems": [[13, "subsystems"]], "Commands": [[13, "commands"]], "initialize()": [[13, "initialize"]], "execute()": [[13, "execute"]], "end(boolean interrupted)": [[13, "end-boolean-interrupted"]], "isFinished()": [[13, "isfinished"]], "Xbox Controls": [[13, "xbox-controls"]], "Motors": [[13, "motors"]], "Extra": [[13, "extra"]], "Preseason Training": [[14, "preseason-training"]], "Index by date": [[14, "index-by-date"]], "Git": [[15, "git"], [20, "git"]], "Cloning": [[15, "cloning"]], "Committing": [[15, "committing"]], "Pushing & Pulling": [[15, "pushing-pulling"]], "Switching branches": [[15, "switching-branches"]], "Merging": [[15, "merging"]], "Applications": [[16, "applications"]], "3 - Coprocessors": [[17, "coprocessors"]], "2 - C++ Programming": [[18, "c-programming"]], "Java / roboRIO Programming": [[19, "java-roborio-programming"]], "Library guides": [[19, "library-guides"]], "API references": [[19, "api-references"]], "Operating system": [[20, "operating-system"]], "GitHub CLI": [[20, "github-cli"]], "Git login": [[20, "git-login"]], "(Only for pre-season) Java": [[20, "only-for-pre-season-java"]], "FRC Game Tools": [[20, "frc-game-tools"]], "Phoenix Tuner X": [[20, "phoenix-tuner-x"]], "REV Hardware Client": [[20, "rev-hardware-client"]], "(Optional) Apache Maven": [[20, "optional-apache-maven"]], "4 - Linux": [[21, "linux"]], "5 - Robot design": [[22, "robot-design"]], "Style guide": [[23, "style-guide"]], "Naming": [[23, "naming"]], "Java": [[23, "java"]], "C++": [[23, "c"]], "Resources": [[24, "resources"]], "Documentation and other websites": [[24, "documentation-and-other-websites"]], "Team #2022 History": [[25, "team-2022-history"]], "Titan Algorithms": [[26, "titan-algorithms"]], "Titan Dashboard": [[27, "titan-dashboard"]], "AprilTag Detection": [[28, "apriltag-detection"]], "Reading Configuration": [[28, "reading-configuration"]], "Detection": [[28, "detection"]], "Multithreading": [[28, "multithreading"]], "How to run": [[29, "how-to-run"]], "What it does": [[29, "what-it-does"]], "OS Support": [[30, "os-support"]], "Building": [[30, "building"]], "Build Options": [[30, "build-options"]], "Configuration": [[30, "configuration"]], "Other Tools": [[30, "other-tools"]], "Localization": [[31, "localization"]], "Networking": [[32, "networking"]], "Why?": [[32, "why"]], "Limitations": [[32, "limitations"]], "C++ Client": [[32, "c-client"]], "Sending Information": [[32, "sending-information"], [32, "id3"]], "Sending Information (With Reply)": [[32, "sending-information-with-reply"], [32, "id4"]], "C Client": [[32, "id1"]], "Python Client": [[32, "python-client"]], "Java Server": [[32, "java-server"]], "Receiving Information": [[32, "receiving-information"]], "Titan Processing": [[33, "titan-processing"]], "Contributing": [[33, "contributing"]], "Titan Robotics #2022 Documentation": [[34, "titan-robotics-2022-documentation"]]}, "indexentries": {}}) \ No newline at end of file