computer_vision_and_shooter_targeting
Differences
This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revision | |||
| computer_vision_and_shooter_targeting [2022/08/14 23:56] – rfhuang | computer_vision_and_shooter_targeting [2022/08/15 00:00] (current) – rfhuang | ||
|---|---|---|---|
| Line 23: | Line 23: | ||
| Our main use of CV was to detect the distance from the robot from the base of the goal and to calculate the angle offset between the robot and the center of the goal. We use the angle offset to align ourselves with the goal, through the use of PID, and we interpolate the distance and RPM presets in order to shoot the ball. We achieved this through the use of a shooter preset, which is a collection of flywheel RPMs that are known to work from specific distances. From this, we select the two closest presets based on our current distance, feed those values into interpolation algorithms, set our shooter RPMs to that of the output from the algorithms, and then fire. Shooting in this manner allows us to shoot the game-peice without fear of bounce outs, thereby increasing reliability and consistency. From our scouting data on our team's robot our **score when shot rate is 95%**. | Our main use of CV was to detect the distance from the robot from the base of the goal and to calculate the angle offset between the robot and the center of the goal. We use the angle offset to align ourselves with the goal, through the use of PID, and we interpolate the distance and RPM presets in order to shoot the ball. We achieved this through the use of a shooter preset, which is a collection of flywheel RPMs that are known to work from specific distances. From this, we select the two closest presets based on our current distance, feed those values into interpolation algorithms, set our shooter RPMs to that of the output from the algorithms, and then fire. Shooting in this manner allows us to shoot the game-peice without fear of bounce outs, thereby increasing reliability and consistency. From our scouting data on our team's robot our **score when shot rate is 95%**. | ||
| + | ---- | ||
| + | |||
| + | ==== Other Notable Structures ==== | ||
| + | |||
| + | |||
| + | === Turn to Goal === | ||
| + | <code java> | ||
| + | if (useCV && vision.hasTarget() && System.currentTimeMillis() - start < 3000) { | ||
| + | double distance = vision.getTargetDistance(); | ||
| + | double angle = vision.getTargetAngle(); | ||
| + | double turnSpeed = angle / 50.0; | ||
| + | |||
| + | preset = interpolate(distance); | ||
| + | |||
| + | turnSpeed = MathUtil.clamp(Math.copySign(Math.max(Math.abs(turnSpeed), | ||
| + | |||
| + | if (useAlignment && Math.abs(angle) > 2) { | ||
| + | isAligned = false; | ||
| + | } else { | ||
| + | var goalPose = drivebase.getGoalPose(); | ||
| + | double centerDistance = Units.feetToMeters(vision.getTargetDistance() + 1.5 + 2); | ||
| + | double poseAngle = drivebase.getPose().getRotation().getDegrees(); | ||
| + | double transformRotation = 0; | ||
| + | if (angle < 0 && poseAngle > 0) { | ||
| + | transformRotation = angle + poseAngle; | ||
| + | } else if (angle > 0 && poseAngle > 0) { | ||
| + | transformRotation = angle + poseAngle + 90; | ||
| + | } else if (angle < 0 && poseAngle < 0) { | ||
| + | transformRotation = angle + poseAngle + 90; | ||
| + | } else if (angle > 0 && poseAngle < 0) { | ||
| + | transformRotation = angle + poseAngle + 90; | ||
| + | } | ||
| + | double newX = goalPose.getX() - centerDistance * Math.sin(Math.toRadians(transformRotation)); | ||
| + | double newY = goalPose.getY() + centerDistance * Math.cos(Math.toRadians(transformRotation)); | ||
| + | | ||
| + | drivebase.resetOdometry(new Pose2d(newX, | ||
| + | } | ||
| + | |||
| + | drivebase.curvatureDrive(0, | ||
| + | } else { | ||
| + | drivebase.curvatureDrive(0, | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | === Interpolate Algorithm === | ||
| + | |||
| + | <code java> | ||
| + | public static ShooterPreset interpolate(double distance) { | ||
| + | ArrayList< | ||
| + | |||
| + | distance -= 0.5; | ||
| + | |||
| + | presets.add(new ShooterPreset(900, | ||
| + | presets.add(new ShooterPreset(1950, | ||
| + | presets.add(new ShooterPreset(2150, | ||
| + | presets.add(new ShooterPreset(2500, | ||
| + | presets.add(new ShooterPreset(2950, | ||
| + | presets.add(new ShooterPreset(3350, | ||
| + | presets.add(new ShooterPreset(4100, | ||
| + | presets.add(new ShooterPreset(4600, | ||
| + | |||
| + | ShooterPreset bottomPreset = presets.get(presets.size() - 1); | ||
| + | ShooterPreset upperPreset; | ||
| + | | ||
| + | for (ShooterPreset p : presets) { | ||
| + | if (distance - p.distance < 0) { | ||
| + | bottomPreset = p; | ||
| + | break; | ||
| + | } | ||
| + | } | ||
| + | |||
| + | try { | ||
| + | bottomPreset = presets.get(presets.indexOf(bottomPreset) - 1); | ||
| + | upperPreset = presets.get(presets.indexOf(bottomPreset) + 1); | ||
| + | } catch (IndexOutOfBoundsException e) { | ||
| + | if (distance > presets.get(presets.size() - 1).distance) { | ||
| + | bottomPreset = presets.get(presets.size() - 1); | ||
| + | } | ||
| + | upperPreset = bottomPreset; | ||
| + | } | ||
| + | |||
| + | double topRPMDifference = upperPreset.topRPM - bottomPreset.topRPM; | ||
| + | double mainRPMDifference = upperPreset.mainRPM - bottomPreset.mainRPM; | ||
| + | double dist = upperPreset.distance - bottomPreset.distance; | ||
| + | |||
| + | if (dist == 0) dist = bottomPreset.distance; | ||
| + | |||
| + | double percentage = (distance - bottomPreset.distance) / dist; | ||
| + | |||
| + | double topRPM = percentage * topRPMDifference + bottomPreset.topRPM; | ||
| + | double mainRPM = percentage * mainRPMDifference + bottomPreset.mainRPM; | ||
| + | | ||
| + | return new ShooterPreset(topRPM, | ||
| + | } | ||
| + | </ | ||
computer_vision_and_shooter_targeting.1660535775.txt.gz · Last modified: 2022/08/14 23:56 by rfhuang
