├── 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 | ![Image Title](imageURL) 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 | ![Image Title](imageURL) 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 | ![Image Title](imageURL) 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 | ![Image Title](imageURL) 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 | ![roboRIO](../assets/images/roboRIO/roboRio.png) 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 | ![Image Title](imageURL) 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 | ![roboRIO](../assets/images/roboRIO/roboRio.png) 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 | ![roboRIO IO](../assets/images/roboRIO/roboRIO_io.png) 26 | -------------------------------------------------------------------------------- /docs/basics/vscode_tips.md: -------------------------------------------------------------------------------- 1 | # Visual Studio Code Tips 2 | 3 | Making life easier 4 | 5 | ![Image Title](../assets/images/logos/code.png) 6 | 7 | ## 💡 Using the light bulb (quick fixes) 8 | 9 | ![](../assets/images/vscode_tips/light_bulb.png) 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 | ![camera](../assets/images/sensors/camera.png) 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 | | ![Limit Switch](../assets/images/sensors/limit_switch.png) | ![Grayhill Encoder](../assets/images/sensors/encoder.png) | ![navX](../assets/images/sensors/navX_micro.png) | 20 | -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | # Introductions 2 | 3 | [![FIRST](assets/images/logos/first.png)](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 | [![sn_banner](assets/images/logos/sn_banner.png)](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 | ![software](assets/images/why_software/programming_header.png) 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 | ![smart-light](assets/images/why_software/smart-light.png) 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 | ![automation](assets/images/why_software/automation.png) 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 | ![](assets/images/why_software/pi.png) 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 | ![roboRIO](../assets/images/roboRIO/roboRio.png) 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 | ![](../assets/images/deploying/w_icon.png) 34 | 35 | !!! summary "" 36 | **2)** Type and hit enter or select: WPILib: Deploy Robot Code 37 | 38 | ![](../assets/images/deploying/deploy_command.png) 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 | ![NI](../assets/images/logos/ni.png){: style="height:150px"} 6 | ![VSCode](../assets/images/logos/code.png){: 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 | > ![](assets/images/contributing/edit_icon.png) 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 | ![Image Title](imageURL) 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 | ![WPI Lib](../assets/images/logos/wpilib.png) 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 | ![Java](../assets/images/logos/java.png) 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 | * 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 | ![VSCode](../assets/images/logos/code.png){: style="height:150px"} 6 | ![](../assets/images/logos/wpilib.png){: 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 | ![](../assets/images/new_project/project/step_1.png) 22 | 23 | !!! summary "" 24 | **2)** Type and hit enter or select **WPILib: Create a new project** 25 | 26 | ![](../assets/images/new_project/project/step_2.png) 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 | ![](../assets/images/new_project/project/step_3.png) 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 | ![](../assets/images/new_project/project/step_4.png) 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 | ![](../assets/images/new_project/project/step_5.png) 46 | 47 | !!! summary "" 48 | **10)** When prompted **“Would you like to open the folder?”**, select **Yes (Current Window)** 49 | 50 | ![](../assets/images/new_project/project/step_6.png) 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 | ![](../assets/images/new_project/default_contents.png) 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 | ![](../assets/images/new_project/subsystem/step_1.png) 88 | 89 | !!! summary "" 90 | **3)** Right click on **subsystems** and select **Create a new class/ command.** 91 | 92 | ![](../assets/images/new_project/subsystem/step_2.png) 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 | ![](../assets/images/new_project/subsystem/step_3.png) 98 | ![](../assets/images/new_project/subsystem/step_4.png) 99 | 100 | !!! summary "" 101 | **5)** Click on the newly created **DesiredSubsystemName.java** (or **Drivetrain.java** if you named it that) 102 | 103 | ![](../assets/images/new_project/subsystem/step_5.png) 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 | ![](../assets/images/new_project/subsystem/step_6.png) 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 | ![](../assets/images/new_project/command/step_1.png) 162 | 163 | !!! summary "" 164 | **3)** Right click on **commands** and select **Create a new class/ command.** 165 | 166 | ![](../assets/images/new_project/command/step_2.png) 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 | ![](../assets/images/new_project/command/step_3.png) 172 | ![](../assets/images/new_project/command/step_4.png) 173 | 174 | !!! summary "" 175 | **5)** Click on the newly created **DesiredCommandName.java** (or **DriveArcade.java** if you named it that) 176 | 177 | ![](../assets/images/new_project/command/step_5.png) 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 | ![Piston](../assets/images/pneumatics/piston.png) 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 | ![Drive base](../assets/images/driving_robot/kitbot.jpg) 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 | ![](../assets/images/driving_robot/e1.png) 91 | 2. 💡 Click the light bulb 92 | ![](../assets/images/driving_robot/e2.png) 93 | 3. Select "Import 'Talon' (edu.wpi.first.wpilibj)" 94 | ![](../assets/images/driving_robot/e3.png) 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 | ![](../assets/images/driving_robot/roboRIO_port.png) 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 | ![](../assets/images/driving_robot/constants/step_1.png) 177 | 178 | !!! summary "" 179 | **3)** Click on the 💡light bulb and select “create constant…” 180 | ![](../assets/images/driving_robot/constants/step_2.png) 181 | 182 | !!! summary "" 183 | **4)** Click on Constants.java tab that just popped up 184 | ![](../assets/images/driving_robot/constants/step_3.png) 185 | 186 | !!! summary "" 187 | **5)** Change the `0` to the correct port for that motor controller on your robot/roboRIO 188 | ![](../assets/images/driving_robot/constants/step_4.png) 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 | --------------------------------------------------------------------------------