### Initialize AdvantageKit Logging Framework in Robot Constructor Source: https://docs.advantagekit.org/getting-started/installation/vscode-welcome This snippet illustrates the initialization of the AdvantageKit logging framework within the `Robot` class constructor. It includes setting metadata, configuring data receivers for real robot and simulation (including replay setup), and starting the logger. It must be called before any other initialization. ```java Logger.recordMetadata("ProjectName", "MyProject"); // Set a metadata value if (isReal()) { Logger.addDataReceiver(new WPILOGWriter()); // Log to a USB stick ("/U/logs") Logger.addDataReceiver(new NT4Publisher()); // Publish data to NetworkTables } else { setUseTiming(false); // Run as fast as possible String logPath = LogFileUtil.findReplayLog(); // Pull the replay log from AdvantageScope (or prompt the user) Logger.setReplaySource(new WPILOGReader(logPath)); // Read replay log Logger.addDataReceiver(new WPILOGWriter(LogFileUtil.addPathSuffix(logPath, "_sim"))); // Save outputs to a new log } Logger.start(); // Start logging! No more data receivers, replay sources, or metadata values may be added. ``` -------------------------------- ### Extend LoggedRobot in Java Source: https://docs.advantagekit.org/getting-started/installation/existing-projects Demonstrates how to configure the main Robot class to extend LoggedRobot, which is a prerequisite for using AdvantageKit's logging features. LoggedRobot provides enhanced functionality over TimedRobot for data logging and replay. ```java public class Robot extends LoggedRobot { // ... } ``` -------------------------------- ### Gversion Gradle Plugin Setup Source: https://docs.advantagekit.org/getting-started/installation/version-control Configures the Gversion Gradle plugin to generate a constants file with Git metadata like SHA and commit status. This ensures the robot code version is captured for log replay. ```gradle plugins { // ... id "com.peterabeles.gversion" version "1.10" } project.compileJava.dependsOn(createVersionFile) gversion { srcDir = "src/main/java/" classPackage = "frc.robot" className = "BuildConstants" dateFormat = "yyyy-MM-dd HH:mm:ss z" timeZone = "America/New_York" // Use preferred time zone indent = " " } ``` -------------------------------- ### Add TargetDistanceMeters Logging in Java Source: https://docs.advantagekit.org/getting-started/what-is-advantagekit/example-output-logging This Java code snippet demonstrates how to add a new output log for the calculated target distance in meters. It assumes you are within the odometry subsystem and have access to the latest robot pose and field constants. This line of code should be added to the existing robot code and will be active during replay. ```java Logger.recordOutput("TargetDistanceMeters", latestPose.getTranslation().getDistance(FieldConstants.hubCenter)); ``` -------------------------------- ### Integrate NavX Gyro with AdvantageKit in Java Source: https://docs.advantagekit.org/getting-started/template-projects/talonfx-swerve-template The project supports custom gyro implementations, defaulting to Pigeon 2. An example for integrating a NavX gyro using `GyroIONavX` is provided. This involves switching the gyro implementation in the `RobotContainer` constructor and registering sensor signals with `PhoenixOdometryThread`. ```java public RobotContainer() { // ... other initializations ... GyroIO gyroIO = new GyroIONavX(IS_COMP ? SerialPort.Port.kMXP : SerialPort.Port.kUSB); // ... Queue yawPositionQueue = PhoenixOdometryThread.getInstance().registerSignal(navX::getAngle); // ... } ``` -------------------------------- ### Update Maven Repository for Legacy AdvantageKit Projects Source: https://docs.advantagekit.org/getting-started/installation This snippet shows how to update the Maven repository configuration in a Gradle build file to migrate legacy AdvantageKit projects (v4.0.0-beta-1 or earlier) to the current repository. It replaces the old GitHub Packages repository with the new FRC Maven repository. ```gradle repositories { maven { url = uri("https://maven.pkg.github.com/Mechanical-Advantage/AdvantageKit") credentials { username = "Mechanical-Advantage-Bot" password = "ghp_nVQlUOLaYnfxn7QITB2LJmUps1m7LZ0vbp_cQ" } } } ``` ```gradle repositories { maven { url = uri("https://frcmaven.wpi.edu/artifactory/littletonrobotics-mvn-release") } } ``` -------------------------------- ### Add AdvantageKit Vendordep URL Source: https://docs.advantagekit.org/getting-started/installation/existing-projects URL to add AdvantageKit as a vendordep in WPILib. This is typically done through the WPILib documentation or VSCode's vendor library manager. ```text https://github.com/Mechanical-Advantage/AdvantageKit/releases/latest/download/AdvantageKit.json ``` -------------------------------- ### Integrating Custom Gyro Implementations (NavX Example) Source: https://docs.advantagekit.org/getting-started/template-projects/spark-swerve-template The project defaults to Pigeon 2 but supports custom gyro implementations like NavX. Change `new GyroIOPigeon2()` in `RobotContainer` to a different implementation, e.g., `GyroIONavX` for a NavX on the MXP SPI port. Ensure the gyro publishes signals at the same frequency as odometry. The `SparkOdometryThread` class is used to read gyro data. ```Java Queue yawPositionQueue = SparkOdometryThread.getInstance().registerSignal(navX::getAngle); ``` -------------------------------- ### Logging Mechanism2d with AdvantageKit Source: https://docs.advantagekit.org/data-flow/supported-types Demonstrates how to log Mechanism2d objects using AdvantageKit. The example shows both the @AutoLogOutput annotation and the manual Logger.recordOutput method. It's important to note that Mechanism objects must use the LoggedMechanism2d class for compatibility. ```java public class Example { @AutoLogOutput // Auto logged as "Example/Mechanism" private LoggedMechanism2d mechanism = new LoggedMechanism2d(3, 3); public void periodic() { // Alternative approach if not using @AutoLogOutput // (Must be called periodically) Logger.recordOutput("Example/Mechanism", mechanism); } } ``` -------------------------------- ### Log Dashboard Chooser for Autonomous Routines (Java) Source: https://docs.advantagekit.org/data-flow/recording-inputs/dashboard-inputs This example demonstrates the correct usage of `LoggedDashboardChooser` to replace `SendableChooser` for selecting autonomous routines. It ensures that the selected command is logged and handled correctly during replay. ```java private final LoggedDashboardChooser autoChooser = new LoggedDashboardChooser<>("Auto Routine"); public RobotContainer() { // ... autoChooser.addDefaultOption("Do Nothing", new InstantCommand()); autoChooser.addOption("My First Auto", new MyFirstAuto()); autoChooser.addOption("My Second Auto", new MySecondAuto()); autoChooser.addOption("My Third Auto", new MyThirdAuto()); } public Command getAutonomousCommand() { return autoChooser.get(); } ``` -------------------------------- ### Recording Git SHA in Robot Code Source: https://docs.advantagekit.org/getting-started/installation/version-control Demonstrates how to record the Git SHA metadata captured by the Gversion plugin into the robot's log using AdvantageKit's Logger. This allows for precise version identification during log replay. ```java public Robot() { Logger.recordMetadata("GitSHA", BuildConstants.GIT_SHA); // ... Logger.start(); } ``` -------------------------------- ### Instantiating Subsystems with Real or Simulated IO in Java Source: https://docs.advantagekit.org/data-flow/recording-inputs/io-interfaces Illustrates how to conditionally instantiate IO implementations based on whether the robot is running in a real environment or a simulator. This approach allows subsystems to accept IO objects via constructor arguments, enabling the central robot class to manage hardware interaction. ```Java public RobotContainer() { if (isReal()) { // Instantiate IO implementations to talk to real hardware driveTrain = new DriveTrain(new DriveTrainIOReal()); elevator = new Elevator(new ElevatorIOReal()); intake = new Intake(new IntakeIOReal()); } else { // Use anonymous classes to create "dummy" IO implementations driveTrain = new DriveTrain(new DriveTrainIO() {}); elevator = new Elevator(new ElevatorIO() {}); intake = new Intake(new IntakeIO() {}); } } ``` -------------------------------- ### Configure PathPlanner Parameters in Java Source: https://docs.advantagekit.org/getting-started/template-projects/talonfx-swerve-template The project includes built-in PathPlanner configuration within the `Drive.java` constructor. Key parameters like robot mass, MOI, wheel coefficient, and PID constants for driving and turning can be manually adjusted. ```java public Drive(DriverStation ds, HardwareInterface hw) { // ... other configurations ... double robotMass = 5.0; // kg double moi = 0.5; // kg m^2 double wheelCoefficient = 0.8; // ... PathPlanner configuration ... AutoBuilder.configureHolonomic(drivetrain::getPose, drivetrain::resetPose, drivetrain::updateChassisSpeeds, drivetrain::updateChassisSpeeds, new HolonomicDriveController(...), RotationConsts.turnPIDConstants(), ...); ``` -------------------------------- ### Log Simple Output Data with Logger.recordOutput Source: https://docs.advantagekit.org/data-flow/recording-outputs Demonstrates how to log simple output data such as speeds, poses, and states using the Logger.recordOutput method. This data is automatically saved to 'RealOutputs' or 'ReplayOutputs' tables and can be organized into subtables using forward slashes. ```java Logger.recordOutput("Flywheel/Setpoint", setpointSpeed); Logger.recordOutput("Drive/Pose", odometryPose); Logger.recordOutput("FeederState", FeederState.RUNNING); ``` -------------------------------- ### Updating and Logging Subsystem Inputs in Java Source: https://docs.advantagekit.org/data-flow/recording-inputs/io-interfaces Demonstrates how to update input data from the IO layer and send it to the AdvantageKit logging framework. This process ensures that all parts of the subsystem access the same input values within a cycle and facilitates data logging for simulation. ```Java io.updateInputs(inputs); // Update input data from the IO layer Logger.processInputs("ExampleSubsystem", inputs); // Send input data to the logging framework (or update from the log during replay) ``` -------------------------------- ### Log File Path Retrieval for Replay Source: https://docs.advantagekit.org/getting-started/traditional-replay This Java code snippet demonstrates how to find and set the log file path for replay operations. It prioritizes the 'AKIT_LOG_PATH' environment variable, then the file open in AdvantageScope, and finally prompts the user. This is a crucial first step in setting up log replay. ```java String logPath = LogFileUtil.findReplayLog(); ``` -------------------------------- ### Filter Invalid Vision Targets by Corner Count (Java) Source: https://docs.advantagekit.org/getting-started/what-is-advantagekit/example-bug-fixes This code snippet checks if the number of reported corners from vision targets is divisible by four and if the counts of X and Y coordinates match. This is a crucial step to filter out inaccurate or incomplete vision data that could lead to incorrect odometry calculations. It assumes an 'inputs' object with 'cornerX' and 'cornerY' arrays. ```java if (inputs.cornerX.length % 4 == 0 && inputs.cornerX.length == inputs.cornerY.length) { // Data looks good, continue processing } else { // Bad data, discard this frame } ``` -------------------------------- ### Setting the Replay Source using WPILOGReader Source: https://docs.advantagekit.org/getting-started/traditional-replay This Java code configures the replay source by instantiating a WPILOGReader with the determined log path. This allows the system to read input and output data from the specified log file for replay. ```java Logger.setReplaySource(new WPILOGReader(logPath)); ``` -------------------------------- ### Initialize LoggedDashboardChooser with SendableChooser (Java) Source: https://docs.advantagekit.org/data-flow/recording-inputs/dashboard-inputs This snippet shows how to initialize a `LoggedDashboardChooser` using an existing `SendableChooser`. This is useful for maintaining compatibility with APIs like PathPlanner's `AutoBuilder` while still benefiting from AdvantageKit's logging capabilities. ```java private final LoggedDashboardChooser autoChooser; public RobotContainer() { // ... // buildAutoChooser() returns a SendableChooser autoChooser = new LoggedDashboardChooser<>("Auto Routine", AutoBuilder.buildAutoChooser()); } ``` -------------------------------- ### Configure SysIdRoutine with AdvantageKit Logging (Java) Source: https://docs.advantagekit.org/data-flow/sysid-compatibility This snippet demonstrates how to create and configure a SysIdRoutine in Java for use with AdvantageKit. It specifies how the test state should be logged as an output through AdvantageKit and sets the log consumer to null, as AdvantageKit handles the data recording. The snippet also shows how to invoke the quasistatic and dynamic routines. ```Java var sysIdRoutine = new SysIdRoutine( new SysIdRoutine.Config( null, null, null, // Use default config (state) -> Logger.recordOutput("SysIdTestState", state.toString()) ), new SysIdRoutine.Mechanism( (voltage) -> subsystem.runVolts(voltage.in(Volts)), null, // No log consumer, since data is recorded by AdvantageKit subsystem ) ); // The methods below return Command objects sysIdRoutine.quasistatic(SysIdRoutine.Direction.kForward); sysIdRoutine.quasistatic(SysIdRoutine.Direction.kReverse); sysIdRoutine.dynamic(SysIdRoutine.Direction.kForward); sysIdRoutine.dynamic(SysIdRoutine.Direction.kReverse); ``` -------------------------------- ### Add AdvantageKit Dependencies and Replay Task to build.gradle Source: https://docs.advantagekit.org/getting-started/installation/vscode-welcome This snippet shows how to add the necessary dependencies and a replay task for AdvantageKit to the `build.gradle` file. It uses Groovy's JsonSlurper to read the AdvantageKit version from a JSON file and configures annotation processing and runtime dependencies. ```gradle task(replayWatch, type: JavaExec) { mainClass = "org.littletonrobotics.junction.ReplayWatch" classpath = sourceSets.main.runtimeClasspath } dependencies { // ... def akitJson = new groovy.json.JsonSlurper().parseText(new File(projectDir.getAbsolutePath() + "/vendordeps/AdvantageKit.json").text) annotationProcessor "org.littletonrobotics.akit:akit-autolog:$akitJson.version" } ``` -------------------------------- ### Manual Power Distribution Configuration - Java Source: https://docs.advantagekit.org/data-flow/built-in-logging This snippet demonstrates how to manually configure the power distribution type and CAN ID when not using the default configuration. It requires the `LoggedPowerDistribution` class and specifies the CAN ID and module type. ```java LoggedPowerDistribution.getInstance(50, ModuleType.kRev); // Example: PDH on CAN ID 50 ``` -------------------------------- ### Event Deploy Gradle Task Configuration Source: https://docs.advantagekit.org/getting-started/installation/version-control Sets up a Gradle task named 'eventDeploy' that automatically commits any uncommitted changes to the current branch before a 'deploy' task is executed. This is crucial for maintaining reproducible code versions during competitions for log replay. ```gradle task(eventDeploy) { doLast { if (project.gradle.startParameter.taskNames.any({ it.toLowerCase().contains("deploy") })) { def branchPrefix = "event" def branch = 'git branch --show-current'.execute().text.trim() def commitMessage = "Update at '${new Date().toString()}'" if (branch.startsWith(branchPrefix)) { exec { workingDir(projectDir) executable 'git' args 'add', '-A' } exec { workingDir(projectDir) executable 'git' args 'commit', '-m', commitMessage ignoreExitValue = true } println "Committed to branch: '$branch'" println "Commit message: '$commitMessage'" } else { println "Not on an event branch, skipping commit" } } else { println "Not running deploy task, skipping commit" } } } createVersionFile.dependsOn(eventDeploy) ``` -------------------------------- ### Implement Profiled Turning PID with Motion Magic Source: https://docs.advantagekit.org/getting-started/template-projects/talonfx-swerve-template This snippet shows how to integrate Motion Magic control requests for profiled turning PID in `ModuleIOTalonFX`. It declares `MotionMagicVoltage` and `MotionMagicTorqueCurrentFOC` objects, which can then replace the standard position request for smoother motion profiles. ```java private final MotionMagicVoltage positionVoltageRequest = new MotionMagicVoltage(0.0); private final MotionMagicTorqueCurrentFOC positionTorqueCurrentRequest = new MotionMagicTorqueCurrentFOC(0.0); ``` -------------------------------- ### Set Max Speed and Slip Current in Java Source: https://docs.advantagekit.org/getting-started/template-projects/talonfx-swerve-template Tune `kSpeedAt12Volts` in `TunerConstants.java` to reflect the robot's effective maximum speed, measured by driving at full speed and observing the maximum velocity. Tune `kSlipCurrent` to prevent wheel slippage by noting the drive motor current when slippage occurs. ```java public static final double kSpeedAt12Volts = 11.0; // Theoretical max speed in m/s public static final double kSlipCurrent = 20.0; // Slip current in Amps ``` -------------------------------- ### Initialize Inputs in AdvantageKit Subsystem Constructor Source: https://docs.advantagekit.org/getting-started/common-issues/uninitialized-inputs Demonstrates how to handle uninitialized inputs in an AdvantageKit subsystem. The provided Java code shows a common pattern where subsystem inputs are only updated during the `periodic` call. The solution involves calling `periodic` from the constructor to ensure inputs are initialized before use. ```java public class Example extends SubsystemBase { private final ExampleIO io; private final ExampleIOInputs inputs = new ExampleIOInputs(); public Example(ExampleIO io) { this.io = io; // Inputs are not updated yet inputs.position; } @Override public void periodic() { io.updateInputs(inputs); Logger.processInputs("Example", inputs); // Inputs are now updated inputs.position; } } ``` -------------------------------- ### Configure Drive/Turn PID Gains in Java Source: https://docs.advantagekit.org/getting-started/template-projects/talonfx-swerve-template Default PID gains for drive velocity and turn position controllers are located in `TunerConstants.java`. These values require tuning for each specific robot. AdvantageKit's PID gains differ from CTRE's defaults due to its handling of the swerve gear ratio on the TalonFX firmware. ```java public static final Gains driveGains = new Gains(0.1, 0.0, 0.01, 0.0, 0.0, 0.0); public static final Gains steerGains = new Gains(0.1, 0.0, 0.01, 0.0, 0.0, 0.0); ``` -------------------------------- ### Log Geometry Objects and Arrays with Logger.recordOutput Source: https://docs.advantagekit.org/data-flow/recording-outputs Illustrates logging common geometry objects like Pose2d, Pose3d, Trajectory, and SwerveModuleState, both as single values and arrays. The Logger.recordOutput method supports direct logging of these objects and arrays, which are serialized to binary data. ```java // Pose2d Pose2d poseA, poseB, poseC; Logger.recordOutput("MyPose2d", poseA); Logger.recordOutput("MyPose2dArray", poseA, poseB); Logger.recordOutput("MyPose2dArray", new Pose2d[] { poseA, poseB }); // Pose3d Pose3d poseA, poseB, poseC; Logger.recordOutput("MyPose3d", poseA); Logger.recordOutput("MyPose3dArray", poseA, poseB); Logger.recordOutput("MyPose3dArray", new Pose3d[] { poseA, poseB }); // Trajectory Trajectory trajectory; Logger.recordOutput("MyTrajectory", trajectory); // SwerveModuleState SwerveModuleState stateA, stateB, stateC, stateD; Logger.recordOutput("MySwerveModuleStates", stateA, stateB, stateC, stateD); Logger.recordOutput("MySwerveModuleStates", new SwerveModuleState[] { stateA, stateB, stateC, stateD }); ``` -------------------------------- ### Adding a Data Receiver with WPILOGWriter Source: https://docs.advantagekit.org/getting-started/traditional-replay This Java code snippet configures a data receiver using WPILOGWriter. It appends a suffix to the log file name to create a new file for storing replay outputs along with original inputs and outputs. This ensures that new data is logged without overwriting the original log. ```java Logger.addDataReceiver(new WPILOGWriter(LogFileUtil.addPathSuffix(logPath, "_sim"))); ``` -------------------------------- ### Characterize Drive Feedforward Gains (kS, kV) Source: https://docs.advantagekit.org/getting-started/template-projects/spark-swerve-template Measures the drive feedforward gains kS and kV without requiring SysId. The robot accelerates forward, and the measured gains are printed to the console. These values should be copied to `driveKs` and `driveKv` constants in `DriveConstants.java`. ```text 1. Tune turning PID gains. 2. Place the robot in an open space. 3. Select the "Drive Simple FF Characterization" auto routine. 4. Enable the robot in autonomous. 5. Disable the robot after at least ~5-10 seconds. 6. Check console output for measured kS and kV values and update `DriveConstants.java`. ``` -------------------------------- ### Avoid Raw FPGA Timestamps with Timer.getFPGATimestamp() Source: https://docs.advantagekit.org/getting-started/common-issues/non-deterministic-data-sources Using raw FPGA timestamps can lead to non-deterministic replay. Instead, utilize `Timer.getTimestamp()` for synchronized and deterministic time values, which is essential for accurate log replay in AdvantageKit. ```java /* Incorrect usage */ // double timestamp = Timer.getFPGATimestamp(); /* Correct usage */ double timestamp = Timer.getTimestamp(); ``` -------------------------------- ### Tune Drive and Turn PID Gains Source: https://docs.advantagekit.org/getting-started/template-projects/spark-swerve-template Details the process for tuning drive velocity PID controllers and turn position PID controllers. Default gains are in `DriveConstants.java`. It recommends using AdvantageScope to plot measured and setpoint values during tuning. ```text Refer to `DriveConstants.java` for default PID gains. Use AdvantageScope to plot measured and setpoint values. Plotting fields include `/RealOutputs/SwerveStates/Measured` and `/RealOutputs/SwerveStates/SetpointsOptimized`. ```