public void init() { Button.LEDPattern(2); colorSensor = new EV3ColorSensor(s1); colorSensor.setFloodlight(Color.WHITE); log = new ArrayList<>(); previousLogging = System.currentTimeMillis(); logger.info("Initialized"); Runnable r = new Runnable() { public void run() { while (!stopped) { int detectedColorId = colorSensor.getColorID(); long now = System.currentTimeMillis(); log.add(String.valueOf(now - previousLogging)); previousLogging = now; if (detectedColorId == lastRegisteredColorId) { sleep(); continue; } if (detectedColorId != lastDetectedColorId) { lastDetectedColorId = detectedColorId; readings = 1; sleep(); continue; } readings++; if (detectedColorId < HIGHEST_SIGNAL_COLOR_ID || readings == CONSECUTIVE_READINGS_REQUIREMENT) { lastRegisteredColorId = detectedColorId; if (detectedColorId != BACKGROUND_COLOR_ID) { sendToBlock("SLEEPER", SleeperColor.convertFromLejosColor(detectedColorId)); } } sleep(); } } }; runAsync(r); }
public void run() { while (true) { if (_suppress) { Thread.yield(); continue; } Pose oldPose = cachePose; cachePose = Rover.poseProvider.getPose(); // get angle and distance where to travel int[] way = wayClass.getPredefinedWay(oldPose, cachePose); cacheWayAngle = way[1]; cacheWayDistance = way[0] * Const.BLOCK_WIDTH; float angle = Const.normalizeAngle(cacheWayAngle - cachePose.getHeading()); if (Const.angleToByte(angle) == 2 && cacheWayDistance == Const.BLOCK_WIDTH) { // if the robot is supposed to rotate 180 deg and travel one block, back out Rover.pilot.travel(-cacheWayDistance, true); } else { // otherwise rotate and travel the distance if (Math.abs(angle) > 2) { // float cacheGyro = Rover.getGyro(); boolean touched = false; Rover.pilot.rotate(angle, true); while (Rover.pilot.isMoving()) { boolean[] touch = Rover.getTouch(); if (touch[0] || touch[1]) touched = true; Thread.yield(); } Pose newPose = Rover.poseProvider.getPose(); /* float angleGyro = Rover.getGyro() - cacheGyro; // if the turn is incomplete, rotate by the difference // TODO maybe turn only when the difference is bigger if (angle > angleGyro + 5 || angle < angleGyro - 5) { Rover.pilot.travel(touched ? -5 : 5); cacheWayDistance += touched ? 5 : -5; Rover.pilot.rotate(angle - angleGyro); newPose = Rover.poseProvider.getPose(); } */ // update pose with normalize heading Rover.poseProvider.setPose(new Pose(newPose.getX(), newPose.getY(), cacheWayAngle)); } float blockAngle = (float) Math.toRadians(cacheWayAngle); byte sin = (byte) Math.round(Math.sin(blockAngle)), cos = (byte) Math.round(Math.cos(blockAngle)); byte blockX = (byte) (Const.roundToMapArea(Const.middlePointToBlock(cachePose.getX()), "X") + cos * (way[0] + 1)), blockY = (byte) (Const.roundToMapArea(Const.middlePointToBlock(cachePose.getY()), "Y") + sin * (way[0] + 1)); // extend the distance to hit a wall if (blockX < 0 || blockY < 0 || blockX > 8 || blockY > 5 || wayClass.getOccupancyMap(blockX, blockY) > 0) { cacheWayDistance += Const.BLOCK_WIDTH; // TODO no way of updating pose if it doesn't hit wall } Rover.pilot.travel(cacheWayDistance, true); } // while the rover is traveling while (Rover.pilot.isMoving()) { boolean[] touch = Rover.getTouch(); if (touch[0] || touch[1]) { Rover.pilot.quickStop(); float sonic = Rover.getSonic(); Pose hitPose = Rover.poseProvider.getPose(); if (hitTheWall(hitPose)) { Rover.pilot.travel(-4); } else if (sonic > 15 && !(touch[0] && touch[1])) { // if the rover touches the obstacle by just one sensor // and distance is more than 15 cm float distanceTraveled = Rover.pilot.getMovement().getDistanceTraveled(); Rover.pilot.travel(-4); Rover.pilot.rotate(touch[0] ? -20 : 20); Pose newPose = Rover.poseProvider.getPose(); Rover.poseProvider.setPose(new Pose(newPose.getX(), newPose.getY(), cacheWayAngle)); cacheWayDistance -= distanceTraveled - 4; Rover.pilot.travel(cacheWayDistance, true); } else { // if the obstacle touched by both sensors // or the distance is less than 15 cm Pose p = Rover.poseProvider.getPose(); byte blockX = Const.roundToMapArea(Const.middlePointToBlock(p.getX()), "X"), blockY = Const.roundToMapArea(Const.middlePointToBlock(p.getY()), "Y"); float blockAngle = (float) Math.toRadians(Const.angleToByte(p.getHeading()) * 90); byte sin = (byte) Math.round(Math.sin(blockAngle)), cos = (byte) Math.round(Math.cos(blockAngle)); boolean isFree; try { isFree = wayClass.getOccupancyMap((byte) (blockX + cos), (byte) (blockY + sin)) < 0; } catch (ArrayIndexOutOfBoundsException e) { isFree = false; } if (!(touch[0] && touch[1]) && isFree) { Rover.pilot.rotate(touch[0] ? -90 : 90); Rover.pilot.travel(15); Rover.pilot.rotate(touch[0] ? 90 : -90); Rover.poseProvider.setPose( new Pose( (blockX + 1 / 2) * Const.BLOCK_WIDTH, (blockY + 1 / 2) * Const.BLOCK_WIDTH, Const.angleToByte(p.getHeading()) * 90)); float distanceTraveled = Rover.pilot.getMovement().getDistanceTraveled(); cacheWayDistance -= distanceTraveled; Rover.pilot.travel(cacheWayDistance, true); } else { System.out.println("ERROR: TRAVEL CORRECTION"); // This shouldn't happen any more Button.LEDPattern(5); } } } Thread.yield(); } } }