Skip to content

Commit 86d7bbc

Browse files
authored
[examples] Add Java Examples and Templates for the XRP (#5529)
1 parent e8b5d44 commit 86d7bbc

40 files changed

+2613
-0
lines changed

shared/examplecheck.gradle

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ def tagList = [
5050
"Command-based",
5151
// Romi
5252
"Romi",
53+
// XRP
54+
"XRP",
5355
// Extremely simple programs showcasing a single hardware API
5456
"Hardware",
5557
// Full robot, with multiple mechanisms

styleguide/spotbugs-exclude.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,10 @@
108108
<Bug pattern="UC_USELESS_VOID_METHOD" />
109109
<Class name="edu.wpi.first.wpilibj.templates.romitimed.Robot" />
110110
</Match>
111+
<Match>
112+
<Bug pattern="UC_USELESS_VOID_METHOD" />
113+
<Class name="edu.wpi.first.wpilibj.templates.xrptimed.Robot" />
114+
</Match>
111115
<Match>
112116
<Bug pattern="UC_USELESS_VOID_METHOD" />
113117
<Class name="edu.wpi.first.wpilibj.templates.timed.Robot" />

wpilibjExamples/src/main/java/edu/wpi/first/wpilibj/examples/examples.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -893,6 +893,21 @@
893893
"mainclass": "Main",
894894
"commandversion": 2
895895
},
896+
{
897+
"name": "XRP Reference",
898+
"description": "An example command-based robot program that can be used with the XRP reference robot design.",
899+
"tags": [
900+
"XRP",
901+
"Command-based",
902+
"Differential Drive",
903+
"Digital Input",
904+
"Joystick"
905+
],
906+
"foldername": "xrpreference",
907+
"gradlebase": "javaxrp",
908+
"mainclass": "Main",
909+
"commandversion": 2
910+
},
896911
{
897912
"name": "Digital Communication Sample",
898913
"description": "Communicates with external devices (such as an Arduino) using the roboRIO's DIO.",
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Copyright (c) FIRST and other WPILib contributors.
2+
// Open Source Software; you can modify and/or share it under the terms of
3+
// the WPILib BSD license file in the root directory of this project.
4+
5+
package edu.wpi.first.wpilibj.examples.xrpreference;
6+
7+
/**
8+
* The Constants class provides a convenient place for teams to hold robot-wide numerical or boolean
9+
* constants. This class should not be used for any other purpose. All constants should be declared
10+
* globally (i.e. public static). Do not put anything functional in this class.
11+
*
12+
* <p>It is advised to statically import this class (or one of its inner classes) wherever the
13+
* constants are needed, to reduce verbosity.
14+
*/
15+
public final class Constants {
16+
public static class OperatorConstants {
17+
public static final int kDriverControllerPort = 0;
18+
}
19+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Copyright (c) FIRST and other WPILib contributors.
2+
// Open Source Software; you can modify and/or share it under the terms of
3+
// the WPILib BSD license file in the root directory of this project.
4+
5+
package edu.wpi.first.wpilibj.examples.xrpreference;
6+
7+
import edu.wpi.first.wpilibj.RobotBase;
8+
9+
/**
10+
* Do NOT add any static variables to this class, or any initialization at all. Unless you know what
11+
* you are doing, do not modify this file except to change the parameter class to the startRobot
12+
* call.
13+
*/
14+
public final class Main {
15+
private Main() {}
16+
17+
/**
18+
* Main initialization function. Do not perform any initialization here.
19+
*
20+
* <p>If you change your main robot class, change the parameter type.
21+
*/
22+
public static void main(String... args) {
23+
RobotBase.startRobot(Robot::new);
24+
}
25+
}
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
// Copyright (c) FIRST and other WPILib contributors.
2+
// Open Source Software; you can modify and/or share it under the terms of
3+
// the WPILib BSD license file in the root directory of this project.
4+
5+
package edu.wpi.first.wpilibj.examples.xrpreference;
6+
7+
import edu.wpi.first.wpilibj.TimedRobot;
8+
import edu.wpi.first.wpilibj2.command.Command;
9+
import edu.wpi.first.wpilibj2.command.CommandScheduler;
10+
11+
/**
12+
* The VM is configured to automatically run this class, and to call the functions corresponding to
13+
* each mode, as described in the TimedRobot documentation. If you change the name of this class or
14+
* the package after creating this project, you must also update the build.gradle file in the
15+
* project.
16+
*/
17+
public class Robot extends TimedRobot {
18+
private Command m_autonomousCommand;
19+
20+
private RobotContainer m_robotContainer;
21+
22+
/**
23+
* This function is run when the robot is first started up and should be used for any
24+
* initialization code.
25+
*/
26+
@Override
27+
public void robotInit() {
28+
// Instantiate our RobotContainer. This will perform all our button bindings, and put our
29+
// autonomous chooser on the dashboard.
30+
m_robotContainer = new RobotContainer();
31+
}
32+
33+
/**
34+
* This function is called every 20 ms, no matter the mode. Use this for items like diagnostics
35+
* that you want ran during disabled, autonomous, teleoperated and test.
36+
*
37+
* <p>This runs after the mode specific periodic functions, but before LiveWindow and
38+
* SmartDashboard integrated updating.
39+
*/
40+
@Override
41+
public void robotPeriodic() {
42+
// Runs the Scheduler. This is responsible for polling buttons, adding newly-scheduled
43+
// commands, running already-scheduled commands, removing finished or interrupted commands,
44+
// and running subsystem periodic() methods. This must be called from the robot's periodic
45+
// block in order for anything in the Command-based framework to work.
46+
CommandScheduler.getInstance().run();
47+
}
48+
49+
/** This function is called once each time the robot enters Disabled mode. */
50+
@Override
51+
public void disabledInit() {}
52+
53+
@Override
54+
public void disabledPeriodic() {}
55+
56+
/** This autonomous runs the autonomous command selected by your {@link RobotContainer} class. */
57+
@Override
58+
public void autonomousInit() {
59+
m_autonomousCommand = m_robotContainer.getAutonomousCommand();
60+
61+
// schedule the autonomous command (example)
62+
if (m_autonomousCommand != null) {
63+
m_autonomousCommand.schedule();
64+
}
65+
}
66+
67+
/** This function is called periodically during autonomous. */
68+
@Override
69+
public void autonomousPeriodic() {}
70+
71+
@Override
72+
public void teleopInit() {
73+
// This makes sure that the autonomous stops running when
74+
// teleop starts running. If you want the autonomous to
75+
// continue until interrupted by another command, remove
76+
// this line or comment it out.
77+
if (m_autonomousCommand != null) {
78+
m_autonomousCommand.cancel();
79+
}
80+
}
81+
82+
/** This function is called periodically during operator control. */
83+
@Override
84+
public void teleopPeriodic() {}
85+
86+
@Override
87+
public void testInit() {
88+
// Cancels all running commands at the start of test mode.
89+
CommandScheduler.getInstance().cancelAll();
90+
}
91+
92+
/** This function is called periodically during test mode. */
93+
@Override
94+
public void testPeriodic() {}
95+
96+
/** This function is called once when the robot is first started up. */
97+
@Override
98+
public void simulationInit() {}
99+
100+
/** This function is called periodically whilst in simulation. */
101+
@Override
102+
public void simulationPeriodic() {}
103+
}
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
// Copyright (c) FIRST and other WPILib contributors.
2+
// Open Source Software; you can modify and/or share it under the terms of
3+
// the WPILib BSD license file in the root directory of this project.
4+
5+
package edu.wpi.first.wpilibj.examples.xrpreference;
6+
7+
import edu.wpi.first.wpilibj.GenericHID;
8+
import edu.wpi.first.wpilibj.Joystick;
9+
import edu.wpi.first.wpilibj.XboxController;
10+
import edu.wpi.first.wpilibj.examples.xrpreference.commands.ArcadeDrive;
11+
import edu.wpi.first.wpilibj.examples.xrpreference.commands.AutonomousDistance;
12+
import edu.wpi.first.wpilibj.examples.xrpreference.commands.AutonomousTime;
13+
import edu.wpi.first.wpilibj.examples.xrpreference.subsystems.Arm;
14+
import edu.wpi.first.wpilibj.examples.xrpreference.subsystems.Drivetrain;
15+
import edu.wpi.first.wpilibj.examples.xrpreference.subsystems.XRPOnBoardIO;
16+
import edu.wpi.first.wpilibj.smartdashboard.SendableChooser;
17+
import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard;
18+
import edu.wpi.first.wpilibj2.command.Command;
19+
import edu.wpi.first.wpilibj2.command.InstantCommand;
20+
import edu.wpi.first.wpilibj2.command.PrintCommand;
21+
import edu.wpi.first.wpilibj2.command.button.JoystickButton;
22+
import edu.wpi.first.wpilibj2.command.button.Trigger;
23+
24+
/**
25+
* This class is where the bulk of the robot should be declared. Since Command-based is a
26+
* "declarative" paradigm, very little robot logic should actually be handled in the {@link Robot}
27+
* periodic methods (other than the scheduler calls). Instead, the structure of the robot (including
28+
* subsystems, commands, and button mappings) should be declared here.
29+
*/
30+
public class RobotContainer {
31+
// The robot's subsystems and commands are defined here...
32+
private final Drivetrain m_drivetrain = new Drivetrain();
33+
private final XRPOnBoardIO m_onboardIO = new XRPOnBoardIO();
34+
private final Arm m_arm = new Arm();
35+
36+
// Assumes a gamepad plugged into channel 0
37+
private final Joystick m_controller = new Joystick(0);
38+
39+
// Create SmartDashboard chooser for autonomous routines
40+
private final SendableChooser<Command> m_chooser = new SendableChooser<>();
41+
42+
/** The container for the robot. Contains subsystems, OI devices, and commands. */
43+
public RobotContainer() {
44+
// Configure the button bindings
45+
configureButtonBindings();
46+
}
47+
48+
/**
49+
* Use this method to define your button->command mappings. Buttons can be created by
50+
* instantiating a {@link GenericHID} or one of its subclasses ({@link
51+
* edu.wpi.first.wpilibj.Joystick} or {@link XboxController}), and then passing it to a {@link
52+
* edu.wpi.first.wpilibj2.command.button.JoystickButton}.
53+
*/
54+
private void configureButtonBindings() {
55+
// Default command is arcade drive. This will run unless another command
56+
// is scheduled over it.
57+
m_drivetrain.setDefaultCommand(getArcadeDriveCommand());
58+
59+
// Example of how to use the onboard IO
60+
Trigger userButton = new Trigger(m_onboardIO::getUserButtonPressed);
61+
userButton
62+
.onTrue(new PrintCommand("USER Button Pressed"))
63+
.onFalse(new PrintCommand("USER Button Released"));
64+
65+
JoystickButton joystickAButton = new JoystickButton(m_controller, 1);
66+
joystickAButton
67+
.onTrue(new InstantCommand(() -> m_arm.setAngle(45.0), m_arm))
68+
.onFalse(new InstantCommand(() -> m_arm.setAngle(0.0), m_arm));
69+
70+
JoystickButton joystickBButton = new JoystickButton(m_controller, 2);
71+
joystickBButton
72+
.onTrue(new InstantCommand(() -> m_arm.setAngle(90.0), m_arm))
73+
.onFalse(new InstantCommand(() -> m_arm.setAngle(0.0), m_arm));
74+
75+
// Setup SmartDashboard options
76+
m_chooser.setDefaultOption("Auto Routine Distance", new AutonomousDistance(m_drivetrain));
77+
m_chooser.addOption("Auto Routine Time", new AutonomousTime(m_drivetrain));
78+
SmartDashboard.putData(m_chooser);
79+
}
80+
81+
/**
82+
* Use this to pass the autonomous command to the main {@link Robot} class.
83+
*
84+
* @return the command to run in autonomous
85+
*/
86+
public Command getAutonomousCommand() {
87+
return m_chooser.getSelected();
88+
}
89+
90+
/**
91+
* Use this to pass the teleop command to the main {@link Robot} class.
92+
*
93+
* @return the command to run in teleop
94+
*/
95+
public Command getArcadeDriveCommand() {
96+
return new ArcadeDrive(
97+
m_drivetrain, () -> -m_controller.getRawAxis(1), () -> -m_controller.getRawAxis(2));
98+
}
99+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// Copyright (c) FIRST and other WPILib contributors.
2+
// Open Source Software; you can modify and/or share it under the terms of
3+
// the WPILib BSD license file in the root directory of this project.
4+
5+
package edu.wpi.first.wpilibj.examples.xrpreference.commands;
6+
7+
import edu.wpi.first.wpilibj.examples.xrpreference.subsystems.Drivetrain;
8+
import edu.wpi.first.wpilibj2.command.Command;
9+
import java.util.function.Supplier;
10+
11+
public class ArcadeDrive extends Command {
12+
private final Drivetrain m_drivetrain;
13+
private final Supplier<Double> m_xaxisSpeedSupplier;
14+
private final Supplier<Double> m_zaxisRotateSupplier;
15+
16+
/**
17+
* Creates a new ArcadeDrive. This command will drive your robot according to the speed supplier
18+
* lambdas. This command does not terminate.
19+
*
20+
* @param drivetrain The drivetrain subsystem on which this command will run
21+
* @param xaxisSpeedSupplier Lambda supplier of forward/backward speed
22+
* @param zaxisRotateSupplier Lambda supplier of rotational speed
23+
*/
24+
public ArcadeDrive(
25+
Drivetrain drivetrain,
26+
Supplier<Double> xaxisSpeedSupplier,
27+
Supplier<Double> zaxisRotateSupplier) {
28+
m_drivetrain = drivetrain;
29+
m_xaxisSpeedSupplier = xaxisSpeedSupplier;
30+
m_zaxisRotateSupplier = zaxisRotateSupplier;
31+
addRequirements(drivetrain);
32+
}
33+
34+
// Called when the command is initially scheduled.
35+
@Override
36+
public void initialize() {}
37+
38+
// Called every time the scheduler runs while the command is scheduled.
39+
@Override
40+
public void execute() {
41+
m_drivetrain.arcadeDrive(m_xaxisSpeedSupplier.get(), m_zaxisRotateSupplier.get());
42+
}
43+
44+
// Called once the command ends or is interrupted.
45+
@Override
46+
public void end(boolean interrupted) {}
47+
48+
// Returns true when the command should end.
49+
@Override
50+
public boolean isFinished() {
51+
return false;
52+
}
53+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Copyright (c) FIRST and other WPILib contributors.
2+
// Open Source Software; you can modify and/or share it under the terms of
3+
// the WPILib BSD license file in the root directory of this project.
4+
5+
package edu.wpi.first.wpilibj.examples.xrpreference.commands;
6+
7+
import edu.wpi.first.wpilibj.examples.xrpreference.subsystems.Drivetrain;
8+
import edu.wpi.first.wpilibj2.command.SequentialCommandGroup;
9+
10+
public class AutonomousDistance extends SequentialCommandGroup {
11+
/**
12+
* Creates a new Autonomous Drive based on distance. This will drive out for a specified distance,
13+
* turn around and drive back.
14+
*
15+
* @param drivetrain The drivetrain subsystem on which this command will run
16+
*/
17+
public AutonomousDistance(Drivetrain drivetrain) {
18+
addCommands(
19+
new DriveDistance(-0.5, 10, drivetrain),
20+
new TurnDegrees(-0.5, 180, drivetrain),
21+
new DriveDistance(-0.5, 10, drivetrain),
22+
new TurnDegrees(0.5, 180, drivetrain));
23+
}
24+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Copyright (c) FIRST and other WPILib contributors.
2+
// Open Source Software; you can modify and/or share it under the terms of
3+
// the WPILib BSD license file in the root directory of this project.
4+
5+
package edu.wpi.first.wpilibj.examples.xrpreference.commands;
6+
7+
import edu.wpi.first.wpilibj.examples.xrpreference.subsystems.Drivetrain;
8+
import edu.wpi.first.wpilibj2.command.SequentialCommandGroup;
9+
10+
public class AutonomousTime extends SequentialCommandGroup {
11+
/**
12+
* Creates a new Autonomous Drive based on time. This will drive out for a period of time, turn
13+
* around for time (equivalent to time to turn around) and drive forward again. This should mimic
14+
* driving out, turning around and driving back.
15+
*
16+
* @param drivetrain The drive subsystem on which this command will run
17+
*/
18+
public AutonomousTime(Drivetrain drivetrain) {
19+
addCommands(
20+
new DriveTime(-0.6, 2.0, drivetrain),
21+
new TurnTime(-0.5, 1.3, drivetrain),
22+
new DriveTime(-0.6, 2.0, drivetrain),
23+
new TurnTime(0.5, 1.3, drivetrain));
24+
}
25+
}

0 commit comments

Comments
 (0)