スキル一覧に戻る
ncssm-robotics

roadrunner

by ncssm-robotics

Marketplace for Claude Plugins for FTC

2🍴 3📅 2026年1月17日
GitHubで見るManusで実行

SKILL.md


name: roadrunner description: >- Helps build autonomous routines using the RoadRunner 1.0 path planning library. Use when creating trajectories, configuring motion profiles, setting up localization, tuning drive constants, building spline paths, combining actions for complex autonomous sequences, or converting coordinates between RoadRunner, Pedro Pathing, and FTC/Limelight coordinate systems. license: MIT compatibility: Claude Code, Codex CLI, VS Code Copilot, Cursor metadata: author: ncssm-robotics version: "1.0.0" category: library

RoadRunner Path Planning

RoadRunner is a motion planning library for FTC that provides trajectory following, feedforward control, and advanced path building. Version 1.0 introduced a new Actions-based API for composing autonomous routines.

Quick Start

Clone the pre-configured project:

git clone https://github.com/acmerobotics/road-runner-quickstart.git

Option 2: Add to Existing Project

Add to TeamCode/build.gradle:

repositories {
    maven {
        url = 'https://maven.brott.dev/'
    }
}

dependencies {
    implementation "com.acmerobotics.roadrunner:ftc:0.1.25"
    implementation "com.acmerobotics.roadrunner:core:1.0.1"
    implementation "com.acmerobotics.roadrunner:actions:1.0.1"
    implementation "com.acmerobotics.dashboard:dashboard:0.5.1"
}

Then copy the tuning OpModes from the quickstart's TeamCode/src/main/java/org/firstinspires/ftc/teamcode folder (including messages and tuning subdirectories).

Basic Autonomous

@Autonomous(name = "Basic Auto")
public class BasicAuto extends LinearOpMode {
    @Override
    public void runOpMode() {
        MecanumDrive drive = new MecanumDrive(hardwareMap, new Pose2d(0, 0, 0));

        Action trajectory = drive.actionBuilder(new Pose2d(0, 0, 0))
            .lineToX(48)
            .turn(Math.PI / 2)
            .lineToY(48)
            .build();

        waitForStart();

        Actions.runBlocking(trajectory);
    }
}

Key Concepts

TermDescription
ActionSmallest unit of robot behavior. Returns true while running, false when complete
TrajectoryA planned path with motion profile (velocity/acceleration constraints)
Pose2dRobot position and heading: new Pose2d(x, y, heading)
Vector2d2D position without heading: new Vector2d(x, y)
FeedforwardOpen-loop motor control using kS, kV, kA constants
inPerTickEncoder conversion factor: inches traveled per encoder tick
trackWidthTicksDistance between drive wheels in encoder ticks

Trajectory Builder Methods

Line Movements

// Move to specific X coordinate (maintains current Y)
.lineToX(48)

// Move to specific Y coordinate (maintains current X)
.lineToY(36)

// Move to specific position
.lineToXY(new Vector2d(48, 36))

Spline Paths

// Curved path to position with exit tangent
.splineTo(new Vector2d(48, 48), Math.PI / 2)

// Spline with constant heading (robot faces same direction)
.splineToConstantHeading(new Vector2d(48, 48), Math.PI / 2)

// Spline with linear heading interpolation
.splineToLinearHeading(new Pose2d(48, 48, Math.PI), Math.PI / 2)

// Spline with spline heading interpolation (smoothest)
.splineToSplineHeading(new Pose2d(48, 48, Math.PI), Math.PI / 2)

Turns

// Turn by angle (relative)
.turn(Math.PI / 2)        // 90 degrees counterclockwise
.turn(-Math.PI / 2)       // 90 degrees clockwise

// Turn to absolute heading
.turnTo(Math.PI)          // Face 180 degrees

Tangent Control

// Set the tangent direction for the next segment
.setTangent(Math.toRadians(45))
.splineTo(new Vector2d(48, 48), Math.PI / 2)

Common Patterns

Pattern 1: Sequential Actions

Action auto = new SequentialAction(
    drive.actionBuilder(startPose)
        .lineToX(24)
        .build(),
    arm.raise(),
    claw.open(),
    drive.actionBuilder(new Pose2d(24, 0, 0))
        .lineToX(0)
        .build()
);

Actions.runBlocking(auto);

Pattern 2: Parallel Actions

// Drive while raising arm simultaneously
Action auto = new ParallelAction(
    drive.actionBuilder(startPose)
        .splineTo(new Vector2d(48, 24), Math.PI / 4)
        .build(),
    arm.raise()  // Happens during drive
);

Actions.runBlocking(auto);

Pattern 3: Custom Action

public class GrabAction implements Action {
    private Claw claw;
    private boolean finished = false;

    public GrabAction(Claw claw) {
        this.claw = claw;
    }

    @Override
    public boolean run(@NonNull TelemetryPacket packet) {
        if (!finished) {
            claw.close();
            finished = true;
            return true;  // Still running (let servo move)
        }
        return false;  // Complete
    }
}

Pattern 4: Wait/Delay

Action auto = new SequentialAction(
    claw.close(),
    new SleepAction(0.5),  // Wait 500ms
    arm.raise()
);

Tuning Process

Important: Follow this order exactly. Each step depends on previous results.

StepOpModeWhat It Tunes
1Configure drive classMotor names, IMU orientation
2Motor direction testVerify motor spin directions
3ForwardPushTestinPerTick
4LateralPushTestlateralInPerTick (mecanum only)
5ForwardRampLoggerCollect feedforward data
6ManualFeedforwardTunerkS, kV, kA
7ManualFeedbackTunerPosition/velocity gains
8SplineTestValidate all tuning

Hardware Naming Convention

// Mecanum drive motors
"leftFront", "leftBack", "rightBack", "rightFront"

// IMU
"imu"

// Dead wheel encoders (if using)
"par"   // Parallel to drive direction
"perp"  // Perpendicular to drive direction

Anti-Patterns

  • Skipping tuning steps - Each step builds on previous results; skipping causes poor tracking
  • Long-running Action.run() - Keep under 100ms; use state machines for complex actions
  • Blocking in run() - Never use Thread.sleep() or while loops inside actions
  • Ignoring units - RoadRunner uses inches and radians; don't mix with cm or degrees
  • Reusing trajectories - Build fresh for each run; pose state changes
  • Hardcoding poses - Use constants or enums for reusability

Examples

Good: Complete Autonomous with Actions

@Autonomous(name = "Sample Auto")
public class SampleAuto extends LinearOpMode {
    @Override
    public void runOpMode() {
        MecanumDrive drive = new MecanumDrive(hardwareMap, new Pose2d(12, -62, Math.PI / 2));
        Arm arm = new Arm(hardwareMap);
        Claw claw = new Claw(hardwareMap);

        // Build the trajectory during init
        Action driveToBasket = drive.actionBuilder(new Pose2d(12, -62, Math.PI / 2))
            .splineTo(new Vector2d(48, -48), Math.PI / 4)
            .build();

        Action scoreSequence = new SequentialAction(
            new ParallelAction(
                driveToBasket,
                arm.raise()
            ),
            claw.open(),
            new SleepAction(0.3),
            arm.lower()
        );

        waitForStart();

        if (opModeIsActive()) {
            Actions.runBlocking(scoreSequence);
        }
    }
}

Bad: Blocking Code in Actions

// ❌ Don't do this - blocks the action loop
public class BadAction implements Action {
    @Override
    public boolean run(TelemetryPacket packet) {
        motor.setPower(1.0);
        Thread.sleep(1000);  // ❌ NEVER block!
        motor.setPower(0);
        return false;
    }
}

// ✓ Use state machine instead
public class GoodAction implements Action {
    private ElapsedTime timer = new ElapsedTime();
    private boolean started = false;

    @Override
    public boolean run(TelemetryPacket packet) {
        if (!started) {
            motor.setPower(1.0);
            timer.reset();
            started = true;
        }

        if (timer.seconds() >= 1.0) {
            motor.setPower(0);
            return false;  // Complete
        }
        return true;  // Still running
    }
}

Bad: Wrong Heading Control

// ❌ Robot spins wildly - tangent heading on sharp corners
.lineToX(48)
.lineToY(48)  // 90-degree corner causes heading discontinuity

// ✓ Use constant heading for sharp turns
.lineToXConstantHeading(48)
.lineToYConstantHeading(48)

// ✓ Or use splines for smooth curves
.splineTo(new Vector2d(48, 48), Math.PI / 2)

Migration from 0.5.x

RoadRunner 1.0 is not backwards compatible. Key changes:

0.5.x1.0
drive.followTrajectoryAsync()Actions.runBlocking(trajectory)
TrajectoryBuilderdrive.actionBuilder()
drive.update() loopActions handle internally
Separate trajectory/turnUnified action system

Remove all 0.5.x references before upgrading.

Coordinate Systems

RoadRunner uses center-origin coordinates (inches, radians):

  • Origin at field center (0, 0)
  • X range: -72" to +72"
  • Y range: -72" to +72"
  • Heading: 0 rad = facing right (+X), CCW positive

This differs from Pedro Pathing which uses corner-origin.

Converting Between Systems

# Convert RoadRunner to Pedro coordinates
python scripts/convert.py roadrunner-to-pedro 12 -62 1.57

# Convert from Limelight/FTC to RoadRunner
python scripts/convert.py ftc-to-roadrunner 0.3 -1.5 90

# Mirror red alliance pose for blue
python scripts/convert.py mirror-blue 12 -62 1.57

See COORDINATES.md for full documentation on coordinate systems and conversion code.

External Resources

スコア

総合スコア

60/100

リポジトリの品質指標に基づく評価

SKILL.md

SKILL.mdファイルが含まれている

+20
LICENSE

ライセンスが設定されている

+10
説明文

100文字以上の説明がある

0/10
人気

GitHub Stars 100以上

0/15
最近の活動

3ヶ月以内に更新がある

0/10
フォーク

10回以上フォークされている

0/5
Issue管理

オープンIssueが50未満

+5
言語

プログラミング言語が設定されている

+5
タグ

1つ以上のタグが設定されている

0/5

レビュー

💬

レビュー機能は近日公開予定です