ftc-mcp 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,3 @@
1
+ export declare const ROADRUNNER_KNOWLEDGE: {
2
+ apiReference: string;
3
+ };
@@ -0,0 +1,481 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ROADRUNNER_KNOWLEDGE = void 0;
4
+ exports.ROADRUNNER_KNOWLEDGE = {
5
+ apiReference: `
6
+ # Road Runner 1.0 API Reference
7
+
8
+ Road Runner is a motion planning library for FTC robots that provides trajectory-based
9
+ autonomous movement with smooth, time-optimal paths. It uses a different paradigm from
10
+ Pedro Pathing — trajectories are pre-planned with velocity/acceleration constraints and
11
+ executed as time-parameterized curves.
12
+
13
+ ---
14
+
15
+ ## Actions System
16
+
17
+ Road Runner 1.0 uses an **Actions** system to compose robot behavior. Actions are the
18
+ fundamental unit of execution.
19
+
20
+ ### SequentialAction
21
+ Runs actions one after another, waiting for each to complete before starting the next:
22
+
23
+ \`\`\`java
24
+ import com.acmerobotics.roadrunner.SequentialAction;
25
+ import com.acmerobotics.roadrunner.Action;
26
+
27
+ Action sequence = new SequentialAction(
28
+ drive.actionBuilder(startPose)
29
+ .lineToX(48)
30
+ .build(),
31
+ liftAction,
32
+ clawOpenAction
33
+ );
34
+ \`\`\`
35
+
36
+ ### ParallelAction
37
+ Runs multiple actions simultaneously. Completes when ALL actions finish:
38
+
39
+ \`\`\`java
40
+ import com.acmerobotics.roadrunner.ParallelAction;
41
+
42
+ Action parallel = new ParallelAction(
43
+ drive.actionBuilder(startPose)
44
+ .lineToX(48)
45
+ .build(),
46
+ liftToHighAction
47
+ );
48
+ \`\`\`
49
+
50
+ ### SleepAction
51
+ Pauses execution for a specified duration (seconds):
52
+
53
+ \`\`\`java
54
+ import com.acmerobotics.roadrunner.SleepAction;
55
+
56
+ Action wait = new SleepAction(0.5); // wait 500ms
57
+ \`\`\`
58
+
59
+ ### Running Actions
60
+ Use \`Actions.runBlocking()\` in LinearOpMode or handle manually in iterative:
61
+
62
+ \`\`\`java
63
+ import com.acmerobotics.roadrunner.ftc.Actions;
64
+
65
+ // In LinearOpMode:
66
+ Actions.runBlocking(myAction);
67
+
68
+ // In iterative OpMode (manual update loop):
69
+ private List<Action> runningActions = new ArrayList<>();
70
+
71
+ // In loop():
72
+ TelemetryPacket packet = new TelemetryPacket();
73
+ List<Action> newActions = new ArrayList<>();
74
+ for (Action action : runningActions) {
75
+ action.preview(packet.fieldOverlay());
76
+ if (action.run(packet)) {
77
+ newActions.add(action);
78
+ }
79
+ }
80
+ runningActions = newActions;
81
+ FtcDashboard.getInstance().sendTelemetryPacket(packet);
82
+ \`\`\`
83
+
84
+ ---
85
+
86
+ ## TrajectoryActionBuilder
87
+
88
+ The \`TrajectoryActionBuilder\` is the primary way to construct trajectories.
89
+ Obtain one from your drive class via \`drive.actionBuilder(startPose)\`.
90
+
91
+ ### Movement Methods
92
+
93
+ #### lineToX(x)
94
+ Drive forward/backward to a specific X coordinate (maintains current heading):
95
+
96
+ \`\`\`java
97
+ drive.actionBuilder(new Pose2d(0, 0, 0))
98
+ .lineToX(48) // drive to x=48
99
+ .build();
100
+ \`\`\`
101
+
102
+ #### lineToY(y)
103
+ Drive to a specific Y coordinate (maintains current heading):
104
+
105
+ \`\`\`java
106
+ drive.actionBuilder(new Pose2d(0, 0, Math.toRadians(90)))
107
+ .lineToY(48) // drive to y=48
108
+ .build();
109
+ \`\`\`
110
+
111
+ #### strafeTo(position)
112
+ Strafe to a specific (x, y) position while maintaining current heading:
113
+
114
+ \`\`\`java
115
+ drive.actionBuilder(startPose)
116
+ .strafeTo(new Vector2d(48, 24))
117
+ .build();
118
+ \`\`\`
119
+
120
+ #### splineTo(position, tangent)
121
+ Follow a smooth spline curve to a position with a specified tangent angle:
122
+
123
+ \`\`\`java
124
+ drive.actionBuilder(startPose)
125
+ .splineTo(new Vector2d(48, 24), Math.toRadians(45))
126
+ .build();
127
+ \`\`\`
128
+
129
+ #### turn(angle)
130
+ Turn in place by a relative angle (radians):
131
+
132
+ \`\`\`java
133
+ drive.actionBuilder(startPose)
134
+ .turn(Math.toRadians(90)) // turn 90 degrees left
135
+ .turn(Math.toRadians(-45)) // turn 45 degrees right
136
+ .build();
137
+ \`\`\`
138
+
139
+ #### waitSeconds(seconds)
140
+ Pause the trajectory for a duration:
141
+
142
+ \`\`\`java
143
+ drive.actionBuilder(startPose)
144
+ .lineToX(48)
145
+ .waitSeconds(1.0) // pause 1 second
146
+ .lineToX(24)
147
+ .build();
148
+ \`\`\`
149
+
150
+ ### Chaining Methods
151
+ Methods can be chained to build complex paths:
152
+
153
+ \`\`\`java
154
+ Action trajectory = drive.actionBuilder(new Pose2d(0, 0, 0))
155
+ .lineToX(36)
156
+ .turn(Math.toRadians(90))
157
+ .lineToY(36)
158
+ .splineTo(new Vector2d(48, 48), Math.toRadians(0))
159
+ .strafeTo(new Vector2d(24, 24))
160
+ .waitSeconds(0.5)
161
+ .lineToX(0)
162
+ .build();
163
+ \`\`\`
164
+
165
+ ### afterTime / afterDisp (Markers)
166
+ Execute actions at specific times or distances along a trajectory:
167
+
168
+ \`\`\`java
169
+ Action trajectory = drive.actionBuilder(startPose)
170
+ .lineToX(48)
171
+ .afterTime(0.5, liftUpAction) // 0.5s after trajectory starts
172
+ .afterDisp(20, clawOpenAction) // after 20 inches of travel
173
+ .build();
174
+ \`\`\`
175
+
176
+ ---
177
+
178
+ ## MecanumDrive Class Setup
179
+
180
+ Road Runner provides a \`MecanumDrive\` class that must be configured for your robot.
181
+ The quickstart project includes this pre-built. Key setup steps:
182
+
183
+ ### Drive Configuration (in MecanumDrive.java)
184
+ \`\`\`java
185
+ public class MecanumDrive {
186
+ // Motor names must match your robot configuration
187
+ public static double WHEEL_RADIUS = 1.8898; // inches (96mm goBILDA mecanum)
188
+ public static double GEAR_RATIO = 1.0; // output/input
189
+ public static double TRACK_WIDTH = 14.0; // inches between left/right wheels
190
+
191
+ // Drive motor max RPM
192
+ public static double MAX_RPM = 435; // goBILDA 435 RPM motor
193
+
194
+ // These are PID coefficients for heading and translation
195
+ public static double HEADING_KP = 8;
196
+ public static double HEADING_KD = 1;
197
+ public static double LATERAL_KP = 6;
198
+ public static double LATERAL_KD = 1;
199
+ public static double AXIAL_KP = 6;
200
+ public static double AXIAL_KD = 1;
201
+
202
+ private DcMotorEx leftFront, leftBack, rightFront, rightBack;
203
+
204
+ public MecanumDrive(HardwareMap hardwareMap, Pose2d startPose) {
205
+ leftFront = hardwareMap.get(DcMotorEx.class, "leftFront");
206
+ leftBack = hardwareMap.get(DcMotorEx.class, "leftBack");
207
+ rightFront = hardwareMap.get(DcMotorEx.class, "rightFront");
208
+ rightBack = hardwareMap.get(DcMotorEx.class, "rightBack");
209
+
210
+ // Reverse motors on one side
211
+ leftFront.setDirection(DcMotorSimple.Direction.REVERSE);
212
+ leftBack.setDirection(DcMotorSimple.Direction.REVERSE);
213
+ }
214
+ }
215
+ \`\`\`
216
+
217
+ ### Using MecanumDrive in an OpMode
218
+ \`\`\`java
219
+ MecanumDrive drive = new MecanumDrive(hardwareMap, new Pose2d(0, 0, 0));
220
+
221
+ Action traj = drive.actionBuilder(drive.pose)
222
+ .lineToX(48)
223
+ .build();
224
+
225
+ Actions.runBlocking(traj);
226
+ \`\`\`
227
+
228
+ ---
229
+
230
+ ## Coordinate System
231
+
232
+ Road Runner uses a **field-centered coordinate system** that differs from Pedro Pathing:
233
+
234
+ - **Origin**: Center of the field (0, 0)
235
+ - **X axis**: Positive X points toward the red alliance wall (→)
236
+ - **Y axis**: Positive Y points toward the audience/blue side (↑)
237
+ - **Angles**: 0 radians faces positive X (+→), counter-clockwise is positive
238
+ - **Units**: Inches for distance, radians for angles
239
+
240
+ ### Key Differences from Pedro Pathing:
241
+ | Feature | Road Runner | Pedro Pathing |
242
+ |--------------------|--------------------------|-------------------------|
243
+ | Origin | Field center (0,0) | Configurable start pose |
244
+ | Coordinate style | Standard math (CCW +) | Standard math (CCW +) |
245
+ | Angle unit | Radians | Radians |
246
+ | Position class | Pose2d, Vector2d | Pose, Point |
247
+ | Path definition | Trajectory (time-based) | Path (follower-based) |
248
+
249
+ ### Pose2d and Vector2d
250
+ \`\`\`java
251
+ import com.acmerobotics.roadrunner.Pose2d;
252
+ import com.acmerobotics.roadrunner.Vector2d;
253
+
254
+ Pose2d startPose = new Pose2d(0, 0, Math.toRadians(0)); // x, y, heading
255
+ Vector2d targetPos = new Vector2d(48, 24); // x, y only
256
+ \`\`\`
257
+
258
+ ---
259
+
260
+ ## MeepMeep Visualizer
261
+
262
+ MeepMeep is a desktop trajectory visualizer for Road Runner. It lets you preview
263
+ paths before deploying to the robot.
264
+
265
+ ### Setup (separate module in Android Studio)
266
+ Add MeepMeep as a Java module in your FTC project:
267
+
268
+ \`\`\`java
269
+ // MeepMeepTesting.java - runs on your desktop, NOT on the robot
270
+ import com.acmerobotics.roadrunner.Pose2d;
271
+ import com.acmerobotics.roadrunner.Vector2d;
272
+ import com.noahbres.meepmeep.MeepMeep;
273
+ import com.noahbres.meepmeep.roadrunner.DefaultBotBuilder;
274
+ import com.noahbres.meepmeep.roadrunner.entity.RoadRunnerBotEntity;
275
+
276
+ public class MeepMeepTesting {
277
+ public static void main(String[] args) {
278
+ MeepMeep meepMeep = new MeepMeep(800); // window size in pixels
279
+
280
+ RoadRunnerBotEntity myBot = new DefaultBotBuilder(meepMeep)
281
+ .setConstraints(60, 60, Math.toRadians(180), Math.toRadians(180), 15)
282
+ // maxVel, maxAccel, maxAngVel, maxAngAccel, trackWidth
283
+ .build();
284
+
285
+ myBot.runAction(myBot.getDrive().actionBuilder(new Pose2d(0, 0, 0))
286
+ .lineToX(48)
287
+ .turn(Math.toRadians(90))
288
+ .lineToY(48)
289
+ .splineTo(new Vector2d(0, 0), Math.toRadians(180))
290
+ .build());
291
+
292
+ meepMeep.setBackground(MeepMeep.Background.FIELD_INTO_THE_DEEP_JUICE_DARK)
293
+ .setDarkMode(true)
294
+ .setBackgroundAlpha(0.95f)
295
+ .addEntity(myBot)
296
+ .start();
297
+ }
298
+ }
299
+ \`\`\`
300
+
301
+ ### Tips
302
+ - Test all trajectories in MeepMeep before deploying to the robot
303
+ - You can add multiple bots to simulate alliance partners
304
+ - Constraints in MeepMeep should match your robot's tuned constraints
305
+ - MeepMeep uses the same trajectory builder API as the real robot code
306
+
307
+ ---
308
+
309
+ ## Tuning Process Overview
310
+
311
+ Road Runner requires careful tuning for accurate path following. The quickstart
312
+ project includes tuning OpModes:
313
+
314
+ ### Step-by-Step Tuning Order
315
+
316
+ 1. **Dead Wheel / Odometry Calibration**
317
+ - Measure wheel positions and radii precisely
318
+ - Run \`ForwardPushTest\` — push robot forward, verify encoder ticks
319
+ - Run \`LateralPushTest\` — push robot sideways, verify lateral encoder
320
+
321
+ 2. **Drive Characterization (FeedForward)**
322
+ - Run \`ForwardRampLogger\` — logs voltage vs. velocity
323
+ - Run \`LateralRampLogger\` — same for strafing
324
+ - Run \`AngularRampLogger\` — logs voltage vs. angular velocity
325
+ - Use the Road Runner tuning web app to compute kS, kV, kA from logs
326
+
327
+ 3. **Localization Test**
328
+ - Run \`LocalizationTest\` — drive robot around manually
329
+ - Verify the pose estimate on FTC Dashboard matches real-world position
330
+ - Fix any encoder direction or sign issues
331
+
332
+ 4. **PID / Feedback Tuning**
333
+ - Run \`ManualFeedforwardTuner\` — fine-tune feedforward gains
334
+ - Run trajectory tests and adjust heading/translation PID gains
335
+ - Iterate until trajectories are accurate
336
+
337
+ 5. **Full Trajectory Testing**
338
+ - Run a test trajectory (e.g., a square) and measure error
339
+ - Adjust gains and constraints as needed
340
+
341
+ ### Tuning Tips
342
+ - Measure physical dimensions carefully (wheel radius, track width)
343
+ - Ensure motor directions are correct before tuning
344
+ - Use FTC Dashboard for real-time graph visualization during tuning
345
+ - Tune on the actual competition surface if possible
346
+
347
+ ---
348
+
349
+ ## Complete Working Autonomous Example
350
+
351
+ \`\`\`java
352
+ package org.firstinspires.ftc.teamcode;
353
+
354
+ import com.acmerobotics.roadrunner.Action;
355
+ import com.acmerobotics.roadrunner.ParallelAction;
356
+ import com.acmerobotics.roadrunner.Pose2d;
357
+ import com.acmerobotics.roadrunner.SequentialAction;
358
+ import com.acmerobotics.roadrunner.SleepAction;
359
+ import com.acmerobotics.roadrunner.Vector2d;
360
+ import com.acmerobotics.roadrunner.ftc.Actions;
361
+ import com.qualcomm.robotcore.eventloop.opmode.Autonomous;
362
+ import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
363
+ import com.qualcomm.robotcore.hardware.DcMotorEx;
364
+ import com.qualcomm.robotcore.hardware.Servo;
365
+
366
+ @Autonomous(name = "RR Auto - Scoring", group = "Auto")
367
+ public class RoadRunnerAutoExample extends LinearOpMode {
368
+
369
+ // Simple lift action — demonstrates custom Action implementation
370
+ public class LiftToPosition implements Action {
371
+ private final DcMotorEx liftMotor;
372
+ private final int targetPosition;
373
+ private boolean initialized = false;
374
+
375
+ public LiftToPosition(DcMotorEx motor, int target) {
376
+ this.liftMotor = motor;
377
+ this.targetPosition = target;
378
+ }
379
+
380
+ @Override
381
+ public boolean run(com.acmerobotics.dashboard.telemetry.TelemetryPacket packet) {
382
+ if (!initialized) {
383
+ liftMotor.setTargetPosition(targetPosition);
384
+ liftMotor.setMode(DcMotorEx.RunMode.RUN_TO_POSITION);
385
+ liftMotor.setPower(1.0);
386
+ initialized = true;
387
+ }
388
+
389
+ double currentPos = liftMotor.getCurrentPosition();
390
+ packet.put("liftTarget", targetPosition);
391
+ packet.put("liftPosition", currentPos);
392
+
393
+ return Math.abs(currentPos - targetPosition) > 10;
394
+ // return true = still running, false = done
395
+ }
396
+ }
397
+
398
+ @Override
399
+ public void runOpMode() throws InterruptedException {
400
+ // Initialize drive at starting position
401
+ Pose2d startPose = new Pose2d(-36, -60, Math.toRadians(90));
402
+ MecanumDrive drive = new MecanumDrive(hardwareMap, startPose);
403
+
404
+ // Initialize mechanisms
405
+ DcMotorEx liftMotor = hardwareMap.get(DcMotorEx.class, "liftMotor");
406
+ liftMotor.setZeroPowerBehavior(DcMotorEx.ZeroPowerBehavior.BRAKE);
407
+ liftMotor.setMode(DcMotorEx.RunMode.STOP_AND_RESET_ENCODER);
408
+
409
+ Servo claw = hardwareMap.get(Servo.class, "claw");
410
+ claw.setPosition(0.0); // closed
411
+
412
+ // Pre-build all trajectories during init
413
+ Action driveToScoring = drive.actionBuilder(startPose)
414
+ .splineTo(new Vector2d(-4, -36), Math.toRadians(90))
415
+ .build();
416
+
417
+ Action driveToPickup = drive.actionBuilder(new Pose2d(-4, -36, Math.toRadians(90)))
418
+ .strafeTo(new Vector2d(-48, -36))
419
+ .lineToY(-12)
420
+ .build();
421
+
422
+ Action driveToScoring2 = drive.actionBuilder(new Pose2d(-48, -12, Math.toRadians(90)))
423
+ .splineTo(new Vector2d(-4, -36), Math.toRadians(90))
424
+ .build();
425
+
426
+ Action driveToPark = drive.actionBuilder(new Pose2d(-4, -36, Math.toRadians(90)))
427
+ .strafeTo(new Vector2d(-48, -60))
428
+ .build();
429
+
430
+ // Build the full autonomous sequence
431
+ Action fullAuto = new SequentialAction(
432
+ // Score preloaded specimen
433
+ new ParallelAction(
434
+ driveToScoring,
435
+ new LiftToPosition(liftMotor, 2000)
436
+ ),
437
+ new SleepAction(0.3),
438
+ new com.acmerobotics.roadrunner.InstantAction(() -> claw.setPosition(1.0)),
439
+ new SleepAction(0.3),
440
+
441
+ // Drive to pickup
442
+ new ParallelAction(
443
+ driveToPickup,
444
+ new LiftToPosition(liftMotor, 0)
445
+ ),
446
+ new com.acmerobotics.roadrunner.InstantAction(() -> claw.setPosition(0.0)),
447
+ new SleepAction(0.3),
448
+
449
+ // Score second piece
450
+ new ParallelAction(
451
+ driveToScoring2,
452
+ new LiftToPosition(liftMotor, 2000)
453
+ ),
454
+ new SleepAction(0.3),
455
+ new com.acmerobotics.roadrunner.InstantAction(() -> claw.setPosition(1.0)),
456
+ new SleepAction(0.3),
457
+
458
+ // Park
459
+ new ParallelAction(
460
+ driveToPark,
461
+ new LiftToPosition(liftMotor, 0)
462
+ )
463
+ );
464
+
465
+ telemetry.addLine("Road Runner Auto Ready");
466
+ telemetry.update();
467
+
468
+ waitForStart();
469
+
470
+ if (isStopRequested()) return;
471
+
472
+ // Execute the entire autonomous routine
473
+ Actions.runBlocking(fullAuto);
474
+
475
+ telemetry.addLine("Autonomous Complete");
476
+ telemetry.update();
477
+ }
478
+ }
479
+ \`\`\`
480
+ `,
481
+ };
@@ -0,0 +1,12 @@
1
+ export declare const VISION_KNOWLEDGE: {
2
+ overview: string;
3
+ visionPortalSetup: string;
4
+ aprilTagDetection: string;
5
+ cameraControls: string;
6
+ limelight: string;
7
+ megaTag: string;
8
+ colorDetection: string;
9
+ visionOptimization: string;
10
+ multiCamera: string;
11
+ visionPatterns: string;
12
+ };