-
Notifications
You must be signed in to change notification settings - Fork 3
Swerve Bézier Trajectory Command for Vision #539
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
base: main
Are you sure you want to change the base?
Changes from all commits
f52122b
4d39762
8c81c2a
3455aed
c984e2d
de944f8
9fa81cc
27e47ba
f4c3b51
49b28cc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,98 @@ | ||
| package xbot.common.subsystems.drive; | ||
|
|
||
| import edu.wpi.first.math.geometry.Pose2d; | ||
| import edu.wpi.first.math.geometry.Rotation2d; | ||
| import edu.wpi.first.math.geometry.Translation2d; | ||
| import xbot.common.logging.RobotAssertionManager; | ||
| import xbot.common.properties.PropertyFactory; | ||
| import xbot.common.subsystems.drive.control_logic.HeadingModule; | ||
| import xbot.common.subsystems.pose.BasePoseSubsystem; | ||
| import xbot.common.trajectory.XbotSwervePoint; | ||
|
|
||
| import javax.inject.Inject; | ||
| import java.util.ArrayList; | ||
| import java.util.List; | ||
|
|
||
| /** | ||
| * A "not-so-simple" SwerveSimpleTrajectoryCommand that does a Bézier curve!~~ | ||
| * TO USE: call setBezierConfiguration and pass it the needed params | ||
| * If you are EXTENDING this because you need some logic to compute control points: | ||
| * Remember to call setBezierConfiguration and super.initialize() | ||
| */ | ||
| public class SwerveBezierTrajectoryCommand extends SwerveSimpleTrajectoryCommand { | ||
|
|
||
| List<Translation2d> controlPoints; | ||
| Pose2d endPoint; | ||
| int steps; | ||
|
|
||
| @Inject | ||
| public SwerveBezierTrajectoryCommand(BaseSwerveDriveSubsystem drive, BasePoseSubsystem pose, PropertyFactory pf, | ||
| HeadingModule.HeadingModuleFactory headingModuleFactory, RobotAssertionManager assertionManager) { | ||
| super(drive, pose, pf, headingModuleFactory, assertionManager); | ||
| } | ||
|
|
||
| @Override | ||
| public void initialize() { | ||
| setBezierCurve(controlPoints, endPoint, steps); | ||
| super.initialize(); | ||
| } | ||
|
|
||
| /** | ||
| * Set the configuration of the Bézier curve, we can't generate our curve immediately as our pose will change | ||
| * @param controlPoints of the Bézier curve | ||
| * @param endPoint of our command | ||
| * @param steps to split our Bézier curve into | ||
| */ | ||
| public void setBezierConfiguration(List<Translation2d> controlPoints, Pose2d endPoint, int steps) { | ||
| this.controlPoints = controlPoints; | ||
| this.steps = steps; | ||
| this.endPoint = endPoint; | ||
| } | ||
|
|
||
| /** | ||
| * Generates a Bézier curve for our command! | ||
| */ | ||
| private void setBezierCurve(List<Translation2d> controlPoints, Pose2d endPoint, int steps) { | ||
| List<XbotSwervePoint> bezierPoints = new ArrayList<>(); | ||
| List<Translation2d> allPoints = new ArrayList<>(); | ||
| allPoints.add(pose.getCurrentPose2d().getTranslation()); | ||
| allPoints.addAll(controlPoints); | ||
| allPoints.add(endPoint.getTranslation()); | ||
|
|
||
| Rotation2d startingRotation = pose.getCurrentPose2d().getRotation(); | ||
| for (int i = 1; i <= steps; i++) { | ||
| double lerpFraction = i / (double) steps; | ||
| XbotSwervePoint point = new XbotSwervePoint( | ||
| deCasteljauIterative(allPoints, lerpFraction), | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Highly recommend watching
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Both videos are worth watching in their entirety, but the first one has a section about deCasteljau early on |
||
| startingRotation.plus((endPoint.getRotation().minus(startingRotation)).times(lerpFraction)), | ||
| 10 | ||
| ); | ||
| bezierPoints.add(point); | ||
| } | ||
|
|
||
| logic.setKeyPoints(bezierPoints); | ||
| } | ||
|
|
||
| /** | ||
| * Generated by some A.I., this tells us where we SHOULD be at while taking in consideration control points | ||
| * Apparently, "Iterative" potentially (not too-sure). | ||
| * @param points include: start, control points, end | ||
| * @param lerpFraction is our completion percentage | ||
| * @return our position during lerpFraction (progress of operation completion) | ||
| */ | ||
| private Translation2d deCasteljauIterative(List<Translation2d> points, double lerpFraction) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ⭐ I wonder if these should be static to make testing easier? |
||
| int n = points.size(); | ||
| List<Translation2d> temp = new ArrayList<>(points); | ||
|
|
||
| // Compute the position using de Casteljau's algorithm (all we know is that it works) | ||
| for (int level = 1; level < n; level++) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You could do some profiling on the Rio, for example, using higher and higher order bezier curves and see how long this function takes to calculate. This would help us set an upper bound for how many points the Rio is willing to accept
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. agreed, level^2 gets scary fast! |
||
| for (int i = 0; i < n - level; i++) { | ||
| double x = (1 - lerpFraction) * temp.get(i).getX() + lerpFraction * temp.get(i + 1).getX(); | ||
| double y = (1 - lerpFraction) * temp.get(i).getY() + lerpFraction * temp.get(i + 1).getY(); | ||
| temp.set(i, new Translation2d(x, y)); | ||
| } | ||
| } | ||
|
|
||
| return temp.get(0); | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we know the n of the highest order bezier curve the vision coprocessor will be sending us?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't expect too-too much, probably 2-3 control points, no more than 5. I don't think we need a bajillion control points to traverse through an obstacle.