Robot for the 2025 Reefscape FRC Competition
Pneumatic systems operated on the power of compressed air. By channeling this compressed air through pipes it can be used to act on (i.e. push) and object. This compressed air can be used in conjuction with Pistons - basic cylinders which can be extended using this air.
Pistons have 2 basic states: open and close. To open them, air must be pushed through the bottom of the piston, which then pushes the piston up (and open). To close them, air must be pushed through the top of the piston, whih pushes it back down and closes it.
The top and bottom holes are connected via pipes to a double electronic valve (double solenoid). When switched to Forward the valve opens one part to air flow which pushes the piston open. When switched to Reverse the valve opens the other part to air flow whih pushes the piston close. When switched to Off the valve is completly closed and air does not flow to the piston.
The solenoids are connected to the Pneumatics Hub which can be controlled from the RobotRIO. It can instruct the solenoids open or close as we request. This is how we control the pistons.
Compressed air is held in Air Tanks (filled before each game) and also generated by a Compressor placed on the robot.
Controlling Pneumatics involves mostly controlling the Solenoids. Each solenoid can be controlled via the DoubleSolenoid class. It has 2 identifiers (numbers indicaing the connection ports on the PH), the forwardIdentifier indicates port for opening the valve into Forward mode and reverseIdentifier indicates port for opening the valve into Reverse mode. Each double solenoid operates a single piston.
public class Robot extends TimedRobot {
private DoubleSolenoid solenoid;
@Override
public void robotInit() {
solenoid = new DoubleSolenoid(PneumaticsModuleType.REVPH, RobotMap.PISTON_FORWARD_CHANNEL, RobotMap.PISTON_REVERSE_CHANNEL);
}
@Override
public void teleopInit() {
// opens into Forward mode. Use kBackward for backward mode and kOff for closed.
solenoid.set(DoubleSolenoid.Value.kForward);
}
}Limit switches are basic electronic switches that open or close electronic circuits based on outside information. We can use them to detect a boolean state, but what they detect exactly is not specific, as they can be used in many ways, but as the name suggests, they are generally used to provide a limit to a system, for example, we can use them to limit the motion of a motor: if the switch is closed, we stop the motor, if it is open we rotate the motor.
Generally, because switches are either open or closed, we can detect their state by connecting them into a circuit which connects to a digital input signal pin on the RoboRIO.

