[wpimath] Replace Trajectory API with new one#8172
[wpimath] Replace Trajectory API with new one#8172zachwaffle4 wants to merge 299 commits intowpilibsuite:2027from
Conversation
|
This PR modifies commands. Please open a corresponding PR in Python Commands and include a link to this PR. |
… new api Signed-off-by: Zach Harel <zach@zharel.me>
Signed-off-by: Zach Harel <zach@zharel.me>
# Conflicts: # wpilibjExamples/src/main/java/edu/wpi/first/wpilibj/examples/simpledifferentialdrivesimulation/Robot.java # wpimath/src/main/java/edu/wpi/first/math/controller/LTVDifferentialDriveController.java # wpimath/src/main/java/edu/wpi/first/math/controller/LTVUnicycleController.java # wpimath/src/main/java/edu/wpi/first/math/trajectory/DifferentialSample.java # wpimath/src/main/java/edu/wpi/first/math/trajectory/Trajectory.java # wpimath/src/main/java/edu/wpi/first/math/trajectory/TrajectoryGenerator.java # wpimath/src/main/java/edu/wpi/first/math/trajectory/TrajectoryParameterizer.java # wpimath/src/main/java/edu/wpi/first/math/trajectory/TrajectorySample.java # wpimath/src/test/java/edu/wpi/first/math/controller/LTVDifferentialDriveControllerTest.java # wpimath/src/test/java/edu/wpi/first/math/controller/LTVUnicycleControllerTest.java # wpimath/src/test/java/edu/wpi/first/math/estimator/DifferentialDrivePoseEstimator3dTest.java # wpimath/src/test/java/edu/wpi/first/math/estimator/DifferentialDrivePoseEstimatorTest.java # wpimath/src/test/java/edu/wpi/first/math/estimator/ExtendedKalmanFilterTest.java # wpimath/src/test/java/edu/wpi/first/math/estimator/KalmanFilterTest.java # wpimath/src/test/java/edu/wpi/first/math/estimator/MecanumDrivePoseEstimator3dTest.java # wpimath/src/test/java/edu/wpi/first/math/estimator/MecanumDrivePoseEstimatorTest.java # wpimath/src/test/java/edu/wpi/first/math/estimator/MerweUKFTest.java # wpimath/src/test/java/edu/wpi/first/math/estimator/S3UKFTest.java # wpimath/src/test/java/edu/wpi/first/math/estimator/SwerveDrivePoseEstimator3dTest.java # wpimath/src/test/java/edu/wpi/first/math/estimator/SwerveDrivePoseEstimatorTest.java # wpimath/src/test/java/edu/wpi/first/math/kinematics/MecanumDriveOdometry3dTest.java # wpimath/src/test/java/edu/wpi/first/math/kinematics/MecanumDriveOdometryTest.java # wpimath/src/test/java/edu/wpi/first/math/kinematics/SwerveDriveOdometry3dTest.java # wpimath/src/test/java/edu/wpi/first/math/kinematics/SwerveDriveOdometryTest.java # wpimath/src/test/java/edu/wpi/first/math/trajectory/CentripetalAccelerationConstraintTest.java # wpimath/src/test/java/edu/wpi/first/math/trajectory/DifferentialDriveKinematicsConstraintTest.java # wpimath/src/test/java/edu/wpi/first/math/trajectory/DifferentialDriveVoltageConstraintTest.java # wpimath/src/test/java/edu/wpi/first/math/trajectory/EllipticalRegionConstraintTest.java # wpimath/src/test/java/edu/wpi/first/math/trajectory/RectangularRegionConstraintTest.java # wpimath/src/test/java/edu/wpi/first/math/trajectory/TrajectoryConcatenateTest.java # wpimath/src/test/java/edu/wpi/first/math/trajectory/TrajectoryGeneratorTest.java # wpimath/src/test/java/edu/wpi/first/math/trajectory/TrajectoryTransformTest.java
Signed-off-by: Zach Harel <zach@zharel.me>
…rential drive kinematics, voltage, and region enforcement and their relevant tests Signed-off-by: Zach Harel <zach@zharel.me>
|
i am very sorry that the git history is kinda cursed because of how i fixed the tests/commands |
…sentation; implement interpolation methods and kinematics handling Signed-off-by: Zach Harel <zach@zharel.me>
…assisSpeeds classes Signed-off-by: Zach Harel <zach@zharel.me>
…jectory data handling Signed-off-by: Zach Harel <zach@zharel.me>
…ve fromSample method, and make transform abstract Signed-off-by: Zach Harel <zach@zharel.me>
…nt interpolation for SwerveModuleState Signed-off-by: Zach Harel <zach@zharel.me>
…r accelerations) and make both classes interpolatable Signed-off-by: Zach Harel <zach@zharel.me>
Signed-off-by: Zach Harel <zach@zharel.me>
Signed-off-by: Zach Harel <zach@zharel.me>
| new ChassisSpeeds( | ||
| vel.vx + accel.ax * dts, vel.vy + accel.ay * dts, vel.omega + accel.alpha * dts); | ||
|
|
||
| var newPose = pose.exp(new Twist2d(newVel.vx * dts, newVel.vy * dts, newVel.omega * dts)); |
There was a problem hiding this comment.
The x and y velocities are typically in the global frame, so the pose exponential won't give correct results.
There was a problem hiding this comment.
The vel and accel properties are (supposed to) be in the robot frame.
| public final Pose2d pose; | ||
|
|
||
| /** The robot velocity at this sample (in the robot's reference frame). */ | ||
| public final ChassisSpeeds vel; |
There was a problem hiding this comment.
| public final ChassisSpeeds vel; | |
| public final ChassisSpeeds velocity; |
There was a problem hiding this comment.
I think the abbreviations here are fine
There was a problem hiding this comment.
I disagree. We're not code golfing here. You can spare 5 more letters.
wpimath/src/main/java/edu/wpi/first/math/trajectory/TrajectorySample.java
Outdated
Show resolved
Hide resolved
wpimath/src/main/java/edu/wpi/first/math/trajectory/DifferentialSample.java
Outdated
Show resolved
Hide resolved
wpimath/src/main/java/edu/wpi/first/math/trajectory/DifferentialSample.java
Outdated
Show resolved
Hide resolved
wpimath/src/main/java/edu/wpi/first/math/trajectory/DifferentialSample.java
Outdated
Show resolved
Hide resolved
| double rightAccel = input.get(1); | ||
|
|
||
| double vx = (vl + vr) / 2.0; | ||
| double trackwidth = (vr - vl) / omega; |
There was a problem hiding this comment.
This is numerically ill-conditioned (divide-by-zero) if the robot isn't rotating. In this expression, trackwidth is undefined if omega = 0. If you substitute in trackwidth and simplify, alpha is undefined if vr - vl = 0.
The ill-conditioning can be avoided by getting the trackwidth directly from the trajectory generator, but I don't see a clean way to do that off the top of my head.
There was a problem hiding this comment.
I can set alpha to 0 if either (vr-vl) or omega = 0 but other than that I don't know how else to resolve this
There was a problem hiding this comment.
If vr - vl = 0, ω = 0, and ar - al ≠ 0, then the trackwidth will be NaN (0/0) while α should be nonzero. The indeterminate value for trackwidth can be resolved with L'Hôpital's rule, but that gives (ar - al)/α, which contains the value we're trying to compute.
There was a problem hiding this comment.
Seems like the best fix is to treat alpha as a model input, then have the trajectory generator provide that in the sample since the trajectory generator knows the trackwidth. Including the angular acceleration along with the wheel linear accelerations is analogous to including the angular velocity along with the wheel linear velocities.
I just fixed this in Choreo: SleipnirGroup/Choreo#1301.
wpimath/src/test/java/org/wpilib/math/controller/LTVDifferentialDriveControllerTest.java
Outdated
Show resolved
Hide resolved
Signed-off-by: Zach Harel <zach@zharel.me>
…for clarity Signed-off-by: Zach Harel <zach@zharel.me>
…djust dynamics methods Signed-off-by: Zach Harel <zach@zharel.me>
…use it already had the protobuf) and fix toString format Signed-off-by: Zach Harel <zach@zharel.me>
Signed-off-by: Zach Harel <zach@zharel.me>
Signed-off-by: Zach Harel <zach@zharel.me>
…celerations, and SwerveModuleAccelerations with relevant protobufs/structs Signed-off-by: Zach Harel <zach@zharel.me>
…anumDriveWheelAccelerations, and SwerveModuleAccelerations with relevant protobufs/structs Signed-off-by: Zach Harel <zach@zharel.me>
# Conflicts: # wpimath/robotpy_pybind_build_info.bzl # wpimath/src/main/python/semiwrap/DifferentialSample.yml # wpimath/src/main/python/semiwrap/DifferentialTrajectory.yml # wpimath/src/main/python/semiwrap/HolonomicTrajectory.yml # wpimath/src/main/python/semiwrap/SplineSample.yml # wpimath/src/main/python/semiwrap/SplineTrajectory.yml # wpimath/src/main/python/semiwrap/TrajectorySample.yml
…om TrajectorySample and add new attributes
…mples from Trajectory
# Conflicts: # wpimath/src/generated/main/java/org/wpilib/math/proto/Trajectory.java # wpimath/src/generated/main/native/cpp/wpimath/protobuf/trajectory.npb.cpp # wpimath/src/main/java/org/wpilib/math/trajectory/proto/TrajectoryProto.java # wpimath/src/main/java/org/wpilib/math/trajectory/proto/TrajectoryStateProto.java # wpimath/src/main/proto/trajectory.proto # wpimath/src/test/java/org/wpilib/math/controller/LTVDifferentialDriveControllerTest.java # wpimath/src/test/java/org/wpilib/math/trajectory/proto/TrajectoryProtoTest.java # wpimath/src/test/java/org/wpilib/math/trajectory/proto/TrajectoryStateProtoTest.java
| // Copyright (c) FIRST and other WPILib contributors. | ||
| // Open Source Software; you can modify and/or share it under the terms of | ||
| // the WPILib BSD license file in the root directory of this project. |
There was a problem hiding this comment.
There's a lot of duplicate copyright headers.
There was a problem hiding this comment.
yeah i think i broke something with the generated quickbuf files
| } | ||
|
|
||
| void FieldObject2d::SetTrajectory(const wpi::math::Trajectory& trajectory) { | ||
| template <typename SampleType> |
There was a problem hiding this comment.
Template function definitions need to be in the header instead.
There was a problem hiding this comment.
oops (for context this was originally not a template function and so i just. updated the function definition in here)
| // v = (v_r + v_l) / 2 (1) | ||
| // w = (v_r - v_l) / (2r) (2) | ||
| // k = w / v (3) | ||
| // | ||
| // v_l = v - wr | ||
| // v_l = v - (vk)r | ||
| // v_l = v(1 - kr) | ||
| // | ||
| // v_r = v + wr | ||
| // v_r = v + (vk)r | ||
| // v_r = v(1 + kr) |
There was a problem hiding this comment.
This derivation is no longer used and can be removed.
| public boolean equals(Object o) { | ||
| return o == this | ||
| || o instanceof ChassisAccelerations c && ax == c.ax && ay == c.ay && alpha == c.alpha; | ||
| || o instanceof ChassisAccelerations c |
There was a problem hiding this comment.
This seems unrelated to the PR and should be separate.
There was a problem hiding this comment.
This is required such that NaN accelerations compare equal so that the tests pass with the spline trajectory generators.
| * @param leftSpeed The left-wheel speed at this sample. | ||
| * @param rightSpeed The right-wheel speed at this sample. |
There was a problem hiding this comment.
| * @param leftSpeed The left-wheel speed at this sample. | |
| * @param rightSpeed The right-wheel speed at this sample. | |
| * @param leftSpeed The left wheel speed at this sample. | |
| * @param rightSpeed The right wheel speed at this sample. |
| * @param pose The robot pose at this sample (in the field reference frame). | ||
| * @param linearVelocity The linear velocity in m/s. | ||
| * @param linearAcceleration The linear acceleration in m/s². | ||
| * @param curvature The curvature of the path at this sample, in 1/m. |
There was a problem hiding this comment.
| * @param curvature The curvature of the path at this sample, in 1/m. | |
| * @param curvature The curvature of the path at this sample, in rad/m. |
| WPILIB_DLLEXPORT | ||
| void to_json(wpi::util::json& json, const Trajectory::State& state); | ||
| protected: | ||
| // Helper: make all samples relative to a Pose2d |
There was a problem hiding this comment.
Need proper docs here. Helper: is redundant.
| return out; | ||
| } | ||
|
|
||
| // Helper: concatenate with another list of samples, offsetting their |
There was a problem hiding this comment.
Need proper docs here. Helper: is redundant.
| wpi::util::Lerp(start.acceleration.ay, end.acceleration.ay, t), | ||
| wpi::util::Lerp(start.acceleration.alpha, end.acceleration.alpha, t)}; | ||
|
|
||
| // v_{k+1} = v_k + a_k * dt |
There was a problem hiding this comment.
| // v_{k+1} = v_k + a_k * dt | |
| // vₖ₊₁ = vₖ + aₖΔt |
| start.velocity.vy + start.acceleration.ay * interpT, | ||
| start.velocity.omega + start.acceleration.alpha * interpT}; | ||
|
|
||
| // x_{k+1} = x_k + v_k * dt + 0.5 a (dt)^2 |
There was a problem hiding this comment.
| // x_{k+1} = x_k + v_k * dt + 0.5 a (dt)^2 | |
| // xₖ₊₁ = xₖ + vₖΔt + ½aₖ(Δt)² |
The new API is based on this document.
Java
TrajectoryclassesC++
TrajectoryclassesNotes
This PR does not remove the old trajectory generators, even though they aren't really used. The
TrajectoryGeneratorclass was refactored to produceTrajectory<SplineSample>, whereSplineSamplereplaces the oldTrajectory.Stateclass. I did that because many tests rely on the oldTrajectoryclass (such as kinematics and Kalman filters), so they have all been updated to useTrajectory<SplineSampleinstead; in another PR I will moveSplineSampleand the oldTrajectoryGenerator/Config/etc classes into the test source set.