|
1 | | -# FRC Robot Project - Sim Skeleton |
| 1 | +# Assignment 2: Getting started with simulation |
2 | 2 |
|
3 | | -This is an FRC robot project using WPILib 2025, AdvantageKit, and CTRE Phoenix 6. |
| 3 | +## Overview |
| 4 | +This lesson is intended to get you familiar with the basic UI and code procedures with runnng a project, as well as implementing a simple, standard trigger function on the robot's drivetrain. |
4 | 5 |
|
5 | | -## Prerequisites |
| 6 | +This project is a standard, clean FRC repo based on our base project template. In the upcoming lessons, we will use this as a scaffold to work in, until you are eventually able to understand/code most of this yourself. |
6 | 7 |
|
7 | | -- WPILib 2025 installed (includes Java JDK) |
8 | | -- Visual Studio Code with WPILib extension (recommended) |
| 8 | +## Learning Objectives |
| 9 | +- Understand command-based robot programming |
| 10 | +- Learn how to modify drive commands with parameters |
| 11 | +- Use button triggers for mode switching |
| 12 | +- Add telemetry for debugging and visualization |
| 13 | +- See real-time changes in AdvantageScope |
9 | 14 |
|
10 | | -## Build Instructions |
| 15 | +## What You'll Build |
| 16 | +A training mode that: |
| 17 | +- Toggles on/off with the a button |
| 18 | +- Limits robot speed to 30% when active |
| 19 | +- Shows status in telemetry |
| 20 | +- Works seamlessly with existing drive code |
11 | 21 |
|
12 | | -### Windows |
| 22 | +## General Step-by-Step Implementation (try doing this by yourself, else follow along with the solution video) |
13 | 23 |
|
14 | | -The project uses Gradle for building. The Java JDK is included with WPILib installation. |
| 24 | +Make sure to create a NEW BRANCH with the feature implementation and create a PR as in the last assignment. |
15 | 25 |
|
16 | | -```bash |
17 | | -# Set JAVA_HOME to WPILib's JDK and build |
18 | | -JAVA_HOME="C:/Users/Public/wpilib/2025/jdk" ./gradlew build |
| 26 | +### Step 1: Modify the Drive Command |
| 27 | +First, we need to add support for variable speed to our drive command. In `DriveCommands.java`, add an overloaded drive function that accepts a new supplier. Add any logging you think may be helpful. |
19 | 28 |
|
20 | | -# Or use the gradlew wrapper directly if JAVA_HOME is configured in your environment |
21 | | -./gradlew build |
22 | | -``` |
| 29 | +### Step 2: Set Up the Button Trigger |
| 30 | +In `RobotContainer.java`, create a trigger for the training mode |
| 31 | + |
| 32 | +### Step 3: Test in Simulation |
| 33 | +1. Run the simulation: `WPILIB: Simlulate robot code` |
| 34 | +2. Open AdvantageScope and connect to the simulation |
| 35 | +3. Drive with the controller normally |
| 36 | +4. Hold the selected button and see if your driving speed changes |
| 37 | +5. Watch your logged fields in Advantage Scope and see if they correspond to your expectations. |
| 38 | + |
| 39 | +## How It Works |
| 40 | + |
| 41 | +### The Command Pattern |
| 42 | +FRC uses a command-based architecture where: |
| 43 | +- **Commands** define robot actions (like driving) |
| 44 | +- **Triggers** respond to button inputs |
| 45 | +- **Suppliers** provide values that can change over time |
| 46 | + |
| 47 | +### Key Concepts |
| 48 | + |
| 49 | +1. **BooleanSupplier**: A functional interface that supplies a boolean value |
| 50 | + - `() -> true` always returns true |
| 51 | + - `() -> controller.a()` returns true or false based on button state |
| 52 | + |
| 53 | +2. **Trigger**: Represents a button or condition |
| 54 | + - `controller.a()` creates a trigger for that button |
23 | 55 |
|
24 | | -### Common Build Issues and Solutions |
| 56 | +3. **Speed Multiplication**: Applied to all movement |
| 57 | + - Translation (X/Y movement) |
| 58 | + - Rotation (turning) |
| 59 | + - Ensures proportional control at lower speeds |
25 | 60 |
|
26 | | -#### Issue 1: JAVA_HOME not set |
27 | | -**Error:** `ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH` |
| 61 | +## Solution |
28 | 62 |
|
29 | | -**Solution:** |
30 | | -- On Windows, WPILib's JDK is located at `C:\Users\Public\wpilib\2025\jdk` |
31 | | -- Set JAVA_HOME before running gradlew: `JAVA_HOME="C:/Users/Public/wpilib/2025/jdk" ./gradlew build` |
32 | | -- Or set it permanently in your system environment variables |
33 | 63 |
|
34 | | -#### Issue 2: Command execution in Windows |
35 | | -**Problem:** Windows command prompt and bash handle commands differently |
| 64 | +## Extension Challenges |
36 | 65 |
|
37 | | -**Solution:** |
38 | | -- Use `./gradlew` in Git Bash or WSL |
39 | | -- Use `gradlew.bat` in Windows Command Prompt |
40 | | -- In PowerShell, use `./gradlew` or `.\gradlew.bat` |
| 66 | +### Challenge 1: Multiple Speed Modes |
| 67 | +Add three modes: Training (30%), Normal (100%), Turbo (120%) |
| 68 | +```java |
| 69 | +// Hint: Use multiple buttons |
| 70 | +``` |
41 | 71 |
|
42 | | -### Important Notes |
| 72 | +### Challenge 2: Smooth Transitions |
| 73 | +Use a SlewRateLimiter to gradually change speeds |
| 74 | +```java |
| 75 | +SlewRateLimiter speedLimiter = new SlewRateLimiter(2.0); // 2 units/sec |
| 76 | +// In command: speedLimiter.calculate(targetMultiplier) |
| 77 | +``` |
43 | 78 |
|
44 | | -#### CTRE Phoenix 6 API |
45 | | -When using CTRE Phoenix 6 with TalonFX (Kraken X60): |
46 | | -- Status signals use typed units (Angle, AngularVelocity, Voltage, etc.) not raw doubles |
47 | | -- Use `.getValue().in(Units.YourUnit)` to get numeric values |
48 | | -- Current limits: Use `SupplyCurrentLimit` and `StatorCurrentLimit` (not threshold-based) |
49 | | -- FOC (Field Oriented Control) is available and recommended for better performance |
| 79 | +### Challenge 3: Visual Feedback |
| 80 | +Add dashboard indicators for current mode |
| 81 | +```java |
| 82 | +Logger.recordOutput("Drive/Mode", |
| 83 | + multiplier < 0.5 ? "Training" : |
| 84 | + multiplier > 1.0 ? "Turbo" : "Normal"); |
| 85 | +``` |
50 | 86 |
|
51 | | -Example: |
| 87 | +### Challenge 4: Persistent Toggle |
| 88 | +Make it toggle on press instead of hold |
52 | 89 | ```java |
53 | | -// Correct Phoenix 6 usage |
54 | | -StatusSignal<Angle> positionSignal = motor.getPosition(); |
55 | | -double rotations = positionSignal.getValue().in(Units.Rotations); |
| 90 | +// Create a boolean that toggles |
| 91 | +BooleanSupplier toggledMode = new BooleanSupplier() { |
| 92 | + boolean enabled = false; |
| 93 | + { controller.rightBumper().onTrue(Commands.runOnce(() -> enabled = !enabled)); } |
| 94 | + public boolean getAsBoolean() { return enabled; } |
| 95 | +}; |
| 96 | +``` |
| 97 | +## Key Takeaways |
56 | 98 |
|
57 | | -// Incorrect (won't compile) |
58 | | -StatusSignal<Double> positionSignal = motor.getPosition(); // Type mismatch! |
59 | | -``` |
| 99 | +- **Separation of Concerns**: Drive logic stays in DriveCommands, button mapping in RobotContainer |
| 100 | +- **Functional Programming**: Suppliers allow dynamic values without complex state management |
| 101 | +- **Telemetry First**: Always add logging for debugging and analysis |
| 102 | +- **Incremental Development**: Start simple (hold button) then add complexity (toggle, multiple modes) |
0 commit comments