SHARE
TWEET
FRC 4787 problems
a guest
Jan 31st, 2014
34
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
- /*----------------------------------------------------------------------------*/
- /* Copyright (c) FIRST 2008. All Rights Reserved. */
- /* Open Source Software - may be modified and shared by FRC teams. The code */
- /* must be accompanied by the FIRST BSD license file in the root directory of */
- /* the project. */
- /*----------------------------------------------------------------------------*/
- package edu.wpi.first.wpilibj.templates;
- import edu.wpi.first.wpilibj.*;
- import java.lang.Math;
- import edu.wpi.first.wpilibj.CounterBase.EncodingType;
- import edu.wpi.first.wpilibj.camera.AxisCamera;
- import edu.wpi.first.wpilibj.camera.AxisCameraException;
- import edu.wpi.first.wpilibj.image.BinaryImage;
- import edu.wpi.first.wpilibj.image.ColorImage;
- import edu.wpi.first.wpilibj.image.CriteriaCollection;
- import edu.wpi.first.wpilibj.image.NIVision;
- import edu.wpi.first.wpilibj.image.NIVisionException;
- import edu.wpi.first.wpilibj.image.ParticleAnalysisReport;
- import edu.wpi.first.wpilibj.image.RGBImage;
- import edu.wpi.first.wpilibj.networktables.NetworkTable;
- import java.util.Vector;
- /**
- * The VM is configured to automatically run this class, and to call the
- * functions corresponding to each mode, as described in the SimpleRobot
- * documentation. If you change the name of this class or the package after
- * creating this project, you must also update the manifest file in the resource
- * directory.
- */
- public class Walle extends SimpleRobot {
- // Variable initializations
- RobotDrive drive;
- Joystick leftStick;
- Joystick rightStick;
- double CAMERA_ANGLE = 49;
- // Joystick constants
- int LEFT_JOYSTICK_USB = 1;
- int RIGHT_JOYSTICK_USB = 2;
- // Motor constants
- int FRONT_LEFT_MOTOR_PWM = 1;
- int REAR_LEFT_MOTOR_PWM = 2;
- int FRONT_RIGHT_MOTOR_PWM = 3;
- int REAR_RIGHT_MOTOR_PWM = 4;
- int LAUNCH_PWM;
- int RIGHT_WINCH_PWM;
- int LEFT_WINCH_PWM;
- int LINE_ACTUATOR_PWM;
- // Motor controller configurations
- Jaguar frontLeft = new Jaguar(FRONT_LEFT_MOTOR_PWM);
- Jaguar rearLeft = new Jaguar(REAR_LEFT_MOTOR_PWM);
- Jaguar frontRight = new Jaguar(FRONT_RIGHT_MOTOR_PWM);
- Jaguar rearRight = new Jaguar(REAR_RIGHT_MOTOR_PWM);
- Jaguar launch = new Jaguar(LAUNCH_PWM);
- Jaguar rightWinch = new Jaguar(RIGHT_WINCH_PWM);
- Jaguar leftWinch = new Jaguar(LEFT_WINCH_PWM);
- Encoder encoder = new Encoder(1, 2, true, EncodingType.k4X);
- // Camera constants for distance calculation
- int IMAGE_RESOLUTION = 480;
- int VIEW_ANGLE = 49;
- /* Limits for the rectangularity and
- * aspect ratio scores, anything below
- * this will not be considered as a
- * target. */
- int RECTANGULARAITY_LIMIT = 40;
- int ASPECT_RATIO_LIMIT = 55;
- int TAPE_WIDTH_LIMIT = 50;
- int VERTICAL_SCORE_LIMIT = 50;
- int LR_SCORE_LIMIT = 50;
- int AREA_MINIMUM = 150;
- int MAX_PARTICLES = 8;
- AxisCamera camera;
- CriteriaCollection criteria;
- public class Scores {
- double rectangularity;
- double aspectRatioVertical;
- double aspectRatioHorizontal;
- }
- /* This object contain data about the target
- * including the scores, the position, and
- * whether or not it is hot. */
- public class TargetReport {
- int verticalPos;
- int horizontalPos;
- boolean hot;
- double totalScore;
- double leftScore;
- double rightScore;
- double tapeWidthScore;
- double verticalScore;
- }
- public Walle() {
- drive = new RobotDrive(frontLeft, rearLeft, frontRight, rearRight);
- leftStick = new Joystick(LEFT_JOYSTICK_USB);
- rightStick = new Joystick(RIGHT_JOYSTICK_USB);
- }
- public void robotInit() {
- camera = AxisCamera.getInstance();
- criteria = new CriteriaCollection();
- criteria.addCriteria(NIVision.MeasurementType.IMAQ_MT_AREA, AREA_MINIMUM, 65535, false);
- }
- /* This function converts a ratio from the
- * range of 0 - 1.0 into a number from 1-100.*/
- public double ratioToScore(double ratio) {
- return (Math.max(0, Math.min(100 * (1 - Math.abs(1 - ratio)), 100)));
- }
- public double rectangularity(ParticleAnalysisReport report) {
- return (report.boundingRectWidth * report.boundingRectHeight != 0)
- ? (100 * (report.particleArea / (report.boundingRectWidth * report.boundingRectHeight))) : 0.0;
- }
- public double aspectRatioScore(BinaryImage image, ParticleAnalysisReport report, boolean vertical, int particle) throws NIVisionException {
- double rectLong, rectShort, idealAspectRatio, aspectRatio;
- // The dimensions of the vertical reflector strip
- // are 4.0 X 32 and the dimensions of the horizontal
- // reflector is 23.5 X 4 used in the game.
- idealAspectRatio = vertical ? (4.0 / 32) : (23.5 / 4);
- // Returns the number of particles on the longer
- // side and the shorter side of the rectangle
- rectLong = NIVision.MeasureParticle(image.image, particle, false, NIVision.MeasurementType.IMAQ_MT_EQUIVALENT_RECT_LONG_SIDE);
- rectShort = NIVision.MeasureParticle(image.image, particle, false, NIVision.MeasurementType.IMAQ_MT_EQUIVALENT_RECT_SHORT_SIDE);
- // If the image is wider than it is long, then calculate the
- // aspect ratio by dividing the longer value by the shorter
- // and the shorter by the longer otherwise
- if (report.boundingRectWidth > report.boundingRectHeight) {
- aspectRatio = ratioToScore((rectLong / rectShort) / idealAspectRatio);
- } else {
- aspectRatio = ratioToScore((rectShort / rectLong) / idealAspectRatio);
- }
- return aspectRatio;
- }
- /* This function determines if the score is a target by determining
- * if it is a rectangle, anything with a rectuanguliry lower than
- * the limit is not considered a rectangle, then the function measures
- * aspect ratio because... */
- public boolean compareScores(Scores score, boolean vertical) {
- boolean isTarget = true;
- isTarget &= score.rectangularity > RECTANGULARAITY_LIMIT;
- if (vertical) {
- isTarget &= score.aspectRatioVertical > ASPECT_RATIO_LIMIT;
- } else {
- isTarget &= score.aspectRatioHorizontal > ASPECT_RATIO_LIMIT;
- }
- return isTarget;
- }
- /* This function computes the distance away from the camera given
- * the image. It uses the reso*/
- public double computeDistance(BinaryImage image, ParticleAnalysisReport report, int particle) throws NIVisionException {
- double rectLong, height;
- int targetHeight = 32;
- rectLong = NIVision.MeasureParticle(image.image, particle, false, NIVision.MeasurementType.IMAQ_MT_EQUIVALENT_RECT_LONG_SIDE);
- height = Math.min(report.boundingRectHeight, rectLong);
- return IMAGE_RESOLUTION * targetHeight / (height * 12 * 2 * Math.tan(VIEW_ANGLE * Math.PI / (180 / 2)));
- }
- public boolean hotOrNot(TargetReport target)
- {
- boolean isHot = true;
- isHot &= target.tapeWidthScore >= TAPE_WIDTH_LIMIT;
- isHot &= target.verticalScore >= VERTICAL_SCORE_LIMIT;
- isHot &= (target.leftScore > LR_SCORE_LIMIT) | (target.rightScore > LR_SCORE_LIMIT);
- return isHot;
- }
- public void setWinchAngle(double angle) {
- int winchAngle = (int)angle;
- }
- /**
- * This function is called once each time the robot enters autonomous mode.
- */
- public void autonomous() {
- TargetReport target = new TargetReport();
- int verticalTargets[] = new int[MAX_PARTICLES];
- int horizontalTargets[] = new int[MAX_PARTICLES];
- int verticalTargetCount, horizontalTargetCount;
- while (isAutonomous() && isEnabled()) {
- try {
- ColorImage image = camera.getImage();
- BinaryImage thresholdImage = image.thresholdHSV(105, 137, 230, 255, 133, 183);
- BinaryImage filteredImage = thresholdImage.particleFilter(criteria);
- Scores scores[] = new Scores[filteredImage.getNumberParticles()];
- horizontalTargetCount = verticalTargetCount = 0;
- if (filteredImage.getNumberParticles() > 0) {
- for (int i = 0; i < MAX_PARTICLES && i < filteredImage.getNumberParticles(); i++) {
- ParticleAnalysisReport report = filteredImage.getParticleAnalysisReport(i);
- scores[i] = new Scores();
- scores[i].rectangularity = rectangularity(report);
- scores[i].aspectRatioVertical = aspectRatioScore(filteredImage, report, true, i);
- scores[i].aspectRatioHorizontal = aspectRatioScore(filteredImage, report, false, i);
- if (compareScores(scores[i], false)) {
- System.out.println("particle: " + i + "is a Horizontal Target centerX: " + report.center_mass_x + "centerY: " + report.center_mass_y);
- horizontalTargets[horizontalTargetCount++] = i;
- } else if (compareScores(scores[i], true)) {
- System.out.println("particle: " + i + "is a Vertical Target centerX: " + report.center_mass_x + "centerY: " + report.center_mass_y);
- verticalTargets[verticalTargetCount++] = i;
- } else {
- System.out.println("particle: " + i + "is not a Target centerX: " + report.center_mass_x + "centerY: " + report.center_mass_y);
- }
- System.out.println("rect: " + scores[i].rectangularity + "ARHoriz: " + scores[i].aspectRatioHorizontal);
- System.out.println("ARVert: " + scores[i].aspectRatioVertical);
- }
- target.totalScore = target.leftScore = target.rightScore = target.tapeWidthScore = target.verticalScore = 0;
- target.verticalPos = verticalTargets[0];
- for (int i = 0; i < verticalTargetCount; i++) {
- ParticleAnalysisReport verticalReport = filteredImage.getParticleAnalysisReport(verticalTargets[i]);
- for (int j = 0; j < horizontalTargetCount; j++) {
- ParticleAnalysisReport horizontalReport = filteredImage.getParticleAnalysisReport(horizontalTargets[j]);
- double horizWidth, horizHeight, vertWidth, leftScore, rightScore, tapeWidthScore, verticalScore, total;
- horizWidth = NIVision.MeasureParticle(filteredImage.image, horizontalTargets[j], false, NIVision.MeasurementType.IMAQ_MT_EQUIVALENT_RECT_LONG_SIDE);
- vertWidth = NIVision.MeasureParticle(filteredImage.image, verticalTargets[i], false, NIVision.MeasurementType.IMAQ_MT_EQUIVALENT_RECT_SHORT_SIDE);
- horizHeight = NIVision.MeasureParticle(filteredImage.image, horizontalTargets[j], false, NIVision.MeasurementType.IMAQ_MT_EQUIVALENT_RECT_SHORT_SIDE);
- //Determine if the horizontal target is in the expected location to the left of the vertical target
- leftScore = ratioToScore(1.2 * (verticalReport.boundingRectLeft - horizontalReport.center_mass_x) / horizWidth);
- //Determine if the horizontal target is in the expected location to the right of the vertical target
- rightScore = ratioToScore(1.2 * (horizontalReport.center_mass_x - verticalReport.boundingRectLeft - verticalReport.boundingRectWidth) / horizWidth);
- //Determine if the width of the tape on the two targets appears to be the same
- tapeWidthScore = ratioToScore(vertWidth / horizHeight);
- //Determine if the vertical location of the horizontal target appears to be correct
- verticalScore = ratioToScore(1 - (verticalReport.boundingRectTop - horizontalReport.center_mass_y) / (4 * horizHeight));
- total = leftScore > rightScore ? leftScore : rightScore;
- total += tapeWidthScore + verticalScore;
- //If the target is the best detected so far store the information about it
- if (total > target.totalScore) {
- target.horizontalPos = horizontalTargets[j];
- target.verticalPos = verticalTargets[i];
- target.totalScore = total;
- target.leftScore = leftScore;
- target.rightScore = rightScore;
- target.tapeWidthScore = tapeWidthScore;
- target.verticalScore = verticalScore;
- }
- }
- //Determine if the best target is a Hot target
- target.hot = hotOrNot(target);
- }
- if (verticalTargetCount > 0) {
- ParticleAnalysisReport distanceReport = filteredImage.getParticleAnalysisReport(target.verticalPos);
- double distance = computeDistance(filteredImage, distanceReport, target.verticalPos);
- if (target.hot) {
- System.out.println("Hot target located");
- System.out.println("Distance: " + distance);
- double targetHeight = Math.tan(VIEW_ANGLE) * distance;
- } else {
- System.out.println("No hot target present");
- System.out.println("Distance: " + distance);
- }
- }
- }
- filteredImage.free();
- thresholdImage.free();
- image.free();
- } catch (AxisCameraException ex) {
- ex.printStackTrace();
- } catch (NIVisionException ex) {
- ex.printStackTrace();
- }
- }
- }
- /**
- * This function is called once each time the robot enters operator control.
- */
- public void operatorControl() {
- while (true && isOperatorControl() && isEnabled()) {
- drive.tankDrive(leftStick.getY(), leftStick.getX());
- if (rightStick.getRawButton(3)) {
- }
- Timer.delay(0.005);
- }
- }
- /**
- * This function is called once each time the robot enters test mode.
- */
- public void test() {
- }
- }
RAW Paste Data
