Conversation
batchen1
left a comment
There was a problem hiding this comment.
overall the math looks fine, but the devil is in the details. I'm not sure how to test this. Of course if you deploy and get perfect shots we declare victory, but what if not? do you have a plan how to diagnose any problems?
|
|
||
| public static final Pose2d BLUE_HUB_POS = new Pose2d(4.6256, 4.0345, new Rotation2d()); | ||
| public static final Pose2d RED_HUB_POS = new Pose2d(11.9154, 4.0345, new Rotation2d()); | ||
| public static final Transform2d TURRET_OFFSET = new Transform2d(.4, .4, new Rotation2d()); |
There was a problem hiding this comment.
these values were just placeholders, if you removed the comment, please measure and plug in the correct valued.
| Twist2d momentumAdjustment = getMomentumAdjustment(robotPose,profile.targetPose, robotSpeeds, | ||
| equalizeFlightTime(calculateDistanceMeters(robotPose, profile.targetPose), robotPose, profile.targetPose, robotSpeeds)); | ||
| PoseControlProfile adjustedProfile = new PoseControlProfile(profile.targetPose, profile.defaultAnglerAngleDegrees, profile.defaultShooterVelocityRpm, profile.defaultTurretAngleDegrees); | ||
| adjustedProfile.targetPose = profile.targetPose.exp(momentumAdjustment); |
There was a problem hiding this comment.
you should change all the calls to use your adjustedProfile instead of profile.
| return 0.0633*computedDistanceMeters + 0.647; | ||
| } | ||
|
|
||
| private double equalizeFlightTime(double initialDistanceMeters, Pose2d robotPose, Pose2d target, ChassisSpeeds robotSpeeds) { |
There was a problem hiding this comment.
how was this formula derived? you need to document it.
There was a problem hiding this comment.
1 - I'm not convinced that the flight-time should depend on the speed of the robot at all. I think it is ok to calculate the flight time based only on the distance from the hub. I doubt that considering the speed our robot will be moving this will make a big difference. There are many things that affect the trajectory that we are not considering (physics related such as friction, drag, texture/compression of the fuel will be changing etc.) and this flight-time based only on distance is one that I'm willing to compromise. It will simplify testing by a lot.
2 - regardless - I'm not even sure this code is correct. What you want is the robot's velocity projected on the robot-to-hub directions. Is this what this expression is using? have you tried it with a few cases?
| } | ||
|
|
||
| public Twist2d getMomentumAdjustment(Pose2d robotPose, Pose2d target, ChassisSpeeds robotSpeeds, double timeOfFlight) { | ||
| Translation2d angularVelocityAdjustment = Constants.TURRET_OFFSET.times(robotSpeeds.omegaRadiansPerSecond).getTranslation(); |
There was a problem hiding this comment.
I think the angular velocity due to the offset from the middle of the robot complicates the code and not sure it will affect the shot that much, it may be easier to test without it. Can you add some option to remove it from the calculation?
| ChassisSpeeds adjustSpeeds = (new ChassisSpeeds(robotSpeeds.vxMetersPerSecond, robotSpeeds.vyMetersPerSecond, 0)).plus | ||
| (ChassisSpeeds.fromRobotRelativeSpeeds(-angularVelocityAdjustment.getY(),angularVelocityAdjustment.getX(),0.0,robotPose.getRotation())); | ||
| return adjustSpeeds.toTwist2d(-timeOfFlight); | ||
| } |
There was a problem hiding this comment.
Here's a suggestion for documenting this code:
| } | |
| // Twist2d is a change in pose (position and rotation) over time. | |
| // the returned value is a field-relative displacement vector (change in position and rotation) over the ball flight time. | |
| // this means how much we need to adjust our shot. | |
| public Twist2d getMomentumAdjustment(Pose2d robotPose, Pose2d target, ChassisSpeeds robotSpeeds, double timeOfFlight) { | |
| // calculate the change per second of the turret's position relative to the center due to robot rotation. This | |
| // is basically angular speed. Result is in robot coordinate system. | |
| Translation2d angularVelocityAdjustment = Constants.TURRET_OFFSET.times(robotSpeeds.omegaRadiansPerSecond).getTranslation(); | |
| // take the robot's current speed (relative to field) | |
| // convert the turret's angular velocity from robot-relative to field-relative | |
| // since the rotation velocity is perpendicular to the robot x-axis, so we need to rotate it by 90 degrees | |
| // which is why we use -Y,X instead of X,Y for the conversion. | |
| // add the two to get the effective speed of the turret/projectile. | |
| ChassisSpeeds adjustSpeeds = (new ChassisSpeeds(robotSpeeds.vxMetersPerSecond, robotSpeeds.vyMetersPerSecond, 0)).plus | |
| (ChassisSpeeds.fromRobotRelativeSpeeds(-angularVelocityAdjustment.getY(),angularVelocityAdjustment.getX(),0.0,robotPose.getRotation())); | |
| // convert the effective speed to a twist (displacement over time) | |
| // positive timeOfFlight tells us how much we move | |
| // negative timeOfFlight tells us how much we need to move to compensate for our movement | |
| return adjustSpeeds.toTwist2d(-timeOfFlight); | |
| } | |
My idea is to do a Logger.recordOutput(adjustProfile.targetPose) and then look at how it changes on advantage scope as you drive around and see if it makes sense. That should (hopefully) be enough before we start testing. The one problem is that hardware seems to be unconvinced with the mathematical/physics equations I implemented. I also need Jackson's true position/delayed pose estimate adjustment branch merged in. |
|
I think your math is sound and this is the way to go. If hardware is skeptical of the math/physics, just add an option to disable the adjustment completely then they can shoot while not moving. |
| } | ||
|
|
||
| private double calculateAnglerAngleDegrees(double computedDistanceMeters, PoseControlProfile profile) { | ||
| if ((profile == BLUE_HUB_PROFILE) || (profile == RED_HUB_PROFILE)) { |
There was a problem hiding this comment.
this condition will now always evaluate to false, the adjusted profile is a new object and the == will always fail. Just pass the color as an additional parm.
| .getTranslation().getAngle()).vxMetersPerSecond+1); | ||
| } | ||
| private double calculateShooterVelocity(double computedDistanceMeters, PoseControlProfile profile) { | ||
| if ((profile == BLUE_HUB_PROFILE) || (profile == RED_HUB_PROFILE)) { |
There was a problem hiding this comment.
same comment as the calculateAnglerAngle.
| return 0.0633*computedDistanceMeters + 0.647; | ||
| } | ||
|
|
||
| private double equalizeFlightTime(double initialDistanceMeters, Pose2d robotPose, Pose2d target, ChassisSpeeds robotSpeeds) { |
There was a problem hiding this comment.
1 - I'm not convinced that the flight-time should depend on the speed of the robot at all. I think it is ok to calculate the flight time based only on the distance from the hub. I doubt that considering the speed our robot will be moving this will make a big difference. There are many things that affect the trajectory that we are not considering (physics related such as friction, drag, texture/compression of the fuel will be changing etc.) and this flight-time based only on distance is one that I'm willing to compromise. It will simplify testing by a lot.
2 - regardless - I'm not even sure this code is correct. What you want is the robot's velocity projected on the robot-to-hub directions. Is this what this expression is using? have you tried it with a few cases?
|
Response to last comment.
|
Adjust the target position for flight time and robot velocities (and angular velocity too)