From 730ed9222bf196da2b845f9a8aa32d7f39dbb42c Mon Sep 17 00:00:00 2001 From: Zach Harel Date: Tue, 2 Sep 2025 17:10:22 -0400 Subject: [PATCH 1/5] add: support for roadrunner MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * setup gradle for roadrunner extension * refactor: update unit test to use JUnit 5 assertions * add: implement FollowTrajectoryCommand and FollowTurnCommand classes * define RoadRunner version in gradle.properties and use it in roadrunn… * refactor: rename FollowTrajectoryCommand and FollowTurnCommand classe… * add: initialize Turn class with name based on angle --- .gitignore | 2 + .idea/gradle.xml | 1 + build.gradle.kts | 2 +- gradle.properties | 7 +- gradle/libs.versions.toml | 7 +- .../dev/nextftc/extensions/ExampleUnitTest.kt | 4 +- roadrunner/build.gradle.kts | 42 ++ .../extensions/roadrunner/FollowTrajectory.kt | 47 ++ .../roadrunner/NextFTCMecanumDrive.kt | 27 + .../roadrunner/TrajectoryCommandBuilder.kt | 670 ++++++++++++++++++ .../roadrunner/TrajectoryCommandUtilities.kt | 44 ++ .../dev/nextftc/extensions/roadrunner/Turn.kt | 39 + settings.gradle.kts | 3 +- 13 files changed, 888 insertions(+), 7 deletions(-) create mode 100644 roadrunner/build.gradle.kts create mode 100644 roadrunner/src/main/kotlin/dev/nextftc/extensions/roadrunner/FollowTrajectory.kt create mode 100644 roadrunner/src/main/kotlin/dev/nextftc/extensions/roadrunner/NextFTCMecanumDrive.kt create mode 100644 roadrunner/src/main/kotlin/dev/nextftc/extensions/roadrunner/TrajectoryCommandBuilder.kt create mode 100644 roadrunner/src/main/kotlin/dev/nextftc/extensions/roadrunner/TrajectoryCommandUtilities.kt create mode 100644 roadrunner/src/main/kotlin/dev/nextftc/extensions/roadrunner/Turn.kt diff --git a/.gitignore b/.gitignore index aa724b7..08e7f17 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,5 @@ .externalNativeBuild .cxx local.properties + +/**/build \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml index f9fd68f..91f47a9 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -10,6 +10,7 @@ diff --git a/build.gradle.kts b/build.gradle.kts index f12339c..53eee50 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -13,7 +13,7 @@ plugins { allprojects { version = property("version") as String - group = "dev.nextftc" + group = "dev.nextftc.extensions" } subprojects { diff --git a/gradle.properties b/gradle.properties index f2c995c..680fbaa 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,5 +2,8 @@ kotlin.code.style=official org.jetbrains.dokka.experimental.gradle.pluginMode=V2Enabled org.jetbrains.dokka.experimental.gradle.pluginMode.noWarn=true -version=1.0.0 -automaticMavenCentralSync=true \ No newline at end of file +automaticMavenCentralSync=true + +android.useAndroidX=true + +versions.roadrunner=0.1.25-1-local.3 \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index d123e5e..07ba9dd 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,10 +1,12 @@ [versions] kotlin = "2.0.0" android = "8.7.3" -nextftc = "1.0.0-SNAPSHOT" +nextftc = "1.0.0-beta.2" kotest = "5.9.1" ftc = "10.3.0" pedro = "2.0.0" +rr-core = "1.0.1" +rr-ftc = "0.1.25" [libraries] kotest-runner = { module = "io.kotest:kotest-runner-junit5", version.ref = "kotest" } @@ -18,11 +20,14 @@ ftc-common = { group = "org.firstinspires.ftc", name = "FtcCommon", version.ref nextftc-ftc = { group = "dev.nextftc", name = "ftc", version.ref = "nextftc" } nextftc-hardware = { group = "dev.nextftc", name = "hardware", version.ref = "nextftc" } pedro = { module = "com.pedropathing:ftc", version.ref = "pedro" } +rr-core = { module = "com.acmerobotics.roadrunner:core", version.ref = "rr-core" } +rr-ftc = { module = "com.acmerobotics.roadrunner:ftc", version.ref = "rr-ftc" } [bundles] kotest = ["kotest-runner", "kotest-assertations", "kotest-property"] ftc = ["ftc-robot-core", "ftc-hardware", "ftc-common"] nextftc = ["nextftc-ftc", "nextftc-hardware"] +roadrunner = ["rr-core", "rr-ftc"] [plugins] kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } diff --git a/pedro/src/test/java/dev/nextftc/extensions/ExampleUnitTest.kt b/pedro/src/test/java/dev/nextftc/extensions/ExampleUnitTest.kt index 2abe954..cc42af8 100644 --- a/pedro/src/test/java/dev/nextftc/extensions/ExampleUnitTest.kt +++ b/pedro/src/test/java/dev/nextftc/extensions/ExampleUnitTest.kt @@ -1,8 +1,8 @@ package dev.nextftc.extensions -import org.junit.Test -import org.junit.Assert.* +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Test /** * Example local unit test, which will execute on the development machine (host). diff --git a/roadrunner/build.gradle.kts b/roadrunner/build.gradle.kts new file mode 100644 index 0000000..5043733 --- /dev/null +++ b/roadrunner/build.gradle.kts @@ -0,0 +1,42 @@ +plugins { + kotlin("android") + id("com.android.library") +} + +android { + namespace = "dev.nextftc.extensions.roadrunner" + compileSdk = 35 + + defaultConfig { + minSdk = 24 + } + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 + } + + kotlinOptions { + jvmTarget = "1.8" + freeCompilerArgs += "-Xjvm-default=all" + } + + publishing { + singleVariant("release") + } +} + +dependencies { + implementation(libs.bundles.nextftc) + implementation(libs.bundles.roadrunner) + implementation(libs.bundles.ftc) +} + +description = + "Support for using RoadRunner with NextFTC." + +nextFTCPublishing { + displayName = "NextFTC Extensions - RoadRunner" + logoPath = "../assets/logo-icon.svg" + version = property("versions.roadrunner") as String +} \ No newline at end of file diff --git a/roadrunner/src/main/kotlin/dev/nextftc/extensions/roadrunner/FollowTrajectory.kt b/roadrunner/src/main/kotlin/dev/nextftc/extensions/roadrunner/FollowTrajectory.kt new file mode 100644 index 0000000..6214e30 --- /dev/null +++ b/roadrunner/src/main/kotlin/dev/nextftc/extensions/roadrunner/FollowTrajectory.kt @@ -0,0 +1,47 @@ +package dev.nextftc.extensions.roadrunner + +import com.acmerobotics.roadrunner.Pose2dDual +import com.acmerobotics.roadrunner.PoseVelocity2d +import com.acmerobotics.roadrunner.Time +import com.acmerobotics.roadrunner.TimeTrajectory +import com.acmerobotics.roadrunner.Trajectory +import com.acmerobotics.roadrunner.Vector2d +import com.qualcomm.robotcore.util.ElapsedTime +import dev.nextftc.core.commands.Command + +/** + * Follows a trajectory parametrized by time. + * + * Note that the output of [TrajectoryCommandBuilder.build] only returns a [Command] + * object and not a [FollowTrajectory] object, + * because the builder sequences the trajectory with other actions, + * such as [Turn]s, [dev.nextftc.core.commands.delays.Delay]s or user-specified callbacks. + */ +class FollowTrajectory(private val mecanumDrive: NextFTCMecanumDrive, private val trajectory: TimeTrajectory) : Command() { + constructor(mecanumDrive: NextFTCMecanumDrive, trajectory: Trajectory) : + this(mecanumDrive, TimeTrajectory(trajectory)) + + val timer = ElapsedTime() + + override val isDone: Boolean + get() = timer.seconds() >= trajectory.duration + + override fun start() { + timer.reset() + } + + override fun update() { + val txWorldTarget: Pose2dDual