-
Notifications
You must be signed in to change notification settings - Fork 146
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add a visual roadrunner path editor #134
base: master
Are you sure you want to change the base?
Conversation
I used the following opmode to run the path that is uploaded (it is in kotlin): package org.firstinspires.ftc.teamcode
import com.acmerobotics.dashboard.message.redux.UploadPath
import com.acmerobotics.dashboard.path.DashboardPath
import com.acmerobotics.dashboard.path.HeadingType
import com.acmerobotics.dashboard.path.PathSegment
import com.acmerobotics.dashboard.path.SegmentType
import com.acmerobotics.roadrunner.geometry.Pose2d
import com.acmerobotics.roadrunner.geometry.Vector2d
import com.qualcomm.robotcore.eventloop.opmode.Autonomous
import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode
import org.firstinspires.ftc.teamcode.drive.SampleMecanumDrive
import org.firstinspires.ftc.teamcode.trajectorysequence.TrajectorySequence
@DashboardPath
@Autonomous
class CustomPath : LinearOpMode() {
companion object {
@JvmField var dashboardPath = UploadPath(PathSegment(), arrayOf())
}
fun makeTrajectory(drive: SampleMecanumDrive): TrajectorySequence {
val builder = drive.trajectorySequenceBuilder(
Pose2d(dashboardPath.start.x, dashboardPath.start.y, dashboardPath.start.heading),
dashboardPath.start.tangent,
)
drive.poseEstimate = Pose2d(dashboardPath.start.x, dashboardPath.start.y, dashboardPath.start.heading)
for (s in dashboardPath.segments) when (s.type) {
SegmentType.WAIT -> builder.waitSeconds(s.time)
SegmentType.LINE -> when (s.headingType) {
HeadingType.TANGENT -> builder.lineTo(Vector2d(s.x, s.y))
HeadingType.CONSTANT -> builder.lineToConstantHeading(Vector2d(s.x, s.y))
HeadingType.LINEAR -> builder.lineToLinearHeading(Pose2d(s.x, s.y, s.heading))
HeadingType.SPLINE -> builder.lineToSplineHeading(Pose2d(s.x, s.y, s.heading))
else -> error("Unknown HeadingType ${s.headingType}")
}
SegmentType.SPLINE -> when (s.headingType) {
HeadingType.TANGENT -> builder.splineTo(Vector2d(s.x, s.y), s.tangent)
HeadingType.CONSTANT -> builder.splineToConstantHeading(Vector2d(s.x, s.y), s.tangent)
HeadingType.LINEAR -> builder.splineToLinearHeading(Pose2d(s.x, s.y, s.heading), s.tangent)
HeadingType.SPLINE -> builder.splineToSplineHeading(Pose2d(s.x, s.y, s.heading), s.tangent)
else -> error("Unknown HeadingType ${s.headingType}")
}
else -> error("Unknown SegmentType ${s.type}")
}
return builder.build()
}
override fun runOpMode() {
val drive = SampleMecanumDrive(hardwareMap)
val path = makeTrajectory(drive)
waitForStart()
if (isStopRequested) return
drive.followTrajectorySequence(path)
sleep(5000)
}
} |
Do you have a screen recording of this? My own PR idea was building out primitives for a generalizable events (mouse click, drag, etc) interaction + drawing api though. It would build on the current field drawing widget which gives dash canvas draw commands. But providing a more generalizable API would imo prove to be more flexible in the future. E.g. Just an idea though. I haven't made an RFC PR since it was just ideas floating around. |
Very cool! I got it working locally, and I'm impressed. I would normally worry about contaminating dash with "knowledge" of RR, though you've helpfully kept a RR dependency out of the patch. I don't want hermetic separation between RR and dash to obstruct a useful feature like this, and the API is general enough to work with RR 1.0.0 I think. My main desire is to leverage the config system to store all of the path state. I imagine the Path widget could scan the config tree for classes with a particular field and shunt updates through the existing config messages. This probably involves adding lists/arrays to the config model, which is a useful and orthogonal feature people have been asking about for some time (#7!). A general third-party component system (a la Noah's RFC) would be a great fit for this PR, but I'm not sure that yak is worth shaving yet with the current scope of the path editor. |
Some places it could be improved: