package NetworkComm; import edu.wpi.first.wpilibj.Timer; import edu.wpi.first.wpilibj.networktables.NetworkTable; public class RPIComm { // camera image parameters private static int frameWidth = 160; private static int frameHeight = 120; // Target accuracy thresholds private static final double X_THRESHOLD = 5; private static final int Y_THRESHOLD = 5; private static final double AREA_THRESHOLD = 20; private static NetworkTable table; private static boolean initialized = false; // movement modes private static boolean lateralMovement = true; private static boolean forwardMovement = false; public static boolean targetCentered = false; public static double numTargets, deltaX, deltaY, targetArea, targetDistance; // Robot drive output private static double driveLeft; private static double driveRight; // Robot targeting speed (% how fast it moves and turns) private static final double DRIVE_SPEED = 0.5; // Number of loops to perform to guarantee the robot is lined up with the target private static final int IS_CENTERED_DELAY = 15; private static int readyTimer = 0; public static void initialize() { if (!initialized) { table = NetworkTable.getTable("RPIComm/Data_Table"); initialized = true; table.putBoolean("autoExposure", true); } } public static void setMovementModes(boolean forwardFlag, boolean lateralFlag) { forwardMovement = forwardFlag; lateralMovement = lateralFlag; } public static void autoInit() { numTargets = 0; deltaX = 0; deltaY = 0; targetArea = 0; targetDistance = 0; reset(); table.putBoolean("autoExposure", true); } public static void teleopInit() { numTargets = 0; deltaX = 0; deltaY = 0; targetArea = 0; targetDistance = 0; reset(); table.putBoolean("autoExposure", true); } public static void disabledInit() { table.putBoolean("autoExposure", true); } public static void reset() { driveLeft = 0; driveRight = 0; readyTimer = 0; targetCentered = false; } public static void updateValues() { if (!initialized) return; // Default data if network table data pull fails double defaultDoubleVal = 0.0; // Pull data from grip numTargets = table.getNumber("targets", defaultDoubleVal); deltaX = table.getNumber("targetX", defaultDoubleVal); deltaY = table.getNumber("targetY", defaultDoubleVal); targetArea = table.getNumber("targetArea",defaultDoubleVal); targetDistance = table.getNumber("targetDistance",defaultDoubleVal); if (numTargets > 0) { // Debug only - print out values read from network table //System.out.println("Time_ms= " + System.currentTimeMillis() + " targets = " + numTargets + ", delta = (" + deltaX + ", " + deltaY + ")"); // do something with position information // if a valid target exists (one that meets filter criteria) // First, focus on centering X! // neg delta X = actual left of goal, turn LEFT => angular velocity = NEG // pos delta X = actual right of goal, turn RIGHT => angular velocity = POS // if no lateral movement needed, pass through if ((Math.abs(deltaX) < X_THRESHOLD) || (!lateralMovement)) { // X is now centered! Next focus on Y! // neg delta Y = actual above goal, move backward => forward velocity = NEG // pos delta Y = actual below goal, move forward => forward velocity = POS // if no forward movement needed, pass through if ((Math.abs(deltaY) < Y_THRESHOLD) || (!forwardMovement)) { // Both X and Y are centered! driveLeft = 0; driveRight = 0; readyTimer++; // if we continued to be centered for a reasonable number of iterations if(readyTimer >= IS_CENTERED_DELAY) { //System.out.println("NetworkCommAssembly: TARGET CENTERED!.... X: " + deltaX + " Y: " + deltaY + // "driveLeft = " + driveLeft + // "driveRight = " + driveRight); String outputStr = String.format("RPIComm: TARGET CENTERED!.... X: %.1f Y: %.1f driveLeft= %.1f driveRight= %.1f", deltaX, deltaY,driveLeft,driveRight); InputOutputComm.putString(InputOutputComm.LogTable.kRPICommLog,"RPIComm",outputStr); targetCentered = true; } return; } else { // Set the left and right motors to help center Y driveLeft = Math.copySign(DRIVE_SPEED, deltaY); driveRight = Math.copySign(DRIVE_SPEED, deltaY); targetCentered = false; readyTimer = 0; String outputStr = String.format("RPIComm: CENTERING Y.... X: %.1f Y: %.1f driveLeft= %.1f driveRight= %.1f", deltaX, deltaY,driveLeft,driveRight); InputOutputComm.putString(InputOutputComm.LogTable.kRPICommLog,"RPIComm",outputStr); return; } } else { // Set the left and right motors to help center X driveLeft = Math.copySign(DRIVE_SPEED, deltaX); driveRight = Math.copySign(DRIVE_SPEED, -deltaX); targetCentered = false; readyTimer = 0; String outputStr = String.format("RPIComm: CENTERING X.... X: %.1f Y: %.1f driveLeft= %.1f driveRight= %.1f", deltaX, deltaY,driveLeft,driveRight); InputOutputComm.putString(InputOutputComm.LogTable.kRPICommLog,"RPIComm",outputStr); return; } } else { // no target found! Reset targeting params InputOutputComm.putString(InputOutputComm.LogTable.kRPICommLog,"RPIComm","No target found"); reset(); } Timer.delay(0.02); } // Returns the value for the left side drivetrain public static double getLeftDriveValue() { return driveLeft; } // Returns the value for the right side drivetrain public static double getRightDriveValue() { return driveRight; } // Returns true if the target is visible, returns false otherwise public static boolean hasTarget() { return (numTargets > 0); } // Returns true if the catapult is ready to shoot, returns false otherwise public static boolean targetCentered() { return targetCentered; } }