Adding more documentation
This commit is contained in:
parent
0f49a82db7
commit
60db20df22
@ -0,0 +1,33 @@
|
||||
# 10 - Basic Drivetrain
|
||||
|
||||
## Actual robot code! What does it do?
|
||||
Well, to start off with we're going to look at getting the robot's drive base to move. This is by far the most common thing you'll have to deal with when developing robot code, and will be something you have to do every year.
|
||||
|
||||
Drive base code like what's in this example should be something you can do in your sleep, and if you're a rookie team or still a relatively new team, this is probably how your robot program is going to start out looking. There are other types of drive bases though that you may encounter or want to use.
|
||||
|
||||
## Wait, there's more than one type of drive base?
|
||||
Yes, speaking very generally, at the time of writing this, there were three main types seen in the competition space. There are of course, exceptions to this, but you'll generally see the following:
|
||||
|
||||
- Differential Drive - These drivebases usually have some combination of 4, 6, or 8 wheels, and in the 6 or 8 wheel configurations, usually the center wheels will be slightly lower to the ground than the front and back wheels. This is probably the simplest robot drive base to build, as it uses simple, high traction wheels, chain or belts, and simple gearboxes to function. It's also probably the simplest to write code for. This is probably the drive base you'll be building if you're a rookie team.
|
||||
- Mecanum Drive - These drivebases aren't super common anymore but they are still around. The use 4 wheels, one at each corner of the drivebase. The wheels themselves are special because they have rollers ([See Here](https://www.adafruit.com/product/4679?gclid=Cj0KCQiAwJWdBhCYARIsAJc4idBJFVX-rSFgrx250d4-8Viu1bxuqatre4KCdgVIoPXs6OSyRL9_On8aAlQXEALw_wcB)) with different spin orientations (left or right). These different spin orientations, when implemented properly, allows the robot to move laterally both forward/backward as well as left/right, while still maintaining the ability to rotate about the robot's center. Mecanum is somewhat more difficult to build, and to program, when compared to Differential Drive, but not so significantly that it's inaccessible to teams who've only been in the game a year or two.
|
||||
- Swerve Drive - Swerve drive is complicated, but it's becoming very quickly a mainstay of the FIRST community. Essentially, at each corner of your robot you have a swerve module, the module has 2 motors, and an Encoder. One motor makes the wheel spin, as a wheel should, but the other motor, in tandem with the encoder, rotates the wheel so it can spin in 360 degrees. Because each module spins independent of the other. You get all the benefits of mechanum drive, without losing the pushing power of Differential Drive. Builting a swerve drive base is not for the faint of heart, it can be a complicated project, both mechanically and programmatically. Not recommended for beginners.
|
||||
|
||||
## So what do I need to get my drive base up and running in code?
|
||||
Not much really. In robotInit(), you should be setting up a few things.
|
||||
- Motor Controllers
|
||||
- For Differential Drive, you'll usually have 2 motors in one gearbox on each side of the robot, so 4 motors total
|
||||
- Motor Controller Groups
|
||||
- You'll need one of these for each side of your drive base, a left side and a right side, the Motor Controller Groups help you to control both motors on a single side together.
|
||||
- A Differential Drive
|
||||
- You'll need just one of these, it'll take the Motor Controller Groups you make and manipulate them so your drive base acts as a single cohesive unit
|
||||
- An XBox Controller (or similar control mechanism, like a Joystick)
|
||||
- You'll need one of these to start, but probably two for competition.
|
||||
Once all that is set up you just need one line of code in teleopPeriodic to make your robot move. There are two options for this:
|
||||
- arcadeDrive(UpDown, LeftRight) - This is like what you might use if you are playing an arcade game, a single joystick on your controller moves the robot forward and back, left and right.
|
||||
- tankDrive(LeftUpDown, RightUpDown) - This is like, well, controlling a tank, you use two joysticks, but only the forward and backward axis of each. Varying how much you push one or the other forward or back, you can make the robot drive forward, turn left or right, or pivot about its center.
|
||||
You can find more detail in the comments of the code.
|
||||
|
||||
## Why do we "import ctre"?
|
||||
Some things that we use in the example use the CTRE (Cross the Road Electronics) library. Specifically, WPI_VictorSPX, some motor controllers (among other features) can't be used without importing a separate module that contains the classes we need to build the objects we want to represent. Similar to how we import wpilib, and wpilib.drive, which contains most of the things we're using like XboxController, DifferentialDrive, MotorControllerGroup, etc, we need to import ctre to gain access to other elements that we want to use as well.
|
||||
|
||||
For much of the examples to come, you'll see the three imports you see now, and not much else, but be aware that there are others out there that you may need as you begin to develop your own robot programs.
|
@ -1,3 +1,4 @@
|
||||
# 11 - Timer Based Autonomous - Challenge
|
||||
Create an autonomous that completes the following steps
|
||||
- Forward for 2 Seconds
|
||||
- Right for .5 Seconds
|
||||
|
@ -0,0 +1,20 @@
|
||||
# 11 - Timer Based Autonomous
|
||||
|
||||
## Why should I care about making my robot do things on its own?
|
||||
Because generally, the beginning 15 seconds of the match have a decent number of points up for grabs, and having an interesting and consistent autonomous will make your team more likely to be picked for playoffs, and open the door to a couple of different awards.
|
||||
|
||||
On top of that, autonomy is everything in industry, understanding how to use sensors and environmental data to make decisions in software is crucial in many different programming fields, not just robotics exclusively.
|
||||
|
||||
## So how do I make my robot do things on its own?
|
||||
There's a lot of different options, but we're going to start off small and simple, and work our way up. Timers are a good place to start. Essentially, we base our autonomous code on the 15 second timeline we have to get work done, before we switch to teleoperated.
|
||||
|
||||
We can observe how much time has passed by asking the timer, and then use if statements to perform certain actions during different spans of time.
|
||||
Maybe while the timer is less than 2 seconds, we drive forward, maybe when the timer is greater than or equal to 2 seconds, but less than three seconds, we turn left, and so on. We ask questions about how much time has passed, to determine what the next action should be.
|
||||
|
||||
Timers are very simple to implement, but they do have there drawbacks, but if you're looking for a quick autonomous to perform one or two simple actions, timers can work well.
|
||||
|
||||
## So wait, what are the drawbacks of timers?
|
||||
There are really two big ones that will influence your robot's autonomous behavior.
|
||||
|
||||
- Environmental obstacles - Because you're not really using a sensor, just basing what you're doing on time, you can't react to changes in the environment that may influence how your robot works. Maybe the field carpet isn't completely flat in spots, maybe testing on cement and playing on carpet causes the robot to do different things, maybe there's another robot in the way. Timers can't really help you with this.
|
||||
- Battery - Motors don't always behave exactly as you would expect them to. It depends on a lot of factors, but two of the bigger ones are the voltage and current available to the motor when it's time to do work. If the battery your using is older or newer, or more or less charged than what you were last testing with, your autonomous may behave differently because the motors aren't getting as far or going further because of differences in the amount of power being applied.
|
@ -0,0 +1,16 @@
|
||||
# 12 - Digital and Analog Inputs
|
||||
|
||||
## What is a Digital Input?
|
||||
This is covered in slightly more detail in [8 - Basic Robot Electronics](../8%20-%20Basic%20Robot%20Electronics/), but to reiterate, something that is digital will only ever have two states, on or off, 1 or 0.
|
||||
|
||||
Digital Inputs for robots will often times manifest themselves as various forms of switches, like buttons, toggles, etc.
|
||||
|
||||
## What is an Analog Input?
|
||||
Again, covered in slightly more detail in [8 - Basic Robot Electronics](../8%20-%20Basic%20Robot%20Electronics/), but to reiterate, something that is analog can have many different values. For robot programming, this range is from 0 to 1, with every decimal number inbetween a different value that the potentiometer is providing (note that this would be different for other types of Analog Inputs, for this example, just focus on the 0 to 1 range).
|
||||
|
||||
Analog Inputs can manifest themselves as a lot of different things. This example shows off an Analog Potentiometer, a Potentiometer being something that turns that produces different analog values the more or less you turn it. Analog potentiometers are used for things like volume knobs and temperature controls.
|
||||
|
||||
## How might I use these sorts of things for an Autonomous?
|
||||
For a drive base exclusively, you probably wouldn't. Analog Potentiometers in particular wouldn't be very useful for just a drive base, but if you had an arm on your robot that you want to go to specific positions, you could use an analog potentiometer for that. You can use Digital Input buttons to detect if your robot has bumped into something, but in general this isn't super safe (for you or the button, depending on speed of travel).
|
||||
|
||||
The example I've provided is more to introduce you to some basic sensors before moving into the more complicated stuff. The basics of environmental interaction can be shown with this simple sensors without getting into too much complex code. Just remember that the use case you see here, isn't a common one.
|
@ -0,0 +1,27 @@
|
||||
# 13 - Encoders
|
||||
|
||||
## Ok, this example looks a little more complicated than the last few...
|
||||
That's because it is, we're getting further along now that you've seen more of the simple stuff, now we need to address more complicated topics.
|
||||
|
||||
## What is an Encoder?
|
||||
This is covered in slightly more detail in [8 - Basic Robot Electronics](../8%20-%20Basic%20Robot%20Electronics/), but to reiterate, an Encoder is something that can be used to determine:
|
||||
- The direction a motor/wheel is moving
|
||||
- The speed at which a motor/wheel is moving
|
||||
- The distance a motor/wheel has moved
|
||||
These are all important tidbits of information if you want to go from saying "drive forward 2 seconds" to "drive forward 60 inches".
|
||||
|
||||
## How does the encoder know how fast or far it's gone?
|
||||
Well, we sort of have to tell it. All encoders are, in some way, counting specific events. Hardware internal to the encoder usually "announces" (or pulses) when there is something to count, and then some software (either on the encoder itself or on the RoboRIO) is taking that count of pulses and determining speed over time and distance travelled.
|
||||
|
||||
All encoders will "announce" there's something to count a certain number of times within a single rotation of the encoder. We can use that information to determine how far, for instance a wheel attached to the same shaft as the encoder turns for one announcement or pulse of the encoder.
|
||||
|
||||
The way we do this is with a specific formula. `math.pi * Wheel Diameter / Pulses Per Revolution`. By doing this, we're basically dividing up the circumference of the wheel into slices that match the pulses (or announcements) the encoder will make in one complete rotation. This will make the information provided by methods (behaviors) like getDistance() and getRate() take on the units of whatever the wheel diameter is. If the wheel diameter provided is in inches, for example, then getDistance() will return inches and getRate will return inches/second
|
||||
|
||||
## This seems like a better solution than timers, what's the catch?
|
||||
While it is a better solution than timers, the way we have this set up doesn't allow for turning, and isn't controlling the drivetrain in a way that will end up being super accurate.
|
||||
|
||||
Averaging both sides of the drivetrain together makes for some easy code. But our target is to drive straight 60 inches, what happens if something slows one side of the drivetrain or the other? Let's say that one side of the drivetrain goes 90 inches, and the other goes 30, that's a right turn, not driving straight, this code has no way to correct for that.
|
||||
|
||||
The other issue here, is lets say the drive base goes forward perfectly straight. What happens if we drive 65 inches because momentum carried us that far? 65 inches may not work for what we're trying to do. With this code, the robot can't correct for overshoot.
|
||||
|
||||
In future examples, we'll see how to solve the above problems.
|
@ -0,0 +1,21 @@
|
||||
# 9 - Robot Program Structure
|
||||
|
||||
## We're finally getting into Robot Programming?
|
||||
Yes! We had to get through some of the basics before we get into the robots. With that being said, we're going to start off easy and escalate and build out from here. Which means, we need to talk about the general structure of a Robot Program. Starting with the different modes that a robot can be in.
|
||||
|
||||
## What are the different Robot Modes?
|
||||
There are 3 modes that we're going to concern ourselves with.
|
||||
|
||||
- Disabled - This is your robot's default state when it first starts up. Disabled just means, well, what the name implies. The robot is disabled, which means no motors, no pneumatics, basically nothing that moves is going to work. LEDs, sensors, and other non-motile systems still can run in the background though.
|
||||
- Teleoperated - This is the mode your Robot is in where you (or your Drive Team) get's to move the robot with controllers. This is the meat and potatoes of a match at the competition. Most of the match is spent in this mode.
|
||||
- Autonomous - This is the mode where you're given the opportunity as a programmer to show your stuff. You make the robot automatically complete some aspect or series of aspects of the game that we are playing that year. An Autonomous program can be very simple, or wildly complex, it depends heavily on two things, your proficiency with programming, and how much time you are given with the robot to develop, test, and rework your autonomous program. No human interaction is allowed when the robot is running autonomous, no driver control at all, which means you'll need to use time, sensors, or both to figure out where you are on the field, and complete whatever tasks are laid out before you.
|
||||
|
||||
Each mode has two methods, an init method and a periodic method. The init method is called (or used) once when your robot enters a mode. So teleopInit() would get called when Teleoperated starts, autonomousInit() would get called when Autonomous starts, and so on. The periodic method is called (or used) every 20ms (roughly 50 times a second) once the robot has run the associated init method for the mode your robot is in.
|
||||
|
||||
There are some special methods that aren't technically a mode. These are the robotInit() and robotPeriodic() methods. The robotInit() method is where you do the setup for your robot. It's kind of like the __init__ method we've seen previously. All of your general setup should happen in robotInit() as it gets called once when your robot first boots up, before it enters any mode. As for robotPeriodic(), this method runs every 20ms (roughly 50 times a second) regardless of what mode your robot is in. You can put code here you want to have run all the time, like LED code, or sensor management code.
|
||||
|
||||
## Every 20ms, that seems like a really small amount of time...
|
||||
It is, you need to ensure that your code fits in this 20ms time period to make sure you don't experience problems controlling your robot. If your code in the periodic methods takes longer than 20ms too many times, something called the watchdog gets mad. When the watchdog doesn't get fed, for safety reasons, it will shut your motors down. Not ideal. Don't worry though, unless your doing something completely insane, it's unlikely normal beginner to intermediate level robot code shouldn't cause any issues.
|
||||
|
||||
## So, is this example how all robot programs will start?
|
||||
Yes...for now. There are other forms of writing robot code that change this up a little bit. But we are nowhere near talking about that. For all of the examples we'll see up through and including example 19 will use this structure as a base.
|
Loading…
Reference in New Issue
Block a user