autonomous_routine_path_planning
Differences
This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| autonomous_routine_path_planning [2022/08/15 00:23] – rfhuang | autonomous_routine_path_planning [2022/09/13 21:51] (current) – rfhuang | ||
|---|---|---|---|
| Line 21: | Line 21: | ||
| Given the modularity of the Command Based architecture, | Given the modularity of the Command Based architecture, | ||
| + | ---- | ||
| + | |||
| + | ===== Architecture (Sequential) ===== | ||
| + | |||
| + | 1. Using PathWeaver with path + splines as inputs, the desired path is turned into JSON which is machine readable to become a RamseteCommand. | ||
| + | {{ :: | ||
| + | 2. TrajectorySequence.java takes in those generated path files, combines it with our drivebase PID constants into a completed RamseteCommand. | ||
| + | <code java> public TrajectorySequence(Drivebase drivetrain, String ... paths) { | ||
| + | drivebase = drivetrain; | ||
| + | |||
| + | for (String pathLocation : paths) { | ||
| + | Command path = generatePath(pathLocation); | ||
| + | if (path == null) return; | ||
| + | } | ||
| + | |||
| + | for (String pathLocation : paths) { | ||
| + | Command path = generatePath(pathLocation); | ||
| + | addCommands(path); | ||
| + | } | ||
| + | } | ||
| + | |||
| + | private Command generatePath(String pathName) { | ||
| + | try { | ||
| + | Path trajectoryPath = Filesystem.getDeployDirectory().toPath().resolve(pathName); | ||
| + | Trajectory trajectory = TrajectoryUtil.fromPathweaverJson(trajectoryPath); | ||
| + | RamseteCommand ramseteCommand = new RamseteCommand( | ||
| + | trajectory, | ||
| + | drivebase:: | ||
| + | new RamseteController(AutoConstants.kRamseteB, | ||
| + | new SimpleMotorFeedforward( | ||
| + | DrivebaseConstants.ksVolts, | ||
| + | DrivebaseConstants.kvVoltSecondsPerMeter, | ||
| + | DrivebaseConstants.kaVoltSecondsSquaredPerMeter), | ||
| + | DrivebaseConstants.kDriveKinematics, | ||
| + | drivebase:: | ||
| + | new PIDController(DrivebaseConstants.kPDriveVel, | ||
| + | new PIDController(DrivebaseConstants.kPDriveVel, | ||
| + | // RamseteCommand passes volts to the callback | ||
| + | drivebase:: | ||
| + | drivebase); | ||
| + | |||
| + | // Reset odometry to the starting pose of the trajectory. | ||
| + | drivebase.resetOdometry(trajectory.getInitialPose()); | ||
| + | // Set up a sequence of commands | ||
| + | // First, we want to reset the drivetrain odometry | ||
| + | return new InstantCommand(() -> drivebase.resetOdometry(trajectory.getInitialPose()), | ||
| + | .andThen(new InstantCommand(() -> drivebase.enableBrakeMode(), | ||
| + | // next, we run the actual ramsete command | ||
| + | .andThen(ramseteCommand) | ||
| + | // Finally, we make sure that the robot stops | ||
| + | .andThen(new InstantCommand(() -> drivebase.tankDriveVolts(0, | ||
| + | } catch (IOException ex) { | ||
| + | DriverStation.reportError(" | ||
| + | } | ||
| + | return null; | ||
| + | }</ | ||
| + | 3. Using a pre-generated GUI in SmartDashbaord the desired path is chosen, this happens in AutoSelector.java. The selected path is able to be read by our code when the match begins. | ||
| + | <code java> | ||
| + | chooser.setDefaultOption(" | ||
| + | new InstantCommand(superstructure.intake:: | ||
| + | new ParallelRaceGroup( | ||
| + | new BallManager(superstructure, | ||
| + | new TrajectorySequence(drivebase, | ||
| + | ), | ||
| + | new ParallelCommandGroup( | ||
| + | new Shoot(drivebase, | ||
| + | new SequentialCommandGroup( | ||
| + | new WaitCommand(0.75), | ||
| + | new InstantCommand(superstructure.intake:: | ||
| + | ) | ||
| + | ), | ||
| + | new ParallelRaceGroup( | ||
| + | new BallManager(superstructure, | ||
| + | new SequentialCommandGroup( | ||
| + | new TrajectorySequence(drivebase, | ||
| + | new WaitCommand(0.75), | ||
| + | new TrajectorySequence(drivebase, | ||
| + | ) | ||
| + | ), | ||
| + | new Shoot(drivebase, | ||
| + | )); | ||
| + | |||
| + | chooser.addOption(" | ||
| + | new InstantCommand(superstructure.intake:: | ||
| + | new ParallelCommandGroup( | ||
| + | new BallManager(superstructure).withInterrupt(() -> { | ||
| + | return superstructure.indexer.hasLowerBall() && superstructure.indexer.hasUpperBall(); | ||
| + | }).withTimeout(4), | ||
| + | new TrajectorySequence(drivebase, | ||
| + | ), | ||
| + | new Shoot(drivebase, | ||
| + | new InstantCommand(superstructure.intake:: | ||
| + | new ParallelRaceGroup( | ||
| + | new BallManager(superstructure), | ||
| + | new SequentialCommandGroup( | ||
| + | new TrajectorySequence(drivebase, | ||
| + | new WaitCommand(1), | ||
| + | new TrajectorySequence(drivebase, | ||
| + | ) | ||
| + | ), | ||
| + | new Shoot(drivebase, | ||
| + | )); | ||
| + | | ||
| + | SmartDashboard.putData(chooser); | ||
| + | } | ||
| + | |||
| + | public Command getSelected() { | ||
| + | return chooser.getSelected(); | ||
| + | }</ | ||
| + | 4. The selected path is taken from the GUI at game start. After that, the RamseteCommand is generated and executed in RobotContainer.java, | ||
autonomous_routine_path_planning.1660537396.txt.gz · Last modified: 2022/08/15 00:23 by rfhuang
