Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Matthew training stuff #66

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/section-5/pull-requests.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Feature branches should go through two code reviews:
1. The first one where there is no new implementation. All code here is either structural code (classes and methods setup but not implemented), or code that we have already written in the past (such as drivetrain code). This is to catch structural problems early on and have the reviewer familiarize themself with the code so it will be easier to do the final review. When unit tests are necessary, they should also be written in this phase.
2. The second one should be the final code review. This is looking at the entire finished feature and making sure that it is written correctly.

Each pull request should be reviewed by at least one student, and it is preferable, although not required, to have that student do both reviews.
Each pull request should be reviewed by at least one student, and it is preferable, although not required, to have that student do both reviews. Also make sure to consult with Dean or any other programming mentor before having a PR fully approved. The more people reviewing, the better.

## Unit Testing
What code needs unit tests is explained in [section 6](/section-6/why-tests/), but the programming leads/mentors may request that unit tests be written for a branch to be merged.
Binary file added docs/section-7/PathPlanner.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/section-7/PathPlanner_Autos.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/section-7/PathPlanner_Paths.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
154 changes: 152 additions & 2 deletions docs/section-7/pathweaver.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,159 @@
In this section, you will learn how to write Autonomous code. As mentioned before, the Autonomous code is for the Autonomous period during the game. While our bots are in the Autonomous period, It can score, leave the safezone, or even ruin other autos depending on how ambitous your autonomous will be. It'll be fun.

Quick note, While you are writing your Autonomous Code and plotting your paths, consider your constraints and strategies. Make sure you are utilizing the robot's potential to the fullest, making as many autonomous paths to give our alliance partners more strategies to work with. Talk with your drive team to see what paths they would like to use during competition. In general, make sure to have a strategic mindset whenever creating autons.

Now let's write some autonomous code!

