├── docs
├── setup
│ ├── 3rd_party_libs.md
│ ├── imaging_roboRIO.md
│ ├── install_other.md
│ └── install_software.md
├── basics
│ ├── driverstation_tips.md
│ ├── roboRIO.md
│ ├── vscode_tips.md
│ ├── sensors.md
│ ├── wpilib.md
│ └── java_basics.md
├── assets
│ ├── favicon.png
│ ├── css
│ │ ├── sn.css
│ │ ├── dark_theme.css
│ │ └── codehilite.css
│ └── images
│ │ ├── logos
│ │ ├── ni.png
│ │ ├── code.png
│ │ ├── first.png
│ │ ├── java.png
│ │ ├── wpilib.png
│ │ ├── java_logo.png
│ │ ├── sn_banner.png
│ │ ├── first_white.png
│ │ └── sn_banner_white.png
│ │ ├── deploying
│ │ ├── w_icon.png
│ │ └── deploy_command.png
│ │ ├── driving_robot
│ │ ├── e1.png
│ │ ├── e2.png
│ │ ├── e3.png
│ │ ├── kitbot.jpg
│ │ ├── roboRIO_port.png
│ │ └── constants
│ │ │ ├── step_1.png
│ │ │ ├── step_2.png
│ │ │ ├── step_3.png
│ │ │ └── step_4.png
│ │ ├── roboRIO
│ │ ├── roboRio.png
│ │ └── roboRIO_io.png
│ │ ├── sensors
│ │ ├── camera.png
│ │ ├── encoder.png
│ │ ├── navX_micro.png
│ │ └── limit_switch.png
│ │ ├── why_software
│ │ ├── pi.png
│ │ ├── automation.png
│ │ ├── smart-light.png
│ │ └── programming_header.png
│ │ ├── pneumatics
│ │ └── piston.png
│ │ ├── install_software
│ │ └── wifi.png
│ │ ├── contributing
│ │ └── edit_icon.png
│ │ ├── vscode_tips
│ │ └── light_bulb.png
│ │ └── new_project
│ │ ├── command
│ │ ├── step_1.png
│ │ ├── step_2.png
│ │ ├── step_3.png
│ │ ├── step_4.png
│ │ └── step_5.png
│ │ ├── project
│ │ ├── step_1.png
│ │ ├── step_2.png
│ │ ├── step_3.png
│ │ ├── step_4.png
│ │ ├── step_5.png
│ │ └── step_6.png
│ │ ├── default_contents.png
│ │ └── subsystem
│ │ ├── step_1.png
│ │ ├── step_2.png
│ │ ├── step_3.png
│ │ ├── step_4.png
│ │ ├── step_5.png
│ │ └── step_6.png
├── version_control
│ └── github.md
├── programming
│ ├── pid.md
│ ├── super_core.md
│ ├── deploying.md
│ ├── shuffleboard.md
│ ├── robotpreferences.md
│ ├── new_project.md
│ ├── using_sensors.md
│ ├── autonomous.md
│ ├── pneumatics.md
│ └── driving_robot.md
├── examples
│ ├── pid_elevator.md
│ ├── pid_shooter.md
│ ├── basic_shooter.md
│ └── basic_elevator.md
├── index.md
├── why_software.md
└── contributing.md
├── .github
├── CODEOWNERS
└── workflows
│ ├── build.yml
│ └── main.yml
├── requirements.txt
├── .gitignore
├── readme.md
├── .markdownlint.json
├── template_page.md
├── .vscode
├── tasks.json
└── settings.json
└── mkdocs.yml
/docs/setup/3rd_party_libs.md:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/docs/basics/driverstation_tips.md:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | * @FRCTeam3255/code-reviewers
2 |
--------------------------------------------------------------------------------
/docs/assets/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FRCTeam3255/FRC-Java-Tutorial/HEAD/docs/assets/favicon.png
--------------------------------------------------------------------------------
/docs/assets/css/sn.css:
--------------------------------------------------------------------------------
1 | .md-header{
2 | background-color: #053B6C
3 | }
4 | .md-tabs{
5 | background-color: #053B6C
6 | }
--------------------------------------------------------------------------------
/docs/assets/images/logos/ni.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FRCTeam3255/FRC-Java-Tutorial/HEAD/docs/assets/images/logos/ni.png
--------------------------------------------------------------------------------
/docs/assets/images/logos/code.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FRCTeam3255/FRC-Java-Tutorial/HEAD/docs/assets/images/logos/code.png
--------------------------------------------------------------------------------
/docs/assets/images/logos/first.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FRCTeam3255/FRC-Java-Tutorial/HEAD/docs/assets/images/logos/first.png
--------------------------------------------------------------------------------
/docs/assets/images/logos/java.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FRCTeam3255/FRC-Java-Tutorial/HEAD/docs/assets/images/logos/java.png
--------------------------------------------------------------------------------
/docs/assets/images/logos/wpilib.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FRCTeam3255/FRC-Java-Tutorial/HEAD/docs/assets/images/logos/wpilib.png
--------------------------------------------------------------------------------
/docs/assets/images/deploying/w_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FRCTeam3255/FRC-Java-Tutorial/HEAD/docs/assets/images/deploying/w_icon.png
--------------------------------------------------------------------------------
/docs/assets/images/driving_robot/e1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FRCTeam3255/FRC-Java-Tutorial/HEAD/docs/assets/images/driving_robot/e1.png
--------------------------------------------------------------------------------
/docs/assets/images/driving_robot/e2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FRCTeam3255/FRC-Java-Tutorial/HEAD/docs/assets/images/driving_robot/e2.png
--------------------------------------------------------------------------------
/docs/assets/images/driving_robot/e3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FRCTeam3255/FRC-Java-Tutorial/HEAD/docs/assets/images/driving_robot/e3.png
--------------------------------------------------------------------------------
/docs/assets/images/logos/java_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FRCTeam3255/FRC-Java-Tutorial/HEAD/docs/assets/images/logos/java_logo.png
--------------------------------------------------------------------------------
/docs/assets/images/logos/sn_banner.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FRCTeam3255/FRC-Java-Tutorial/HEAD/docs/assets/images/logos/sn_banner.png
--------------------------------------------------------------------------------
/docs/assets/images/roboRIO/roboRio.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FRCTeam3255/FRC-Java-Tutorial/HEAD/docs/assets/images/roboRIO/roboRio.png
--------------------------------------------------------------------------------
/docs/assets/images/sensors/camera.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FRCTeam3255/FRC-Java-Tutorial/HEAD/docs/assets/images/sensors/camera.png
--------------------------------------------------------------------------------
/docs/assets/images/sensors/encoder.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FRCTeam3255/FRC-Java-Tutorial/HEAD/docs/assets/images/sensors/encoder.png
--------------------------------------------------------------------------------
/docs/assets/images/why_software/pi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FRCTeam3255/FRC-Java-Tutorial/HEAD/docs/assets/images/why_software/pi.png
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | # Install requirements:
2 | # pip install -r requirements.txt
3 | mkdocs~=1.5
4 | pymdown-extensions
5 | mkdocs-minify-plugin
--------------------------------------------------------------------------------
/docs/assets/images/logos/first_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FRCTeam3255/FRC-Java-Tutorial/HEAD/docs/assets/images/logos/first_white.png
--------------------------------------------------------------------------------
/docs/assets/images/pneumatics/piston.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FRCTeam3255/FRC-Java-Tutorial/HEAD/docs/assets/images/pneumatics/piston.png
--------------------------------------------------------------------------------
/docs/assets/images/roboRIO/roboRIO_io.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FRCTeam3255/FRC-Java-Tutorial/HEAD/docs/assets/images/roboRIO/roboRIO_io.png
--------------------------------------------------------------------------------
/docs/assets/images/sensors/navX_micro.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FRCTeam3255/FRC-Java-Tutorial/HEAD/docs/assets/images/sensors/navX_micro.png
--------------------------------------------------------------------------------
/docs/assets/images/driving_robot/kitbot.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FRCTeam3255/FRC-Java-Tutorial/HEAD/docs/assets/images/driving_robot/kitbot.jpg
--------------------------------------------------------------------------------
/docs/assets/images/install_software/wifi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FRCTeam3255/FRC-Java-Tutorial/HEAD/docs/assets/images/install_software/wifi.png
--------------------------------------------------------------------------------
/docs/assets/images/logos/sn_banner_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FRCTeam3255/FRC-Java-Tutorial/HEAD/docs/assets/images/logos/sn_banner_white.png
--------------------------------------------------------------------------------
/docs/assets/images/sensors/limit_switch.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FRCTeam3255/FRC-Java-Tutorial/HEAD/docs/assets/images/sensors/limit_switch.png
--------------------------------------------------------------------------------
/docs/assets/images/contributing/edit_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FRCTeam3255/FRC-Java-Tutorial/HEAD/docs/assets/images/contributing/edit_icon.png
--------------------------------------------------------------------------------
/docs/assets/images/vscode_tips/light_bulb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FRCTeam3255/FRC-Java-Tutorial/HEAD/docs/assets/images/vscode_tips/light_bulb.png
--------------------------------------------------------------------------------
/docs/assets/images/why_software/automation.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FRCTeam3255/FRC-Java-Tutorial/HEAD/docs/assets/images/why_software/automation.png
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | SuperNURDS tutorial Notes checkoff.pages
2 | FRC Programming Tutorial VSC.pdf
3 | *.key
4 | .DS_Store
5 | site/
6 | .unotes/templates/title_date.hbs
7 |
--------------------------------------------------------------------------------
/docs/assets/images/deploying/deploy_command.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FRCTeam3255/FRC-Java-Tutorial/HEAD/docs/assets/images/deploying/deploy_command.png
--------------------------------------------------------------------------------
/docs/assets/images/driving_robot/roboRIO_port.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FRCTeam3255/FRC-Java-Tutorial/HEAD/docs/assets/images/driving_robot/roboRIO_port.png
--------------------------------------------------------------------------------
/docs/assets/images/new_project/command/step_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FRCTeam3255/FRC-Java-Tutorial/HEAD/docs/assets/images/new_project/command/step_1.png
--------------------------------------------------------------------------------
/docs/assets/images/new_project/command/step_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FRCTeam3255/FRC-Java-Tutorial/HEAD/docs/assets/images/new_project/command/step_2.png
--------------------------------------------------------------------------------
/docs/assets/images/new_project/command/step_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FRCTeam3255/FRC-Java-Tutorial/HEAD/docs/assets/images/new_project/command/step_3.png
--------------------------------------------------------------------------------
/docs/assets/images/new_project/command/step_4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FRCTeam3255/FRC-Java-Tutorial/HEAD/docs/assets/images/new_project/command/step_4.png
--------------------------------------------------------------------------------
/docs/assets/images/new_project/command/step_5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FRCTeam3255/FRC-Java-Tutorial/HEAD/docs/assets/images/new_project/command/step_5.png
--------------------------------------------------------------------------------
/docs/assets/images/new_project/project/step_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FRCTeam3255/FRC-Java-Tutorial/HEAD/docs/assets/images/new_project/project/step_1.png
--------------------------------------------------------------------------------
/docs/assets/images/new_project/project/step_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FRCTeam3255/FRC-Java-Tutorial/HEAD/docs/assets/images/new_project/project/step_2.png
--------------------------------------------------------------------------------
/docs/assets/images/new_project/project/step_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FRCTeam3255/FRC-Java-Tutorial/HEAD/docs/assets/images/new_project/project/step_3.png
--------------------------------------------------------------------------------
/docs/assets/images/new_project/project/step_4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FRCTeam3255/FRC-Java-Tutorial/HEAD/docs/assets/images/new_project/project/step_4.png
--------------------------------------------------------------------------------
/docs/assets/images/new_project/project/step_5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FRCTeam3255/FRC-Java-Tutorial/HEAD/docs/assets/images/new_project/project/step_5.png
--------------------------------------------------------------------------------
/docs/assets/images/new_project/project/step_6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FRCTeam3255/FRC-Java-Tutorial/HEAD/docs/assets/images/new_project/project/step_6.png
--------------------------------------------------------------------------------
/docs/assets/images/why_software/smart-light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FRCTeam3255/FRC-Java-Tutorial/HEAD/docs/assets/images/why_software/smart-light.png
--------------------------------------------------------------------------------
/docs/assets/images/new_project/default_contents.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FRCTeam3255/FRC-Java-Tutorial/HEAD/docs/assets/images/new_project/default_contents.png
--------------------------------------------------------------------------------
/docs/assets/images/new_project/subsystem/step_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FRCTeam3255/FRC-Java-Tutorial/HEAD/docs/assets/images/new_project/subsystem/step_1.png
--------------------------------------------------------------------------------
/docs/assets/images/new_project/subsystem/step_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FRCTeam3255/FRC-Java-Tutorial/HEAD/docs/assets/images/new_project/subsystem/step_2.png
--------------------------------------------------------------------------------
/docs/assets/images/new_project/subsystem/step_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FRCTeam3255/FRC-Java-Tutorial/HEAD/docs/assets/images/new_project/subsystem/step_3.png
--------------------------------------------------------------------------------
/docs/assets/images/new_project/subsystem/step_4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FRCTeam3255/FRC-Java-Tutorial/HEAD/docs/assets/images/new_project/subsystem/step_4.png
--------------------------------------------------------------------------------
/docs/assets/images/new_project/subsystem/step_5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FRCTeam3255/FRC-Java-Tutorial/HEAD/docs/assets/images/new_project/subsystem/step_5.png
--------------------------------------------------------------------------------
/docs/assets/images/new_project/subsystem/step_6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FRCTeam3255/FRC-Java-Tutorial/HEAD/docs/assets/images/new_project/subsystem/step_6.png
--------------------------------------------------------------------------------
/docs/assets/images/driving_robot/constants/step_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FRCTeam3255/FRC-Java-Tutorial/HEAD/docs/assets/images/driving_robot/constants/step_1.png
--------------------------------------------------------------------------------
/docs/assets/images/driving_robot/constants/step_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FRCTeam3255/FRC-Java-Tutorial/HEAD/docs/assets/images/driving_robot/constants/step_2.png
--------------------------------------------------------------------------------
/docs/assets/images/driving_robot/constants/step_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FRCTeam3255/FRC-Java-Tutorial/HEAD/docs/assets/images/driving_robot/constants/step_3.png
--------------------------------------------------------------------------------
/docs/assets/images/driving_robot/constants/step_4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FRCTeam3255/FRC-Java-Tutorial/HEAD/docs/assets/images/driving_robot/constants/step_4.png
--------------------------------------------------------------------------------
/docs/assets/images/why_software/programming_header.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FRCTeam3255/FRC-Java-Tutorial/HEAD/docs/assets/images/why_software/programming_header.png
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | # FRC Java Tutorial
2 |
3 | A tutorial on how to program a robot for use in the FIRST Robotics Competition.
4 |
5 | Updated for 2021
6 |
7 | Viewable at [https://frcteam3255.github.io/FRC-Java-Tutorial/](https://frcteam3255.github.io/FRC-Java-Tutorial/)
--------------------------------------------------------------------------------
/.markdownlint.json:
--------------------------------------------------------------------------------
1 | {
2 | "default": true,
3 | "line-length": false,
4 | "no-hard-tabs": false,
5 | "no-space-in-code": false,
6 | "blanks-around-fences": false,
7 | "MD005": false,
8 | "MD007": false,
9 | "MD009": false,
10 | "MD045": false,
11 | "MD033": false
12 | }
--------------------------------------------------------------------------------
/docs/version_control/github.md:
--------------------------------------------------------------------------------
1 | # [WIP] Using GitHub
2 |
3 | This page is currently a work in progress. Check back later
4 |
5 |
19 |
--------------------------------------------------------------------------------
/docs/programming/pid.md:
--------------------------------------------------------------------------------
1 | # [WIP] Getting started with PID
2 |
3 | This page is currently a work in progress. Check back later
4 |
5 |
19 |
--------------------------------------------------------------------------------
/docs/programming/super_core.md:
--------------------------------------------------------------------------------
1 | # [WIP] Using SuperCORE
2 |
3 | This page is currently a work in progress. Check back later
4 |
5 |
19 |
--------------------------------------------------------------------------------
/.github/workflows/build.yml:
--------------------------------------------------------------------------------
1 | name: Build MkDocs
2 | on:
3 | pull_request:
4 | branches:
5 | - main
6 | jobs:
7 | build:
8 | runs-on: ubuntu-latest
9 | steps:
10 | - uses: actions/checkout@v4
11 | - uses: actions/setup-python@v5
12 | with:
13 | python-version: 3.x
14 | - run: pip install -r requirements.txt
15 | - run: mkdocs build
16 |
--------------------------------------------------------------------------------
/.github/workflows/main.yml:
--------------------------------------------------------------------------------
1 | name: Publish docs via GitHub Pages
2 | on:
3 | push:
4 | branches:
5 | - main
6 | jobs:
7 | deploy:
8 | runs-on: ubuntu-latest
9 | steps:
10 | - uses: actions/checkout@v2
11 | - uses: actions/setup-python@v2
12 | with:
13 | python-version: 3.x
14 | - run: pip install -r requirements.txt
15 | - run: mkdocs gh-deploy --force
16 |
--------------------------------------------------------------------------------
/template_page.md:
--------------------------------------------------------------------------------
1 | # Page title
2 |
3 |
4 | Subtitle
5 |
6 |
7 | 
8 |
9 | ## Overview
10 |
11 | This section will help you learn to BLANK.
12 |
13 | **See table of contents for a breakdown of this section.**
14 |
15 | ***
16 |
17 | ## Section One
18 |
19 | - Some info
20 | - Some other into
21 | - Some sub info
22 |
23 | ### Section One Subsection
24 |
25 | ***
26 |
27 | ## Section Two
28 |
29 | - Info
30 | - Info 2
31 |
32 | !!! Tip
33 | This is a tip.
34 |
--------------------------------------------------------------------------------
/docs/examples/pid_elevator.md:
--------------------------------------------------------------------------------
1 | # [WIP] PID Driven Elevator
2 |
3 |
4 | Subtitle
5 |
6 |
7 | 
8 |
9 | ## Overview
10 |
11 | This section will help you learn to BLANK.
12 |
13 | **See table of contents for a breakdown of this section.**
14 |
15 | ***
16 |
17 | ## Section One
18 |
19 | - Some info
20 | - Some other into
21 | - Some sub info
22 |
23 | ### Section One Subsection
24 |
25 | ***
26 |
27 | ## Section Two
28 |
29 | - Info
30 | - Info 2
31 |
32 | !!! Tip
33 | This is a tip.
34 |
--------------------------------------------------------------------------------
/docs/examples/pid_shooter.md:
--------------------------------------------------------------------------------
1 | # [WIP] PID Driven Shooter
2 |
3 |
4 | Subtitle
5 |
6 |
7 | 
8 |
9 | ## Overview
10 |
11 | This section will help you learn to BLANK.
12 |
13 | **See table of contents for a breakdown of this section.**
14 |
15 | ***
16 |
17 | ## Section One
18 |
19 | - Some info
20 | - Some other into
21 | - Some sub info
22 |
23 | ### Section One Subsection
24 |
25 | ***
26 |
27 | ## Section Two
28 |
29 | - Info
30 | - Info 2
31 |
32 | !!! Tip
33 | This is a tip.
34 |
--------------------------------------------------------------------------------
/docs/examples/basic_shooter.md:
--------------------------------------------------------------------------------
1 | # [WIP] Basic Shooting Subsystem
2 |
3 |
4 | Subtitle
5 |
6 |
7 | 
8 |
9 | ## Overview
10 |
11 | This section will help you learn to BLANK.
12 |
13 | **See table of contents for a breakdown of this section.**
14 |
15 | ***
16 |
17 | ## Section One
18 |
19 | - Some info
20 | - Some other into
21 | - Some sub info
22 |
23 | ### Section One Subsection
24 |
25 | ***
26 |
27 | ## Section Two
28 |
29 | - Info
30 | - Info 2
31 |
32 | !!! Tip
33 | This is a tip.
34 |
--------------------------------------------------------------------------------
/.vscode/tasks.json:
--------------------------------------------------------------------------------
1 | {
2 | // See https://go.microsoft.com/fwlink/?LinkId=733558
3 | // for the documentation about the tasks.json format
4 | "version": "2.0.0",
5 | "tasks": [
6 | {
7 | "label": "Deploy to GitHub",
8 | "type": "shell",
9 | "command": "mkdocs gh-deploy",
10 | "group": {
11 | "kind": "build",
12 | "isDefault": true
13 | },
14 | "problemMatcher": []
15 | },
16 | {
17 | "label": "Run Locally",
18 | "type": "shell",
19 | "command": "mkdocs serve",
20 | "problemMatcher": [],
21 | "runOptions": {
22 | "runOn": "folderOpen"
23 | }
24 | }
25 | ]
26 | }
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "restructuredtext.confPath": "${workspaceFolder}/docs/source",
3 | "files.exclude": {
4 | "**/.git": true,
5 | "**/.svn": true,
6 | "**/.hg": true,
7 | "**/CVS": true,
8 | "**/.DS_Store": true,
9 | "**/site": true
10 | },
11 | "MarkdownPaste.path": "${workspaceRoot}/docs/assets/images/${fileBasenameNoExtension}",
12 | "cSpell.words": [
13 | "CTRE",
14 | "Driverstation",
15 | "Grayhill",
16 | "Mecanum",
17 | "SRXs",
18 | "Sayasane",
19 | "betterem",
20 | "codehilite",
21 | "drivestation",
22 | "hardcode",
23 | "inlinehilite",
24 | "ints",
25 | "kitbot",
26 | "pymdownx",
27 | "robo",
28 | "robotmap",
29 | "robotpreferences",
30 | "smartdashboard",
31 | "superfences",
32 | "tasklist",
33 | "teleop",
34 | "wpilibj"
35 | ]
36 | }
--------------------------------------------------------------------------------
/docs/setup/imaging_roboRIO.md:
--------------------------------------------------------------------------------
1 | # Imaging the roboRIO
2 |
3 | Flashing the firmware
4 |
5 | 
6 |
7 | ## Overview
8 |
9 | Before we can deploy code to the robot, we must flash a software image on to the roboRIO and possibly update the firmware. This can be accomplished with the roboRIO imaging tool:
10 |
11 | !!! Warning "IMPORTANT NOTE"
12 | The [FRC Game Tools (Windows Only)](imaging_roboRIO.md#installing-the-frc-game-tools) need to be installed to access the roboRIO imaging tool.
13 | ***
14 |
15 | ## Using the roboRIO imaging tool
16 |
17 | Following the instructions linked below will explain how to **image/update** the roboRIO.
18 |
19 | For **Windows ONLY:**
20 |
21 | [Official 2020 FRC roboRIO Imaging guide (Windows only)](https://docs.wpilib.org/en/stable/docs/getting-started/getting-started-frc-control-system/imaging-your-roborio.html){target=_blank}
22 |
--------------------------------------------------------------------------------
/docs/examples/basic_elevator.md:
--------------------------------------------------------------------------------
1 | # [WIP] Basic Elevator Subsystem
2 |
3 |
4 | Subtitle
5 |
6 |
7 | 
8 |
9 | ## Overview
10 |
11 | This section will help you learn to create a basic elevator or lift subsystem.
12 |
13 | This subsystem will contain:
14 |
15 | - Two motors in a single gear box
16 | - Use single encoder to lift to specific distances
17 | - 3 distances 2, 5, 10 inches
18 | - 3 buttons to get to those distances
19 | - Hard stop safeties using limit switches
20 | - Top and bottom
21 | - Run motors at 25% speed so we can watch easier
22 |
23 | **See table of contents for a breakdown of this section.**
24 |
25 | ***
26 |
27 | ## Section One
28 |
29 | - Some info
30 | - Some other into
31 | - Some sub info
32 |
33 | ### Section One Subsection
34 |
35 | ***
36 |
37 | ## Section Two
38 |
39 | - Info
40 | - Info 2
41 |
42 | !!! Tip
43 | This is a tip.
44 |
--------------------------------------------------------------------------------
/docs/basics/roboRIO.md:
--------------------------------------------------------------------------------
1 | # roboRIO
2 |
3 | The Brains of the Bot!
4 |
5 | 
6 |
7 | ## The roboRIO Basics
8 |
9 | - The roboRIO is the brain of an FRC robot.
10 | - It is the main processing unit and is where the code is stored and run.
11 | - It is very similar to something like a Raspberry Pi, it’s a mini computer!
12 | - The roboRIO can connect to many different devices such as **motor controllers, servos, and sensors** through its various interface connections such as:
13 | - **Digital I/O, PWM, CAN Bus, Ethernet, USB, MXP**
14 |
15 | ***
16 |
17 | ## The roboRIO IO
18 |
19 | - **Digital IO** (DIO) used for sensors and switches
20 | - **PWM** used for motor controllers and servos
21 | - **CAN** used for motor controllers and sensors
22 | - **MXP** used for functionality expansion
23 | - Check the roboRIO [user manual](http://www.ni.com/pdf/manuals/375274a.pdf){target=_blank} for more details
24 |
25 | 
26 |
--------------------------------------------------------------------------------
/docs/basics/vscode_tips.md:
--------------------------------------------------------------------------------
1 | # Visual Studio Code Tips
2 |
3 | Making life easier
4 |
5 | 
6 |
7 | ## 💡 Using the light bulb (quick fixes)
8 |
9 | 
10 |
11 | - When auto complete is available, click enter on the correct completion to auto import classes.
12 | - If this is not done an error can occur denoted by an underline on what you just typed. To fix this, click on the error and click the light bulb that pops up. Then click import.
13 | - From this point on this tutorial will assume you are doing this on your own so if errors occur, click the light bulb and see if it suggest importing something.
14 | - The light bulb can also be used to make programming easier by auto creating things for us. This tutorial will go over that in future sections
15 |
16 |
17 |
18 |
30 |
--------------------------------------------------------------------------------
/docs/basics/sensors.md:
--------------------------------------------------------------------------------
1 | # Sensors
2 |
3 | How does the robot see?
4 |
5 | 
6 |
7 | ## Some types of sensors
8 |
9 | - **Limit Switches** - detects contact
10 | - **Camera** - provides sight
11 | - **Encoders** - measures rotational or linear motion
12 | - **Ultrasonic** - measures distances
13 | - **Gyroscope** - measures orientation
14 | - **Processed Vision** - measures target's distance, angle, and offset from robot
15 | - For more info on sensors see: [High Tech High Top Hat Technicians](http://tophattechnicians.com){target=_blank} - [Electrical Tutorial](https://drive.google.com/file/d/1ip54fjNDFaq-ZWw9lQrZj6vXamX33QDP/view){target=_blank}
16 |
17 | | Limit Switch | Grayhill brand Quadrature Encoder | Kauai Labs navX Gyro/ Accelerometer |
18 | | :--------------------------------------------------------: | :-------------------------------------------------------: | :----------------------------------------------: |
19 | |  |  |  |
20 |
--------------------------------------------------------------------------------
/docs/index.md:
--------------------------------------------------------------------------------
1 | # Introductions
2 |
3 | [](https://www.firstinspires.org/robotics/frc/){target=_blank}
4 |
5 | The unofficial FIRST Robotics Competition Java Programming Tutorial.
6 |
7 | !!! Info
8 | Updated for the 2021 Season
9 | Last updated: 9/30/21
10 |
11 | **Disclaimer:** Some screenshots may have different colors, icons, more/less folders/files than you due to themes or personal settings. This is normal and should not impact the tutorial. If you still have any questions please contact us.
12 |
13 | ## Powered by
14 |
15 | [](https://SuperNURDs.com/){target=_blank}
16 |
17 | ## Contributors
18 |
19 | | Name | Team | Team Role |
20 | | :----------------------------------------------: | :--------------------------------------------: | :-------: |
21 | | [Tayler Uva](https://Tayler.Tech){target=_blank} | [3255](https://SuperNURDs.com/){target=_blank} | Coach |
22 | | Isaac Sayasane | [3255](https://SuperNURDs.com/){target=_blank} | Alumni |
23 | | Sharon Riggs | [6995](https://frc6995.org){target=_blank} | Mentor |
24 |
--------------------------------------------------------------------------------
/docs/why_software.md:
--------------------------------------------------------------------------------
1 |
2 | # What is software
3 |
4 | What is software? Why should you care?
5 |
6 |
7 | 
8 |
9 | ## Where is software
10 |
11 | - Everywhere!
12 | - Games, apps, websites
13 | - All smart devices
14 | - It’s the stuff on your phone and computer that you see and interact with
15 | - It is also handling complex parts behind what you see and interact with
16 | - Even things that didn't before have software now
17 | - Cars, Planes, Ovens, Light Bulbs, Garbage Trucks, Children's Toys, etc.
18 |
19 | 
20 |
21 | ***
22 |
23 | ## But what is it
24 |
25 | - It’s the language of computers!
26 | - Logical building blocks for controlling the devices around us
27 | - Software makes devices smart
28 | - Software allows us to automate things
29 |
30 | 
31 |
32 | ## Why should you do software
33 |
34 | - Learn Creative Problem Solving
35 | - Peek be hind the curtain of what makes technology tick
36 | - Better understanding and appreciation of technology
37 | - Programming is the FUTURE
38 | - Your imagination is your only limitation
39 | - Low barrier to entry
40 | - Only need a computing device (can be a cheap $35 computer or even your phone)
41 | - Lucrative job opportunities
42 | - Many job opportunities from Game Development to App Development to Robotics
43 |
44 | 
45 |
46 | ***
47 |
--------------------------------------------------------------------------------
/mkdocs.yml:
--------------------------------------------------------------------------------
1 | # Navigation
2 | nav:
3 | - Home:
4 | - 'index.md'
5 | - 'why_software.md'
6 | - Programming Basics:
7 | - 'basics/roboRIO.md'
8 | - 'basics/sensors.md'
9 | - 'basics/wpilib.md'
10 | - 'basics/java_basics.md'
11 | - 'basics/vscode_tips.md'
12 | # - 'basics/driverstation_tips.md'
13 | - FRC Development Environment Setup:
14 | - 'setup/install_software.md'
15 | - 'setup/install_other.md'
16 | - 'setup/imaging_roboRIO.md'
17 | - FRC Programming:
18 | - 'programming/new_project.md'
19 | - 'programming/driving_robot.md'
20 | - 'programming/deploying.md'
21 | - 'programming/using_sensors.md'
22 | - 'programming/pneumatics.md'
23 | - 'programming/shuffleboard.md'
24 | - 'programming/robotpreferences.md'
25 | - 'programming/autonomous.md'
26 | - 'programming/pid.md'
27 | # - 'programming/super_core.md'
28 | - Example Subsystems:
29 | - 'examples/basic_elevator.md'
30 | - 'examples/basic_shooter.md'
31 | - 'examples/pid_elevator.md'
32 | - 'examples/pid_shooter.md'
33 | - Version Control:
34 | - 'version_control/github.md'
35 | - Improve the Documentation:
36 | - 'contributing.md'
37 |
38 | # Setup
39 | site_name: FRC Java Programming
40 | repo_name: Tutorial Bot
41 | repo_url: https://github.com/FRCTeam3255/FRC-Java-Tutorial/tree/main
42 | edit_uri: https://github.com/FRCTeam3255/FRC-Java-Tutorial/edit/main/Docs_Source/docs/
43 | site_author: Tayler Uva
44 |
45 | # Theme
46 | theme:
47 | name: 'readthedocs'
48 | favicon: assets/favicon.png
49 | icon:
50 | logo: assets/favicon.png
51 | use_directory_urls: false
52 |
53 | # Extensions
54 | markdown_extensions:
55 | - admonition
56 | - pymdownx.superfences
57 | - pymdownx.critic
58 | - pymdownx.details
59 | - pymdownx.betterem
60 | - pymdownx.tasklist
61 | - pymdownx.extra
62 | - pymdownx.inlinehilite
63 | - pymdownx.highlight:
64 | css_class: 'codehilite'
65 | - toc:
66 | permalink: "#"
67 |
68 | # Plugins
69 | plugins:
70 | - search
71 | - minify:
72 | minify_html: true
73 | minify_js: true
74 |
75 | google_analytics:
76 | - UA-47256977-4
77 | - auto
--------------------------------------------------------------------------------
/docs/programming/deploying.md:
--------------------------------------------------------------------------------
1 | # Deploying Robot Code
2 |
3 | Bring your creation to life!
4 |
5 | 
6 |
7 | ## Overview
8 |
9 | This section will help you learn to deploy code to your robot.
10 |
11 | **See table of contents for a breakdown of this section.**
12 |
13 | ***
14 |
15 | ## How to deploy
16 |
17 | ### Hardware
18 |
19 | To deploy code, first make sure your computer is connected to the robot in **ONE** of the following ways:
20 |
21 | - **USB**
22 | - **Ethernet**
23 | - **Robot's Wireless Network**
24 |
25 | ### Software
26 |
27 | !!! Note
28 | Make sure your team number in **wpilib_preferences.json** in the **.wpilib** folder is set to the same team number your roboRIO was programmed for (it should be the number you set when creating the project and you will NOT need to check this every time as it should not change by itself).
29 |
30 | !!! summary ""
31 | **1)** Select the **W icon** from the tab bar or use the shortcut by holding down **Ctrl+Shift+P** at the same time. (Replace ctrl with cmd on macOS)
32 |
33 | 
34 |
35 | !!! summary ""
36 | **2)** Type and hit enter or select: WPILib: Deploy Robot Code
37 |
38 | 
39 |
40 | !!! Tip
41 | Alternatively you can do one of the following:
42 |
43 | - Use **Shift+F5** at any time to deploy. (you may also need to hold fn depending on your computer configuration)
44 | - Right-click on the build.gradle file in the project hierarchy and select "Build Robot Code”
45 | - Open the shortcut menu indicated by the ellipses in the top right corner of the VS Code window and select "Build Robot Code"
46 |
47 | ***
48 |
49 | ## Testing
50 |
51 | 1. Open up the DriverStation software on any computer that has it installed.
52 | 2. Enable the robot
53 | 3. Try moving the joysticks on your controller when enabled.
54 | 1. If it doesn’t, check your port numbers for your controller, axes, and motor controllers
55 |
56 |
--------------------------------------------------------------------------------
/docs/setup/install_other.md:
--------------------------------------------------------------------------------
1 | # Installing Other Software
2 |
3 | ## Overview
4 |
5 | There are other pieces of software necessary for programming a robot depending on your circumstances. If you are using Talon or Spark Max motor controllers, those have their own debugging tools that are necessary. If you plan on motion profiling for your drivetrain in autonomous, (check our [motion profiling tutorial] for more on that) you will need to download a pathing software as well.
6 |
7 | **See table of contents for a breakdown of this section.**
8 |
9 |
10 | ## Installing Pheonix software (for talon motor controllers)
11 |
12 | If you are using Talons on your robot, the Pheonix tuner software is a must have. It allows you to deploy software updates, debug/test your talons, and name/organize your talons.
13 |
14 | ### Installing the Pheonix suite
15 |
16 | For **Windows ONLY:**
17 |
18 | [Download link for CTRE Framework (next to 'Installer')](http://www.ctr-electronics.com/hro.html#product_tabs_technical_resources){target=_blank}
19 |
20 |
21 | ***
22 |
23 | ## Installing Spark Max Client
24 |
25 | If you are using Spark Max motor controllers on your robot, the Spark Max tuner software is a must have. It allows you to deploy software updates, debug/test your Spark maxes, and name/organize your Spark Maxes.
26 |
27 | ### Installing the Spark Max Client
28 |
29 | For **Windows ONLY:**
30 |
31 | [Download Spark Max Client (click 'Download Latest SPARK MAX Client)](https://www.revrobotics.com/sparkmax-software/){target=_blank}
32 |
33 | ***
34 |
35 | ## Installing PathPlanner
36 |
37 | In order to utilize motion profiling on a drivetrain, it is extremely helpful to have a tool such as Pathplanner. Pathplanner allows for seamless creation and deployment of motion profiles from your laptop to your robot, and has a nice interface for doing so. There are other available tools we may add in the future if pathplanner does not suit your needs, but we at 3255 found it comprehensive for our motion profiling needs (note, this software is only for driving in autonomous, it is likely not useful for other mechanisms).
38 |
39 | ### Installing Pathplanner
40 |
41 | For **Windows ONLY:**
42 |
43 | [Pathplanner Github (to install, click on the latest version under releases on the right)](https://github.com/mjansen4857/PathPlanner){target=_blank}
44 |
--------------------------------------------------------------------------------
/docs/assets/css/dark_theme.css:
--------------------------------------------------------------------------------
1 | /*
2 | //////////////////
3 | // Main content //
4 | //////////////////
5 | */
6 |
7 | /*
8 | Default text color
9 | and background color
10 | */
11 | .md-main {
12 | color: #F5F5F5 !important;
13 | background-color: #212121 !important;
14 | }
15 |
16 | /*
17 | Main headlines
18 | */
19 | .md-main h1 {
20 | color: white !important;
21 | }
22 |
23 | /*
24 | Tables
25 | */
26 | table {
27 | background-color: #616161 !important;
28 | }
29 |
30 | tbody {
31 | background-color: #484848 !important;
32 | }
33 |
34 | /*
35 | Blockquotes
36 | */
37 | .md-typeset blockquote {
38 | color: rgba(255,255,255,0.8) !important;
39 | border-color: rgba(255,255,255,0.54) !important;
40 | }
41 |
42 | /*
43 | ////////////////////
44 | // Navigation bar //
45 | ////////////////////
46 | */
47 |
48 | /*
49 | Left and right toc scrollbar
50 | */
51 | .md-sidebar__scrollwrap::-webkit-scrollbar-thumb {
52 | background-color: #E0E0E0 !important;
53 | }
54 |
55 |
56 |
57 | .md-nav {
58 | color: #F5F5F5 !important;
59 | background-color: #212121 !important;
60 | }
61 |
62 | /*
63 | Arrow Left Icon
64 | */
65 | html .md-nav--primary .md-nav__title:before {
66 | color: #FAFAFA !important;
67 | }
68 |
69 | .md-nav__title {
70 | color: rgba(255,255,255,1) !important;
71 | background-color: #212121 !important;
72 | }
73 |
74 | /*
75 | Arrow Right Icon
76 | */
77 | .md-nav--primary .md-nav__link:after {
78 | color: #FAFAFA !important;
79 | }
80 |
81 | .md-nav__list {
82 | color: rgba(255,255,255,1) !important;
83 | background-color: #212121 !important;
84 | }
85 |
86 | .md-nav__item {
87 | color: rgba(255,255,255,1) !important;
88 | background-color: #212121 !important;
89 | }
90 |
91 | .md-nav__link[data-md-state=blur] {
92 | color: rgba(255,255,255,0.54) !important;
93 | }
94 |
95 | /*
96 | ////////////
97 | // Search //
98 | ////////////
99 | */
100 |
101 | /*
102 | scroll bar
103 |
104 | attention:
105 | background is scroll handle color!
106 | */
107 | .md-search__scrollwrap::-webkit-scrollbar-thumb {
108 | background-color: #E0E0E0 !important;
109 | }
110 | /*
111 | scroll bar background color
112 | */
113 | .md-search__scrollwrap {
114 | background-color: #424242 !important;
115 | }
116 |
117 | /*
118 | Icon color
119 | */
120 | .md-search-result__article--document:before {
121 | color: #EEEEEE !important;
122 | }
123 |
124 | /*
125 | headline color and
126 | result list background
127 | */
128 | .md-search-result__list {
129 | color: #EEEEEE !important;
130 | background-color: #212121 !important;
131 | }
132 |
133 | /*
134 | result info/count
135 | */
136 | .md-search-result__meta {
137 | background-color: #EEEEEE !important;
138 | }
139 |
140 | /*
141 | article preview text color
142 | */
143 | .md-search-result__teaser {
144 | color: #BDBDBD !important;
145 | }
146 |
--------------------------------------------------------------------------------
/docs/setup/install_software.md:
--------------------------------------------------------------------------------
1 | # Installing Necessary Software
2 |
3 | Lets get started
4 |
5 | {: style="height:150px"}
6 | {: style="height:150px"}
7 |
8 | ## Overview
9 |
10 | Before we can start programing a robot we must install the necessary software for programming and driving the robot.
11 |
12 | **See table of contents for a breakdown of this section.**
13 |
14 | !!! tip
15 | You can install both the **Development Tools** and the **FRC Game Tools** on the same computer or separate computers. However many teams (3255 included) have a development laptop (with both) and a dedicated driverstation laptop (with only the FRC Game Tools) that often stays disconnected from the internet.
16 |
17 | ***
18 |
19 | ## Installing Java Development Tools
20 |
21 | If all you are doing is writing and deploying code to a robot, all you need are the development tools. Following the instructions linked below will get you set up with a development environment and get you setup with all the tools necessary to **program** a robot.
22 |
23 | ### Installing Java and Visual Studio Code (VSCode)
24 |
25 | For **Windows, macOS, or Linux:**
26 |
27 | [Official FRC installation guide (Windows, macOS, or Linux)](https://docs.wpilib.org/en/stable/docs/getting-started/getting-started-frc-control-system/wpilib-setup.html){target=_blank}
28 |
29 | !!! Warning "IMPORTANT NOTE"
30 | These tools only allow you to program and deploy code to an already imaged roboRIO. They do not allow you to drive the robot or image/update the roboRIO. To accomplish those tasks you must install the [FRC Game Tools](#installing-the-frc-game-tools).
31 |
32 | ***
33 |
34 | ## Installing the FRC Game Tools
35 |
36 | If all you are doing is driving an already programmed robot or imaging/updating the roboRIO all you need is the FRC Game Tools. Following the instructions linked below will get you set up with the tools to **drive** the robot and **image/update** the roboRIO.
37 |
38 | ### Installing the Driverstation software and roboRIO imaging tool
39 |
40 | For **Windows ONLY:**
41 |
42 | [Official FRC installation guide (Windows only)](https://docs.wpilib.org/en/stable/docs/getting-started/getting-started-frc-control-system/frc-game-tools.html){target=_blank}
43 |
44 | !!! Warning "IMPORTANT NOTE"
45 | These tools only allow you to drive the robot and image/update a roboRIO. They do not allow you to program the robot. To accomplish those tasks you must install the [Java Development Tools](#installing-java-development-tools).
46 |
47 | ***
48 |
49 | ## Installing the FRC Radio Configuration Utility
50 |
51 | In order to enable wireless connectivity to the robot outside of FRC events or to allow connectivity to other network attached devices (i.e.Limelight Vision Camera), you must configure the robot's radio. Following the instructions linked below will get you set up with the Radio Configuration Utility and how to program the radio.
52 |
53 | ### Installing the Radio Configuration Utility and Programming the Radio
54 |
55 | For **Windows ONLY:**
56 |
57 | [Official FRC Radio Configuration Utility and Use guide (Windows only)](https://docs.wpilib.org/en/stable/docs/getting-started/getting-started-frc-control-system/radio-programming.html){target=_blank}
58 |
--------------------------------------------------------------------------------
/docs/contributing.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | Helping out with the project!
4 |
5 | ## Example Project Code
6 |
7 | If you make Example Project Code changes please contribute changes that reflect this in the Documentation. This will make it easier for us and more likely that your contribution will be approved.
8 |
9 | ## Documentation
10 |
11 | If you make documentation changes please contribute changes that reflect this in the Example Project Code. This will make it easier for us and more likely that your contribution will be approved.
12 |
13 | There are a couple of ways to contribute to this project:
14 |
15 | - [Via the web](#via-the-web)
16 | - [Via local source](#via-local-source)
17 |
18 | ***
19 |
20 | ## Via the web
21 |
22 | ### Editing Pages
23 |
24 | On each page there is an option to edit the page. Any changes you make through this option will be submitted and become live once they are approved.
25 |
26 | > The edit icon looks like this:
27 | >
28 | > 
29 |
30 | Alternatively you could create a pull request and clone the repository
31 |
32 | ### New Pages
33 |
34 | You can help the project by making new pages. Any pages you make will become live once they are approved.
35 |
36 | [Click here to create a new page](https://github.com/FRCTeam3255/FRC-Java-Tutorial/new/main/Docs_Source/docs){target=_blank}
37 |
38 | Please use the [New Page Template](#new-page-template)
39 |
40 | [Click here to see tips on creating markdown documents](https://www.markdownguide.org/cheat-sheet/){target=_blank}
41 |
42 | !!! Warning
43 | Make sure all documentation files end in `.md`
44 |
45 | !!! Tip
46 | You can add to a certain tab by appending `/tab_name/` to the file name
47 |
48 | !!! Tip
49 | Visit [Admonitions (call-out) references](https://squidfunk.github.io/mkdocs-material/reference/admonitions/) for a list off call-outs like this one.
50 |
51 | ***
52 |
53 | ## Via local source
54 |
55 | ### Prerequisites
56 |
57 | 1. [Install GitHub Desktop](https://desktop.github.com){target=_blank} (Beginner) or [Install Git](https://git-scm.com){target=_blank} (Expert)
58 | 2. [Install Python](https://www.python.org){target=_blank}
59 | 3. [Install pip requirements](https://raw.githubusercontent.com/FRCTeam3255/FRC-Java-Tutorial/main/Docs_Source/requirements.txt){target=_blank}
60 | 1. Run one of the following commands. Try each one in order until successful.
61 | - `pip install -r requirements.txt`
62 | - `python -m pip install -r requirements.txt`
63 | - `py -m pip install -r requirements.txt`
64 |
65 | ### Creating local edits
66 |
67 | 1. Visit and fork the repository.
68 | 2. Clone your the newly created fork to your machine and open it
69 | 3. Run the command `mkdocs serve` to open up a live local version of the project in your browser
70 | - If `mkdocs serve` does not work on its own, try each one in order until successful:
71 | - `python -m mkdocs serve`
72 | - `py -m mkdocs serve`
73 | 4. Make your changes or additions in the `docs` directory.
74 | - Please maintain the organizational folder structure.
75 | 5. If added a new page, add the relative url to the `mkdocs.yml` file in the `# Navigation` (`nav:`) section.
76 | 1. For new pages please use the [New Page Template](#new-page-template)
77 | 2. [Click here to see tips on creating markdown documents](https://www.markdownguide.org/cheat-sheet/){target=_blank}
78 |
79 | ### Pushing your local edits to the web
80 |
81 | 1. Commit your changes
82 | 2. Push your changes to GitHub
83 | 3. Back on the webpage for your fork of the project select Pull Request
84 | 1. Create a new pull request
85 | 4. Wait for the pull request to be approved.
86 |
87 | ***
88 |
89 | ## New Page Template
90 |
91 | Please copy this code as a template to create your new page
92 |
93 | ```markdown
94 | # Page title
95 |
96 |
97 | Subtitle
98 |
99 |
100 | 
101 |
102 | ## Overview
103 |
104 | This section will help you learn to BLANK.
105 |
106 | **See table of contents for a breakdown of this section.**
107 |
108 | ***
109 |
110 | ## Section One
111 |
112 | - Some info
113 | - Some other into
114 | - Some sub info
115 |
116 | ### Section One Subsection
117 |
118 | ***
119 |
120 | ## Section Two
121 |
122 | - Info
123 | - Info 2
124 |
125 | !!! Tip
126 | This is a tip.
127 | ```
128 |
--------------------------------------------------------------------------------
/docs/programming/shuffleboard.md:
--------------------------------------------------------------------------------
1 | # [WIP] Using Shuffleboard
2 |
3 |
4 |
5 | ## Overview
6 |
7 | In this section we will be going over
8 |
9 | 1. Using and organizing the Shuffleboard
10 | 2. Creating the Telemetry subsystem and adding buttons and data to be viewed in Shuffleboard
11 |
12 | ***
13 |
14 | ## What is Shuffleboard
15 |
16 | - **Shuffleboard** is one of the boards the driverstation displays robot data with
17 | - It can have widgets like graphs, camera streams, and meters
18 | - Unique to **shuffleboard** is the ability to have tabs for different boards
19 |
20 | ## What is Telemetry
21 |
22 | - **Telemetry** is where we add data to be viewed or command buttons on **shuffleboard** or **smartdashboard**
23 | - For this section of our tutorial we will be adding switch and encoder data to **shuffleboard**
24 |
25 | ## Creating the Telemetry Subsystem
26 |
27 | !!! summary ""
28 | **1)** Create a new **Subsystem** called **Telemetry**
29 |
30 | !!! summary ""
31 | **2)** Create a constructor for the **Telemetry** class
32 |
33 | - The constructor is where we will create buttons for shuffleboard
34 |
35 | !!! summary ""
36 | **3)** Inside type:
37 |
38 | ```java
39 | SmartDashboard.putData(“Reset Drive Encoder”, new DriveResetEncoder());
40 | ```
41 |
42 | !!! summary ""
43 | **4)** Create a public method called update
44 |
45 | - This method will run periodically in Robot.java to update sensor data on shuffleboard
46 |
47 | !!! summary ""
48 | **5)** Inside type:
49 |
50 | ```java
51 | SmartDashboard.putNumber(“Drivetrain Encoder Count”, Robot.m_drivetrain.getDriveEncoderCount());
52 | ```
53 |
54 | !!! summary ""
55 | **6)** Do the same for the **getDriveEncoderDistance** method
56 |
57 | !!! summary ""
58 | **7)** Try adding the **Shooter** Subsystem commands and sensor methods where they should be
59 |
60 | ??? Example
61 |
62 | Your full **Telemetry.java** should look like this
63 |
64 | ```java
65 | package frc.robot.subsystems;
66 |
67 | import edu.wpi.first.wpilibj.command.Subsystem;
68 | import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard;
69 | import frc.robot.Robot;
70 | import frc.robot.commands.*;
71 |
72 | /**
73 | * Add your docs here.
74 | */
75 | public class Telemetry extends Subsystem {
76 | // Put methods for controlling this subsystem
77 | // here. Call these from Commands.
78 |
79 | public Telemetry() {
80 | // Drivetrain
81 | SmartDashboard.putData("Reset Drive Encoder", new DriveResetEncoder());
82 |
83 | // Shooter
84 | SmartDashboard.putData("Shooter Up", new ShooterUp());
85 | SmartDashboard.putData("Shooter Down", new ShooterDown());
86 | SmartDashboard.putData("Shooter Up Auto", new ShooterUpAuto());
87 | }
88 |
89 | public void update() {
90 | // Drivetrain
91 | SmartDashboard.putNumber("Drive Encoder Count", Robot.m_drivetrain.getDriveEncoderCount());
92 |
93 | // Shooter
94 | SmartDashboard.putBoolean("Shooter Switch", Robot.m_shooter.isShooterSwitchClosed());
95 | }
96 |
97 | @Override
98 | public void initDefaultCommand() {
99 | // Set the default command for a subsystem here.
100 | // setDefaultCommand(new MySpecialCommand());
101 | }
102 | }
103 | ```
104 |
105 | ## Adding The Telemetry Subsystem to Robot.java
106 |
107 | !!! summary ""
108 | **1)** When adding **Telemetry** to **Robot.java**, in **robotInit** we must add **Telemetry** after the other subsystems
109 |
110 | - This is because the **Telemetry** subsystem relies on methods that are created in other subsystems before it
111 | - It can be added before or after **OI** since they don’t use methods from each other
112 |
113 |
114 |
115 | !!! summary ""
116 |
117 | **2)** It is **important** that we add the **update** method to **disabledPeriodic, autonomousPeriodic**, and **teleopPeriodic** so that the **Shuffleboard** is always being updated with information on our sensors.
118 |
119 | ??? Example
120 |
121 | The code you typed before **robotInit** should be this
122 |
123 | ```java
124 | public static Telemetry m_telemetry;
125 | ```
126 |
127 | The code you typed in **robotInit** should be this
128 |
129 | ```java
130 | m_telemetry = new Telemetry(); //This must be initialized after all other robot subsystems
131 | ```
132 |
133 | The code you typed in **disabledPeriodic, autonomousPeriodic**, and **teleopPeriodic** should be this
134 |
135 | ```java
136 | Robot.m_telemetry.update();
137 | ```
138 |
139 | ## Testing Shuffleboard
140 |
141 |
142 |
143 | - After saving and deploying code, open the driver station
144 | - Click the gear on the left side and configure your team number and set the dashboard type to “ShuffleBoard”
145 | - If you are still connected to the robot you should see boxes for the buttons and data we added in Telemetry
146 |
147 | ## Using Shuffleboard
148 |
149 |
150 |
--------------------------------------------------------------------------------
/docs/programming/robotpreferences.md:
--------------------------------------------------------------------------------
1 | # [WIP] Using RobotPreferences
2 |
3 |
4 |
5 | ## Overview
6 |
7 | In this section we will be going over
8 |
9 | 1. Creating and using RobotPreferences in shuffleboard
10 | 2. How to convert encoder counts to inches
11 |
12 | ***
13 |
14 | ## What Are RobotPreferences
15 |
16 | - On SmartDashboard or ShuffleBoard there is a widget called Robot Preferences that can store variables that can be quickly changed
17 | - For example you might have a variable that changes PID values which can be changed from Robot Preferences on SmartDashboard/ShuffleBoard
18 | - For this section of our tutorial we will create a robot preference called driveEncoderCountsPerFoot
19 |
20 | ## Creating RobotPreferences
21 |
22 | !!! summary ""
23 | **1)** Create a new **empty class** called **RobotPreferences**
24 |
25 | - This is where we store all of our **RobotPreferences** to access anywhere
26 | - If we want to use a **RobotPreference** we call RobotPreferences.preferenceName()
27 |
28 | !!! summary ""
29 | **2)** Inside the constructor type:
30 |
31 | ```java
32 | public static double driveEncoderCountsPerFoot(){
33 | return Preferences.getInstance().getDouble(“driveEncoderCountsPerFoot”, 1.0);
34 | }
35 | ```
36 |
37 | - The format for creating a RobotPreference is
38 |
39 | ```java
40 | public static variableType preferenceName(){
41 | return Preferences.getInstance().getVariableType("preferenceName", value);
42 | ```
43 |
44 | ??? Example
45 |
46 | Your full **RobotPreferences.java** should look like this
47 |
48 | ```java
49 | package frc.robot;
50 |
51 | import edu.wpi.first.wpilibj.Preferences;
52 |
53 | /**
54 | * Add your docs here.
55 | */
56 | public class RobotPreferences {
57 | // Drivetrain
58 | /**
59 | * Default value is 1.0
60 | */
61 | public static double driveEncoderCountsPerFoot() {
62 | return Preferences.getInstance().getDouble("driveEncoderCountsPerFoot", 1.0);
63 | }
64 |
65 | }
66 | ```
67 |
68 | ## Creating getDriveEncoderDistance Method
69 |
70 | - We will use this **RobotPreference** to help us create a method that can keep track of the distance our robot has driven in inches
71 |
72 | !!! summary ""
73 | **1)** Create a method called **getDriveEncoderDistance** inside of **Drivetrain**
74 |
75 | !!! summary ""
76 | **2)** Inside type:
77 |
78 | ```java
79 | return (getDriveEncoderCount() / RobotPreferences.driveEncoderCountsPerFoot()) * 12;
80 | ```
81 |
82 | - This will divide the current encoder count by however many counts there are in a foot then multiply that number by 12 to give us the encoder distance in inches
83 |
84 | !!! Note
85 | You may need to invert this value if your encoder counts backward when the robot is driving forward
86 |
87 | !!! Example
88 |
89 | The code you typed should be this
90 |
91 | ```java
92 | public double getDriveEncoderDistance() {
93 | return (getDriveEncoderCount() / RobotPreferences.driveEncoderCountsPerFoot()) * 12;
94 | }
95 | ```
96 |
97 | !!! summary ""
98 | **3)** Add the method to the **update** method in **Telemetry**
99 |
100 | ## Using RobotPreferences
101 |
102 |
103 |
104 | - After deploying the code to your robot find the **RobotPreferences** widget and add it to your page
105 | - Click the add button and enter the **string** of the **RobotPreference** and its type (doubles and ints are numbers)
106 | - If you double click on the preference value you will notice that you can change its value
107 | - If you change a preference value it will update **immediately**
108 |
109 | !!! Tip
110 | If you want to save your robot preference values that you've changed make sure you hardcode them in **RobotPreferences.java** later or take a picture if you want to use them again later
111 |
112 | ## Measuring Distance Using Encoders
113 |
114 | - Right now the encoders tell us distance in terms of encoder counts
115 | - We will use our **driveEncoderCountsPerFoot** preference to save how many counts there are when the robot drives 1 foot
116 |
117 | !!! summary ""
118 | **1)** Move the wheel on your robot with the **Drivetrain** encoder attached 1 foot or drive your robot 1 foot
119 |
120 | !!! summary ""
121 | **2)** Read how many counts your encoder has in the **Drive Encoder Count** window
122 |
123 | - If you want to measure again press the **Reset Drive Encoder** command button to reset the **Drivetrain** encoder count
124 |
125 | !!! summary ""
126 | **3)** Change the value of **driveEncoderCountsPerFoot** in the widget to this number
127 |
128 | !!! summary ""
129 | **4)** Reset the **Drivetrain** encoder and move the wheel 1 foot or drive the robot 1 foot again
130 |
131 | !!! summary ""
132 | **5)** Make sure your **Drive Encoder Distance** window reads approximately 12 (this is in inches)
133 |
134 | - If not repeat these steps again
135 |
136 | !!! summary ""
137 | **6)** Save your **RobotPreferences** widget with this value
138 |
139 | !!! summary ""
140 | **7)** Hardcode this value in **RobotPreferences.java** in the **driveEncoderCountsPerFoot** method incase you cannot recover your **RobotPreferences** save
141 |
--------------------------------------------------------------------------------
/docs/assets/css/codehilite.css:
--------------------------------------------------------------------------------
1 | /*
2 | /////////////////
3 | // Inline Code //
4 | /////////////////
5 | */
6 |
7 | .md-typeset code {
8 | background-color: #424242;
9 | color: #F5F5F5;
10 | margin: 0;
11 | padding: 0.07353em 0.29412em;
12 | box-shadow: none;
13 | }
14 |
15 | /*
16 | /////////////////
17 | // Code Blocks //
18 | /////////////////
19 | */
20 |
21 | /*
22 | line number
23 | */
24 | .linenos {
25 | color: #F5F5F5 !important;
26 | background-color: #313131 !important;
27 | }
28 |
29 | /*
30 | code block background
31 | */
32 | .codehilite {
33 | background-color: #424242 !important;
34 | }
35 |
36 | /*
37 | scroll bar size
38 | */
39 |
40 | .md-typeset .codehilite::-webkit-scrollbar {
41 | height: 1rem !important;
42 | }
43 |
44 | /*
45 | actual syntax highlighting
46 | */
47 | .codehilite pre { color: #FAFAFA !important; background-color: transparent !important; }
48 | .codehilite .hll { background-color: #272822 !important; }
49 | .codehilite .c { color: #a1a1b6 !important } /* Comment */
50 | .codehilite .err { color: #960050 !important; background-color: #1e0010 !important } /* Error */
51 | .codehilite .k { color: #66d9ef !important } /* Keyword */
52 | .codehilite .l { color: #ae81ff !important } /* Literal */
53 | .codehilite .n { color: #f8f8f2 !important } /* Name */
54 | .codehilite .o { color: #f92672 !important } /* Operator */
55 | .codehilite .p { color: #f8f8f2 !important } /* Punctuation */
56 | .codehilite .cm { color: #a1a1b6 !important } /* Comment.Multiline */
57 | .codehilite .cp { color: #a1a1b6 !important } /* Comment.Preproc */
58 | .codehilite .c1 { color: #a1a1b6 !important } /* Comment.Single */
59 | .codehilite .cs { color: #a1a1b6 !important } /* Comment.Special */
60 | .codehilite .ge { font-style: italic !important } /* Generic.Emph */
61 | .codehilite .gs { font-weight: bold !important } /* Generic.Strong */
62 | .codehilite .kc { color: #66d9ef !important } /* Keyword.Constant */
63 | .codehilite .kd { color: #66d9ef !important } /* Keyword.Declaration */
64 | .codehilite .kn { color: #f92672 !important } /* Keyword.Namespace */
65 | .codehilite .kp { color: #66d9ef !important } /* Keyword.Pseudo */
66 | .codehilite .kr { color: #66d9ef !important } /* Keyword.Reserved */
67 | .codehilite .kt { color: #66d9ef !important } /* Keyword.Type */
68 | .codehilite .ld { color: #e6db74 !important } /* Literal.Date */
69 | .codehilite .m { color: #ae81ff !important } /* Literal.Number */
70 | .codehilite .s { color: #e6db74 !important } /* Literal.String */
71 | .codehilite .na { color: #a6e22e !important } /* Name.Attribute */
72 | .codehilite .nb { color: #f8f8f2 !important } /* Name.Builtin */
73 | .codehilite .nc { color: #a6e22e !important } /* Name.Class */
74 | .codehilite .no { color: #66d9ef !important } /* Name.Constant */
75 | .codehilite .nd { color: #a6e22e !important } /* Name.Decorator */
76 | .codehilite .ni { color: #f8f8f2 !important } /* Name.Entity */
77 | .codehilite .ne { color: #a6e22e !important } /* Name.Exception */
78 | .codehilite .nf { color: #a6e22e !important } /* Name.Function */
79 | .codehilite .nl { color: #f8f8f2 !important } /* Name.Label */
80 | .codehilite .nn { color: #f8f8f2 !important } /* Name.Namespace */
81 | .codehilite .nx { color: #a6e22e !important } /* Name.Other */
82 | .codehilite .py { color: #f8f8f2 !important } /* Name.Property */
83 | .codehilite .nt { color: #f92672 !important } /* Name.Tag */
84 | .codehilite .nv { color: #f8f8f2 !important } /* Name.Variable */
85 | .codehilite .ow { color: #f92672 !important } /* Operator.Word */
86 | .codehilite .w { color: #f8f8f2 !important } /* Text.Whitespace */
87 | .codehilite .mf { color: #ae81ff !important } /* Literal.Number.Float */
88 | .codehilite .mh { color: #ae81ff !important } /* Literal.Number.Hex */
89 | .codehilite .mi { color: #ae81ff !important } /* Literal.Number.Integer */
90 | .codehilite .mo { color: #ae81ff !important } /* Literal.Number.Oct */
91 | .codehilite .sb { color: #e6db74 !important } /* Literal.String.Backtick */
92 | .codehilite .sc { color: #e6db74 !important } /* Literal.String.Char */
93 | .codehilite .sd { color: #e6db74 !important } /* Literal.String.Doc */
94 | .codehilite .s2 { color: #e6db74 !important } /* Literal.String.Double */
95 | .codehilite .se { color: #ae81ff !important } /* Literal.String.Escape */
96 | .codehilite .sh { color: #e6db74 !important } /* Literal.String.Heredoc */
97 | .codehilite .si { color: #e6db74 !important } /* Literal.String.Interpol */
98 | .codehilite .sx { color: #e6db74 !important } /* Literal.String.Other */
99 | .codehilite .sr { color: #e6db74 !important } /* Literal.String.Regex */
100 | .codehilite .s1 { color: #e6db74 !important } /* Literal.String.Single */
101 | .codehilite .ss { color: #e6db74 !important } /* Literal.String.Symbol */
102 | .codehilite .bp { color: #f8f8f2 !important } /* Name.Builtin.Pseudo */
103 | .codehilite .vc { color: #f8f8f2 !important } /* Name.Variable.Class */
104 | .codehilite .vg { color: #f8f8f2 !important } /* Name.Variable.Global */
105 | .codehilite .vi { color: #f8f8f2 !important } /* Name.Variable.Instance */
106 | .codehilite .il { color: #ae81ff !important } /* Literal.Number.Integer.Long */
107 |
108 | .codehilite .gh { } /* Generic Heading & Diff Header */
109 | .codehilite .gu { color: #a1a1b6 !important ; } /* Generic.Subheading & Diff Unified/Comment? */
110 | .codehilite .gd { color: #f92672 !important ; } /* Generic.Deleted & Diff Deleted */
111 | .codehilite .gi { color: #a6e22e !important ; } /* Generic.Inserted & Diff Inserted */
112 |
113 | .codehilite .md-clipboard:before { color: rgba(255, 255, 255, 0.07) } /* Clipboard button (no hover) */
114 | .codehilite:hover .md-clipboard:before { color: rgba(255, 255, 255, 0.54) } /* Clipboard button (hovered) */
115 |
--------------------------------------------------------------------------------
/docs/basics/wpilib.md:
--------------------------------------------------------------------------------
1 | # WPILib Programming Basics
2 |
3 | Making FRC Programming Easy
4 |
5 | 
6 |
7 | ## What is WPILib
8 |
9 | - The WPI Robotics library (WPILib) is a set of software classes that interfaces with the hardware and software in your FRC RoboRIO.
10 | - There are classes to handle sensors, motor speed controllers, the driver station, and a number of other utility functions.
11 | - Documentation is available at
12 | - WPILib adds those sensors and controllers as additional data types (like `#!java int` or `#!java double`) and classes.
13 | - !!!example "Examples"
14 | `Talon`, `Solenoid`, `Encoder`...
15 |
16 | ***
17 |
18 | ## Command Based Robot
19 |
20 | - For our programming tutorial we will be creating a Command based robot
21 | - Command Based Robots are much like Lego, with very basic pieces you can make something **simple** like a small house or **complicated** like an entire Lego city.
22 | - A command based robot is broken down into **subsystem** classes and **command** classes.
23 | - In the code, a command based robot is made up of 3 **packages** (**folders**) labeled robot, commands, and subsystems
24 | - There are other types of robots but we will use Command Based
25 |
26 | ### Subsystems
27 |
28 | - A **subsystem** is a special template class made by FRC.
29 | - In robotics, subsystems are sections of the whole robot.
30 | - For example every FRC robot has a **Drivetrain** subsystem which is what controls the robot’s driving both physically and programmatically.
31 | - To avoid confusion between software and mechanical teams, subsystems should be called the same thing. If we have a ball intake system, we will both call it **Intake** or **Collector**.
32 | - Subsystems of a robot can contain parts to control or read data from.
33 | - The **Drivetrain** subsystem could contain **motor controllers** and **encoders** both physically and programmatically.
34 | - Using a dog as an example: the **legs**, **tail**, and **head** are **subsystems**.
35 | - The **head** subsystem has the parts: **eyes**, **ears**, and **nose**.
36 | - When programming subsystems we use variables and methods to tell our subsystem what it has and what it is capable of or should do.
37 | - These variables will be the parts in the subsystem
38 | - These methods will define what those parts are capable of.
39 | - Using a dog **head** subsystem as an example:
40 | - Some variables (parts) would be: **leftEye**, **rightEye**, **nose**, **leftEar**, **rightEar**.
41 | - Some example methods would be **closeEyes** or **openEyes** since these are things the dog are capable of.
42 | - These methods would use both the **leftEye** and **rightEye** and close them.
43 | - ??? example
44 | ```java
45 | //This method closes the dog eyes
46 | public void closeEyes(){
47 | leftEye.close();
48 | rightEye.close();
49 | ```
50 | - A robot example of a **Drivetrain** subsystem would have **leftMotor**, and **rightMotor** as variables and **setSpeed** as a method telling it how to set the speed of those motor controllers.
51 | - Having the **setSpeed** method tells our program that our **Drivetrain** subsystem can set its speed.
52 | - ??? example
53 | ```java
54 | //This method sets the speed of the drivetrain
55 | public void setSpeed(double speed){
56 | leftMotor.set(speed);
57 | rightMotor.set(speed);
58 | }
59 | ```
60 |
61 | ***
62 |
63 | ### Commands
64 |
65 | - A **command** is a special template class (file) made by FRC.
66 | - In robotics, commands are actions you want a robot to do (just like a real life command).
67 | - A **command** is an action a **subsystem(s)** performs.
68 | - For example you may want your robot to drive full speed forward so you make a command class called **DriveForward**.
69 | - Since a robot uses a **Drivetrain** subsystem to control its motors, this command would call our previously created **setSpeed** method from that subsystem.
70 | - !!! Tip
71 | **Subsystems** define what the robot is made of and what it can do while **commands** actually tell the robot to do those things
72 | - Using a dog as an example we can tell the dog to blink by creating a **BlinkEyes** command
73 | - The command would call the method, **closeEyes()** then the method **openEyes()**
74 | - ??? example "BlinkEyes Command"
75 | ```java
76 | //This command will continuously run the two methods in execute
77 | protected void execute() {
78 | dog.head.closeEyes();
79 | dog.head.openEyes();
80 | }
81 | ```
82 | - A robot example of a **DriveForward** command would call (use) the **setSpeed** methods that we created in the **Drivetrain** subsystem
83 | - **DriveForward**, when executed, will tell our robot to drive forward using the **Drivetrain** subsystem
84 | - ??? example "DriveForward Command"
85 | ```java
86 | //This command tells the robot to drive forward full speed
87 | protected void initialize(){
88 | robot.drivetrain.setSpeed(1.0);
89 | }
90 | ```
91 |
92 | #### Default Command Structure
93 |
94 | - The template for FRC commands actually come with some pre-defined methods that have special properties for FRC robots, they are:
95 | - `#!java void initialize()` - Methods in here are called just before this Command runs the first time.
96 | - `#!java void execute()` - Methods in here are called repeatedly when this Command is scheduled to run
97 | - `#!java boolean isFinished()` - When this returns true, the Command stops running execute()
98 | - `#!java void end()` - Methods in here are called once after isFinished returns true
99 | - `#!java void interrupted()` - Methods in here are called when another command which requires one or more of the same subsystems is scheduled to run
100 | - !!! Tip
101 | It is good practice to call `end()` in `interrupted()`
102 |
103 | ***
104 |
105 | ### Overview of execution
106 |
107 | - In FRC programming our main class is **Robot.java** and all other classes (command files and subsystem files) must be loaded from **Robot.java** either directly or indirectly
108 | - !!! Example
109 | **Robot.java** loads **RobotContainer.java**, **RobotContainer.java** loads **DriveForward.java**.
110 | - All **subsystem** files must be added to **RobotContainer.java**.
111 | - This loads our **subsystems** into the code and allow its public methods to be useable by other files such as commands later by typing `#!java RobotContainer.nameOfSubsystem.desiredMethod();`
112 |
113 | ***
114 |
115 | ### New Project Files
116 |
117 | See [Default Project Contents](../programming/new_project.md#default-project-contents)
118 |
119 | ***
120 |
121 | ## Summary
122 |
123 | - Command based robots are broken down into **subsystems** and **commands**
124 | - **Subsystems** define what the robot is made of and what it can do while **commands** actually tell the robot to do those things
125 | - All classes must directly or indirectly connect to **Robot.java**.
126 | - All **Subsystems** must be added to **RobotContainer.java**
127 | - **RobotMap.java** holds port numbers and IDs accessible throughout the program by typing: `#!java RobotMap.NameOfMotor()`
128 | - **RobotContainer.java** contains our publicly accessible instances of our subsystems. It also connects our commands to physical controllers.
129 |
--------------------------------------------------------------------------------
/docs/basics/java_basics.md:
--------------------------------------------------------------------------------
1 | # Java Programming Basics
2 |
3 | Learning What's What
4 |
5 | 
6 |
7 | ## Overview
8 |
9 | - Objects, variables, and classes (in Java) make up our programs. We define, modify, and use these variables and objects to make our programs run.
10 | - Programs use key words to define characteristics of variables or objects. Basic keywords:
11 | - `#!java public` - an object accessible by other classes (files)
12 | - `#!java private` - an object only accessible by its containing class (file).
13 | - `#!java protected` - like private but can be seen by subclasses
14 | - `#!java return` - value to return or give back after method execution (run).
15 | - `#!java void` - a method that returns no value
16 | - `#!java null` - a value that means empty or nothing
17 |
18 | !!! Warning "IMPORTANT NOTE"
19 | Java is case sensitive, meaning capitalization matters!
20 | ***
21 |
22 | ## Classes
23 |
24 | - Classes are the files that contain our programming
25 | - A program can be made up of one class but can also be made up of many classes
26 | - All programs run a main class that can optionally load additional classes either directly or indirectly
27 | - !!! example
28 | main loads class1, class1 loads class2
29 | - Classes are made up of variables and methods and are often used to separate and organize your code.
30 | - Classes can also **call** (use) variables or methods of other classes if those have been set to public.
31 |
32 | ### Constructors
33 |
34 | - Classes can also have a ***constructor*** which is a special type of **method** that has the **same name (case sensitive)** as the class file
35 | - Constructors are always called when the class is loaded into the program for the first time. This is often the only time they are called.
36 | - Constructors are called when trying to access the class in other files.
37 | - They can be called again if the class is programmed to be unloaded (destroyed) and reloaded.
38 | - Calls to methods, and assignment of values, within the constructor will run as soon as the class is called (loaded) in the code.
39 | - The **new** operator creates an object of a type of class using a constructor
40 | - !!! example
41 | classObject = new className();
42 |
43 | ***
44 |
45 | ## Methods
46 |
47 | - Methods, also known as functions, can be thought of as subprograms or routines that run inside of your main program.
48 | - Methods are used when you want to run the same code multiple times. Copying and pasting code is ***BAD!*** Use methods instead!
49 | - Methods are also useful to access only certain parts or functions of another class.
50 | - Methods can also have their own variables (**local**) or use variables available throughout the whole class (**global variables**), this will be explained more in the [scope section](#scope).
51 | - Methods can call (use) other methods, even multiple times.
52 |
53 | ??? example
54 | ```java
55 | int value;
56 | void increment(){
57 | value++;
58 | }
59 | ```
60 |
61 | ### Parameters
62 |
63 | - Parameters are variables that are passed (sent) to a method for it to use.
64 | - You can pass more than one parameter but order matters when calling the method.
65 |
66 | ??? example
67 | ```java
68 | // Example of a method with a parameter
69 | double half(int num1){
70 | double multiplier = 0.5;
71 | return num1*multiplier;
72 | }
73 |
74 | int newNumber = half(12); // <---- Method being called (used) in code
75 | ```
76 |
77 | ***
78 |
79 | ## Variables
80 |
81 | - Variables are objects that contain data, they are characterized by data types
82 | - Variables are assigned names and data types on creation
83 | - Names can be anything with the exception of pre-existing keywords such as `public` or `int`
84 | - Data types define what type of data is being stored in the variables:
85 | - `#!java int` - integers (whole numbers)
86 | - `#!java double` - double precision floating point (fractional/decimal values)
87 | - `#!java boolean` - true or false (true = 1 or false = 0) values.
88 | - `#!java string` - text values contained in parentheses
89 | - !!! Example "Example: `#!java int sum;`"
90 | A variable that can hold whole number values
91 | - !!! Example "Example: `#!java boolean isFull = true;`"
92 | A variable can either hold a true or false value and is being assigned a true value
93 |
94 | ### Constants
95 |
96 | Most variables can have their values assigned or reassigned at any point elsewhere in your program. To avoid having a variable change its value during runtime you can make it a **constant**
97 |
98 | - In Java you can create constants using the `#!java static final` keywords together in front of the data type of the variable
99 | - The static modifier causes the variable to be available without loading the class where it is defined.
100 | - The final modifier causes the variable to be unchangeable.
101 | - Java constants are normally declared in ALL CAPS. Words in Java constants are normally separated by underscores.
102 | - !!! Example "Example: `#!java public static final double PI_VALUE = 3.14159;`"
103 | A variable that cannot be modified during code run time.
104 |
105 | ### Scope
106 |
107 | - When creating a variable, where you create it matters. This is known as the scope of a variable.
108 | - The scope is where a variable can be seen within a class
109 | - A variable created in a method can only be seen in that method. This is a local variable.
110 | - A variable created outside a method can be seen in all methods of that class (file). This is a global variable.
111 | - It is good practice to put them all at the top before your first method.
112 |
113 | ??? example "Example of a Local Variable"
114 | ```java
115 | public int testMethod() {
116 | int example = 12; // Inside of method
117 | example = example + 1;
118 | return example
119 | }
120 | ```
121 |
122 | ??? example "Example of a Global Variable"
123 | ```java
124 | int example = 12; // Outside of method
125 | public void testMethod() {
126 | example = example + 1;
127 | return example
128 | }
129 | ```
130 | ***
131 |
132 | ## Comments
133 |
134 | - Comments are a programmer-readable explanation or annotation in the source code of a program.
135 | - Comments do not affect what the code does.
136 | - Comments are often used to leave notes or explanations of what methods or classes are doing so that it is easier to understand the code.
137 |
138 | ??? example "Example: Single Line Comments"
139 | ```java
140 | // This is what a single line comment looks like
141 |
142 | // You can also have multiple
143 | // single line comments in a row
144 | ```
145 |
146 | ??? example "Example: Multi Line Comments"
147 | ```java
148 | /*
149 | This is what a
150 | multiline comment
151 | looks like
152 | */
153 | ```
154 |
155 | ??? example "Example: Doc Comments"
156 | ```java
157 | /**
158 | * This is a doc comment
159 | *
160 | *
161 | * - They can be viewed by hovering over code they are attached to
162 | * - They can be formatted with HTML
163 | *
164 | */
165 | ```
166 |
167 | ***
168 |
169 | ## Conventions
170 |
171 | - There are also many different conventions when programming, this ensures that programs are readable between different people.
172 | - A common naming convention:
173 | - Programming is often done in CamelCase or lowerCamelCase
174 | - Instead of adding spaces, capitalize the first letter of each word
175 | - !!! example
176 | ThreeMotorDrive, driveForward, setSpeed
177 |
178 | !!! info
179 | There are other naming conventions, but for this tutorial we will use the camel cases
180 |
--------------------------------------------------------------------------------
/docs/programming/new_project.md:
--------------------------------------------------------------------------------
1 | # Creating Project Files
2 |
3 | Lets get started
4 |
5 | {: style="height:150px"}
6 | {: style="height:150px"}
7 |
8 | ## Overview
9 |
10 | Before we can start programing a robot, we must create a new project in Visual Studio Code (VSCode).
11 |
12 | **See table of contents for a breakdown of this section.**
13 |
14 | ***
15 |
16 | ## Creating a New Project
17 |
18 | !!! summary ""
19 | **1)** Select the **W icon** from the tab bar or use the shortcut by holding down **Ctrl+Shift+P** at the same time. (Replace ctrl with command on macOS)
20 |
21 | 
22 |
23 | !!! summary ""
24 | **2)** Type and hit enter or select **WPILib: Create a new project**
25 |
26 | 
27 |
28 | !!! summary ""
29 | **3)** Click **Select a Project Type** and choose **Template**
30 | **4)** Click **Select a Language** and choose **Java**
31 | **5)** Click **Select a project base** and choose **Command Robot**
32 |
33 | 
34 |
35 | !!! summary ""
36 | **6)** Click **Select a new project folder** and choose where on your computer you would like to store the program
37 |
38 | 
39 |
40 | !!! summary ""
41 | **7)** **Enter a project name** in the text field labeled as such
42 | **8)** **Enter your team number** in the text field labeled as such
43 | **9)** Select **Generate Project**
44 |
45 | 
46 |
47 | !!! summary ""
48 | **10)** When prompted **“Would you like to open the folder?”**, select **Yes (Current Window)**
49 |
50 | 
51 |
52 | ### Default Project Contents
53 |
54 | Newly created projects have many files within them. We only care about the contents within the **src/main/java/frc/robot/** folder. Everything else can be ignored at this point in the tutorial.
55 |
56 | **Files in the robot folder:**
57 |
58 | - **ExampleCommand.java**
59 | - An example Command
60 | - **ExampleSubsystem.java**
61 | - An example SubSystem
62 | - **Constants.java** (new in 2020, replaces RobotMap.java)
63 | - Used to map physical ports (digital if using the CAN bus) of sensors or devices connected to the robot and assign them a variable name to be used in other parts of the code.
64 | - This provides flexibility for changing wiring, makes checking the wiring easier, and significantly reduces the number of magic numbers floating around.
65 | - Can also be used to store generic constant values as variables in the code
66 | - **Main.java**
67 | - Used for advanced programming
68 | - Will be ignored/left as is for this tutorial
69 | - **RobotContainer.java** (new in 2020, replaces OI.java)
70 | - Used to declare our subsystem
71 | - Used to create a connection between commands and Operator Interfaces (OI) such as Joysticks or buttons
72 | - **Robot.java**
73 | - The main class of the robot which is run when a robot boots up.
74 | - Used to run special methods in the init and period phases of the auto, teleop, and disabled states
75 |
76 | ??? Example
77 | 
78 |
79 | ***
80 |
81 | ## Creating a New Subsystem
82 |
83 | !!! summary ""
84 | **1)** Click on the **src** folder to expand it.
85 | **2)** Do the same for **java** then **subsystems**
86 |
87 | 
88 |
89 | !!! summary ""
90 | **3)** Right click on **subsystems** and select **Create a new class/ command.**
91 |
92 | 
93 |
94 | !!! summary ""
95 | **4)** Select **Subsystem (New)** and type your **DesiredSubsystemName** (i.e. **Drivetrain**) for the name and hit enter on your keyboard.
96 |
97 | 
98 | 
99 |
100 | !!! summary ""
101 | **5)** Click on the newly created **DesiredSubsystemName.java** (or **Drivetrain.java** if you named it that)
102 |
103 | 
104 |
105 | ### Adding the Subsystem to RobotContainer.java
106 |
107 |
108 | !!! warning "Do not forget this step!"
109 | When a robot program runs on the roboRIO it only runs the main file Robot.java and anything Robot.java links to such as RobotContainer.java.
110 | We have created a new subsystem but we have not yet linked it to Robot.java through RobotContainer.java.
111 |
112 | !!! danger "***We must do this for EVERY subsystem we create***"
113 |
114 | !!! summary ""
115 | **1)** In RobotContainer.java we will create a new **public** **global** **constant** variable of type `DesiredSubsystemName` (i.e. `Drivetrain`):
116 | `#!java public static final m_desiredSubsystemName = new DesiredSubsystemName();`
117 | (i.e. `#!java public static final m_drivetrain = new Drivetrain();`)
118 |
119 | 
120 |
121 | Now when we use this subsystem in commands, we must call `#!java RobotContainer.m_desiredSubsystemName.` to get access to it and its methods. (i.e. `#!java RobotContainer.m_drivetrain.someMethod()`)
122 |
123 | ### Default Subsystem Contents
124 |
125 | Newly created subsystems are empty with the exception of the periodic.
126 |
127 | - Currently there is no constructor, we will create a constructor ourselves later.
128 | - **periodic** - a method that will be called periodically (once per robot scheduler run)
129 | - Useful for adding/updating data to Driverstation dashboard
130 | - Useful updating variables that need to always up to date
131 |
132 | ??? Example
133 | ```java
134 | package frc.robot.subsystems;
135 |
136 | import edu.wpi.first.wpilibj2.command.SubsystemBase;
137 |
138 | public class Drivetrain extends SubsystemBase {
139 | /**
140 | * Creates a new Drivetrain.
141 | */
142 | public Drivetrain() {
143 |
144 | }
145 |
146 | @Override
147 | public void periodic() {
148 | // This method will be called once per scheduler run
149 | }
150 | }
151 | ```
152 |
153 | ***
154 |
155 | ## Creating a New Command
156 |
157 | !!! summary ""
158 | **1)** Click on the **src** folder to expand it (if it isn't already).
159 | **2)** Do the same for **commands**
160 |
161 | 
162 |
163 | !!! summary ""
164 | **3)** Right click on **commands** and select **Create a new class/ command.**
165 |
166 | 
167 |
168 | !!! summary ""
169 | **4)** Select **Command (New)** and type **DesiredCommandName** (i.e. DriveArcade) for the name and hit enter on your keyboard.
170 |
171 | 
172 | 
173 |
174 | !!! summary ""
175 | **5)** Click on the newly created **DesiredCommandName.java** (or **DriveArcade.java** if you named it that)
176 |
177 | 
178 |
179 | ### Default Command Contents
180 |
181 | Newly created commands have some predefined methods in them specific for a command based robot.
182 |
183 | - **Constructor** - Called when the robot program is ___FIRST___ loaded.
184 | - Subsystem dependencies are declared here.
185 | - **initialize()** - Called ___ONCE___ just before this Command runs the first time.
186 | - **execute()** - Called ___REPEATEDLY___ when this Command is scheduled to run
187 | - **end()** - Called ___ONCE___ after isFinished returns true or when ___another command___ which requires one or more of the same subsystems is scheduled to run
188 | - **isFinished()** - Make this return ___TRUE___ when this Command no longer needs to run `execute()` (initialize always runs once regardless).
189 |
190 | ??? Example
191 | ```java
192 | package frc.robot.commands;
193 |
194 | import edu.wpi.first.wpilibj2.command.CommandBase;
195 |
196 | public class DriveArcade extends CommandBase {
197 | /**
198 | * Creates a new DriveArcade.
199 | */
200 | public DriveArcade() {
201 | // Use addRequirements() here to declare subsystem dependencies.
202 | }
203 |
204 | // Called when the command is initially scheduled.
205 | @Override
206 | public void initialize() {
207 | }
208 |
209 | // Called every time the scheduler runs while the command is scheduled.
210 | @Override
211 | public void execute() {
212 | }
213 |
214 | // Called once the command ends or is interrupted.
215 | @Override
216 | public void end(boolean interrupted) {
217 | }
218 |
219 | // Returns true when the command should end.
220 | @Override
221 | public boolean isFinished() {
222 | return false;
223 | }
224 | }
225 | ```
226 |
--------------------------------------------------------------------------------
/docs/programming/using_sensors.md:
--------------------------------------------------------------------------------
1 | # [WIP] Using Sensors and Switches
2 |
3 |
4 |
5 | ## Overview
6 |
7 | In this section we will be going over
8 |
9 | 1. Creating and using a switch in a shooter subsystem
10 | 1. Create this subsystem now. (See [Creating a New Subsystem](new_project.md#creating-a-new-subsystem))
11 | 2. Creating an encoder in the [drivetrain subsystem](driving_robot.md) (See creating a driving robot)
12 |
13 | ***
14 |
15 | ## What Are Sensors
16 |
17 | - There are different types of sensors that give feedback on different things (i.e. **Encoders** measure distance, **switches** detect contact, **gyros** give orientation).
18 | - Most of these interface with the roboRIO through either the DIO, analog input, or custom electronics port.
19 |
20 | ## Programming Switches (i.e. Limit Switches)
21 |
22 | !!! summary ""
23 | **1)** For this tutorial we are going to add a **switch** to a **shooter subsystem** to automatically change the pitch of the shooter
24 |
25 | - Inside the shooter subsystem we are going to create a **switch** called **shooterSwitch**
26 | - It will be created as a **DigitalInput**
27 | - The **DigitalInput** constructor only takes 1 parameter - DigitalInput(port)
28 | - The port refers to the port numbers on the RoboRIO’s DIO
29 | - Store the port in **Constants**
30 |
31 | ??? Example
32 |
33 | The code you typed should be this
34 |
35 | ```java
36 | DigitalInput shooterSwitch = null;
37 | ```
38 |
39 | In the constructor
40 |
41 | ```java
42 | shooterSwitch = new DigitalInput(Constants.SHOOTER_SWITCH);
43 | ```
44 |
45 | In **Constants.Java**
46 |
47 | ```java
48 | // Digital Inputs
49 | public static final int SHOOTER_SWITCH = 0;
50 | ```
51 |
52 | ### Creating isShooterSwitchClosed Method
53 |
54 | !!! summary ""
55 | **1)** Create a **public boolean** method called **isShooterSwitchClosed**
56 |
57 | - This method will tell us when the shooter switch is pressed
58 |
59 | !!! summary ""
60 | **2)** Inside type:
61 |
62 | ```java
63 | return shooterSwitch.get();
64 | ```
65 |
66 | - Switches have 2 states: open and closed.
67 |
68 |
69 | - Make sure you know which is true or false or you may have to invert the switch by rewiring or using the ! operator
70 |
71 | ??? Example
72 |
73 | Your **isShooterSwitchClosed()** should look like this
74 |
75 | ```java
76 | public boolean isShooterSwitchClosed() {
77 | return shooterSwitch.get();
78 | }
79 | ```
80 |
81 | ??? Example "Full Shooter.java Example"
82 |
83 | ```java
84 | package frc.robot.subsystems;
85 |
86 | import edu.wpi.first.wpilibj.DigitalInput;
87 | import edu.wpi.first.wpilibj2.command.SubsystemBase;
88 | import frc.robot.Constants;
89 |
90 | public class Shooter extends SubsystemBase {
91 | /**
92 | * Creates a new Shooter.
93 | */
94 | DigitalInput shooterSwitch = null;
95 |
96 | public Shooter() {
97 | shooterSwitch = new DigitalInput(Constants.SHOOTER_SWITCH);
98 | }
99 |
100 | public boolean isShooterSwitchClosed() {
101 | return shooterSwitch.get();
102 | }
103 |
104 | @Override
105 | public void periodic() {
106 | // This method will be called once per scheduler run
107 | }
108 | }
109 | ```
110 |
111 | ### Creating ShooterUpAuto Command
112 |
113 | - We will create a **command** that gives an example of how a Shooter switch may be used
114 |
115 | !!! summary ""
116 | **1)** For this tutorial we will use the switch to create a button that automatically pitches the shooter up after the switch is pressed
117 |
118 | !!! summary ""
119 | **2)** Create a new **command** called **ShooterUpAuto**
120 |
121 | !!! summary ""
122 | **3)** In the constructor add requires(Robot.m_Shooter)
123 |
124 | !!! summary ""
125 | **4)** In isFinished return our **isShooterSwitchClosed** method
126 |
127 | - we will not put anything in initialize or execute because we don't want anything to happen until the switch is closed
128 |
129 | !!! summary ""
130 | **5)** In end add our **pitchUp** method
131 |
132 | - we will not put end in interrupted either because we only want to change the pitch of the shooter if the switch is closed
133 |
134 | ??? Example
135 |
136 | Your full **ShooterUpAuto.java** should look like this
137 |
138 | ```java
139 | package frc.robot.commands;
140 |
141 | import edu.wpi.first.wpilibj.command.Command;
142 | import frc.robot.Robot;
143 |
144 | public class ShooterUpAuto extends Command {
145 | public ShooterUpAuto() {
146 | // Use requires() here to declare subsystem dependencies
147 | // eg. requires(chassis);
148 | requires(Robot.m_shooter);
149 | }
150 |
151 | // Called just before this Command runs the first time
152 | @Override
153 | protected void initialize() {
154 | }
155 |
156 | // Called repeatedly when this Command is scheduled to run
157 | @Override
158 | protected void execute() {
159 | }
160 |
161 | // Make this return true when this Command no longer needs to run execute()
162 | @Override
163 | protected boolean isFinished() {
164 | return Robot.m_shooter.isShooterSwitchClosed();
165 | }
166 |
167 | // Called once after isFinished returns true
168 | @Override
169 | protected void end() {
170 | Robot.m_shooter.pitchUp();
171 | }
172 |
173 | // Called when another command which requires one or more of the same
174 | // subsystems is scheduled to run
175 | @Override
176 | protected void interrupted() {
177 | }
178 | }
179 | ```
180 |
181 | #### Mapping ShooterAutoUpCommand
182 |
183 | - To be able to test our command right now we can map it to a joystick button like we did our other Shooter commands
184 | - It would be best to make it a whenPressed or whileHeld button
185 | - whileHeld will run normally while the button is being held and be interrupted when released
186 |
187 | ??? Example
188 |
189 | The code you typed should be this
190 |
191 | ```java
192 | D3.whenPressed(new ShooterUpAuto());
193 | ```
194 |
195 | Or this
196 |
197 | ```java
198 | D3.whileHeld(new ShooterUpAuto());
199 | ```
200 |
201 | ## Programming Encoders
202 |
203 | !!! summary ""
204 | **1)** For this tutorial we are going to add a **encoder** to the **Drivetrain** subsystem to keep track of the distance the robot has driven
205 |
206 | !!! summary ""
207 | **2)** Inside the **Drivetrain** subsystem we are going to create an **encoder** called **driveEncoder**
208 |
209 | - It will be created as an Encoder
210 | - The Encoder constructor takes 2 parameters - (new Encoder(port1,port2))
211 | - These are DIO ports on the RoboRIO
212 | - Store ports in Constants as DRIVE_ENCODER_A and B
213 |
214 | ??? Example
215 |
216 | The code you typed outside the constructor should be this
217 |
218 | ```java
219 | Encoder driveEncoder = null;
220 | ```
221 |
222 | Inside the constructor
223 |
224 | ```java
225 | driveEncoder = new Encoder(Constants.DRIVETRAIN_ENCODER_A, Constants.DRIVETRAIN_ENCODER_B);
226 | ```
227 |
228 | ### Creating Drive Encoder Methods
229 |
230 | !!! summary ""
231 | **1)** Create a public double method called **getDriveEncoderCount**
232 |
233 | !!! summary ""
234 | **2)** Inside type:
235 |
236 | ```java
237 | return driveEncoder.get();
238 | ```
239 |
240 |
241 |
242 | - Encoders will return counts as an int
243 | - Depending which direction the encoder shaft rotates the value will increase or decrease
244 |
245 | !!! summary ""
246 | **3)** Create a public method called **resetDriveEncoderCount**
247 |
248 | !!! summary ""
249 | **4)** Inside type:
250 |
251 | ```java
252 | driveEncoder.reset();
253 | ```
254 |
255 | - This method will reset the drive encoder to zero which is useful for autonomous or when we use the robot as a ruler
256 |
257 | ??? Example
258 |
259 | The code you typed should be this
260 |
261 | ```java
262 | public double getDriveEncoderCount() {
263 | return driveEncoder.get();
264 | }
265 |
266 | public void resetDriveEncoder() {
267 | driveEncoder.reset();
268 | }
269 | ```
270 |
271 | ### Creating ResetDriveEncoder InstantCommand
272 |
273 | - We need to create a command to use the **resetDriveEncoder** method since it’s a **void** method
274 | - We will create a **InstantCommand** since we will only use it to reset the drive encoder
275 |
276 | !!! summary ""
277 | **1)** Create a new **InstantCommand** called **DriveResetEncoder**
278 |
279 | !!! summary ""
280 | **2)** In the constructor add requires(Robot.m_drivetrain)
281 |
282 | !!! summary ""
283 | **3)** In initialize() add our **resetDriveEncoder** method
284 |
285 | ??? Example
286 |
287 | Your full **DriveResetEncoder** command should look like this
288 |
289 | ```java
290 | package frc.robot.commands;
291 |
292 | import edu.wpi.first.wpilibj.command.InstantCommand;
293 | import frc.robot.Robot;
294 |
295 | /**
296 | * Add your docs here.
297 | */
298 | public class DriveResetEncoder extends InstantCommand {
299 | /**
300 | * Add your docs here.
301 | */
302 | public DriveResetEncoder() {
303 | super();
304 | // Use requires() here to declare subsystem dependencies
305 | // eg. requires(chassis);
306 | requires(Robot.m_drivetrain);
307 | }
308 |
309 | // Called once when the command executes
310 | @Override
311 | protected void initialize() {
312 | Robot.m_drivetrain.resetDriveEncoder();
313 | }
314 | }
315 | ```
316 |
--------------------------------------------------------------------------------
/docs/programming/autonomous.md:
--------------------------------------------------------------------------------
1 | # [WIP] Creating an Autonomous Command
2 |
3 |
4 |
5 | ## Overview
6 |
7 | In this section we will be going over
8 |
9 | 1. Creating an autonomous command group
10 | 2. Using RobotPreferences to quickly change our autonomous values
11 | 3. Using an encoder to autonomously drive
12 | 4. Creating a delay timer to pace our commands in autonomous
13 |
14 |
15 |
16 |
17 | ***
18 |
19 | ## What Is an Autonomous Command
20 |
21 | - An autonomous command is a command that is ran during "autonomous mode" under the **autonomousInit** method in **Robot.java**
22 | - It could be a single **command** or a **command group**
23 | - It's especially helpful to have if you don't have any cameras to drive the robot during a
24 | "sandstorm" period (2019 game mechanic where the drivers couldn't see during the pre tele-op phase)
25 | - For this tutorial we will create an autonomous **command group** that makes the robot drive forward 5 feet, wait 5 seconds, and then pitch the shooter up during autonomous
26 |
27 | ## Creating Commands For Autonomous
28 |
29 | - Since we can't control our robot during an autonomous command we will want to create commands that allow the robot to move independently of a driver
30 |
31 | ## Creating the DriveDistance Command
32 |
33 | !!! summary ""
34 | **1)** Create a new command called **DriveDistance**
35 |
36 | !!! summary ""
37 | **2)** Before the constructor create a **double** called **distance**
38 |
39 | - We will use this to tell the command to finish when the robot drives the inputted distance
40 |
41 | !!! summary ""
42 | **3)** In the **DriveDistance** constructor add a **double** parameter called **inches**
43 |
44 | !!! summary ""
45 | **4)** Inside type:
46 |
47 | ```java
48 | distance = inches;
49 | ```
50 |
51 | !!! summary ""
52 | **5)** In **initialize** add our **resetDriveEncoder** method
53 |
54 | - We want to reset the encoder before we drive so that it counts the distance from zero
55 |
56 | !!! summary ""
57 | **6)** In **execute** add our **arcadeDrive** method and change the **moveSpeed** parameter to a **RobotPreference** named **driveDistanceSpeed** and **rotateSpeed** to 0.0
58 |
59 | - We only want to drive the robot forward; a **RobotPreference** will help us tune the drive speed
60 |
61 | !!! summary ""
62 | **7)** In **isFinished** type:
63 |
64 | ```java
65 | return Robot.m_drivetrain.getDriveEncoderDistance() == distance;
66 | ```
67 | !!! summary ""
68 | **8)** In **end** stop the **Drivetrain** and call **end** in **interrupted**
69 |
70 | ??? Example
71 |
72 | Your full **DriveDistance.java** should look like this
73 |
74 | ```java
75 | package frc.robot.commands;
76 |
77 | import edu.wpi.first.wpilibj.command.Command;
78 | import frc.robot.Robot;
79 | import frc.robot.RobotPreferences;
80 |
81 | public class DriveDistance extends Command {
82 |
83 | private double distance;
84 |
85 | public DriveDistance(double inches) {
86 | // Use requires() here to declare subsystem dependencies
87 | // eg. requires(chassis);
88 | requires(Robot.m_drivetrain);
89 | distance = inches;
90 | }
91 |
92 | // Called just before this Command runs the first time
93 | @Override
94 | protected void initialize() {
95 | Robot.m_drivetrain.resetDriveEncoder();
96 | }
97 |
98 | // Called repeatedly when this Command is scheduled to run
99 | @Override
100 | protected void execute() {
101 | Robot.m_drivetrain.arcadeDrive(RobotPreferences.driveDistanceSpeed(), 0.0);
102 | }
103 |
104 | // Make this return true when this Command no longer needs to run execute()
105 | @Override
106 | protected boolean isFinished() {
107 | return Robot.m_drivetrain.getDriveEncoderDistance() == distance;
108 | }
109 |
110 | // Called once after isFinished returns true
111 | @Override
112 | protected void end() {
113 | Robot.m_drivetrain.arcadeDrive(0.0, 0.0);
114 | }
115 |
116 | // Called when another command which requires one or more of the same
117 | // subsystems is scheduled to run
118 | @Override
119 | protected void interrupted() {
120 | end();
121 | }
122 | }
123 | ```
124 |
125 | The code you typed in **RobotPreferences.java** should be this
126 |
127 | ```java
128 | public static final double driveDistanceSpeed() {
129 | return Preferences.getInstance().getDouble("driveDistanceSpeed", 0.5);
130 | }
131 | ```
132 |
133 | ## Creating The Autonomous Command
134 |
135 | - We will create an **Autonomous command group** with the **DriveDistance** command and the **ShooterPitchUp** command
136 |
137 | !!! summary ""
138 | **1)** Create a new **Command Group** named **Autonomous**
139 |
140 | !!! summary ""
141 | **2)** In the constructor type
142 |
143 | ```java
144 | addSequential(new DriveDistance(RobotPreferences.autoDriveDistance()));
145 | addSequential(new ShooterUp());
146 | ```
147 |
148 | - To add a **command** to run in a **command group** use **addSequential** to execute commands in order
149 |
150 | ## Creating the DoDelay Command
151 |
152 | - In order to add timing in between our **commands** in our **command groups** we will need to create a **DoDelay** command
153 | - Unlike regular **delays** the **DoDelay** command will not stall our robot, but wait a certain amount of time before running a command
154 |
155 | !!! summary ""
156 | **1)** Create a new command called **DoDelay**
157 |
158 | !!! summary ""
159 | **2)** Before the constructor add two private **doubles** called **expireTime** and **timeout**
160 |
161 | !!! summary ""
162 | **3)** In the constructor add a **double** called **seconds** in the parameter
163 |
164 | !!! summary ""
165 | **4)** Inside the constructor set **timeout** equal to **seconds**
166 |
167 | !!! summary ""
168 | **5)** Create a protected **void** method called **startTimer**
169 |
170 | !!! summary ""
171 | **6)** Inside set **expireTime** equal to **timeSinceInitialized** + **timeout**
172 |
173 | - This will let the robot know how much time will have passed since the command was initialized when it finishes
174 |
175 | !!! summary ""
176 | **7)** In **initialized** add our **startTimer** method
177 |
178 | !!! summary ""
179 | **8)** In **isFinished** return **timeSinceInitialized** is greater or equal to **expireTime**
180 |
181 | ??? Example
182 |
183 | Your full **DoDelay.java** should look like this
184 |
185 | ```java
186 | package frc.robot.commands;
187 |
188 | import edu.wpi.first.wpilibj.command.Command;
189 |
190 | public class DoDelay extends Command {
191 |
192 | private double expireTime;
193 | private double timeout;
194 |
195 | public DoDelay(double seconds) {
196 | // Use requires() here to declare subsystem dependencies
197 | // eg. requires(chassis);
198 | timeout = seconds;
199 | }
200 |
201 | protected void startTimer() {
202 | expireTime = timeSinceInitialized() + timeout;
203 | }
204 |
205 | // Called just before this Command runs the first time
206 | @Override
207 | protected void initialize() {
208 | startTimer();
209 | }
210 |
211 | // Called repeatedly when this Command is scheduled to run
212 | @Override
213 | protected void execute() {
214 | }
215 |
216 | // Make this return true when this Command no longer needs to run execute()
217 | @Override
218 | protected boolean isFinished() {
219 | return (timeSinceInitialized() >= expireTime);
220 | }
221 |
222 | // Called once after isFinished returns true
223 | @Override
224 | protected void end() {
225 | }
226 |
227 | // Called when another command which requires one or more of the same
228 | // subsystems is scheduled to run
229 | @Override
230 | protected void interrupted() {
231 | }
232 | }
233 | ```
234 |
235 | ## Adding the DoDelay Command to Autonomous.java
236 |
237 | !!! summary ""
238 | - Add our **DoDelay** command in between **DriveDistance** and **ShooterPitchUp** with a **RobotPreference** called **autoDelay**
239 |
240 | ??? Example
241 |
242 | Your full **Autonomous.java** should look like this
243 |
244 | ```java
245 | package frc.robot.commands;
246 |
247 | import edu.wpi.first.wpilibj.command.CommandGroup;
248 | import frc.robot.RobotPreferences;
249 |
250 | public class Autonomous extends CommandGroup {
251 | /**
252 | * Add your docs here.
253 | */
254 | public Autonomous() {
255 | addSequential(new DriveDistance(RobotPreferences.autoDriveDistance()));
256 | addSequential(new DoDelay(RobotPreferences.autoDelay()));
257 | addSequential(new ShooterUp());
258 | }
259 | }
260 | ```
261 |
262 | The code you typed in **RobotPreferences.java** should look like this
263 |
264 | ```java
265 | public static double autoDelay() {
266 | return Preferences.getInstance().getDouble("autoDelay", 5.0);
267 | }
268 |
269 | public static double autoDriveDistance() {
270 | return Preferences.getInstance().getDouble("autoDriveDistance", 12.0);
271 | }
272 | ```
273 |
274 | ## Adding Our Autonomous Command to Robot.java
275 |
276 | - In order to run our **Autonomous** command in autonomous we will have to put it in **Robot.java** so that it will run as soon as the robot enters the autonomous mode
277 |
278 | - In **Robot.java** under **autonomousInit** find **m_autonomousCommand = m_chooser.getSelected();** and change it to
279 |
280 |
281 |
282 | ```java
283 | public void autonomousInit() {
284 | m_autonomousCommand = new Autonomous();
285 | ...
286 | ```
287 |
288 | ## Testing Our Autonomous Command
289 |
290 | - Now that we have finished coding our **Autonomous** command deploy code and add our new **RobotPreferences** to the widget on the **ShuffleBoard**
291 | - We have three preferences that change our autonomous behavior **driveDistanceSpeed**, **autoDriveDistance** and **autoDelay**
292 | - **driveDistanceSpeed** will determine the **direction** and how **fast** the robot drives
293 | - **autoDriveDistance** will determine how many **inches** the robot drives **forward** or **backward**
294 | - **autoDelay** will determine how long the robot **waits** before executing **ShooterPitchUp**
295 | - Change these values before enabling your robot in autonomous to make you get the desired results
296 |
297 | ## Tips For Debugging Our Autonomous Command
298 |
299 | - If the robot doesn't seem to stop moving or drive in the right direction check for inversions in your **Drive** commands or in the **Drivetrain** subsystem
300 | - You may also need to check if your **encoder** is working, if there are inversions, or if you are using the **getEncoderCount** method instead of the **getEncoderDistanceMethod**
301 | - If your robot doesn't move make sure you typed in the **RobotPreference** names exactly or check your talon IDs/Connection
302 | - If nothing happens after your robot is finished driving check your **autoDelay** preference and whether your **Shooter piston** is already actuated or if your solenoids are working
303 |
--------------------------------------------------------------------------------
/docs/programming/pneumatics.md:
--------------------------------------------------------------------------------
1 | # [WIP] Using Pneumatics
2 |
3 | Check the air pressure
4 |
5 | 
6 |
7 | ## Overview
8 |
9 | This section will help you learn to program pneumatic for your robot. For this section we are going to create a new subsystem called shooter and add one pneumatic piston (cylinder) which will be used for changing the pitch of the shooter.
10 |
11 | **See table of contents for a breakdown of this section.**
12 |
13 | ***
14 |
15 | ## Background info
16 |
17 | ### What Are Pneumatics
18 |
19 | - You have probably heard of hydraulics before (which is based on water pressure). Pneumatics are essentially the same but with air pressure.
20 | - Unlike motors and gears which are commonly infinitely positional, pneumatic cylinders are typically dual-positional or sometimes tri-positional.
21 | - Pneumatic cylinders are actuated through devices called solenoids.
22 | - Solenoids are used to control pneumatic pistons (air cylinders) similar to how Talons control motors.
23 |
24 | ### What Are Solenoids
25 |
26 | - Cylinders are actuated with either **single solenoids** or **double solenoids**.
27 | - A **single solenoid** actuates with one air line, using air to switch to and hold the extended state and releasing air (sometimes paired with a spring) to allow the cylinder to return to the retracted state.
28 | - A single solenoid valve has one solenoid, and shifts when voltage is **CONSTANTLY** supplied to that solenoid. When voltage is removed, it shifts back to a "home" position.
29 | - A **double solenoid** actuates with two air lines, using air to switch and hold states between retracted and extended.
30 | - A double solenoid has two solenoids, and when voltage is supplied to one (and not the other) the valve shifts.
31 | - Solenoids are connected to the Pneumatics Control Module (PCM)
32 | - The PCM is connected to the roboRIO via the CAN bus.
33 |
34 | ## Programming Solenoids
35 |
36 | For this section we are going to create a new subsystem called shooter and add one pneumatic piston (cylinder) which will be used for changing the pitch of the shooter.
37 |
38 | See [Creating a New Subsystem](new_project.md#creating-a-new-subsystem){target=_blank}.
39 |
40 | ### What will be added to the Shooter subsystem
41 |
42 | !!! summary ""
43 | **1)**
44 |
45 | - Create a new Shooter subsystem.
46 | - It will be controlled through a double solenoid.
47 | - We are going to create a DoubleSolenoid named pitchSolenoid.
48 | - DoubleSolenoids have 2 controllable positions (deployed(forward) and retracted(reverse)).
49 | - The DoubleSolenoid constructor takes 2 parameters - (new DoubleSolenoid(port1, port2) )
50 | - Port 1 and Port 2 refer to Forward control and Reverse control ports on the PCM.
51 | - Like all ports we use, we will store this in the RobotMap.
52 |
53 | !!! summary ""
54 | **2)** Create your DoubleSolenoid named pitchSolenoid now using the same technique used to create a talon but replacing Talon with DoubleSolenoid. (For single solenoids just use Solenoid).
55 |
56 | ??? Example
57 |
58 | Your full **Shooter.java** should look like this
59 |
60 | ```java
61 | package frc.robot.subsystems;
62 | import edu.wpi.first.wpilibj.DoubleSolenoid;
63 | import edu.wpi.first.wpilibj.command.Subsystem;
64 | import frc.robot.RobotMap;
65 |
66 | /**
67 | * Add your docs here.
68 | */
69 | public class Shooter extends Subsystem {
70 | // Put methods for controlling this subsystem
71 | // here. Call these from Commands.
72 | DoubleSolenoid pitchSolenoid = null;
73 |
74 | public Shooter() {
75 | pitchSolenoid = new DoubleSolenoid(RobotMap.SHOOTER_PITCH_SOLENOID_DEPLOY, RobotMap.SHOOTER_PITCH_SOLENOID_RETRACT);
76 | }
77 |
78 | @Override
79 | public void initDefaultCommand() {
80 | // Set the default command for a subsystem here.
81 | // setDefaultCommand(new MySpecialCommand());
82 | }
83 | }
84 | ```
85 |
86 | The code you typed in **Robot.java** should be this
87 |
88 | Outside robotInit
89 | ```java
90 | public static Shooter m_shooter = null;
91 | ```
92 | Inside robotInit
93 | ```java
94 | m_shooter = new Shooter();
95 | ```
96 |
97 | The code you typed in **RobotMap.java** should be this
98 |
99 | ```java
100 | // Solenoids
101 | public static final int SHOOTER_PITCH_SOLENOID_DEPLOY = 0;
102 | public static final int SHOOTER_PITCH_SOLENOID_RETRACT = 1;
103 | ```
104 |
105 | ### Creating Pitch Up/Down Methods
106 |
107 | !!! summary ""
108 | **1)** Create a public void method called pitchUp.
109 |
110 | !!! summary ""
111 | **2)** Inside type:
112 |
113 | ```java
114 | pitchSolenoid.set(Value.kForward);
115 | ```
116 |
117 | - This sets the value of the solenoid to forward (deployed)
118 | !!! Note
119 | if you wanted multiple solenoids to deploy at the same time also have them do .set(Value.kForward);
120 |
121 | !!! summary ""
122 | **3)** Do the same for the **pitchDown** method but change **kForward** to **kReverse**.
123 |
124 | ??? Example
125 |
126 | The code you typed should be this
127 |
128 | ```java
129 | public void pitchUp(){
130 | pitchSolenoid.set(Value.kForward);
131 | }
132 |
133 | public void pitchDown(){
134 | pitchSolenoid.set(Value.kForward);
135 | }
136 | ```
137 |
138 | ### Creating The Commands to Use Pneumatics
139 |
140 | ### Creating Deploy/Retract Instant Commands
141 |
142 | - Now that we have created the methods we must create commands to use them.
143 | - Since changing the state of a solenoid only requires us to send a signal once (not continuously) we will create an **InstantCommand** instead of a **Command**
144 | - **InstantCommands** work the same as regular commands but hide everything except for initialize(). (InstantCommand extends Command)
145 | - Internally, they set isFinished to return always true so execute never runs.
146 |
147 | !!! summary ""
148 | **1)** Create a new **InstantCommand** called **ShooterUp**
149 |
150 | - Alternatively: Create a regular **Command** and set **isFinished** to **true**
151 |
152 | !!! summary ""
153 | **2)** In the constructor adds requires(Robot.m_shooter)
154 |
155 | !!! summary ""
156 | **3)** In initialize() add our newly created method **pitchUp** method
157 |
158 | !!! summary ""
159 | **4)** Repeat steps for **ShooterDown** command but change **pitchUp* to **pitchDown**
160 |
161 | ??? Example
162 |
163 | Your full **ShooterUp.java** should look like this
164 |
165 | ```java
166 | package frc.robot.commands;
167 |
168 | import edu.wpi.first.wpilibj.command.InstantCommand;
169 | import frc.robot.Robot;
170 |
171 | /**
172 | * Add your docs here.
173 | */
174 | public class ShooterUp extends InstantCommand {
175 | /**
176 | * Add your docs here.
177 | */
178 | public ShooterUp() {
179 | super();
180 | // Use requires() here to declare subsystem dependencies
181 | // eg. requires(chassis);
182 | requires(Robot.m_shooter);
183 | }
184 |
185 | // Called once when the command executes
186 | @Override
187 | protected void initialize() {
188 | Robot.m_shooter.pitchUp();
189 | }
190 | }
191 | ```
192 |
193 | Your full **ShooterDown.java** should look like this
194 |
195 | ```java
196 | package frc.robot.commands;
197 |
198 | import edu.wpi.first.wpilibj.command.InstantCommand;
199 | import frc.robot.Robot;
200 |
201 | /**
202 | * Add your docs here.
203 | */
204 | public class ShooterDown extends InstantCommand {
205 | /**
206 | * Add your docs here.
207 | */
208 | public ShooterDown() {
209 | super();
210 | // Use requires() here to declare subsystem dependencies
211 | // eg. requires(chassis);
212 | requires(Robot.m_shooter);
213 | }
214 |
215 | // Called once when the command executes
216 | @Override
217 | protected void initialize() {
218 | Robot.m_shooter.pitchDown();
219 | }
220 | }
221 | ```
222 |
223 |
224 |
225 | ### Mapping Commands to Buttons
226 |
227 | ### Creating Joystick Buttons
228 |
229 | - Now that we have created our ShooterUp and ShooterDown commands we need a way to run them.
230 | - Lets map them to buttons on our controller!
231 |
232 | !!! summary ""
233 | **1)** Open OI.java
234 |
235 | !!! summary ""
236 | **2)** Under our created joystick we will create Button variables and assign them to a button on our joystick
237 |
238 | !!! summary ""
239 | **3)** Type:
240 |
241 | ```java
242 | Button D1 = new JoystickButton(driverController, 1);
243 | ```
244 |
245 | - This creates a new Button named D1 (D representing driverController and 1 representing the button number) and sets it as a JoystickButton on the controller ‘driverController’ and button value 1 (this can be found in the Driverstation software).
246 |
247 | !!! summary ""
248 | **4)** Do this for the rest of the buttons on your controller.
249 |
250 | ??? Example
251 |
252 | Your full **OI.Java** should look like this
253 |
254 | ```java
255 | package frc.robot;
256 |
257 | import edu.wpi.first.wpilibj.Joystick;
258 | import edu.wpi.first.wpilibj.buttons.Button;
259 | import edu.wpi.first.wpilibj.buttons.JoystickButton;
260 |
261 | /**
262 | * This class is the glue that binds the controls on the physical operator
263 | * interface to the commands and command groups that allow control of the robot.
264 | */
265 | public class OI {
266 | public Joystick driverController = new Joystick(RobotMap.OI_DRIVER_CONTROLLER);
267 |
268 | Button D1 = new JoystickButton(driverController, 1);
269 | Button D2 = new JoystickButton(driverController, 2);
270 | Button D3 = new JoystickButton(driverController, 3);
271 | Button D4 = new JoystickButton(driverController, 4);
272 | Button D5 = new JoystickButton(driverController, 5);
273 | Button D6 = new JoystickButton(driverController, 6);
274 | Button D7 = new JoystickButton(driverController, 7);
275 | Button D8 = new JoystickButton(driverController, 8);
276 | Button D9 = new JoystickButton(driverController, 9);
277 | Button D10 = new JoystickButton(driverController, 10);
278 | }
279 | ```
280 |
281 | ### Mapping Joystick Buttons
282 |
283 | - Now that we have created the buttons in the code we can map certain commands to them.
284 |
285 | !!! summary ""
286 | **1)** Create a constructor for OI
287 |
288 | !!! summary ""
289 | **2)** In the constructor type:
290 |
291 | ```java
292 | D1.whenPressed(new ShooterUp());
293 | ```
294 |
295 | - This means **when** the button D1 is **pressed** it runs the ShooterUp command and deploys our pneumatic piston.
296 | - There are other types of activations for buttons besides **whenPressed** like: **whenRelease, whileHeld, etc**.
297 |
298 | !!! summary ""
299 | **3)** Create a whenPressed button for ShooterDown as well
300 |
301 | ??? Example
302 |
303 | The code you typed should be this
304 |
305 | ```java
306 | public OI(){
307 | D1.whenPressed(new ShooterUp());
308 | D2.whenPressed(new ShooterDown());
309 | }
310 | ```
311 |
312 | !!! Tip
313 | You can change your import at the top of the file from:
314 | `import frc.robot.commands.ShooterUp;` to
315 | `import frc.robot.commands.*;`
316 |
317 | The asterisk (wildcard) makes it so all files in the .command package (folder) are imported. This way you only have to import once.
318 |
--------------------------------------------------------------------------------
/docs/programming/driving_robot.md:
--------------------------------------------------------------------------------
1 | # Creating a Basic Driving Robot
2 |
3 |
4 |
5 | Lets get moving!
6 |
7 | 
8 | > [Picture source: Team 2984](http://ljrobotics.org/games/power-up-2018/){target=_blank}
9 |
10 | ## Overview
11 |
12 | This section is designed to help you program a basic driving robot, start to finish.
13 |
14 | **See table of contents for a breakdown of this section.**
15 |
16 | ***
17 |
18 | ## Creating the Drivetrain Subsystem
19 |
20 | Before we begin we must create the class file for the drivetrain subsystem. See [Creating a New Subsystem](new_project.md#creating-a-new-subsystem){target=_blank} for info on how to do this.
21 |
22 | ### What will be added to the Drivetrain
23 |
24 | In the Drivetrain class we will tell the subsystem what type of components it will be using.
25 |
26 | - A Drivetrain needs motor controllers. In our case we will use 4 Talon SRs (a brand of controller for motors).
27 | - You could use other motor controllers such as Victor SPs or Talon SRXs but we will be using Talon SRs
28 | - If you are using other motor controllers, replace Talon with TalonSRX, Victor, or VictorSP in the code you write depending on the type you use.
29 | - You can use 2 motors (left and right), but for this tutorial we will use 4.
30 |
31 | !!! Tip
32 | Be sure to read [Visual Studio Code Tips](../basics/vscode_tips.md){target=_blank} before getting started! It will make your life a lot easier.
33 |
34 | ### Creating the Talon Variables
35 |
36 | !!! summary ""
37 | **1)** Create 4 global variables of data type **Talon** and name them: `leftFrontTalon`, `rightFrontTalon`, `leftBackTalon`, `rightBackTalon`
38 |
39 | - To get started type the word Talon followed by the name i.e. `#!java Talon leftFrontTalon;`
40 | - These will eventually hold the object values for Talons and their port numbers.
41 |
42 | !!! summary ""
43 | **2)** Next assign their values to `#!java null` ([more info on `null`](../basics/java_basics.md#overview){target=_blank}).
44 |
45 | - We do this to make sure it is empty at this point.
46 | - When we assign these variables a value, we will be getting the motor controller's port numbers out of Constants
47 | - This means we cannot assign them at the global level
48 |
49 | ??? Example
50 |
51 | The code you typed should be this:
52 |
53 | ```java
54 | Talon leftFrontTalon = null;
55 | Talon leftBackTalon = null;
56 | Talon rightFrontTalon = null;
57 | Talon rightBackTalon = null;
58 | ```
59 |
60 | Your full **Drivetrain.java** should look like this:
61 |
62 | ```java
63 | package frc.robot.subsystems;
64 |
65 | import edu.wpi.first.wpilibj.Talon;
66 | import edu.wpi.first.wpilibj.command.Subsystem;
67 |
68 | /**
69 | * Add your docs here.
70 | */
71 | public class Drivetrain extends Subsystem {
72 | // Put methods for controlling this subsystem
73 | // here. Call these from Commands.
74 |
75 | Talon leftFrontTalon = null;
76 | Talon leftBackTalon = null;
77 | Talon rightFrontTalon = null;
78 | Talon rightBackTalon = null;
79 |
80 | @Override
81 | public void periodic() {
82 | // This method will be called once per scheduler run
83 | }
84 | }
85 | ```
86 |
87 |
88 | ??? fail "If an error occurs (red squiggles)"
89 | 1. Click the word Talon
90 | 
91 | 2. 💡 Click the light bulb
92 | 
93 | 3. Select "Import 'Talon' (edu.wpi.first.wpilibj)"
94 | 
95 | 4. Your error should be gone!
96 |
97 | ### Creating and filling the constructor
98 |
99 | !!! summary ""
100 | **1)** Create the constructor for Drivetrain.java ([more info on constructors](../basics/java_basics.md#constructors){target=_blank})
101 |
102 | - The constructor is where we will assign values to our talon variables.
103 |
104 | !!! summary ""
105 | Now that we have created the Talons we must initialize them and tell them what port on the roboRIO they are on.
106 |
107 | **2)** Initialize (set value of) `leftFrontTalon` to `#!java new Talon(0)`.
108 |
109 | - This initializes a new talon, `leftFrontTalon`, in a new piece of memory and states it is on port 0 of the roboRIO.
110 | - This should be done within the constructor `#!java Drivetrain()`
111 | - This calls the constructor `#!java Talon(int)` in the Talon class.
112 | - The constructor `#!java Talon(int)` takes a variable of type `#!java int`. In this case the `#!java int` (integer) refers to the port number on the roboRIO.
113 |
114 | ??? Info "roboRIO port diagram"
115 | 
116 |
117 | ??? Example
118 |
119 | The code you typed should be this:
120 |
121 | ```java
122 | public Drivetrain() {
123 | // Talons
124 | leftFrontTalon = new Talon(0);
125 | }
126 | ```
127 |
128 | Your full **Drivetrain.java** should look like this:
129 |
130 | ```java
131 | package frc.robot.subsystems;
132 |
133 | import edu.wpi.first.wpilibj.Talon;
134 | import edu.wpi.first.wpilibj.command.Subsystem;
135 |
136 | /**
137 | * Add your docs here.
138 | */
139 | public class Drivetrain extends Subsystem {
140 | // Put methods for controlling this subsystem
141 | // here. Call these from Commands.
142 |
143 | Talon leftFrontTalon = null;
144 | Talon leftBackTalon = null;
145 | Talon rightFrontTalon = null;
146 | Talon rightBackTalon = null;
147 |
148 | public Drivetrain() {
149 | // Talons
150 | leftFrontTalon = new Talon(0);
151 | }
152 |
153 | @Override
154 | public void periodic() {
155 | // This method will be called once per scheduler run
156 | }
157 | ```
158 |
159 | ### Using Constants
160 |
161 |
162 |
163 | Since each subsystem has its own components with their own ports, it is easy to lose track of which ports are being used and for what. To counter this you can use a class called **Constants** to hold all these values in a single location.
164 |
165 | !!! summary ""
166 | **1)** To use Constants, instead of putting `0` for the port on the Talon type:
167 | ```java
168 | Constants.DRIVETRAIN_LEFT_FRONT_TALON
169 | ```
170 |
171 | - Names should follow the pattern SUBSYSTEM_NAME_OF_COMPONENT
172 | - The name is all caps since it is a **constant** ([more info on constants](../basics/java_basics.md#constants){target=_blank}).
173 |
174 | !!! summary ""
175 | **2)** Click on the underlined text
176 | 
177 |
178 | !!! summary ""
179 | **3)** Click on the 💡light bulb and select “create constant…”
180 | 
181 |
182 | !!! summary ""
183 | **4)** Click on Constants.java tab that just popped up
184 | 
185 |
186 | !!! summary ""
187 | **5)** Change the `0` to the correct port for that motor controller on your robot/roboRIO
188 | 
189 |
190 | !!! Danger
191 | ***If you set this to the wrong value, you could damage your robot when it tries to move!***
192 |
193 | !!! summary ""
194 | **6)** Repeat these steps for the remaining Talons.
195 |
196 | !!! Tip
197 | Remember to save both **Drivetrain.java** and **Constants.java**
198 |
199 | ??? Example
200 |
201 | The code you type should be this:
202 |
203 | ```java
204 | leftFrontTalon = new Talon(Constants.DRIVETRAIN_LEFT_FRONT_TALON);
205 | ```
206 |
207 | Your full **Drivetrain.java** should look like this:
208 |
209 | ```java
210 | package frc.robot.subsystems;
211 |
212 | import edu.wpi.first.wpilibj.Talon;
213 | import edu.wpi.first.wpilibj.command.Subsystem;
214 | import frc.robot.Constants;
215 |
216 | /**
217 | * Add your docs here.
218 | */
219 | public class Drivetrain extends Subsystem {
220 | // Put methods for controlling this subsystem
221 | // here. Call these from Commands.
222 |
223 | Talon leftFrontTalon = null;
224 | Talon leftBackTalon = null;
225 | Talon rightFrontTalon = null;
226 | Talon rightBackTalon = null;
227 |
228 | public Drivetrain() {
229 | // Talons
230 | leftFrontTalon = new Talon(Constants.DRIVETRAIN_LEFT_FRONT_TALON);
231 | leftBackTalon = new Talon(Constants.DRIVETRAIN_LEFT_BACK_TALON);
232 | rightFrontTalon = new Talon(Constants.DRIVETRAIN_RIGHT_FRONT_TALON);
233 | rightBackTalon = new Talon(Constants.DRIVETRAIN_RIGHT_BACK_TALON);
234 | }
235 |
236 | @Override
237 | public void periodic() {
238 | // This method will be called once per scheduler run
239 | }
240 | }
241 | ```
242 |
243 | Your full **Constants.java** should look similar to this:
244 |
245 | ```java
246 | package frc.robot;
247 |
248 | public class Constants {
249 | // Talons
250 | public static final int DRIVETRAIN_LEFT_FRONT_TALON = 0;
251 | public static final int DRIVETRAIN_LEFT_BACK_TALON = 1;
252 | public static final int DRIVETRAIN_RIGHT_FRONT_TALON = 2;
253 | public static final int DRIVETRAIN_RIGHT_BACK_TALON = 3;
254 | }
255 | ```
256 |
257 | !!! Warning
258 | Remember to use the values for **YOUR** specific robot or you could risk damaging it!
259 |
260 | ### Creating the arcade drive
261 |
262 | #### What is the Drive Class
263 |
264 | - The FIRST Drive class has many pre-configured methods available to us including DifferentialDrive, and many alterations of MecanumDrive.
265 | - DifferentialDrive contains subsections such as TankDrive and ArcadeDrive.
266 |
267 | - For our tutorial we will be creating an ArcadeDrive
268 | - Arcade drives run by taking a moveSpeed and rotateSpeed. moveSpeed defines the forward and reverse speed and rotateSpeed defines the turning left and right speed.
269 | - To create an arcade drive we will be using our already existing Drivetrain class and adding to it.
270 |
271 | #### Programing a RobotDrive
272 |
273 |
274 |
275 | !!! summary ""
276 | **1)** In the same place we created our talons (outside of the constructor) we will create a **DifferentialDrive** and **SpeedControllerGroups** for our left and right motor controllers.
277 |
278 | Outside of the constructor type:
279 |
280 | ```java
281 | SpeedControllerGroup leftMotors = null;
282 | SpeedControllerGroup rightMotors = null;
283 |
284 | DifferentialDrive differentialDrive = null;
285 | ```
286 |
287 | - Since DifferentialDrive only takes 2 parameters we need to create speed controller groups to combine like motor controllers together.
288 | - In this case we will combine the left motors together and the right motors together.
289 |
290 | !!! Warning
291 | You should only group motors that are spinning the same direction physically when positive power is being applied otherwise you could damage your robot.
292 |
293 | !!! summary ""
294 | **2)** Now we must initialize the **SpeedControllerGroups** and **DifferentialDrive** like we did our talons. ...
295 |
296 | In the constructor type:
297 |
298 | ```java
299 | leftMotors = new SpeedControllerGroup(leftFrontTalon, leftBackTalon);
300 | rightMotors = new SpeedControllerGroup(rightFrontTalon, rightBackTalon);
301 |
302 | differentialDrive = new DifferentialDrive(leftMotors, rightMotors);
303 | ```
304 |
305 | ??? Example
306 |
307 | The code you type outside the constructor should be this:
308 |
309 | ```java
310 | SpeedControllerGroup leftMotors = null;
311 | SpeedControllerGroup rightMotors = null;
312 |
313 | DifferentialDrive differentialDrive = null;
314 | ```
315 |
316 | The code you type inside the constructor should be this:
317 |
318 | ```java
319 | leftMotors = new SpeedControllerGroup(leftFrontTalon, leftBackTalon);
320 | rightMotors = new SpeedControllerGroup(rightFrontTalon, rightBackTalon);
321 |
322 | differentialDrive = new DifferentialDrive(leftMotors, rightMotors);
323 | ```
324 |
325 | Your full **Drivetrain.java** should look like this:
326 |
327 | ```java
328 | package frc.robot.subsystems;
329 |
330 | import edu.wpi.first.wpilibj.SpeedControllerGroup;
331 | import edu.wpi.first.wpilibj.Talon;
332 | import edu.wpi.first.wpilibj.command.Subsystem;
333 | import edu.wpi.first.wpilibj.drive.DifferentialDrive;
334 | import frc.robot.Constants;
335 |
336 | /**
337 | * Add your docs here.
338 | */
339 | public class Drivetrain extends Subsystem {
340 | // Put methods for controlling this subsystem
341 | // here. Call these from Commands.
342 |
343 | Talon leftFrontTalon = null;
344 | Talon leftBackTalon = null;
345 | Talon rightFrontTalon = null;
346 | Talon rightBackTalon = null;
347 |
348 | SpeedControllerGroup leftMotors = null;
349 | SpeedControllerGroup rightMotors = null;
350 |
351 | DifferentialDrive differentialDrive = null;
352 |
353 | public Drivetrain() {
354 | // Talons
355 | leftFrontTalon = new Talon(Constants.DRIVETRAIN_LEFT_FRONT_TALON);
356 | leftBackTalon = new Talon(Constants.DRIVETRAIN_LEFT_BACK_TALON);
357 | rightFrontTalon = new Talon(Constants.DRIVETRAIN_RIGHT_FRONT_TALON);
358 | rightBackTalon = new Talon(Constants.DRIVETRAIN_RIGHT_BACK_TALON);
359 |
360 | leftMotors = new SpeedControllerGroup(leftFrontTalon, leftBackTalon);
361 | rightMotors = new SpeedControllerGroup(rightFrontTalon, rightBackTalon);
362 |
363 | differentialDrive = new DifferentialDrive(leftMotors, rightMotors);
364 | }
365 |
366 | @Override
367 | public void periodic() {
368 | // This method will be called once per scheduler run
369 | }
370 | }
371 | ```
372 |
373 | #### Creating the arcadeDrive method
374 |
375 | Now it’s time to make an arcadeDrive from our differentialDrive!
376 |
377 | !!! summary ""
378 | **1)** Let’s create a public void method called “arcadeDrive” with type “double” parameters moveSpeed and rotateSpeed.
379 |
380 | Below the constructor type:
381 |
382 | ```java
383 | public void arcadeDrive(double moveSpeed, double rotateSpeed) {
384 |
385 | }
386 | ```
387 |
388 | !!! Tip
389 | By putting something in the parentheses it makes the method require a parameter when it is used. When the method gets used and parameters are passed, they will be store in moveSpeed and rotateSpeed (in that order). See [parameters](../basics/java_basics.md#parameters){target=_blank} for more info.
390 |
391 | !!! summary ""
392 | **2)** Now lets make our method call the differentialDrive's arcadeDrive method.
393 |
394 | Inside our method type:
395 |
396 | ```java
397 | differentialDrive.arcadeDrive(moveSpeed, rotateSpeed);
398 | ```
399 |
400 | DifferentialDrive's arcadeDrive method takes parameters moveValue and rotateValue.
401 |
402 | !!! Note
403 | At this point you could instead create a tank drive, however implementation differs slightly.
404 | To do so type `#!java differentialDrive.tankDrive(moveSpeed, rotateSpeed);` instead of `#!java differentialDrive.arcadeDrive(moveSpeed, rotateSpeed);` and change the method name reflect this.
405 |
406 | !!! Tip
407 | If you want to limit the max speed you can multiple the speeds by a decimal (i.e. 0.5*moveSpeed will make the motors only move half of their maximum speed)
408 |
409 | You may want to do this for initial testing to make sure everything is going the right direction.
410 |
411 | ??? Example
412 |
413 | The code you type should be this:
414 |
415 | ```java
416 | public void arcadeDrive(double moveSpeed, double rotateSpeed) {
417 | differentialDrive.arcadeDrive(moveSpeed, rotateSpeed);
418 | }
419 | ```
420 |
421 | Your full **Drivetrain.java** should look like this:
422 |
423 | ```java
424 | package frc.robot.subsystems;
425 |
426 | import edu.wpi.first.wpilibj.SpeedControllerGroup;
427 | import edu.wpi.first.wpilibj.Talon;
428 | import edu.wpi.first.wpilibj.command.Subsystem;
429 | import edu.wpi.first.wpilibj.drive.DifferentialDrive;
430 | import frc.robot.Constants;
431 |
432 | /**
433 | * Add your docs here.
434 | */
435 | public class Drivetrain extends Subsystem {
436 | // Put methods for controlling this subsystem
437 | // here. Call these from Commands.
438 |
439 | Talon leftFrontTalon = null;
440 | Talon leftBackTalon = null;
441 | Talon rightFrontTalon = null;
442 | Talon rightBackTalon = null;
443 |
444 | SpeedControllerGroup leftMotors = null;
445 | SpeedControllerGroup rightMotors = null;
446 |
447 | DifferentialDrive differentialDrive = null;
448 |
449 | public Drivetrain() {
450 | // Talons
451 | leftFrontTalon = new Talon(Constants.DRIVETRAIN_LEFT_FRONT_TALON);
452 | leftBackTalon = new Talon(Constants.DRIVETRAIN_LEFT_BACK_TALON);
453 | rightFrontTalon = new Talon(Constants.DRIVETRAIN_RIGHT_FRONT_TALON);
454 | rightBackTalon = new Talon(Constants.DRIVETRAIN_RIGHT_BACK_TALON);
455 |
456 | leftMotors = new SpeedControllerGroup(leftFrontTalon, leftBackTalon);
457 | rightMotors = new SpeedControllerGroup(rightFrontTalon, rightBackTalon);
458 |
459 | differentialDrive = new DifferentialDrive(leftMotors, rightMotors);
460 | }
461 |
462 | public void arcadeDrive(double moveSpeed, double rotateSpeed) {
463 | differentialDrive.arcadeDrive(moveSpeed, rotateSpeed);
464 | }
465 |
466 | @Override
467 | public void periodic() {
468 | // This method will be called once per scheduler run
469 | }
470 | }
471 | ```
472 |
473 | ***
474 |
475 | ## Making our robot controllable
476 |
477 | ### Creating the Joystick
478 |
479 | In order to drive our robot, it needs to know what will be controlling it. To do so, we will create a new joystick in RobotContainer.java
480 |
481 | !!! summary ""
482 | **1)** Open RobotContainer.java
483 |
484 | **2)** Type:
485 | ```java
486 | public Joystick driverController = new Joystick(Constants.DRIVER_CONTROLLER);
487 | ```
488 |
489 |
490 |
491 | - Import any classes if necessary such as: `#!java import edu.wpi.first.wpilibj.Joystick;`
492 | - A variable `driverController` of type Joystick pointing to a joystick on port `DRIVER_CONTROLLER` from **Constants**
493 |
494 | **3)** Click the 💡 light bulb to create a new **CONSTANT** and set the value to the port number the joystick uses on the laptop (this can be found in the Driverstation software).
495 |
496 |
497 |
498 | ??? Example
499 |
500 | The code you type should be this:
501 |
502 | ```java
503 | public Joystick driverController = new Joystick(Constants.DRIVER_CONTROLLER);
504 | ```
505 |
506 | Your full **RobotContainer.java** should look like this:
507 |
508 | ```java
509 | package frc.robot;
510 |
511 | import edu.wpi.first.wpilibj.Joystick;
512 |
513 | /**
514 | * This class is where the bulk of the robot should be declared. Since
515 | * Command-based is a "declarative" paradigm, very little robot logic should
516 | * actually be handled in the {@link Robot} periodic methods (other than the
517 | * scheduler calls). Instead, the structure of the robot (including subsystems,
518 | * commands, and button mappings) should be declared here.
519 | */
520 | public class RobotContainer {
521 | // The robot's subsystems and commands are defined here...
522 | public Joystick driverController = new Joystick(Constants.DRIVER_CONTROLLER);
523 | }
524 | ```
525 |
526 | Your full **Constants.java** should look similar to this:
527 |
528 | ```java
529 | package frc.robot;
530 |
531 | public class Constants {
532 | // Talons
533 | public static final int DRIVETRAIN_LEFT_FRONT_TALON = 0;
534 | public static final int DRIVETRAIN_LEFT_BACK_TALON = 1;
535 | public static final int DRIVETRAIN_RIGHT_FRONT_TALON = 2;
536 | public static final int DRIVETRAIN_RIGHT_BACK_TALON = 3;
537 |
538 | // Joysticks
539 | public static final int DRIVER_CONTROLLER = 0;
540 | }
541 | ```
542 |
543 | ### Creating the DriveArcade Command
544 |
545 | - Remember that **methods** tell the robot what it can do but in order to make it do these things we must give it a **command**. See [Command Based Robot](../basics/wpilib.md#command-based-robot){target=_blank}
546 | - Now that we have created the method, we need to create a command to call and use that method.
547 | - Let’s create a new command called **DriveArcade** that calls arcadeDrive method we just created!
548 |
549 | Before we begin we must create the class file for the DriveArcade command. See [Creating a New Command](new_project.md#creating-a-new-command){target=_blank} for info on how to do this and info on what each pre-created method does.
550 |
551 | #### In the constructor
552 |
553 | !!! summary ""
554 | **1)** In the constructor `#!java DriveArcade()` type:
555 |
556 | ```java
557 | addRequirements(RobotContainer.m_drivetrain);
558 | ```
559 |
560 | - This means, this command will end all other commands currently using drivetrain and will run instead when executed.
561 | - It also means, other commands that require drivetrain will stop this command and run instead when executed.
562 |
563 | !!! Warning
564 | If you use the light bulb to import ‘Robot', be sure to import the one with “frc.robot”
565 |
566 | #### In the execute method
567 |
568 | !!! summary ""
569 | **1)** In the execute method we will create 2 variables of type double called moveSpeed and rotateSpeed.
570 |
571 | - We want these variables to be the value of the axis of the controller we are using to drive the robot. So we will set them equal to that by using the joystick getRawAxis method.
572 | - Controllers return an axis value between 1 and -1 to indicate how far the joystick is pushed up or down. Our personal controller returns up as -1 so we want to invert it.
573 | - In Java you can put a negative “ - “in front of a numeric value to invert it (value * -1)
574 | - The joystick’s getRawAxis method will get the position value of the axis as you move it. The method takes parameter “axis number.” (This can be found in the Driverstation software and we will store it in Constants).
575 |
576 | In the execute() method type:
577 |
578 | ```java
579 | double moveSpeed = -RobotContainer.driverController.getRawAxis(Constants.DRIVER_CONTROLLER_MOVE_AXIS);
580 | double rotateSpeed = RobotContainer.driverController.getRawAxis(Constants.DRIVER_CONTROLLER_ROTATE_AXIS);
581 | ```
582 |
583 | !!! Tip
584 | Remember to use the light bulb for importing and creating constants if needed!
585 |
586 | !!! summary ""
587 | **2)** Also in the execute method we will we want to call the **arcadeDrive** method we created in **Drivetrain** and give it the variables **moveSpeed** and **rotateSpeed** we created as parameters.
588 |
589 | In the execute() method below rotateSpeed type:
590 |
591 | ```java
592 | RobotContainer.m_drivetrain.arcadeDrive(moveSpeed, rotateSpeed);
593 | ```
594 |
595 | #### In the isFinished method
596 |
597 | Since we will be using this command to control the robot we want it to run indefinitely.
598 |
599 | !!! summary ""
600 | **1)** To do this we are going to continue having isFinished return false, meaning the command will never finish.
601 |
602 | (We don't need to change anything as this is the default)
603 |
604 | !!! Tip
605 | - If we did want a command to finish, we make this return true.
606 | - This can be done by replacing false with true to make it finish instantly
607 | - Alternatively we can make a condition which can return true
608 | - For example `(timePassed > 10)` will return true after 10 seconds but return false anytime before 10 seconds have passed.
609 |
610 | #### In the end method
611 |
612 | !!! summary ""
613 | **1)** We will call the arcadeDrive method and give it 0 and 0 as the parameters.
614 |
615 | In the end() method type:
616 |
617 | ```java
618 | RobotContainer.m_drivetrain.arcadeDrive(0, 0);
619 | ```
620 |
621 | - This make the motors stop running when the command ends by setting the movement speed to zero and rotation speed to zero.
622 |
623 | #### Completed Example
624 |
625 | ??? Example
626 |
627 | Your full **Constants.java** should look similar to this:
628 |
629 | ```java
630 | package frc.robot;
631 |
632 | public class Constants {
633 | // Talons
634 | public static final int DRIVETRAIN_LEFT_FRONT_TALON = 0;
635 | public static final int DRIVETRAIN_LEFT_BACK_TALON = 1;
636 | public static final int DRIVETRAIN_RIGHT_FRONT_TALON = 2;
637 | public static final int DRIVETRAIN_RIGHT_BACK_TALON = 3;
638 |
639 | // Joysticks
640 | public static final int DRIVER_CONTROLLER = 0;
641 | public static final int DRIVER_CONTROLLER_MOVE_AXIS = 1; // Change for your controller
642 | public static final int DRIVER_CONTROLLER_ROTATE_AXIS = 2; // Change for your controller
643 | }
644 | ```
645 |
646 | Your full **DriveArcade.java** should look like this:
647 |
648 | ```java
649 | package frc.robot.commands;
650 |
651 | import edu.wpi.first.wpilibj.command.Command;
652 | import frc.robot.RobotContainer;
653 | import frc.robot.Constants;
654 |
655 | public class DriveArcade extends Command {
656 | public DriveArcade() {
657 | // Use addRequirements() here to declare subsystem dependencies.
658 | addRequirements(RobotContainer.m_drivetrain);
659 | }
660 |
661 | // Called just before this Command runs the first time
662 | @Override
663 | protected void initialize() {
664 | }
665 |
666 | // Called repeatedly when this Command is scheduled to run
667 | @Override
668 | protected void execute() {
669 | double moveSpeed = -RobotContainer.driverController.getRawAxis(Constants.DRIVER_CONTROLLER_MOVE_AXIS);
670 | double rotateSpeed = RobotContainer.driverController.getRawAxis(Constants.DRIVER_CONTROLLER_ROTATE_AXIS);
671 |
672 | RobotContainer.m_drivetrain.arcadeDrive(moveSpeed, rotateSpeed);
673 | }
674 |
675 | // Called once the command ends or is interrupted.
676 | @Override
677 | protected void end(boolean interrupted) {
678 | Robot.m_drivetrain.arcadeDrive(0, 0);
679 | }
680 |
681 | // Make this return true when this Command no longer needs to run execute()
682 | @Override
683 | protected boolean isFinished() {
684 | return false;
685 | }
686 | }
687 | ```
688 |
689 | ### Using setDefaultCommand
690 |
691 | - Commands passed to this method will run when the robot is enabled.
692 | - They also run if no other commands using the subsystem are running.
693 | - This is why we write **addRequirements(Robot.m_subsystemName)** in the commands we create, it ends currently running commands using that subsystem to allow a new command is run.
694 |
695 | !!! summary ""
696 | **1)** Back in **RobotContainer.java** in the constructor we will call the `setDefaultCommand` of `m_drivetrain` and pass it the `DriveArcade` command
697 |
698 | In the **RobotContainer.java** constructor type:
699 |
700 | ```java
701 | m_drivetrain.setDefaultCommand(new DriveArcade());
702 | ```
703 |
704 | !!! Tip
705 | Remember to use the light bulb for importing if needed!
706 |
707 | ??? Example
708 |
709 | Your full **RobotContainer.java** should look like this:
710 |
711 | ```java
712 | package frc.robot;
713 |
714 | import edu.wpi.first.wpilibj.Joystick;
715 | import frc.robot.commands.*;
716 | import frc.robot.subsystems.*;
717 | import edu.wpi.first.wpilibj2.command.Command;
718 |
719 | /**
720 | * This class is where the bulk of the robot should be declared. Since Command-based is a
721 | * "declarative" paradigm, very little robot logic should actually be handled in the {@link Robot}
722 | * periodic methods (other than the scheduler calls). Instead, the structure of the robot
723 | * (including subsystems, commands, and button mappings) should be declared here.
724 | */
725 | public class RobotContainer {
726 | // The robot's subsystems and commands are defined here...
727 | public static final Drivetrain m_drivetrain = new Drivetrain();
728 | private final ExampleSubsystem m_exampleSubsystem = new ExampleSubsystem();
729 |
730 | private final ExampleCommand m_autoCommand = new ExampleCommand(m_exampleSubsystem);
731 |
732 | public Joystick driverController = new Joystick(Constants.DRIVER_CONTROLLER);
733 |
734 | /**
735 | * The container for the robot. Contains subsystems, OI devices, and commands.
736 | */
737 | public RobotContainer() {
738 | // Configure the button bindings
739 | configureButtonBindings();
740 |
741 | // Set default commands on subsystems
742 | m_drivetrain.setDefaultCommand(new DriveArcade());
743 | }
744 |
745 | /**
746 | * Use this method to define your button->command mappings. Buttons can be created by
747 | * instantiating a {@link GenericHID} or one of its subclasses ({@link
748 | * edu.wpi.first.wpilibj.Joystick} or {@link XboxController}), and then passing it to a
749 | * {@link edu.wpi.first.wpilibj2.command.button.JoystickButton}.
750 | */
751 | private void configureButtonBindings() {
752 | }
753 |
754 |
755 | /**
756 | * Use this to pass the autonomous command to the main {@link Robot} class.
757 | *
758 | * @return the command to run in autonomous
759 | */
760 | public Command getAutonomousCommand() {
761 | // An ExampleCommand will run in autonomous
762 | return m_autoCommand;
763 | }
764 | }
765 | ```
766 |
--------------------------------------------------------------------------------