(Needs proofreading! Written by: Dhruva)

About This Book
This is a palce to store any and all resources and information relating to FRC Team 8726’s control subteam to provide a quick reference to all members and teach new members or members of other subteams some basics. You can quickly access this site anytime you need to on a laptop or phone at this URL.
Navigation
You can jump to different sections of the book using the sidebar on the left, and there is a search button in the top left you can use to search for words or phrases throughout the book.
There are also options on the top bar to change the theme and print the book (you can also save it as a PDF from there).
How was this made?
This book was created using mdBook, a tool for organizing markdown (.md) files into books which can also be hosted and navigated on a website. These files are hosted on GitHub - you can click on the GitHub logo in the top right to go to the repository. We use GitHub Pages to host the website.
It is the responsibility of the control subteam to keep this information up-to-date and document anything new. Feel free to reach out to a control member if you have any questions, or if you would like something added to this page. Or, better yet, add it yourself! For more information on doing this, see contributing.
(Needs proofreading! Written by: Dhruva)
Contributing
The GitHub repository containing all of the markdown files that make up this book and more can be found by clicking the GitHub icon in the top right. From there, you can make changes just like any other Git repository. If you are not familiar with Git, you may find it easier to use the web editor in GitHub, which should be sufficient for most purposes - just click the “Add File” button or click the edit button while viewing a specific file.
What’s in the repository?
An mdBook project contains a couple things.
- The
srcfolder contains all of the markdown files used to build this book. - The
themefolder contains overrides for the theme. The is only used right now to override thehighlight.jsfile. - The
book.tomlfile contains a few configuration options for the book as a whole. src/SUMMARY.mdis a special file which specifies how all of the pages are organized.
How to add or move pages
The src/SUMMARY.md file must be edited in order to add new chapter to the book or
change the ordering and organization of the chapters. The file looks something like this:
# Summary
- [Name of Chapter 1](path/to/page_1.md)
- [Name of Chapter 2](path/to/page_2.md)
- [This is a sub-chapter](chapter/sub_chapter.md)
- [You can go further too](source_file.md)
If you’re familiar with markdown, you probably recognize that this is just a bulleted list of links. (If not, don’t worry! It’s quite simple and there are some resources below to help you get started.) Simply add the name of the page you want to the list in brackets and then the path to the file in parantheses after in order to add another section.
Writing in markdown
Markdown (.md file extension) is a markup language used to style documents. You have likely already seen it in README.md files on GitHub, Discord messages, or somewhere else. It can do things such as bold or italicize text, add images, links, headings, code blocks, and more.
To get started, looking at a cheat sheet such as this one will show you how to format common things. Please do not write out code or equations in plain text.
Code can be written in short code blocks or longer ones like this:
void myFunction() {
}
The markdown syntax for that code block is:
```java
void myFunction() {
}
```
Additionally, mdBook supports several extensions to the markdown syntax which may be useful. The full list of supported extensions can be found in mdBook’s official documentation. Some of the supported features include tables and admonitions, which can be seen below:
| This is a | Table |
|---|---|
| Row 1 | Row 2 |
Note
This is an example of an admonition.
Adding equations
Rendering equations using LaTeX is supported in mdBook using MathJax.
This must be first enabled in the book.toml file, which has already been done.
If you are not familiar with LaTeX it looks a bit confusing but it uses backslashes to
insert special characters or functions into an equation. A cheat sheet can be found
here and a longer guide can be found
here (although it’s more in the
context of using LaTeX for a whole document).
Wrap inline equations in \\( \\) and equations that need their own line in \\[ \\]. For example, this:
\\( F_f = \mu \times F_N \\)
Looks like: \(F_f = \mu \times F_N \)
Linking to other parts of the documentation
Inserting hyperlinks in markdown is done using this syntax: [display text](https://example.com).
The same syntax is used to link to other parts of the book similar
to how you would link to other parts of a normal website. Instead of a URL,
use the local file path or the filename of the page you want to link to.
If you are linking to a page found in the same folder as the current page, then simply use the filename. Otherwise, you would need to cd back into the /src folder using ../ and then follow it up with the path to the destination (you may need to write ../ more than once).
For example, this page is located at src/about/contributing.md. If I wanted to provide a link to about.md,
which is found in the same folder, then I would write [about page](about.md).
If I wanted to link to the inventory page, which is found under /src/parts/, then I’d write [inventory page](../parts/inventory.md).
You can either use the markdown file ending (.md) or swap it out for .html, since an HTML file of the same name will be generated
when the book is built.
If you want to link to a specific section of a page, you can do that by adding
a ‘#’ after the file and then the name of the section, converted to kebab-case
with special characters like ‘.’ removed.
This is the same as the end of the URL you see in your browser when you visit
a certain page of the docs, so you can also just copy everything after the #
and use that to link to a specific section. For example, the link to this
section is https://cryptohawks8726.github.io/docs/about/contributing.html#linking-to-other-parts-of-the-documentation,
so to link to this section you would use contributing.html#linking-to-other-parts-of-the-documentation.
You can also use the full URL without the domain name, for example, /docs/about/contributing.html.
However, this will not work if the site is run locally or deployed somewhere other than /docs, so
it is recommended to use the local file paths instead.
What’s with highlight.js?
As mentioned earlier, the files in the theme folder overwrite
certain elements of the theme. The highlight.js file is responsible for syntax
highlighting in code blocks, and for some reason the default highlight.js file
only supports a small range of languages. It is notably missing support for Dart.
Because of this, it has been swapped out for a replacement file downloaded from the highlight.js library’s website which supports many more languages.
Building and Deploying
Anytime you make changes to the repository’s main branch, GitHub actions will automatically
rebuild the book and deploy it to the GitHub Pages site, so you do not need to do anything
manually for your changes to appear on the website. This is configured in .github/workflows/deploy.yml,
which has been copied from mdBook’s automated deployment examples.
This tells GitHub to run a few commands to build and then deploy the book to the site.
If you want to build the book locally to test it out, you can install mdBook’s command line tool
and run mdBook build, which will build a website in a folder titled book. Running mdbook serve will
host the website at localhost:3000. For more information and installation instructions,
see mdBook’s user guide.
Resources
Below are some helpful resources to reference when creating docs:
Important
Please don’t copy these verbatim. Only include information that is necessary and specific to our needs.
| Resource | Description |
|---|---|
| REV Documention | Provides information on different REV components/software (components are found in their own subcategories) |
List of Parts
Inventory
Radio
ismail - not proofread nor complete
SparkMax
Can be found in the Mech Room on the gray shelves (not to be confused with the toolcarts).
Overview
Sparkmaxes are the motor controllers of choice for 8726, at least for our REV motors. They can be configured, analyzed, and controlled via a USB connection using REV Hardware Client.
Ports
| Port | Wire Type | Current Draw | Required | Where is it? | Additional Info |
|---|---|---|---|---|---|
| CAN port | 22 gauge | amps | ✓ | Side connecting to PDH, next to USB-C port | Used to connect the CAN bus |
| 6-pin Encoder port | 22 gauge | amps | ✓ | Side connecting to motor | Enables connection to the motor’s encoder |
Status Lights
ismail - not proofread nor complete
REV motors
The two REV motors we use are apart of the REV ION Brushless package.
NEO
NEOs are compact and lightweight brushless motors.
NEO Vortex
A NEO Vortex (Vortex for short) is essentially an upgraded version of a regular NEO, designed for high-power applications.
NEO Vortexes are typically controlled using a SparkFlex motor controller. SparkFlexes are mounted directly onto Vortexes; they contain most of the key features found in SparkMaxes along with a few additions. 8726 does not use SparkFlexes, however. Instead, a special Solo Adapter has been mounted in place for Sparkmaxes to connect to.
| Port | Wire Type | Current Draw | Required | Where is it? | Additional Info |
|---|---|---|---|---|---|
| 6-pin Encoder port | 22 gauge | amps | ✓ | Side connecting to motor controller | Enables connection to the motor’s encoder |
RoboRIO
Batteries
SystemCore
PDH/PDP and Fuses
Kraken X60
Playing sounds
Wagos
Tools
VRM
RSL
Pigeon
Cameras and Limelights
120a Breaker
Encoders
CANCoders
FRC Software
Visual Studio Code
Game Tools (Driver station)
Choreo and PathPlanner
(TODO: Jathon)
Phoenix Tuner X
REV Hardware Client
(Written by: Dhruva - should there be anything here?)
Aluminum
Aluminum is an app made by the team which has various utilities to help the team, including a custom dashboard for drivers and ways to monitor or control the robot through NetworkTables.
For more information, see the section in the “Our Projects” Chapter
RoboRIO Imaging Tool
GitHub Desktop
(honestly mostly just link to the git & github section you don’t need to explain git here)
WPILib Tools (Glass, SysID, etc)
Glass
GrappleHook
Limelight Hardware Manager
(Needs proofreading, should we add anything else here? Written by: Dhruva)
Our Projects
This chapter contains in-depth information about some of our projects besides our robots themselves. You can find guides on what they are, how they are meant to be used, and information to help maintain them in the future.
(Needs proofreading! Written by: Dhruva)
Aluminum
Aluminum is an app made by the team. It should be kept up to date on all team laptops. If it is not installed or is out of date, please let someone know or update it yourself.
Aluminum has a variety of utilities and may have more features added in the future. It can communicate with robots through NetworkTables, allowing the app to observe and change data sent from the robot. It can also connect to a simulated robot.
The app will switch between red and blue themes depending on the robot’s current alliance.
Using Aluminum
Aluminum will open to the dashboard screen, with a field view and information displays that would be useful to a driver during matches. To get to other parts of the app, click on the logo in the bottom right and select a page to go to. The auto selector is also located here, which is used to set the auto routine the robot will run if it is activated in the autonomous period. You can find the version number at the bottom of this panel.
Above the logo button is an expand button. Clicking on this will toggle between the window being docked above the driver station window. When the driver station is open (preferably in its docked mode at the bottom of the screen) and this button is clicked, the app will automatically resize itself to take up all of the remaining screen area above the driver station and the window bar above it will disappear. Clicking the button again returns the window to its normal state.
Settings
Aluminum has some settings you may need to change. Settings can also be saved to a JSON file and loaded onto another computer if needed.
Important
Make sure to click the “Save Changes” button in the top right after making any changes!
Aluminum has several settings which must be set correctly to connect to the robot. The default settings should work for a real robot. The team number and port must be set correctly - the default port used for NetworkTables is 5810, and our team number is (obviously) 8726. If the “Use server name instead of team number when connecting” option is enabled, instead of attempting to connect to 10.TE.AM.1:PORT, the app will attempt to connect to the specified port at whatever address you put in the server name field. This can be used to connect to a simulated robot by connecting to “localhost”.
Cameras are also configured from settings. Aluminum can display any number of MJPEG streams on the dashboard screen. The IP address of each stream must be set to the correct IP or you will not see anything on the dashboard. See the page on cameras for more information about where to find these IPs.
The Dashboard
The dashboard is the first screen you see in Aluminum and has several pieces of information. The live feed from any connected cameras is shown on the left. On the right, you can find the match number, game timer, and alliance. There is also a field view, which shows the robot’s position on the field and has a button to reset the robot’s gyro if needed. Information about the robot’s current state and specific values can be displayed below. Finally, there is a network connection indicator in the bottom right which will turn green if connected to a robot.
The Debug Panel
Aluminum’s debug panel functions similarly to Glass, although it can be more convenient since it is organized to work with how our team typically structures data in NetworkTables, allowing you to easily view data for each individual subsystem.
Testing Motors
Aluminum provides an interface to make working with the MotorTester code easier. For more information on this feature see the section on MotorTester.
(Needs proofreading! Written by: Dhruva)
Codebase Overview
Aluminum is built using the Flutter framework, a framework made by Google for building modern cross-platform GUI apps. We only target Windows currently, but the app has been shown to build successfully on MacOS and Linux and would likely be usable on other platforms as well.
Aluminum is currently split into several branches to keep game-specific code isolated, since we may add specific displays to the dashboard or other changes which are only useful for one season. A basic template and any utilities which should be shared across different games should be kept on the main branch. Separate branches are created for the specific configurations used for each game (e.g. 2026-main).
About Flutter
Flutter uses Dart as its primary scripting language, although it uses a C++ engine on the
backend. Dart is similar to Java as it is also run inside a virtual machine and compiles
to bytecode (well sort of, usually… see here for more info),
although it has more modern syntax features such as
null safety, optional support
for dynamic types, and is organized by “libraries” instead of classes, allowing you to
have functions or variables which are not associated with a class for more functional
programming. Dart also has better type inference—while Java allows you to declare local
variables with var, it is not very commonly used. In Dart, you will often see variables
declared with only var or final and the compiler will infer the variable’s type. Dart
has similar object-oriented features, although it does not have explicit public or private
modifiers, however, prefixing a class or function with an underscore will make it inaccessible
outside of the current library.
For help getting started with Flutter, you should look at the official docs, where there are beginner tutorials, videos, API docs for the full library, and more.
Building apps with Flutter requires the Flutter SDK to be installed, which comes with a command-line tool for building and running Flutter projects. As of right now, this is only installed on Laptop #8 but this may change in the future. There is also a VS Code extension for running flutter directly from VS Code. A guide to installing the SDK can be found here in official documentation.
NTCore Bindings and FFIGen
This project uses Dart FFI (Foreign Function Interface) bindings to interface with the NTCore library, part of WPILib. This library has a C API which can easily be called from other languages, like Dart. Dart bindings were automatically generated using the ffigen package, creating lib/ntcore/ntcore.g.dart. The main app code shouldn’t directly use these bindings—instead, go through the classes provided in lib/ntcore/instance.dart, which have all been documented and have methods which can safely and easily be called from dart without interacting with native memory. You can easily add extra methods to NTInstance or create another class if you need to access other parts of the C library which do not currently have safe dart bindings written for them.
In order to regenerate the bindings, run tool/ffigen.dart (dart run tool/ffigen.dart). You may need to provide the location
of the C standard library headers, which it for some reason can’t find sometimes (linux error, no clue if this happens on windows :P ),
so locate wherever those headers are on your
system and set your CPATH environment variable to that or temporarily add it to the compiler arguments in tool/ffigen.dart.
You may need to update the bindings if WPILib changes or adds to the NTCore C API. To do this, download the headers (the easiest place to get them is wpilib’s maven releases. Go to the ntcoreffi releases, where there is a .zip file containing all the headers. Unzip all the NTCore headers into ntcore_headers/include, replacing the old files. Then, follow the above instructions to regenerate the bindings, and make sure there are no new errors and implement any new functionality.
Dart bindings for NTCore have been made in lib/ntcore, which contain several classes and methods to perform
common functions without having to directly interface with native functions and handle things like memory
allocation. lib/ntcore/instance.dart contains the NTInstance and NTValueNotifier classes which handle most of
this functionality. lib/ntcore/library_link.dart contains code necessary to load NTCore at startup and
lib/ntcore/values.dart contains the NTValue class, which is a sealed class
that can be used to handle the different types of values in NetworkTables.
NTCore uses pointers to the WPI_String struct for strings. You can convert to/from dart strings using toWpiString and wpiToDartString methods. If you don’t have a pointer to a WPI_String struct you can also cast the str field to a Utf8 pointer and then call toDartString() with the length from the len field.
Using the NTCore Bindings from Dart
The app should make a single instance of NTInstance (ntcore/instance.dart), which is the main class responsible for communication with NetworkTables. Then, use updateConnectionSettings or updateServerNamePort to connect to a specific NT server. You can either connect to the rio via team number and port 5810, or to a sim using localhost:5810. The NTInstance will then keep track of any entry handles in use to publish/subscribe to avoid memory leaks and keep publishers alive.
The NetworkTablesValue class is a sealed class with subclasses for each value type in NT. You can use a switch statement to check what type a value is or use an if statement to check if it matches a certain type. Also, the toString method will return an appropriate string representation of the value, whatever type it is.
The NTValueNotifier class is used to provide a ChangeNotifierProvider object which notifies listeners any time the value at a certain path in NetworkTables changes. Internally, NTInstance polls listeners and updates them in a loop, and this is how these updates are handed out. The easiest way to create new NTValueNotifiers is to use the .fromName factory, which either creates a new one or returns an existing listener for that entry. We keep most of the paths and notifiers (and the NTInstance) used as global variables in one file (lib/ntreferences.dart). There is also an NTPrefixNotifier class which tracks a map of all the values under a certain prefix.
Where to find specific things
- lib/screens contains files for each one of the screens on the dashboard - the main dash, settings, motor tester panel, etc. Each just has a class extending Widget which contains all the logic for that screen.
- lib/widgets contains some specific widgets used such as the field view widget and the auto chooser widget.
- main.dart is the entry point and has the main app and scaffold as well as the side drawer. It also maintains a list of all the screens, labels, and icons for each one - if you’re adding a new screen make sure to add it to that list.
- util.dart contains some random things
- settings.dart contains the logic for saving, loading, and accessing settings to/from json files.
The settings system
This system is contained entirely inside lib/settings.dart.
Settings are stored in a settings.json file in the app’s config directory (the appropriate
directory for the current platform is fetched by the app_dirs package). This is loaded into
the Settings class at startup inside an instane of the Settings class. In order to change the settings,
you can first make a copy of the current settings using Settings.copyInstance(), modify it,
and then overwrite the settings by calling Settings.overwriteSettings(). The Settings class
is converted using dart:convert from the standard library into JSON automatically.
Reading from settings is done using the static getters on Settings.
(Needs proofreading! Written by: Dhruva)
Building and Installing
Since this is a normal Flutter project it can be built with flutter build windows and flutter run will run
the project in debug mode. However, you may need to do a few things first.
Since this project relies on the ntcoreffi binaries published by WPILib to interface with the ntcore library,
you will need to download them first.
These binaries can be downloaded from wpilib’s maven releases, however, there is also
a script in this project to automatically download them for you. It’s in tool/download_ntcore.dart—run it using dart run tool/download_ntcore.dart.
flutter run will run the project in debug mode and flutter build {platform}
will build and places a bundle in build/{platform}/{architecture}/{debug or release}/bundle
containing the executable and all project assets/libraries.
On macos, you’ll need to install the cocoapods package manager for xcode. To do this, you can use the homebrew package manager (download it through github or through the terminal as shown on the website). Run brew install cocoapods in the terminal to install cocoapods, then run pod setup to complete the setup. You may need to restart your IDE and manually type flutter run after initially installing.
Windows additionally requires enabling developer mode to allow flutter to create symlinks. Thanks, Microslop.
Building installers
We primarily use installers to quickly get Aluminum onto all of our laptops, and the installer will also automatically create start menu shortcuts.
First, build the project normally (flutter build windows --release).
Installers are built using NSIS and the setup.nsi script in the repository root.
The fastest way to downloaded NSIS is using winget: winget install NSIS.NSIS.
Alternatively, you can download the installer from here.
Then, run the installed NSIS app and select “Compile NSI scripts”, then open
the setup.nsi file in this repository. An installer will be produced in the build directory.
Important
Please remember to update the version number when publishing new releases - all you need to do is change the number at the top of pubspec.yaml!
(Needs proofreading! Written by: Dhruva (this was copied from stuff in the Aluminum repo))
How to Make Common Changes
Displaying custom values on the dashboard
- The NTValuesDisplay widget (lib/widgets/nt_values_display.dart) is used to display different widgets that show things like numbers or booleans in NT.
- There are some useful widgets already added, such as ones which show a number, boolean, string, or a number and change color depending on the value.
- These widgets are passed as a list in the constructor. This is called in lib/screens/main_dashboard.dart. You can search for NTValuesDisplay. The code from the general branch should have good examples.
Displaying custom status icons on the dashboard
- Status lights are displayed on the right side of the dashboard screen.
- Right now, they’re all set up in lib/screens/main_dashboard.dart. This might get moved out to another widget later if it gets complex enough.
- For now just add more widgets to the list of children (should be labeled with a comment saying “Status icons” or something like that)
Changing the information shown for different states
- Go to lib/widgets/state_bindings.dart
- Edit the map at the top of the file
Adding to the soundboard
- Add the desired sound to the sounds/ directory
- Add the name and path to the sound to the list at the top of lib/screens/soundboard.dart
Adding to the image gallery
- Upload image/gif files into images/gallery
- Add the file name to the list in the top of widgets/image_gallery.dart
Updating to newer WPILib versions
All you need to do is change the version number at the top of the download script in tool/download_ntcore.dart.
Then, delete ntcoreffi.dll (or the equivalent file on your platform) and redownload it.
You’ll probably also want to change the version number at the top of pubspec.yaml.
SwerveBase
(TODO: Keshav)
(Needs proofreading! Written by: Dhruva)
MotorTester
MotorTester is a WPILib project with source code that can be found here. It is used primarily for testing motor functionality and running prototypes.
In the future, it will likely support SystemCore, but it has currently only been tested with roboRIOs. This code currently works with motors controlled by SparkMax motor controllers or TalonFX controllers, but support for other motor types may be added.
This code can also play music in the .chrp format on
Kraken X60 motors.
Why was this made?
This was primarily made for testing prototypes. The team often wants to make prototypes of subsystems using basic materials, and to test them a couple of motors may need to be run at the same time with specific speeds. While this can be done using REV Hardware Client, only one motor can be run at a time so multiple laptops must be used, which makes things get messy. By deploying the MotorTester code to a roboRIO (or SystemCore in the future), multiple motors can be configured and run at once. You can also easily see the speed and position of the motor’s built-in encoder.
How to use MotorTester
MotorTester exposes some values in NetworkTables which can be used to register connected motors and then control the connected motors. This is most easily done using Aluminum, which has an interface to add or run motors. However, it can also be used manually through a tool like Glass.
First, deploy the MotorTester code onto the roboRIO (or SystemCore) and ensure all motors are connected to the CAN bus and are receiving power. You will need to know the CAN IDs of each motor, so make sure to check or set them if needed. Additionally, make sure you have the driver station open, as you will need it to enable and disable the robot.
Then, add each motor to the list of connected motors. In Aluminum, this is done by entering the CAN ID of the motor, selecting the type of motor from the dropdown menu, and then clicking “Add Motor”. To do this manually from Glass, go to SmartDashboard and set the “CAN ID” value to the CAN ID of the motor, set the “Motor Type” value to one of the strings listed in “Motor Types”, and then set “publish” to true.
Once this is done, you should see the motor appear on the list in Aluminum or see new entries appear under “Motors” in SmartDashboard. You can then enter a voltage to run the motor at (-12 to 12) and once the robot is enabled, the motor will begin running at that speed. Disabling the robot will cause all motors to stop as you would expect.
Music can also now be played on any connected Kraken X60 motors by uploading files directly through Aluminum and then clicking the play button.
Project structure
This is a normal WPILib robot project and so it should be similar to typical season code, although it is missing most things you would have on an actual robot.
RobotContainer.java contains the main logic for adding and running motors. The class
implements Sendable, and in its initSendable method the interface for adding
motors is defined.
Each supported motor type has a matching class which extends from the abstract class MotorWrapper,
which also implements Sendable.
When new motors are added, a new MotorWrapper object is created corresponding to the motor type
the user selected and placed in NetworkTables under Motors/{CAN ID}.
To add support for a new type of motor controller, create a new class extending from MotorWrapper
and implement the required abstract methods. Then, go to RobotContainer.java and add the motor type
to the enum MotorModels and add a new case in createNewMotor() which creates a new instance of
the new class and puts it on SmartDashboard, similar to the existing cases for other motor controllers.
Note that care must be taken here to avoid a ConcurrentModificationException by calling
SmartDashboard.postListenerTask() (see the documentation of this method)
Playing music uses the Orchestra class from CTRE’s PhoenixLib. The raw data from a .chrp file is sent through NetworkTables by setting the “music” value. When this value is set, MotorTester will attempt to save it to a temporary file which can then later be used for playback.
Electrical Guide
(TODO: Kabir and Jacob)
Programming Guide
(TODO: Keshav + Dhruva)
Overview of WPILib and Robot Code
Interfacing with Physical Devices
REV Motors
CTRE Motors
Sensors
Cameras
Odometry
Object Detection
NetworkTables
Swerve Drive
Using WPILib’s Controller Classes
Programming Autos
Commands
Finite State Machines
Susbsytem Coding Guide
Subsystem Checklist
Control Theory Guide
This is the section of the guide on Control Theory. Control Theory is “a field of control engineering and applied mathematics that deals with the control of dynamical systems”.1 In simple terms, Control Theory is using mathematical formulas to drive a system to its desired state. Motors only speak the language of voltages and percentages, so we can’t directly set its acceleration, velocity, or posistion.2 For that reason, we have to calculate voltages to get a motor to do basically anything. After reading this guide, you will have a basic understanding of the control theory needed for most common FRC applications.
-
https://en.wikipedia.org/wiki/Control_theory ↩
-
For most common applications, we use control theory to set specific positions and velocities. It is very rare that we will have to set something else. ↩
Introduction to Control Theory
Necessary Vocab
System: The thing you are trying to control. Examples: Climber, Shooter, Turret, Elevator, Arm, etc.
States: All systems have states. A state is simply the property of the system that you are trying to control. Examples: position of a turret, velocity of a flywheel, height of an elevator, etc.
Inputs: Inputs are features of a system that have an ability to change its state. For FRC control, voltage is (almost always) the input that we are controlling and it can change the state of the system.
Measurement: Also known as outputs, these are the states of a system as understood by sensors. Sensors can be inaccurate, so the actual state may be hard to determine. Measurements are usually estimates based on data, and are usually good enough for FRC. We use a variety of sensors to get information but primarily motor encoders.
Setpoint: Also known as references, this is the desired state of a system. Examples: desired RPM of a flywheel, desired height of an elevator.
Error: Error is the difference between the setpoint and the measurement in the system. For example, if a flywheel is at 2000RPM and its setpoint is 8726RPM then the error is \( 8726 RPM - 2000 RPM = 6726 RPM \).
Control Algorithm: A control algorithm will, using the setpoint and measurement, produce an input to feed into the system. The input will affect the state of the system. A good control algorithm minimizes the error as quickly as possible. However, moving too quickly may result in overshooting the setpoint, so a trade-off must be made which may vary from system to system.
States we Typically Control in FRC
Position Control
This is a very common state that we control in FRC applications. Climbers, elevators, turrets, and arms are all clasified as position control. This is because the setpoint and measurements that we are dealing with are both positions. We have one position and want to go to another position so we are controlling the position and need position control.
Note
Note on position control with angles:
When a system is moving in circles, such as a turret, it sometimes be more effiecient to go in the opposite direction (since it’s a circle). This also varies with the mechanical constraints of the system.
Velocity Control
This is also very common to control in FRC. Flywheels, rollers, and drivetrains all rely on velocity control. This is because the setpoint and measurements that we are dealing with are both velocities. Our goal is to reach a certain velocity, which can be seen most obviously in flywheels.
(Needs proofreading! Written by: Keshav)
Feedback vs Feedforward
Feedforward Control
Feedforward Control is
Feedback Control
Feedback Control is
Feedforward Control
(Needs proofreading! Written by: Keshav)
System Identification
(Needs proofreading! Written by: Keshav)
Commonly Used Constants
(Needs proofreading! Written by: Keshav)
Uncommonly Used Constants
(Needs proofreading! Written by: Keshav)
Feedback Control
(Needs proofreading! Written by: Keshav)
PID
(Needs proofreading! Written by: Keshav)
The PID Equation & How it Works
(Needs proofreading! Written by: Keshav)
Tuning PIDs
(Needs proofreading! Written by: Keshav)
Bang Bang Controllers
(Needs proofreading! Written by: Keshav)
Using Feedback & Feedforward Control
(Needs proofreading! Written by: Keshav)
Motion Profiling
(Needs proofreading! Written by: Keshav)
(Needs proofreading! Written by: Keshav)
Sources
These are the sources I used in writing this section of the guide as well as additional resources for you to learn more about Control Theory.
https://en.wikipedia.org/wiki/Control_theory
Troubleshooting Guides
(TODO: Jacob + Keshav)
How to Diagnose Common Issues
CAN errors
Less Common Issues
(TODO: Everyone talk about this?)
Git and Github
(TODO: Ronith)