diff --git a/README.org b/README.org index 2d4b907..cad64fa 100644 --- a/README.org +++ b/README.org @@ -1,7 +1,84 @@ -* RyABI +* RyABI (/Robótica y Aprendizaje Bio-Inspirado/ - Robotics and Bio-Inspired Learning) ** Abstract -RyABI (/Robótica y Aprendizaje Bio-Inspirado/ - Robotics and Bio-Inspired Learning) is a control program for LEGO Mindstorms NXT using the LeJOS NXJ -firmware. It is developed as part of the homonimous course being taught at the Computer Sciences School of the UCV. -Future verions of this README file will include a technical report on the development of the project. +RyABI is a control program for LEGO Mindstorms NXT using the LeJOS NXJ firmware. The controller is based on the +subsumption reactive control architecture. + +** Objective + +The controller assumes an environment like the following: + +#+BEGIN_SRC ditaa :file environment.png :cmdline -o -E + . +-----------+ + . | | + . |cBLK | + +----+ +------+----+ + | | | | + | | | | + | | +---------+ | | + | | | | | | + | | | | | | + | | | | | | + | | | | | | + | | +-----+ | | | | + | | |Robot| | | | | + | | |cGRE | | | | | + | | +-----+ | | | | + | | | | | | + | | | | +---------+ | | + | | | cBLK | | | | | +-----+ + | | +---------+ | | | | |Ball | + | | | | | | |cYEL | + | | | | | | +-----+ + | | | | | | + | | | | | | + | | | | | | + | | | | | | + | | | cBLK | | | + | | +---------+ | | + | | | | + | | | | + | | | | + | | | | + |cBLU| |cPNK| + +----+ +------+----+ + . | | + . |cBLK | + . +-----------+ + +#+END_SRC + +#+RESULTS: +[[file:environment.png]] + +The goal of the controller is to find a ball (in yellow) that is located on one side of a goal line (in pink), +while avoiding any obstacles (in black) it can find. Once the ball is found, or the robot has collided with any +of the two obstacles at the sides of the goal line, the controller will return to the starting line (in blue). + +The floor and the start/goal lines must be of constrasting colors. Contrary to what the diagram implies, both +the start and goal lines *must* be of a similar color. + +** Robot + +The robot is based on a differential drive and must use the following motors: + + * Motors A and C :: Attached to the wheels. Used to move and steer the robot. + * Motor B :: Attached to a gripper claw. Used to catch the ball. + +It must also use the following sensors: + + * Ultrasonic ranger :: Used to find the ball. Attached to port 1. + * Touch bumper :: Used to detect obstacles. Attached to port 2. + * HiTechnic compass :: Used to steer and move with some precission. Attached to port 3. + * Greyscale light detector :: Used to find the start and goal lines. Attached to port 4. + +** Subsumption + +The controller uses the following five behaviors: + + * Wander :: Simply moves the robot forward. + * Search :: When the goal line is found the robot will start searching for the ball using the range sensor. + * Catch :: When the ball has been found the robot will attempt to grab it with it's gripper. + * Victory :: When the start line is crossed the robot will stop moving a play a little tune. + * Avoid :: If the robot bumped against an obstacle then the robot will move a bit to the right to avoid it. It may take many attempts to clear a wide obstacle. diff --git a/environment.png b/environment.png new file mode 100644 index 0000000..109b8a1 Binary files /dev/null and b/environment.png differ diff --git a/src/ve/ucv/ciens/cicore/icaro/ryabi/RyABI.java b/src/ve/ucv/ciens/cicore/icaro/ryabi/RyABI.java index 79aeddb..f87385e 100644 --- a/src/ve/ucv/ciens/cicore/icaro/ryabi/RyABI.java +++ b/src/ve/ucv/ciens/cicore/icaro/ryabi/RyABI.java @@ -46,7 +46,7 @@ import ve.ucv.ciens.cicore.icaro.ryabi.utils.QuitButtonListener; @SuppressWarnings("deprecation") public class RyABI { private static final float WHEEL_DIAMETER = 56.0f; - private static final float TRACK_WIDTH = 155.0f; + private static final float TRACK_WIDTH = 144.0f; private static ArcRotateMoveController pilot; private static UltrasonicSensor sonar; diff --git a/src/ve/ucv/ciens/cicore/icaro/ryabi/behaviors/CatchBallBehavior.java b/src/ve/ucv/ciens/cicore/icaro/ryabi/behaviors/CatchBallBehavior.java index 57997d7..7f4b2f0 100644 --- a/src/ve/ucv/ciens/cicore/icaro/ryabi/behaviors/CatchBallBehavior.java +++ b/src/ve/ucv/ciens/cicore/icaro/ryabi/behaviors/CatchBallBehavior.java @@ -53,14 +53,15 @@ public class CatchBallBehavior extends BaseBehavior { @Override public void action() { - pilot.travel(65); + pilot.travel(60); Motor.B.backward(); try { Thread.sleep(2000); } catch(InterruptedException e) { }; Motor.B.stop(true); + Motor.B.suspendRegulation(); /* Turn towards the start line and start moving. */ Rotations.rotate90(compass, pilot); Rotations.rotate90(compass, pilot); - pilot.travel(200); + pilot.travel(350); state.setState(States.WANDER); } diff --git a/src/ve/ucv/ciens/cicore/icaro/ryabi/behaviors/SearchBallBehavior.java b/src/ve/ucv/ciens/cicore/icaro/ryabi/behaviors/SearchBallBehavior.java index 34a2d0b..516cb5d 100644 --- a/src/ve/ucv/ciens/cicore/icaro/ryabi/behaviors/SearchBallBehavior.java +++ b/src/ve/ucv/ciens/cicore/icaro/ryabi/behaviors/SearchBallBehavior.java @@ -63,18 +63,19 @@ public class SearchBallBehavior extends BaseBehavior { @Override public boolean takeControl() { /* If the ball has already been found then this behavior should not take control again. */ - if(ballFound) + if(ballFound) { return false; + } /* If the current state is SEARCH_BALL then set the detectors and take control. */ - if(state.getState() == States.SEARCH_BALL) { + if(state.getState() == States.SEARCH_BALL && !ballFound) { setDetectors(); return true; } /* If the state is not SEARCH_BALL but there is at least one light feature detected * indicating that the finish line has been reached then set the detectors and take control. */ - if(queue.hasNextLightSensorEvent()) { + if(queue.hasNextLightSensorEvent() && !ballFound) { state.setState(States.SEARCH_BALL); setDetectors(); @@ -91,6 +92,7 @@ public class SearchBallBehavior extends BaseBehavior { @Override public void action() { + boolean _ballFound = false; boolean obstacleFound = false; /* Discard unneeded touch events. */ @@ -106,9 +108,11 @@ public class SearchBallBehavior extends BaseBehavior { pilot.stop(); if(!obstacleFound) { - ballFound = searchBall(); - if(ballFound) + _ballFound = searchBall(); + if(_ballFound) { + ballFound = true; state.setState(States.BALL_FOUND); + } } else { ballFound = true; Rotations.rotate90(compass, pilot); @@ -127,7 +131,7 @@ public class SearchBallBehavior extends BaseBehavior { private void setDetectors() { detectorHandler.enableTouchDetector(); detectorHandler.disableLightDetector(); - detectorHandler.disableRangeDetector(); + detectorHandler.enableRangeDetector(); } private void moveLeft() { @@ -157,17 +161,17 @@ public class SearchBallBehavior extends BaseBehavior { private boolean searchBall() { boolean found = false; - detectorHandler.enableRangeDetector(); - activeWait(1000); + while(queue.hasNextRangeSensorEvent()) + queue.getNextRangeSensorEvent(); + + try { Thread.sleep(2000); } catch(InterruptedException e) { }; if(queue.hasNextRangeSensorEvent()) { - /* If the pedestal has been found then stop the robot and set the state to BALL_FOUND. */ - state.setState(States.BALL_FOUND); + found = true; /* Discard unneeded range features. */ while(queue.hasNextRangeSensorEvent()) queue.getNextRangeSensorEvent(); } - detectorHandler.disableRangeDetector(); return found; } @@ -188,12 +192,4 @@ public class SearchBallBehavior extends BaseBehavior { return obstacleFound; } - - private void activeWait(long milliseconds) { - long then = System.currentTimeMillis(), now; - System.out.println("Waiting."); - do { - now = System.currentTimeMillis(); - } while(now - then < 1000); - } } diff --git a/src/ve/ucv/ciens/cicore/icaro/ryabi/sensors/FeatureDetectorsHandler.java b/src/ve/ucv/ciens/cicore/icaro/ryabi/sensors/FeatureDetectorsHandler.java index a0d4623..4f818af 100644 --- a/src/ve/ucv/ciens/cicore/icaro/ryabi/sensors/FeatureDetectorsHandler.java +++ b/src/ve/ucv/ciens/cicore/icaro/ryabi/sensors/FeatureDetectorsHandler.java @@ -41,7 +41,7 @@ public final class FeatureDetectorsHandler { /** * Gets the singleton instance of this class. * - * @return the instacne. + * @return the instance. */ public static FeatureDetectorsHandler getInstance() { return SingletonHolder.INSTANCE;