Project Structure
A robot project has three kinds of Java file and a handful of files that are not Java at all. Each kind of code has one place it goes, and the folders tell you which.
- The
Workshopproject from Project Setup, building clean.
This page is a map, and nothing on it gets typed. By the end of Workshop 3 your project looks like the tree below. Every lesson after this one adds a file to a folder named here.
The tree
Workshop/ build.gradle how to build, and which libraries settings.gradle where Gradle finds WPILib gradlew, gradlew.bat run Gradle without installing it .wpilib/ wpilib_preferences.json your team number vendordeps/ CommandsV3.json one file per vendor library Phoenix6-26.70.0-alpha-2.json src/main/deploy/ files copied onto the robot src/main/java/first/ Main.java starts the program. Never edited robot/ Robot.java owns the mechanisms mechanisms/ Arm.java one class per mechanism Flywheel.java opmode/ MyTeleop.java one class per mode MyAuto.java build/ made by every build. Never editedThe mechanisms folder does not exist yet. You make it in the next lesson. Everything else is already there from the New Project Creator.
Three things you leave alone. Main.java holds one line that matters, RobotBase.startRobot(first.robot.Robot::new). Its own comment says to leave the file alone. build/ is rewritten on every build, so an edit there disappears. The gradle/wrapper files pin the Gradle version for everyone on the team.
Three kinds of Java file
Robot.java owns the mechanisms, one public final field each, and runs the scheduler once per loop in robotPeriodic(). Its constructor is where a binding goes that must work in every mode. On this course that constructor stays empty.
public class Robot extends OpModeRobot { public final Arm arm = new Arm(); public final Flywheel flywheel = new Flywheel(); public Robot() {} @Override public void robotPeriodic() { Scheduler.getDefault().run(); }}A mechanism class is one physical thing on the robot. It implements Mechanism and keeps its motors and sensors private. Its public methods either return a Command, like arm.vertical(), or answer a question, like arm.isAtTarget(). Nothing outside the class touches the motor.
An OpMode class is one entry on the driver station list. @Teleop or @Autonomous above the class puts it there. Its constructor binds buttons to commands, and it reaches the mechanisms through robot.arm and robot.flywheel.
An OpMode only shows up if it sits in first.robot or a folder under it. The framework searches that package and nowhere else.
Where numbers live
There is no Constants file on any branch of this course. A number sits in the class that uses it, next to the line that uses it.
- CAN IDs sit where the device is made:
new TalonFX(21, canivore). - Gains sit in the configuration you paste from Tuner X, in the mechanism's constructor.
- Setpoints sit in the command that asks for them:
setVelocity(75.0)insiderunFast(). - Tolerances are a
private finalfield at the top of the mechanism.
When an OpMode needs to know whether the arm has arrived, it calls robot.arm.isAtTarget(). It never compares angles itself, so the tolerance stays in one place and changes in one place.
Where new code goes
Ask what the code talks to.
- A motor or a sensor. The mechanism that owns it, as a
privatemethod. - Something one mechanism does. A
publicmethod on that mechanism that returns aCommand. - A button. The constructor of the OpMode it belongs to. A button for every mode goes in the
Robotconstructor. - Two mechanisms working together. The OpMode that runs the routine.
spinUpWhenReadylives inMyTeleopfor that reason. - A vendor library.
vendordeps/, added through the WPILib Vendor Dependencies view, never by copying a jar. - A file the robot reads while running.
src/main/deploy/. A deploy copies it onto the SystemCore.
New file, wrong folder
Every Java file starts with a package line, and it has to match the folder. Arm.java in robot/mechanisms/ says package first.robot.mechanisms;. Put the file one level up and VS Code marks that line red: the declared package does not match the expected package. Move the file, not the line.
Check your work
Open the Explorer in VS Code and expand src/main/java/first. Then sort the four quiz questions below without scrolling back up.
You should see
Main.javabeside arobotfolder, andRobot.javabeside anopmodefolder.MyTeleop.javaandMyAuto.javainsideopmode.- Four out of four in the quiz.
Check yourself
You need the CAN ID of a second flywheel motor. Where do you write it?
Pressing B should lower the arm to horizontal, but only in Teleop. What do you add, and where?
A routine raises the arm and then spins the flywheel. Where does it go?
You write a new OpMode in src/main/java/first/auto with package first.auto. It builds. Why does it not appear on the driver station?