When the switch is closed, the circuit is closed and thus the voltage on the line is LOW. When it is open, the voltage on the line is HIGH (due to the pull-up resistor on the pin). So we can read this state using the DigitalInput class.
Switches have 2 kinds of configurations:
- Normally Open: in normally open mode, when the switch is not pressed, the circuit is open. And due to the pull-up resistor, the voltage will be HIGH on the pin. When it is pressed, the circuit is closed with resistance and thus the voltage level becomes LOW.
- Normally Closed: in normally closed mode, when the switch is not pressed, the circuit is closed with resistance so the voltage is LOW. When it is pressed, the circuit is open and voltage becomes high.
public class Robot extends TimedRobot {
private DigitalInput input;
@Override
public void robotInit() {
input = new DigitalInput(1);
}
...
@Override
public void teleopPeriodic() {
boolean isHigh = input.get();
if (isHigh) {
// the voltage level is HIGH on the pin
// so in normally-open, this means the switch isn't pressed
} else {
// the voltage level is LOW on the pin
// so in normally-open, this means the switch is pressed.
}
}
...
}Example Code for initializing with factory reset
public class Robot extends TimedRobot {
private SparkMax motor;
@Override
public void robotInit() {
motor = new SparkMax(RobotMap.MOTOR_IDENTIFIER, SparkLowLevel.MotorType.kBrushless);
SparkMaxConfig config = new SparkMaxConfig();
motor.configure(config, SparkBase.ResetMode.kNoResetSafeParameters, SparkBase.PersistMode.kNoPersistParameters);
}
}The robot is divided into 3 large parts: the drive system, components for collecting and placing Coral and components for collecting and placing Alge. These can be further subdivided into more specific parts.
SHALEV DO ME
SHALEV DO ME
SHALEV DO ME
In this phase we'll be implementing the basic subsystems of the robot. This is the base of the robot from which we can do the rest. For each subsystem, please read the description and specs of the subsystems to understand how it works.
The CoralElevator operates the elevator for extending the Coral components for higher reach. It is a basic Pneumatic system operated by 2 pistons which are in turn. Opening both pistons extends
the elevator up, retracting them lowers the elevator. These are operated each by a DoubleSolenoid with 2 limits switches indicating if the elevator is raised or lowered (one for raised one for lowered).
- Create the subsystem
- Create and initialize the 2 solenoids
- Create and initialize the 2 limit switches
- Implement
public boolean isRaised()method- returns
trueif the upper limit switch indicates the elevator is raised,falseotherwise - query the limit switch with
.get - remember that the limit switch is normally open and so
getreturnstruewhen not pressed
- returns
- Implement
public boolean isLowered()method- returns
trueif the lower limit switch indicates the elevator is lowered,falseotherwise - query the limit switch with
.get - remember that the limit switch is normally open and so
getreturnstruewhen not pressed
- returns
- Implement
public void raise()method- extends both pistons
- use
set(DoubleSolenoid.Value.kForward)on both solenoids
- Implement
public void lower()method- retracts both pistons
- use
set(DoubleSolenoid.Value.kReverse)on both solenoids
- Implement
public void stop()method- close both valves
- use
set(DoubleSolenoid.Value.kOff)on both solenoids
- Add
periodicmethod which prints the values fromisRaisedisLowered
Implement Basic Operational Commands for the subsystem:
RaiseCoralElevator- runs on
CoralElevatorsubsystem - on
initializecallraiseto start raising system - on
executedo nothing - on
isFinishedreturntrueifisRaisedistrue,falseotherwise - on
enddo nothing
- runs on
LowerCoralElevator- runs on
LowerElevatorsubsystem - on
initializecalllowerto start lowering system - on
executedo nothing - on
isFinishedreturntrueifisLoweredistrue,falseotherwise - on
enddo nothing
- runs on
The CoralArm operates a two-phased arm on top of the CoralElevator. This arm mounts the Coral gripper and as such manouvers it around. It is operated by 2 Pistons and has two positions. The pistons are operated each by a DoubleSolenoid with 2 limits switches indicating if the position of this arm.
- Create the subsystem
- Create and initialize the 2 solenoids
- Create and initialize the 2 limit switches
- Implement
public boolean isExtended()method- returns
trueif the limit switch on the extended position indicates the arm is extended,falseotherwise - query the limit switch with
.get - remember that the limit switch is normally open and so
getreturnstruewhen not pressed
- returns
- Implement
public boolean isRetracted()method- returns
trueif the limit switch on the retracted position indicates the arm is retracted,falseotherwise - query the limit switch with
.get - remember that the limit switch is normally open and so
getreturnstruewhen not pressed
- returns
- Implement
public void extend()method- extends both pistons
- use
set(DoubleSolenoid.Value.kForward)on both solenoids
- Implement
public void retract()method- retracts both pistons
- use
set(DoubleSolenoid.Value.kReverse)on both solenoids
- Implement
public void stop()method- close both valves
- use
set(DoubleSolenoid.Value.kOff)on both solenoids
- Add
periodicmethod which prints the values fromisExtendedisRetracted
Implement Basic Operational Commands for the subsystem:
ExtendedCoralArm- runs on
CoralArmsubsystem - on
initializecallextendto start extending system - on
executedo nothing - on
isFinishedreturntrueifisExtendedistrue,falseotherwise - on
enddo nothing
- runs on
RetractCoralArm- runs on
CoralArmsubsystem - on
initializecallretractto start retracting system - on
executedo nothing - on
isFinishedreturntrueifisRetractedistrue,falseotherwise - on
enddo nothing
- runs on
The CoralGripper sits on top of the CoralArm and is used to collect and hold the Coral pieces. The gripper uses two wheels to grip onto the Coral, collect it and hold it in place. A single NEO 550 and SparkMax motor controller operate this system. A limit switch is placed on the system to indicate if a Coral is present.
- Create the subsystem
- Create and initialize the SparkMax motor controller
- make sure to reset the motor controller settings
- Create and initialize the limit switch
- Implement
public boolean hasCoral()method- returns
trueif the limit switch indicates a Coral is in the system,falseotherwise - query the limit switch with
.get - remember that the limit switch is normally open and so
getreturnstruewhen not pressed
- returns
- Implement
public void rotateCollect()method- rotate the motor at a constant speed for collecting a Coral
- use the speed value
0.8
- Implement
public void rotateRelease()method- rotate the motor at a constant speed for release a Coral
- use the speed value
-0.5
- Implement
public void rotateHold()method- rotate the motor at a constant speed for holding a collected Coral in place
- use the speed value
0.2
- Implement
public void stop()method- stops the motor
- Add
periodicmethod which prints the values fromhasCoral
Implement Basic Operational Commands for the subsystem:
CollectCoral- runs on
CoralGrippersubsystem - on
initializecallrotateCollectto start rotating - on
executedo nothing - on
isFinishedreturntrueifhasCoralistrue,falseotherwise - on
enddo nothing
- runs on
ReleaseCoral- runs on
CoralGrippersubsystem - on
initializecallrotateReleaseto start rotating - on
executedo nothing - on
isFinishedreturntrueifhasCoralisfalse,falseotherwise - on
enddo nothing
- runs on
HoldCoral- runs on
CoralGrippersubsystem - on
initializecallrotateHoldto start retracting system - on
executedo nothing - on
isFinishedreturnfalse - on
enddo nothing
- runs on
The AlgaeArm operates a two-phased arm on top of the chassis. This arm mounts the Algae gripper and as such manouvers it around. It is operated by 2 Pistons and has two positions. The pistons are operated each by a DoubleSolenoid with 2 limits switches indicating if the position of this arm.
- Create the subsystem
- Create and initialize the 2 solenoids
- Create and initialize the 2 limit switches
- Implement
public boolean isExtended()method- returns
trueif the limit switch on the extended position indicates the arm is extended,falseotherwise - query the limit switch with
.get - remember that the limit switch is normally open and so
getreturnstruewhen not pressed
- returns
- Implement
public boolean isRetracted()method- returns
trueif the limit switch on the retracted position indicates the arm is retracted,falseotherwise - query the limit switch with
.get - remember that the limit switch is normally open and so
getreturnstruewhen not pressed
- returns
- Implement
public void extend()method- extends both pistons
- use
set(DoubleSolenoid.Value.kForward)on both solenoids
- Implement
public void retract()method- retracts both pistons
- use
set(DoubleSolenoid.Value.kReverse)on both solenoids
- Implement
public void stop()method- close both valves
- use
set(DoubleSolenoid.Value.kOff)on both solenoids
- Add
periodicmethod which prints the values fromisExtendedisRetracted
Implement Basic Operational Commands for the subsystem:
ExtendedAlgaeArm- runs on
AlgaeArmsubsystem - on
initializecallextendto start extending system - on
executedo nothing - on
isFinishedreturntrueifisExtendedistrue,falseotherwise - on
enddo nothing
- runs on
RetractAlgaeArm- runs on
AlgaeArmsubsystem - on
initializecallretractto start retracting system - on
executedo nothing - on
isFinishedreturntrueifisRetractedistrue,falseotherwise - on
enddo nothing
- runs on
The AlgaeGripper sits on top of the AlgaeArm and is used to collect and hold the Algae pieces. The gripper uses two wheels to grip onto the Algae, collect it and hold it in place. A single NEO 550 and SparkMax motor controller operate this system. A limit switch is placed on the system to indicate if a Algae is present.
- Create the subsystem
- Create and initialize the SparkMax motor controller
- make sure to reset the motor controller settings
- Create and initialize the limit switch
- Implement
public boolean hasAlgae()method- returns
trueif the limit switch indicates a Algae is in the system,falseotherwise - query the limit switch with
.get - remember that the limit switch is normally open and so
getreturnstruewhen not pressed
- returns
- Implement
public void rotateCollect()method- rotate the motor at a constant speed for collecting a Algae
- use the speed value
0.8
- Implement
public void rotateRelease()method- rotate the motor at a constant speed for release a Algae
- use the speed value
-0.5
- Implement
public void rotateHold()method- rotate the motor at a constant speed for holding a collected Algae in place
- use the speed value
0.2
- Implement
public void stop()method- stops the motor
- Add
periodicmethod which prints the values fromhasAlgae
Implement Basic Operational Commands for the subsystem:
CollectAlgae- runs on
AlgaeGrippersubsystem - on
initializecallrotateCollectto start rotating - on
executedo nothing - on
isFinishedreturntrueifhasAlgaeistrue,falseotherwise - on
enddo nothing
- runs on
ReleaseAlgae- runs on
AlgaeGrippersubsystem - on
initializecallrotateReleaseto start rotating - on
executedo nothing - on
isFinishedreturntrueifhasAlgaeisfalse,falseotherwise - on
enddo nothing
- runs on
HoldAlgae- runs on
AlgaeGrippersubsystem - on
initializecallrotateHoldto start rotating - on
executedo nothing - on
isFinishedreturnfalse - on
enddo nothing
- runs on
The project has several pre-made run configurations for your convenience. These configurations will be loaded automatically when you open the project.
To use a run configuration, select it from the configurations drop down box and click on run
Select the Robot Deploy run configuration and click on run. This will build and deploy the code to the robot.
Select the Robot Deploy Debug run configuration to deploy the code with debugger enabled.
To attach a debugger, after a successful deployment (i.e. wait for the deployment to finish successfully), select and run the RoboRIO Debugger (run with debug, the bug button, not the run button).
Select the Simulate run configuration and click on run. This will build and run the code in the simulator.
Select the Simulate Debug run configuration and click on run. This will run the simulation with debugger enabled.
Once the console prints Listening for transport dt_socket at address select and run the Simulation Debugger run configuration (run with debug, the bug button, not the run button).
Note that doing all these will run two configuration simultaneously. This is fine, but when you wish to stop the simulation you will need to stop both the simulation and the debugger.












