diff --git a/examples/stage1/stage1b/snippets/src/main/java/sources/CommandBasedKitbotPt2.java b/examples/stage1/stage1b/snippets/src/main/java/sources/CommandBasedKitbotPt2.java
index b385475d..de9b838a 100644
--- a/examples/stage1/stage1b/snippets/src/main/java/sources/CommandBasedKitbotPt2.java
+++ b/examples/stage1/stage1b/snippets/src/main/java/sources/CommandBasedKitbotPt2.java
@@ -7,6 +7,10 @@
import static org.wpilib.units.Units.Seconds;
+import com.ctre.phoenix6.CANBus;
+import com.ctre.phoenix6.hardware.TalonFX;
+import com.revrobotics.spark.SparkLowLevel.MotorType;
+import com.revrobotics.spark.SparkMax;
import java.util.function.DoubleSupplier;
import org.wpilib.command3.Command;
import org.wpilib.command3.Mechanism;
@@ -17,25 +21,49 @@
import org.wpilib.opmode.PeriodicOpMode;
class CommandBasedKitbotPt2 {
- // [drivetrainDef]
- public class Drivetrain implements Mechanism {
- private static final int leftLeaderID = 0, rightLeaderID = 2;
- private final TalonFX leftLeader = new TalonFX(leftLeaderID, CANBus.systemcore(0)),
- leftFollower = new TalonFX(1, CANBus.systemcore(0)),
- rightLeader = new TalonFX(rightLeaderID, CANBus.systemcore(0)),
- rightFollower = new TalonFX(3, CANBus.systemcore(0));
+ class CtreExamples {
+ // [ctreDrivetrainDef]
+ public class Drivetrain implements Mechanism {
+ private static final int leftLeaderID = 0, rightLeaderID = 2;
+ private final TalonFX leftLeader = new TalonFX(leftLeaderID, CANBus.systemcore(0)),
+ leftFollower = new TalonFX(1, CANBus.systemcore(0)),
+ rightLeader = new TalonFX(rightLeaderID, CANBus.systemcore(0)),
+ rightFollower = new TalonFX(3, CANBus.systemcore(0));
+
+ private final OnboardIMU imu = new OnboardIMU(MountOrientation.FLAT);
+ private final DifferentialDrive differentialDrive =
+ new DifferentialDrive(leftLeader::setThrottle, rightLeader::setThrottle);
+
+ private final DrivetrainSim drivetrainSim = new DrivetrainSim(leftLeader, rightLeader);
+
+ public void periodic() {
+ drivetrainSim.periodic();
+ }
+ }
+ // [/ctreDrivetrainDef]
+ }
- private final OnboardIMU imu = new OnboardIMU(MountOrientation.FLAT);
- private final DifferentialDrive differentialDrive =
- new DifferentialDrive(leftLeader::setThrottle, rightLeader::setThrottle);
+ class RevExamples {
+ // [revDrivetrainDef]
+ public class Drivetrain implements Mechanism {
+ private static final int leftLeaderID = 0, rightLeaderID = 2;
+ private final SparkMax leftLeader = new SparkMax(leftLeaderID, 0, MotorType.kBrushed),
+ leftFollower = new SparkMax(1, 0, MotorType.kBrushed),
+ rightLeader = new SparkMax(rightLeaderID, 0, MotorType.kBrushed),
+ rightFollower = new SparkMax(3, 0, MotorType.kBrushed);
- private final DrivetrainSim drivetrainSim = new DrivetrainSim(leftLeader, rightLeader);
+ private final OnboardIMU imu = new OnboardIMU(MountOrientation.FLAT);
+ private final DifferentialDrive differentialDrive =
+ new DifferentialDrive(leftLeader::setThrottle, rightLeader::setThrottle);
- public void periodic() {
- drivetrainSim.periodic();
+ private final DrivetrainSim drivetrainSim = new DrivetrainSim(leftLeader, rightLeader);
+
+ public void periodic() {
+ drivetrainSim.periodic();
+ }
}
+ // [/revDrivetrainDef]
}
- // [/drivetrainDef]
// [opModeSkeleton]
class MyOpModeName extends PeriodicOpMode {
@@ -112,21 +140,11 @@ Command rotateInPlaceHint(double angleDegrees) {
}
}
- static class TalonFX {
- TalonFX(int id, CANBus bus) {}
-
- void setThrottle(double throttle) {}
- }
-
- static class CANBus {
- static CANBus systemcore(int busNumber) {
- return new CANBus();
- }
- }
-
static class DrivetrainSim {
DrivetrainSim(TalonFX leftLeader, TalonFX rightLeader) {}
+ DrivetrainSim(SparkMax leftLeader, SparkMax rightLeader) {}
+
void periodic() {}
}
}
diff --git a/examples/stage1/stage1b/snippets/vendordeps/Phoenix6.json b/examples/stage1/stage1b/snippets/vendordeps/Phoenix6.json
new file mode 100644
index 00000000..23443a3f
--- /dev/null
+++ b/examples/stage1/stage1b/snippets/vendordeps/Phoenix6.json
@@ -0,0 +1,447 @@
+{
+ "fileName": "Phoenix6-26.50.0-alpha-1.json",
+ "name": "CTRE-Phoenix (v6)",
+ "version": "26.50.0-alpha-1",
+ "wpilibYear": "2027_alpha5",
+ "uuid": "e995de00-2c64-4df5-8831-c1441420ff19",
+ "mavenUrls": ["https://maven.ctr-electronics.com/release/"],
+ "jsonUrl": "https://maven.ctr-electronics.com/release/com/ctre/phoenix6/latest/Phoenix6-frc2027-latest.json",
+ "conflictsWith": [
+ {
+ "uuid": "e7900d8d-826f-4dca-a1ff-182f658e98af",
+ "errorMessage": "Users cannot have both the replay and regular Phoenix 6 vendordeps in their robot program.",
+ "offlineFileName": "Phoenix6-replay-frc2027-latest.json"
+ }
+ ],
+ "javaDependencies": [
+ {
+ "groupId": "com.ctre.phoenix6",
+ "artifactId": "wpiapi-java",
+ "version": "26.50.0-alpha-1"
+ }
+ ],
+ "jniDependencies": [
+ {
+ "groupId": "com.ctre.phoenix6",
+ "artifactId": "api-cpp",
+ "version": "26.50.0-alpha-1",
+ "isJar": false,
+ "skipInvalidPlatforms": true,
+ "validPlatforms": [
+ "windowsx86-64",
+ "linuxx86-64",
+ "linuxarm64",
+ "linuxsystemcore"
+ ],
+ "simMode": "hwsim"
+ },
+ {
+ "groupId": "com.ctre.phoenix6",
+ "artifactId": "tools",
+ "version": "26.50.0-alpha-1",
+ "isJar": false,
+ "skipInvalidPlatforms": true,
+ "validPlatforms": [
+ "windowsx86-64",
+ "linuxx86-64",
+ "linuxarm64",
+ "linuxsystemcore"
+ ],
+ "simMode": "hwsim"
+ },
+ {
+ "groupId": "com.ctre.phoenix6.sim",
+ "artifactId": "api-cpp-sim",
+ "version": "26.50.0-alpha-1",
+ "isJar": false,
+ "skipInvalidPlatforms": true,
+ "validPlatforms": [
+ "windowsx86-64",
+ "linuxx86-64",
+ "linuxarm64",
+ "osxuniversal"
+ ],
+ "simMode": "swsim"
+ },
+ {
+ "groupId": "com.ctre.phoenix6.sim",
+ "artifactId": "tools-sim",
+ "version": "26.50.0-alpha-1",
+ "isJar": false,
+ "skipInvalidPlatforms": true,
+ "validPlatforms": [
+ "windowsx86-64",
+ "linuxx86-64",
+ "linuxarm64",
+ "osxuniversal"
+ ],
+ "simMode": "swsim"
+ },
+ {
+ "groupId": "com.ctre.phoenix6.sim",
+ "artifactId": "simTalonSRX",
+ "version": "26.50.0-alpha-1",
+ "isJar": false,
+ "skipInvalidPlatforms": true,
+ "validPlatforms": [
+ "windowsx86-64",
+ "linuxx86-64",
+ "linuxarm64",
+ "osxuniversal"
+ ],
+ "simMode": "swsim"
+ },
+ {
+ "groupId": "com.ctre.phoenix6.sim",
+ "artifactId": "simVictorSPX",
+ "version": "26.50.0-alpha-1",
+ "isJar": false,
+ "skipInvalidPlatforms": true,
+ "validPlatforms": [
+ "windowsx86-64",
+ "linuxx86-64",
+ "linuxarm64",
+ "osxuniversal"
+ ],
+ "simMode": "swsim"
+ },
+ {
+ "groupId": "com.ctre.phoenix6.sim",
+ "artifactId": "simPigeonIMU",
+ "version": "26.50.0-alpha-1",
+ "isJar": false,
+ "skipInvalidPlatforms": true,
+ "validPlatforms": [
+ "windowsx86-64",
+ "linuxx86-64",
+ "linuxarm64",
+ "osxuniversal"
+ ],
+ "simMode": "swsim"
+ },
+ {
+ "groupId": "com.ctre.phoenix6.sim",
+ "artifactId": "simProTalonFX",
+ "version": "26.50.0-alpha-1",
+ "isJar": false,
+ "skipInvalidPlatforms": true,
+ "validPlatforms": [
+ "windowsx86-64",
+ "linuxx86-64",
+ "linuxarm64",
+ "osxuniversal"
+ ],
+ "simMode": "swsim"
+ },
+ {
+ "groupId": "com.ctre.phoenix6.sim",
+ "artifactId": "simProTalonFXS",
+ "version": "26.50.0-alpha-1",
+ "isJar": false,
+ "skipInvalidPlatforms": true,
+ "validPlatforms": [
+ "windowsx86-64",
+ "linuxx86-64",
+ "linuxarm64",
+ "osxuniversal"
+ ],
+ "simMode": "swsim"
+ },
+ {
+ "groupId": "com.ctre.phoenix6.sim",
+ "artifactId": "simProCANcoder",
+ "version": "26.50.0-alpha-1",
+ "isJar": false,
+ "skipInvalidPlatforms": true,
+ "validPlatforms": [
+ "windowsx86-64",
+ "linuxx86-64",
+ "linuxarm64",
+ "osxuniversal"
+ ],
+ "simMode": "swsim"
+ },
+ {
+ "groupId": "com.ctre.phoenix6.sim",
+ "artifactId": "simProPigeon2",
+ "version": "26.50.0-alpha-1",
+ "isJar": false,
+ "skipInvalidPlatforms": true,
+ "validPlatforms": [
+ "windowsx86-64",
+ "linuxx86-64",
+ "linuxarm64",
+ "osxuniversal"
+ ],
+ "simMode": "swsim"
+ },
+ {
+ "groupId": "com.ctre.phoenix6.sim",
+ "artifactId": "simProCANrange",
+ "version": "26.50.0-alpha-1",
+ "isJar": false,
+ "skipInvalidPlatforms": true,
+ "validPlatforms": [
+ "windowsx86-64",
+ "linuxx86-64",
+ "linuxarm64",
+ "osxuniversal"
+ ],
+ "simMode": "swsim"
+ },
+ {
+ "groupId": "com.ctre.phoenix6.sim",
+ "artifactId": "simProCANdi",
+ "version": "26.50.0-alpha-1",
+ "isJar": false,
+ "skipInvalidPlatforms": true,
+ "validPlatforms": [
+ "windowsx86-64",
+ "linuxx86-64",
+ "linuxarm64",
+ "osxuniversal"
+ ],
+ "simMode": "swsim"
+ },
+ {
+ "groupId": "com.ctre.phoenix6.sim",
+ "artifactId": "simProCANdle",
+ "version": "26.50.0-alpha-1",
+ "isJar": false,
+ "skipInvalidPlatforms": true,
+ "validPlatforms": [
+ "windowsx86-64",
+ "linuxx86-64",
+ "linuxarm64",
+ "osxuniversal"
+ ],
+ "simMode": "swsim"
+ }
+ ],
+ "cppDependencies": [
+ {
+ "groupId": "com.ctre.phoenix6",
+ "artifactId": "wpiapi-cpp",
+ "version": "26.50.0-alpha-1",
+ "libName": "CTRE_Phoenix6_WPI",
+ "headerClassifier": "headers",
+ "sharedLibrary": true,
+ "skipInvalidPlatforms": true,
+ "binaryPlatforms": [
+ "windowsx86-64",
+ "linuxx86-64",
+ "linuxarm64",
+ "linuxsystemcore"
+ ],
+ "simMode": "hwsim"
+ },
+ {
+ "groupId": "com.ctre.phoenix6",
+ "artifactId": "tools",
+ "version": "26.50.0-alpha-1",
+ "libName": "CTRE_PhoenixTools",
+ "headerClassifier": "headers",
+ "sharedLibrary": true,
+ "skipInvalidPlatforms": true,
+ "binaryPlatforms": [
+ "windowsx86-64",
+ "linuxx86-64",
+ "linuxarm64",
+ "linuxsystemcore"
+ ],
+ "simMode": "hwsim"
+ },
+ {
+ "groupId": "com.ctre.phoenix6.sim",
+ "artifactId": "wpiapi-cpp-sim",
+ "version": "26.50.0-alpha-1",
+ "libName": "CTRE_Phoenix6_WPISim",
+ "headerClassifier": "headers",
+ "sharedLibrary": true,
+ "skipInvalidPlatforms": true,
+ "binaryPlatforms": [
+ "windowsx86-64",
+ "linuxx86-64",
+ "linuxarm64",
+ "osxuniversal"
+ ],
+ "simMode": "swsim"
+ },
+ {
+ "groupId": "com.ctre.phoenix6.sim",
+ "artifactId": "tools-sim",
+ "version": "26.50.0-alpha-1",
+ "libName": "CTRE_PhoenixTools_Sim",
+ "headerClassifier": "headers",
+ "sharedLibrary": true,
+ "skipInvalidPlatforms": true,
+ "binaryPlatforms": [
+ "windowsx86-64",
+ "linuxx86-64",
+ "linuxarm64",
+ "osxuniversal"
+ ],
+ "simMode": "swsim"
+ },
+ {
+ "groupId": "com.ctre.phoenix6.sim",
+ "artifactId": "simTalonSRX",
+ "version": "26.50.0-alpha-1",
+ "libName": "CTRE_SimTalonSRX",
+ "headerClassifier": "headers",
+ "sharedLibrary": true,
+ "skipInvalidPlatforms": true,
+ "binaryPlatforms": [
+ "windowsx86-64",
+ "linuxx86-64",
+ "linuxarm64",
+ "osxuniversal"
+ ],
+ "simMode": "swsim"
+ },
+ {
+ "groupId": "com.ctre.phoenix6.sim",
+ "artifactId": "simVictorSPX",
+ "version": "26.50.0-alpha-1",
+ "libName": "CTRE_SimVictorSPX",
+ "headerClassifier": "headers",
+ "sharedLibrary": true,
+ "skipInvalidPlatforms": true,
+ "binaryPlatforms": [
+ "windowsx86-64",
+ "linuxx86-64",
+ "linuxarm64",
+ "osxuniversal"
+ ],
+ "simMode": "swsim"
+ },
+ {
+ "groupId": "com.ctre.phoenix6.sim",
+ "artifactId": "simPigeonIMU",
+ "version": "26.50.0-alpha-1",
+ "libName": "CTRE_SimPigeonIMU",
+ "headerClassifier": "headers",
+ "sharedLibrary": true,
+ "skipInvalidPlatforms": true,
+ "binaryPlatforms": [
+ "windowsx86-64",
+ "linuxx86-64",
+ "linuxarm64",
+ "osxuniversal"
+ ],
+ "simMode": "swsim"
+ },
+ {
+ "groupId": "com.ctre.phoenix6.sim",
+ "artifactId": "simProTalonFX",
+ "version": "26.50.0-alpha-1",
+ "libName": "CTRE_SimProTalonFX",
+ "headerClassifier": "headers",
+ "sharedLibrary": true,
+ "skipInvalidPlatforms": true,
+ "binaryPlatforms": [
+ "windowsx86-64",
+ "linuxx86-64",
+ "linuxarm64",
+ "osxuniversal"
+ ],
+ "simMode": "swsim"
+ },
+ {
+ "groupId": "com.ctre.phoenix6.sim",
+ "artifactId": "simProTalonFXS",
+ "version": "26.50.0-alpha-1",
+ "libName": "CTRE_SimProTalonFXS",
+ "headerClassifier": "headers",
+ "sharedLibrary": true,
+ "skipInvalidPlatforms": true,
+ "binaryPlatforms": [
+ "windowsx86-64",
+ "linuxx86-64",
+ "linuxarm64",
+ "osxuniversal"
+ ],
+ "simMode": "swsim"
+ },
+ {
+ "groupId": "com.ctre.phoenix6.sim",
+ "artifactId": "simProCANcoder",
+ "version": "26.50.0-alpha-1",
+ "libName": "CTRE_SimProCANcoder",
+ "headerClassifier": "headers",
+ "sharedLibrary": true,
+ "skipInvalidPlatforms": true,
+ "binaryPlatforms": [
+ "windowsx86-64",
+ "linuxx86-64",
+ "linuxarm64",
+ "osxuniversal"
+ ],
+ "simMode": "swsim"
+ },
+ {
+ "groupId": "com.ctre.phoenix6.sim",
+ "artifactId": "simProPigeon2",
+ "version": "26.50.0-alpha-1",
+ "libName": "CTRE_SimProPigeon2",
+ "headerClassifier": "headers",
+ "sharedLibrary": true,
+ "skipInvalidPlatforms": true,
+ "binaryPlatforms": [
+ "windowsx86-64",
+ "linuxx86-64",
+ "linuxarm64",
+ "osxuniversal"
+ ],
+ "simMode": "swsim"
+ },
+ {
+ "groupId": "com.ctre.phoenix6.sim",
+ "artifactId": "simProCANrange",
+ "version": "26.50.0-alpha-1",
+ "libName": "CTRE_SimProCANrange",
+ "headerClassifier": "headers",
+ "sharedLibrary": true,
+ "skipInvalidPlatforms": true,
+ "binaryPlatforms": [
+ "windowsx86-64",
+ "linuxx86-64",
+ "linuxarm64",
+ "osxuniversal"
+ ],
+ "simMode": "swsim"
+ },
+ {
+ "groupId": "com.ctre.phoenix6.sim",
+ "artifactId": "simProCANdi",
+ "version": "26.50.0-alpha-1",
+ "libName": "CTRE_SimProCANdi",
+ "headerClassifier": "headers",
+ "sharedLibrary": true,
+ "skipInvalidPlatforms": true,
+ "binaryPlatforms": [
+ "windowsx86-64",
+ "linuxx86-64",
+ "linuxarm64",
+ "osxuniversal"
+ ],
+ "simMode": "swsim"
+ },
+ {
+ "groupId": "com.ctre.phoenix6.sim",
+ "artifactId": "simProCANdle",
+ "version": "26.50.0-alpha-1",
+ "libName": "CTRE_SimProCANdle",
+ "headerClassifier": "headers",
+ "sharedLibrary": true,
+ "skipInvalidPlatforms": true,
+ "binaryPlatforms": [
+ "windowsx86-64",
+ "linuxx86-64",
+ "linuxarm64",
+ "osxuniversal"
+ ],
+ "simMode": "swsim"
+ }
+ ]
+}
diff --git a/examples/stage1/stage1b/snippets/vendordeps/REVLib.json b/examples/stage1/stage1b/snippets/vendordeps/REVLib.json
new file mode 100644
index 00000000..533eadc8
--- /dev/null
+++ b/examples/stage1/stage1b/snippets/vendordeps/REVLib.json
@@ -0,0 +1,124 @@
+{
+ "fileName": "REVLib.json",
+ "name": "REVLib",
+ "version": "2027.0.0-alpha-3",
+ "wpilibYear": "2027_alpha5",
+ "uuid": "3f48eb8c-50fe-43a6-9cb7-44c86353c4cb",
+ "mavenUrls": ["https://maven.revrobotics.com/"],
+ "jsonUrl": "https://software-metadata.revrobotics.com/REVLib-2027.json",
+ "javaDependencies": [
+ {
+ "groupId": "com.revrobotics.frc",
+ "artifactId": "REVLib-java",
+ "version": "2027.0.0-alpha-3"
+ }
+ ],
+ "jniDependencies": [
+ {
+ "groupId": "com.revrobotics.frc",
+ "artifactId": "REVLib-driver",
+ "version": "2027.0.0-alpha-3",
+ "skipInvalidPlatforms": true,
+ "isJar": false,
+ "validPlatforms": [
+ "windowsx86-64",
+ "linuxarm64",
+ "linuxx86-64",
+ "linuxsystemcore",
+ "osxuniversal"
+ ]
+ },
+ {
+ "groupId": "com.revrobotics.frc",
+ "artifactId": "RevLibBackendDriver",
+ "version": "2027.0.0-alpha-3",
+ "skipInvalidPlatforms": true,
+ "isJar": false,
+ "validPlatforms": [
+ "windowsx86-64",
+ "linuxarm64",
+ "linuxx86-64",
+ "linuxsystemcore",
+ "osxuniversal"
+ ]
+ },
+ {
+ "groupId": "com.revrobotics.frc",
+ "artifactId": "RevLibWpiBackendDriver",
+ "version": "2027.0.0-alpha-3",
+ "skipInvalidPlatforms": true,
+ "isJar": false,
+ "validPlatforms": [
+ "windowsx86-64",
+ "linuxarm64",
+ "linuxx86-64",
+ "linuxsystemcore",
+ "osxuniversal"
+ ]
+ }
+ ],
+ "cppDependencies": [
+ {
+ "groupId": "com.revrobotics.frc",
+ "artifactId": "REVLib-cpp",
+ "version": "2027.0.0-alpha-3",
+ "libName": "REVLib",
+ "headerClassifier": "headers",
+ "sharedLibrary": false,
+ "skipInvalidPlatforms": true,
+ "binaryPlatforms": [
+ "windowsx86-64",
+ "linuxarm64",
+ "linuxx86-64",
+ "linuxsystemcore",
+ "osxuniversal"
+ ]
+ },
+ {
+ "groupId": "com.revrobotics.frc",
+ "artifactId": "REVLib-driver",
+ "version": "2027.0.0-alpha-3",
+ "libName": "REVLibDriver",
+ "headerClassifier": "headers",
+ "sharedLibrary": false,
+ "skipInvalidPlatforms": true,
+ "binaryPlatforms": [
+ "windowsx86-64",
+ "linuxarm64",
+ "linuxx86-64",
+ "linuxsystemcore",
+ "osxuniversal"
+ ]
+ },
+ {
+ "groupId": "com.revrobotics.frc",
+ "artifactId": "RevLibBackendDriver",
+ "version": "2027.0.0-alpha-3",
+ "libName": "BackendDriver",
+ "sharedLibrary": true,
+ "skipInvalidPlatforms": true,
+ "binaryPlatforms": [
+ "windowsx86-64",
+ "linuxarm64",
+ "linuxx86-64",
+ "linuxsystemcore",
+ "osxuniversal"
+ ]
+ },
+ {
+ "groupId": "com.revrobotics.frc",
+ "artifactId": "RevLibWpiBackendDriver",
+ "version": "2027.0.0-alpha-3",
+ "libName": "REVLibWpi",
+ "sharedLibrary": true,
+ "skipInvalidPlatforms": true,
+ "binaryPlatforms": [
+ "windowsx86-64",
+ "linuxarm64",
+ "linuxx86-64",
+ "linuxsystemcore",
+ "osxuniversal"
+ ]
+ }
+ ]
+}
diff --git a/src/content/docs/contribution/styleguide.mdx b/src/content/docs/contribution/styleguide.mdx
index 4b7214fb..e30f3ecc 100644
--- a/src/content/docs/contribution/styleguide.mdx
+++ b/src/content/docs/contribution/styleguide.mdx
@@ -157,3 +157,64 @@ This pulls from `CommandBasedKitbotPt2.java`:
```
````
+
+#### Code Block Tabs
+
+Use Starlight's `Tabs` and `TabItem` components to show alternate versions of a code block, such as CTRE vs.
+REV variants of the same code.
+Import them from `@astrojs/starlight/components`, then wrap each variant's code fence in its own `TabItem`:
+
+{/* rli:ignore */}
+
+````mdx
+import { TabItem, Tabs } from '@astrojs/starlight/components';
+
+
+
+ ```java #ctreDrivetrainDef
+
+ ```
+
+
+ ```java #revDrivetrainDef
+
+ ```
+
+
+
+````
+
+If multiple `Tabs` on the same page (or across different pages) should stay in sync when the reader switches
+between CTRE and REV, give the `Tabs` component a `syncKey`.
+Rather than inlining a raw string, define a shared constant in `src/data/tabsSyncKeys.ts` and import it:
+
+{/* rli:ignore */}
+
+```ts
+/** The sync key for REV/CTRE choosers */
+export const REV_CTRE_CHOOSER_KEY = 'rev-ctre-chooser';
+```
+
+{/* rli:ignore */}
+
+````mdx
+import { REV_CTRE_CHOOSER_KEY } from '@data/tabsSyncKeys.ts';
+import { TabItem, Tabs } from '@astrojs/starlight/components';
+
+
+
+ ```
+
+ ```
+
+
+ ```
+
+ ```
+
+
+
+````
+
+This way, once a reader picks CTRE or REV in one set of tabs, every other synced `Tabs` block on the site
+defaults to the same choice, instead of having to reselect it on every page.
diff --git a/src/content/docs/learning-course/stage1/stage1b/command-based-kitbot-pt2.mdx b/src/content/docs/learning-course/stage1/stage1b/command-based-kitbot-pt2.mdx
index 00eb2a17..87a65cc0 100644
--- a/src/content/docs/learning-course/stage1/stage1b/command-based-kitbot-pt2.mdx
+++ b/src/content/docs/learning-course/stage1/stage1b/command-based-kitbot-pt2.mdx
@@ -8,6 +8,8 @@ codeRegionSources:
---
import Aside from '@components/Aside.astro';
+import { REV_CTRE_CHOOSER_KEY } from '@data/tabsSyncKeys.ts';
+import { TabItem, Tabs } from '@astrojs/starlight/components';
### What You'll Accomplish
@@ -24,9 +26,19 @@ Create a new file named `Drivetrain.java` in the `mechanisms` package.
Then,
copy-paste the following code into the file:
-```java #drivetrainDef
+
+
+ ```java #ctreDrivetrainDef
-```
+ ```
+
+
+ ```java #revDrivetrainDef
+
+ ```
+
+
+
Then implement the following:
@@ -161,3 +173,9 @@ It should rotate the robot 90 degrees from its starting position, at a throttle
Use the `Scheduler` to schedule a new `rotateInPlace` command, just like how
task 3 accomplishes this.
+
+# Solution
+
+The solutions to this stage can be found below:
+[CTRE](https://github.com/frcsoftware/Stage1B-Solution-CTRE)
+[REV](https://github.com/frcsoftware/Stage1B-Solution-REV)
diff --git a/src/content/docs/learning-course/stage1/stage1b/command-based-kitbot.mdx b/src/content/docs/learning-course/stage1/stage1b/command-based-kitbot.mdx
index 0c76b472..589f5fcc 100644
--- a/src/content/docs/learning-course/stage1/stage1b/command-based-kitbot.mdx
+++ b/src/content/docs/learning-course/stage1/stage1b/command-based-kitbot.mdx
@@ -8,6 +8,8 @@ codeRegionSources:
---
import Aside from '@components/Aside.astro';
+import { REV_CTRE_CHOOSER_KEY } from '@data/tabsSyncKeys.ts';
+import { TabItem, Tabs } from '@astrojs/starlight/components';
### What You'll Accomplish
@@ -28,11 +30,23 @@ Use git to clone stage 1 template code.
Because both stage 1A and stage 1B
use the same template, use the following terminal command to create a new project:
-{/* rli:ignore */}
+
+
+ {/* rli:ignore */}
-```
-git clone https://github.com/frcsoftware/Stage1-Template-CTRE stage1b-ctre
-```
+ ```
+ git clone https://github.com/frcsoftware/Stage1-Template-CTRE stage1b-ctre
+ ```
+
+
+ {/* rli:ignore */}
+
+ ```
+ git clone https://github.com/frcsoftware/Stage1-Template-REV stage1b-rev
+ ```
+
+
+
Then, navigate to the `Robot` class under `src/main/java/first/robot`.
For commands to function, you must call `Scheduler.getDefault().run()` in
@@ -53,7 +67,7 @@ will contain the code for our feeder and intake launcher mechanisms.
Then, create a new file in the `mechanisms` package named `Feeder.java`.
Define a class named `Feeder` that implements `Mechanism`, then add the following:
-1. A private `TalonFX` motor controller object, named `motor`, with an ID of 5.
+1. A private `TalonFX` or `SparkMax` motor controller object, named `motor`, with an ID of 5.
It is connected to a systemcore CANBus with ID 0.
2. A `feed()` command that sets the throttle of the motor to 0.75 forever.
3. An `intake()` command that sets the throttle of the motor to -1 forever.
@@ -72,13 +86,13 @@ The `feed()`, `intake()`, `outtake()` and `idle()` commands should be returned f
- Item 1, Hint 2
- You can create a `CANBus` object via `CANBus.systemcore(id)`.
+ Item 1, Hint 2 (CTRE only)
+ For CTRE devices, a `CANBus` object can be created via `CANBus.systemcore(id)`.
{/* prettier-ignore */}
Item 1, Hint 3
- Remember that `TalonFX` is a class, and that creating objects within another
+ Remember that `TalonFX` and `SparkMax` are classes, and that creating objects within another
class is done like so:
{/* rli:ignore */}
```java
@@ -112,7 +126,7 @@ to allow for simulation to work:
Create a file named `IntakeLauncher.java` in the `mechanisms` package.
Define a class named `IntakeLauncher` that implements `Mechanism`; then, add the following:
-1. A private `TalonFX` motor controller object, named `motor`, with an ID of 4.
+1. A private `TalonFX` or `SparkMax` motor controller object, named `motor`, with an ID of 4.
It is connected to a systemcore CANBus with ID 0.
2. A `shoot()` command that waits 2 seconds, then sets the throttle of the motor to 0.9 forever.
3. A `intake()` command that sets throttle to 0.8 forever.
diff --git a/src/data/tabsSyncKeys.ts b/src/data/tabsSyncKeys.ts
new file mode 100644
index 00000000..eedf4dee
--- /dev/null
+++ b/src/data/tabsSyncKeys.ts
@@ -0,0 +1,2 @@
+/** The sync key for REV/CTRE choosers */
+export const REV_CTRE_CHOOSER_KEY = 'rev-ctre-chooser';
diff --git a/tsconfig.json b/tsconfig.json
index bb515185..0670440a 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -4,7 +4,8 @@
"exclude": ["dist"],
"compilerOptions": {
"paths": {
- "@components/*": ["./src/components/*"]
+ "@components/*": ["./src/components/*"],
+ "@data/*": ["./src/data/*"]
},
"checkJs": true
}