Adding a bunch more readme content

This commit is contained in:
Bradley Bickford 2022-12-26 14:40:10 -05:00
parent 60db20df22
commit 9aad9e7a4e
10 changed files with 164 additions and 1 deletions

View File

@ -1,3 +1,4 @@
# 14 - Gyroscopes - Challenge
Combine the use of encoders and gyroscopes to do the following
- Drive forward 60 inches
- Rotate to 45 degrees (assume a left turn is negative rotation, right turn is positive rotation)

View File

@ -0,0 +1,22 @@
# 14 - Gyroscopes
## What is a Gyroscope?
This is covered in slightly more detail in [8 - Basic Robot Electronics](../8%20-%20Basic%20Robot%20Electronics/), but to reiterate, a Gyroscope is a device that tells you the (near) instantaneous acceleration at which your robot is turning (often in 3 dimensions). Special software is used to calculate from the acceleration data the rate your turning, and the angle you've turned relative to a starting point (that you can control).
Gyroscopes can take you from saying "turn left for .75 seconds" to "turn to -45 degrees"
## How does a gyroscope know how fast or far it's gone?
It depends a lot on the type of gyroscope, but generally the ones you'll see in FRC use a trick of electrical capacitance (not capacity, two different things).
If you're really interested, you can [learn more about capacitive gyroscope sensing here](https://www.analog.com/en/technical-articles/mems-gyroscope-provides-precision-inertial-sensing.html). Be warned though, it's a dense read, and is far outside the scope of what you need to know if you actually just want to use the gyroscope.
## Another solution that seems better than timers, but I'm guessing there's a catch?
Yep. Definitely still a better solution than timers in many cases, however, gyroscopes alone can't help you determine the speed or distance you have traveled, just how much you've rotated.
Similar to Encoders, this example I've provided here also has the same overshoot problem. We'll see how to fix this next example, but just keep in mind that the way this example is written, you may ask for 45 degrees, and get 46, or 50, or maybe even 55 depending on the conditions around your robot.
Gyroscopes also have another issue, drift. Because of how the rotation is sensed, and the math involved to go from acceleration to rate and angle, a certain amount of drift (that is, a certain amount of rotation is preceived by the underlying code that isn't actually happening) is accumulated over time. It varies from sensor to sensor, even if there the same part from the same manufacturer.
Calling .calibrate() on your Gyro can help mitigate some of this, and for simple to moderately complex processes, this would be enough (and in general is going to be enough for most situations you might want to write code for). But some teams (and perhaps you in the future) will want to do something more complex that requires <i>very</i> accurate gyroscope readings. This is where filters come in. Filters help to wash away the noise while still allowing the actual activity to pass through appropriately.
Filters could be an example all there own, and in the Java training, we covered them very little, because setting up filters isn't usually necessary for beginner to intermediate work. If you're interested in reading more about filters, [refer to the WPILib documentation](https://docs.wpilib.org/en/stable/docs/software/advanced-controls/filters/index.html) for more information. They provide a significant amount of detailed information, as well as graphs made with sample data to give a rough idea about the behavior of each filter type.

View File

@ -1,3 +1,5 @@
# 15 - PID Control - Challenge
Repeat the previous challenge from section 14 using PID Control
Combine the user of encoders and gyroscopes to do the following

View File

@ -0,0 +1,52 @@
# 15 - PID Control
This is going to be an intermediate level topic that is <i>not</i> required for you to have a functional robot for competition. It can be a very powerful solution for managing the interaction between a sensor and a system (like a drivetrain, arm, elevator, shooter, etc.) but it isn't necessarily required for those systems to work.
## What is PID?
PID stands for Proportional, Integral, and Derivative. These three "pieces" are combined together to create a form feedback control for a motor or collection of motors on your robot. Each piece plays a different role, and more often than not you won't see more than 2 of the pieces used at any given time in FRC. The explanation below of each of the pieces, and the additional components needed for functional PID control, is not going to be fully comprehensive, but I'll do what I can to ensure that I cover enough to get you exploring.
First thing to understand is the controller has to have an input. This input is defined by you. It could be the rate or the current angle from a Gyroscope, the rate or the current position of the robot as received from an Encoder, and so on.
The second thing to understand is the setpoint, this is the position or the speed you want the PID controller to help you achieve, the units of the setpoint come from the units of your input. Each component (the P, I, and D) plays a different role in getting to your desired state as represented by the setpoint. Note that each of the mathematical functions represented by the three letters are looking at the difference between the current setpoint, and the most recent input from the sensor into the controller.
The third thing to understand is the tolerance of your controller. PID controllers can be tuned to perform very accurate calculations but there is a limit to how close they can get you to being exactly on target. The tolerance is the amount of error you're ok with before the PID controller says it's at the desired setpoint and stops telling motors to do work. For example, if your setpoint is 60, and the toleraance is +/- 1, then the range of values that is considered "at setpoint" for the controller is 59-61. Tolerance is something you have to evaluate for yourself between the amount of time you want to spend tuning the PID versus how much error you're willing to have left over when the PID controller stops doing work.
The next 3 values will talk about are multipliers for the P, I, and D portions of the control loop. If the value for any of these is 0, then the result of that particularly mathematical process is ignored by the controller, and doesn't influence the overall output provided to motors.
P, or Proportional, is the amount of effort the controller puts in to close the gap between your desired setpoint, and your current input value. Sometimes, you can get away with just having a value for P, and the I and D values can be 0. You will basically always have a value for P.
I, or Integral, is a calculation performed to determine the area under a curve on a graph, but at a single point, rather than the range between two points. The I portion informs the controller of what you've been doing previously, and uses that information to influence what happens next. In FRC, this value is usually ignored, i.e. is 0.
D, or Derivative, is a calculation perform to determine the slope of a line, but at a single point, rather than the range between two points. The D portion informs the controller what might happen or need to happen next, and uses that information to influence the output of the controller. It's not uncommon to see teams have relatively small values for D. To help compensate for an issue called oscillation, which is where the P value is so large that it causes the system to constantly overshoot the setpoint, then overcompensate and overshoot in the opposite direction, overcompensate again and overshoot, and so on. Small amounts of D can suppress these osciallations fairly easily, with ample time spent on tuning, of course.
## Where can I use PID Control?
Lots of different places. PID Control has been available to FRC for a long time which is why I show it here in these examples, it's fairly versatile and can handle the work of a lot of systems. Drivetrains, elevators, arms, shooters, you name it, PID control has probably done it. You're implementation and you're willingness to spend time on finding values for P, I, and D and tuning those values is what will make PID control useful to you.
## How do I find values for P, I, D?
This is where things get tricky. It can be <i>very</i> hard to find values for P, I, and D depending on the system. I'll describe the manual way that can work for many systems, and then mention a more automated mechanism you can use and research on your own.
First, if you're manually tuning your PID controller, assume your robot is never going to drive at full speed when using PID control. Because of the manual effort in testing required to figure out the PID values, a safe speed is half speed in both directions, forward and back. In the example, you'll see that I've written a small function (method/behavior) called clamp. It takes in a value, plus a high/low range, if the value is higher than the high value, the high value is returned, if it's lower than the low value, then low is returned, if the value is between high and low, then the value itself is returned. This makes it so you can constrain your motors to a specific speed range and keep you and your robot safe (or at least safer) from out of control behavior.
For the tuning we'll be doing, you can ignore I (set it to 0), as I mentioned before, I is not often used in FRC and can be very tempermental to tune. Just leave it be.
While tuning, slowly begin increasing P (with I and D set to 0), adding small amounts each time. What constitutes a small amount varies from system to system, use your best judgement, but starting off between .01 and .1 is usually safe. If the system your tuning takes off and seems out of control, go smaller.
Overtime as you increase P, one of two things will happen, either your system will get to the setpoint you want, or it will begin to oscilate. If it gets to your setpoint, your done. Leave I and D at 0 and revel in your accomplishment. If it begins to oscilate, that's when you start adding small values to D. For many systems, adding .001 to .01 to start with is pretty safe. Continue to increase D until the oscillations stop and you're still able to achieve your setpoint. If you get to this point, you're done!
Sometimes increasing D can cause your system to constantly fall short of its setpoint, this is called steady state error. In this situation, you need to, very slowly, increase P, or decrease D, by very small increments, until the problem is solved. Depending on the scenario, you may need to increase P, or you may not. You should be able to go with either option, but make sure you write down the values that got you to the "steady state error" issue, so you can go back if your tinkering doesn't work out.
Now, I mentioned an automated mechanism. As of this moment, I wouldn't call this mechanism a full on replacement for manual tuning. But if you're willing to learn the software, you can get some <i>very</i> close values for P and D that may even work as well as you want them to immediately after running the program.
The software used for automating the calculation of the values is called SysID. It's not new software, but I wouldn't call it "mature" software either. It takes a bit of getting used to to get through it's sometimes errant quirkiness. I'm hoping that through the next several seasons it's ease of use will improve. But for the work that it does, the difficulties and learning curve can be overlooked.
The values that SysID calculates for P and D are estimates, based on SysID actually capturing real world data about the system you want to make a PID Controller for, and the parameters you provide for the calculation beyond the sampled data.
SysID will upload custom code to your robot based on the parameters you specify for what motor controllers to use, what sensors to observe, etc, and then have you run several routines on your robot to identify different characteristics about how the motors behave when certain amounts of voltage are applied. By observing these values, SysID can calculate P and D values that should work in most situations, even at full speed (although your mileage may vary).
SysID is more of an advanced topic, but you can learn more [in the WPILib documentation](https://docs.wpilib.org/en/stable/docs/software/pathplanning/system-identification/introduction.html), note that some portions of this part of the documentation are <i>very</i> dense.
## Is PID Control the only option for controlling motors from sensor input?
Absolutely not, there are several others available to you that are useful for various types of control already available in WPILib. They aren't covered here, because they lean more towards the advanced end of robot programming (at least most of them do). If you want to explore more, you can start here [in the WPILib documentation](https://docs.wpilib.org/en/stable/docs/software/advanced-controls/controllers/index.html).

View File

@ -0,0 +1,38 @@
# 16 - NetworkTables and Limelight
As we progress through the next several examples, we're going to see some aspects of robot programming that aren't always necessary. Generally speaking most of the things we've covered so far with the exception of the structure and drivetrain code isn't always necessary. It depends a lot on what you're doing. But the next few examples are going to be slightly more "on the fringe" because you may find a reason to use these things, you may not. On top of that, several of the things we're going to talk about have budgetary requirements that your team may not necessarily be able to meet.
None the less, you should know what these things are, just in case you want to use them in the future.
## Ok, I'll start with the first thing in the example name, what's a NetworkTable?
NetworkTables is a software mechanism for sending data between systems over a network. Data is formed by a structure of key/value pairs, sort of like a dictionary, where you have a word (the key) and a definition (the value). These key/value pairs are organization into tables, the tables themselves are values associated with keys further up in the hierarchy.
It's basically a bunch of nested Excel spreadsheets, which is a terrible example, but it's the one I'm going with.
To use NetworkTables, you have to have a NetworkTables server, that NetworkTables clients can connect to. Thankfully, the work of creating a NetworkTables server is managed for you. When you run your robot code on the RoboRIO, a NetworkTables server is automatically created, and begins listening for connections from clients.
There are several different forms of clients in FRC. You could use the NetworkTables libraries to create your own client for accessing data or you could use built in tools like Outline Viewer, Shuffleboard, and the LabVIEW Dashboard to begin interacting with the NetworkTables data.
In this example, we'll be interacting with the NetworkTables libraries directly to create a class that manages interaction between our robot and a device called a Limelight.
## A second new thing, great, what's a Limelight?
I'm pretty sure I talk a little bit about the Limelight in [8 - Basic Robot Electronics](../8%20-%20Basic%20Robot%20Electronics/) but to recap, a Limelight is a camera with LEDs on it that you use for computer vision tracking. It's based on the ever popular Raspberry Pi small board computers and can be configured and used to provide your robot with real time object tracking for things like field goals and score-able game elements.
The Limelight takes a ton of the work required to create a workable vision tracking algorithm and gives you a simple web based user interface to configure specific settings to tune for what you want to track. <b>Many</b> teams rely on the Limelight over manual vision tracking because in the vast majority of cases it performs well enough for what a team wants to accomplish.
The Limelight communicates with the rest of your robot program over Networktables. The software connects to the NetworkTables server running on your RoboRIO and creates a table with a key called "limelight" (this is actually the default, but you can change the table name if you want). By interacting with this table (whether you're retrieving or setting values), you can manipulate the Limelight and retrive information about what it is tracking based on the configuration you set up using the web user interface prior to putting your robot on the competition field.
The Limelight has several important values you can observe to if it's looking at a target, and if it is, where the target is and roughly how large it is (compared to the overall size of the image). These elements are (by key name):
- tv - tv will return a decimal (float) with a value of either 0 or 1. It'll be 0 if there's no target currently in view, or 1 if there is
- tx - tx returns a decimal (float) with a value that is the number of degrees from the left/right center (by default) of the image the target it sees is. The value can be negative or positive up to about 30 degrees (depends on model).
- ty - ty returns a decimal (float) with a value that is the number of degrees from the up/down center (by default) of the image the target it sees is. This value can be negative or positive up to about 27 degrees (depends on model).
- ta - ta returns a percentage (float) with a value that is the area that the current target takes up in the image as a whole. If the target covers more than half the image, then it returns 50.
These values can be a pain to work with directly, especially if you have to work with them repeatedly throught different sections of your code. We are going to look at creating a Limelight class that we can use to interact with our Limelight with, and to give better names to the different elements we are working with.
The Limelight also has settings you can change from your robot code, you'll see explanations of these in the comments, more than likely you won't need to interact with them to get what you want out of the Limelight, but they are there for completeness.
## What else can I do with NetworkTables?
Interacting directly with NetworkTables? Not a lot at this point, you'd have to have some other goal in mind. Indirectly working with NetworkTables however, we'll see that in [18 - CameraServer and Shuffleboard](../18%20-%20CameraServer%20and%20Shuffleboard/)

View File

@ -0,0 +1,18 @@
# 17 - Pneumatics
## P What?
Pneumatics (new-matics) is working with air to have your robot perform various functions. These actions tend to be very linear in nature (up/down, in/out, etc.). Pneumatics provide robots with a consistent motion experience for relatively simple tasks where a motor would require some form of complicated sensing to complete the same task.
<b>Big disclaimer, all robots can be dangerous, but pneumatics tend to add an extra layer of possible danger, be wary of your pneumatics setup and always [refer to the documentation](https://www.firstinspires.org/sites/default/files/uploads/resource_library/frc/technical-resources/frc_pneumatics_manual.pdf) if you're unsure if something is set up correctly. DO NOT charge your system before verifying your pneumatics are setup correctly.</b>
## So how do I go about using Pneumatics?
You need a pneumatics setup first, the documentation in the above disclaimer can help you with that. This is a programming training after all. The parts you'll be most concerned with are:
- What type of cylinders are we using? (Single or Double Action)
- What type of control module are we using? (Pnuematics Control Module (PCM) from CTRE or Pneumatics Control Hub (PCH) from REV)
The type of cylinder is important because it will inform you what class to create an object from when writing your pneumatics oriented code. You may have a mix of single and double, and that's ok, you just need to make sure that you configure the right ports with the right objects.
Speaking of ports, the PCM and PCH devices are sub-boards that help the RoboRIO manage not only your cylinders and how they're directing air, but also your compressor and the amount of stored air you have in your tanks. These devices have a number of ports that can be used to control solenoids (either single or double solenoids, again, depending on the type of cylinder). The ports are numbered, similar to how they are on the RoboRIO and PDP/PDH, you should be able to spot them pretty easily. Note that a double solenoid, like the name implies, will take up two ports, rather than just one.
The PCM/PCH as I mentioned also play a role in managing your compressor and your tank stored air. If you're using the PCM from CTRE, you're limited to Digital Only pressure sensing, meaning that, a digital switch informs the PCM whether or not to turn the compressor on. This isn't a bad thing, but it can cause the PCM to turn the compressor on more often than it really needs to, which can waste battery power. If you've got a PCH from REV though, you can use Analog sensing, and get real time pressure data that will tell you (within a tolerance) the exact amount of air you have stored for use. This way, you can use your better programming judgement to determine when the compressor should come on. For example, if your working pressure (the pressure you actually send to mechanisms) is 60, and your desired standing pressure tank pressure is no less than 75. With digital, the compressor is going to turn on basically every time the storage tank pressure hits 112 PSI or so, whereas with Analog, you could tell the PCH to not turn the compressor on until you hit the 75 or less mark you care about, saving a bunch of start/stop compressor runs that really aren't necessary.

View File

@ -0,0 +1 @@
# 18 - CameraServer and Shuffleboard - Challenge

View File

@ -0,0 +1,10 @@
# 18 - CameraServer and Shuffleboard
# <b><i>THIS EXAMPLE IS BROKEN, PLEASE PROCEED TO THE NEXT SECTION AND COME BACK LATER TO VIEW THIS EXAMPLE</i></b>
Notes:
- Example will probably never work on Windows with the current state of the libraries, libraries will need to change in order to get to the point where the example will work on Windows
- The limitation has something to do with OpenCV, and manually compiling OpenCV in a specific way to get the Windows stuff to work
- The development team for RobotPy indicates in the documentation that Windows is only very lightly tested and may or may not work.
- Sooner or later, I will work on getting a Ubuntu 18.04 VM set up with the appropriate configuration to try and get this working.

View File

@ -1 +1,5 @@
Make your own LED animation, be creative, no wrong answers on this challenge, assuming your code runs as you describe in comments.
# 19 - AddressableLED - Challenge
Make your own LED animation, be creative, no wrong answers on this challenge, assuming your code runs as you describe in comments.
## A note from the editor
The animation provided as a solution to this challenge is something I wrote several years ago called "plasma", which is based on various other pieces of code I've found over the years to form this weird, liquid type effect. It's somewhat complicated, and I don't necessarily expect you to understand what it does and how, because even I'm not 100% sure about how someone came up with the functional structure to make the plasma (the function is from somewhere with psuedorandom tweaks from me). But after a few read-throughs with comments, you should be able to get the jist of what's going on.

View File

@ -0,0 +1,15 @@
# 19 - AddressableLED
## Are you telling me I can make my robot RGB?
Yes, you can! (with some caveats).
LEDs in FRC should be used tastefully, the LEDs you use should either serve a purpose (like those on the Limelight camera) or be discrete enough that they aren't painful to look at while you're on the playing field.
You're limited to using LEDs from the WS2812 family or similar (most consumers are familar with this type of LED under the name Adafruit NeoPixel). You CANNOT use APA102s (again, more commonly known as Adafruit DotStars) with the libraries shown in this example. With that being said, theoretically, you could use APA102s with the RoboRIO, but it would require extra development effort on your part, again, at least at the time of writing.
You do have a limit on the number of LEDs you can run, it's something like 5700 LEDs though, so that shouldn't be a problem. However, you can only use one continuous strip of LEDs on the RoboRIO at a time, if you want to have separate strips on your robot doing different things, you'll need to make long wire runs and separate the different sections of the singular strip logically, rather than physically. This is easy enough to do, but will require more than just beginner level programming experience if you want to get too complicated.
## When can I start installing the LEDs? Moar RGB moar better.
If your LEDs are going to serve a purpose, like indicating when a shooter wheel is fully spun up or provide extra light for vision tracking, then set those up at the same time you're implementing code for that system. Your drive team will need the opportunity to get used to using the LEDs as reference.
If you're just using LEDs for looks, like underglow or flame animation, it should wait towards the end (if not the very end) of robot construction. LEDs for looks should be an after thought that comes later, and shouldn't ever obstruct getting work done on real mechanisms that are designed to complete game objectives.