## PathPlanner Tool
Our robots use the [`PathPlanner`](https://pathplanner.dev/home.html) tool for our autonomous as it is an easy and efficient way to set up pathways

So how exactly do we set this up and get the paths running?

## Setup in RobotContainer
Firstoff, we want to settup and import PathPlanner into RobotContainer. We will generally use this template to help us configure the PathPlanner tool. Always reference to the [`PathPlanner Docs`](https://pathplanner.dev/home.html) whenever you are configuring the autonomous.

Here when setting up the auto, we want to get constants such as robot's current positions and plug it into the methods, that way PathPlanner knows where our robot is
``` Java
public class DriveSubsystem extends SubsystemBase {
public DriveSubsystem() {
// All other subsystem initialization
// ...

// Load the RobotConfig from the GUI settings. You should probably
// store this in your Constants file
RobotConfig config;
try{
config = RobotConfig.fromGUISettings();
} catch (Exception e) {
// Handle exception as needed
e.printStackTrace();
}

// Configure AutoBuilder last
AutoBuilder.configure(
this::getPose, // Robot pose supplier
this::resetPose, // Method to reset odometry (will be called if your auto has a starting pose)
this::getRobotRelativeSpeeds, // ChassisSpeeds supplier. MUST BE ROBOT RELATIVE
(speeds, feedforwards) -> driveRobotRelative(speeds), // Method that will drive the robot given ROBOT RELATIVE ChassisSpeeds. Also optionally outputs individual module feedforwards
new PPHolonomicDriveController( // PPHolonomicController is the built in path following controller for holonomic drive trains
new PIDConstants(5.0, 0.0, 0.0), // Translation PID constants
new PIDConstants(5.0, 0.0, 0.0) // Rotation PID constants
),
config, // The robot configuration
() -> {
// Boolean supplier that controls when the path will be mirrored for the red alliance
// This will flip the path being followed to the red side of the field.
// THE ORIGIN WILL REMAIN ON THE BLUE SIDE

var alliance = DriverStation.getAlliance();
if (alliance.isPresent()) {
return alliance.get() == DriverStation.Alliance.Red;
}
return false;
},
this // Reference to this subsystem to set requirements
);
}
}
```

## Creating Named Commands
Now that we have configured our autonomous, we need to create named commands to store the methods we will use in the PathPlanner tool(Example: Shooter Commands)

We always want to name our commands, that way we know which one to use when creating our autonomous

Then we want to run one actual command we created such as shooter so we would put the command name in there, and list the subsystem name as one of the parameters that way it knows what subsytem to use

``` Java
public class RobotContainer() {
public RobotContainer() {
// Subsystem initialization
swerve = new Swerve();
exampleSubsystem = new ExampleSubsystem();

// Register Named Commands
NamedCommands.registerCommand("autoBalance", swerve.autoBalanceCommand());
NamedCommands.registerCommand("exampleCommand", exampleSubsystem.exampleCommand());
NamedCommands.registerCommand("someOtherCommand", new SomeOtherCommand());
//Example of a command we used on our bot
NamedCommands.registerCommand("PassToOuttake", new PassToOuttake(intakeShooter));

// Do all other initialization
configureButtonBindings();

// ...
}
}
```
## Registering Autos On SmartDashboard
During competitions, strategies will change throughout matches, so you are going to want to change your autos depending on that strategy drive team comes up with

The question is how do we select auto right before a match?

It's pretty simple, all you have to do is register your autos onto SmartDashboard:

``` Java
private List<Command> autoCommands = new ArrayList<Command>();
private SendableChooser<Integer> autoSelector = new SendableChooser<Integer>();

private boolean hasSetupAutos = false;
private final String[] autoNames = new String[] {
/* These are assumed to be equal to the AUTO ames in pathplanner */

"1 Piece Shoot Auto", "2 Piece Shoot Auto", "3 Piece Shoot Auto",

"Raise Arm", "Swing Arm", "Still Arm",

"Auto Ruiner", "Safehouse Move", "No Moving",
};
DigitalInput[] autoSelectors = new DigitalInput[Math.min(autoNames.length, 10)];

public RobotContainer() {
registerAutoCommands();
SmartDashboard.putData(autoSelector);
SmartDashboard.setPersistent("SendableChooser[0]");
}

```
What is happening here is we are putting our auto names in this array and creating a SmartDashboard selector to select our autos during a competition

## Running Autos In Code
Now that we have all of our Autos set up, we need to tell the robot to run and build the autonomous command

``` Java
public class RobotContainer {
private final SendableChooser<Command> autoChooser;

public RobotContainer() {
// Another option that allows you to specify the default auto by its name
// autoChooser = AutoBuilder.buildAutoChooser("My Default Auto");

public Command getAutonomousCommand() {
return autoSelectors.getSelected();
}
}
```
What this code does is that it gets the autonomous we chose from SmartDashboard and plugs it into the getAutonomousCommand()

## creating autos!
Now that we have settup the neccesary code for auto, you can start creating autos and setting up paths. One of the best parts of the autonomous creation process.

Open up your PathPlanner app, and open your robot project. Once that is finished, your going to create a new path, and set the robot's starting postion on the field(the green box). You can add paths by simply clicking on add a waypoint and moving it. Once you have a path created, exit out of your path creation and head to the autos section. The autos section is where you can combine paths and commands(like shoot) to make a fully functioning autonomous. It's pretty similar to creating a path. When creating an auto, you are going to add your different paths and registered commands from robot container to your auto. Once you have an auto created, it should automatically register on your source branch, and you can commit it!

![PathPlanner](PathPlanner).png)

![PathPlanner Paths](PathPlanner_Paths.png)

![PathPlanner Autos](PathPlanner_Autos.png)

That's about it, have fun creating your autonomous code!


## PathWeaver Section(Old Stuff)
One advantage of a characterized drivetrain is that it more effectively drives the robot to a precise location. This makes following autonomous paths a more viable option. All we need to do is tell the robot a specific path to follow and the robot will drive the path pretty accurately.

But how do we specify these paths? We use the `Trajectory` class along with WPILib's Pathweaver tool. For a more detailed description of how to use this class, check out WPIlib's [documentation](https://docs.wpilib.org/en/stable/docs/software/examples-tutorials/trajectory-tutorial/index.html).

Let's write some autonomous code!

## Trajectories
The [`Trajectory`](https://first.wpi.edu/FRC/roborio/release/docs/java/edu/wpi/first/wpilibj/trajectory/Trajectory.html) class creates a smooth path through a list of states. Each state contains information such as the position on the field, time elapsed, velocity, acceleration, pose, and the curvature of the path. Once you have built your paths using Pathweaver, you can use the [`fromPathweaverJson()`](https://first.wpi.edu/FRC/roborio/release/docs/java/edu/wpi/first/wpilibj/trajectory/TrajectoryUtil.html#fromPathweaverJson(java.nio.file.Path)) method from [`TrajectoryUtil`](https://first.wpi.edu/FRC/roborio/release/docs/java/edu/wpi/first/wpilibj/trajectory/TrajectoryUtil.html) to create a Trajectory from the built path. This will be the primary way in which we create our `Trajectory` objects.

Expand Down