NXT/LeJOs bot navigates maze consisting of black tape on white paper, object in front of robot is the maze exit (Pavol Lescinsky)

From RoboWiki
Jump to: navigation, search

About project

Aim of this project is to create a robot capable of crawling through a maze consisting of black tape on the floor, using LEGO NXT MINDSTORMS brick. The program ends when robot reaches an object in front of him. Bot.jpg
Ingredients (hardware):
LEGO MINDSTORMS NXT brick
ultrasonic sensor (1x)
color sensor (1x)
(light sensor) (1x)
NXT servo motors (2x)
many, many lego bricks and parts

Due to the lack of sensors (only one color/light sensor + perhaps one more which will not save the day) the maze specifications were modified:
- the maze path is the black tape, i.e. black tape does not represent walls, but the path the robot follows

Project diary

Saturday, May 25, 2013
Driving base built according to lego building instructions for driving base (with minor modifications), LeJOS installed, explored basic functionality of LeJOS objects..

Thursday, June 06, 2013
LeJOs objects for movement studied. Chosen use of DifferentialPilot class for robot movement. Class DifferentialPilot has the following constructor:
DifferentialPilot(float wheelDiameter, float trackWidth, Motor leftMotor, Motor rightMotor)
Since the robot moves on belts, wheelDiameter and trackWidth combination was chosen by trial and error and measuring, averaging and chosing the most suitable combination. The measurement process was done by first finding the right combination so that pilot.rotate(180); would represent a 180 degree rotation.
After that, markers have been made on the floor marking front corners of the color sensor and a line in the back to verify right orientation of the bot. (see pictures)
The first successful combination was wheelDiameter=0.1 and trackWidth=0.526. This was the starting point for trials. The travel method was chosen for movement instead of forward() since it travels according to tachometer readings and therefore is more independent on battery voltage. Testing code:

DifferentialPilot p = new DifferentialPilot(0.1,0.528,Motor.A,Motor.B);<br/>
p.setRotateSpeed(40);<br/>
for(int i=0;i<4;i++){<br/>

p.travel(3);<br/>
p.rotate(180);<br/>

Button.waitForAnyPress();<br/>
iwheelDiametertrackWidthresult
40.10.526precise landing
70.10.526too few
40.10.526too few
40.10.526too few
40.10.540too much
40.10.538too much
40.10.536too much
40.10.534too much
40.10.530too much
40.10.520too few
40.10.522almost
40.10.528precise landing
40.10.528precise landing
40.10.528almost

Enough for today...batteries are drained, recharge is taking too long - charger only takes 4 batteries, needed are six, recharge time over 12 hours...
Not to forget - ColorSensor have been tested, too. Approx. readings for black <10, surroundings opposite. Captain out... </p>

Friday, June 14, 2013
Maze has been constructed...well painted - black tape is not that easy to get. So the whole maze was drawn using black permanent marker. This poses another limitations for the project - the largest piece of paper I was able to get is about 125x95cm large or so. The gap between two neighbouring parallell paths is only 8cm (had i given it 10, i would have drawn over the paper). The problem isn't the gap, actually - it's the robot width - about twice as much! Another, yet not that much of a problem is the line - drawn using permanent marker - width is not constant, neither is the right angle. LeJOS documentation mentions DifferentialPilot's method forward() as method moving the bot in a hopefully straight path. This hope has died with assigning "bulgarian constants" 0.528 as trackWidth and 0.1 as wheelDiameter. Statistically, it's correct. In a real world, it is not. Therefore, a line following has been implemented. From now on, I no longer expect the maze to be orthogonal. The robot scans for the path the moment it is off the line.
MazeXXL.jpg
.

Saturday, June 15, 2013
After observing robot following the line I altered this algorithm (line following) so that it is possible to crawl within the maze. The pseudo code could look like this:

if moving forward is possible -> move forward
	if not, check if deviation from the line occured
		if so, return to the line and continue moving forward
		otherwise try turning left
		if turning left is possible -> turn left and check for line, make deviation correction etc.
			otherwise turn right, check for line, make deviation corrections etc.

After evaluating the algorithm in connection with this specific maze, i came to conclusion, this is quite simple yet functional solution. As robot line readings are about 70% accurate (my own estimate), this randomness creates some possibility for crawling the whole maze. But if destination object is located somewhere on the edges of the maze, there is almost 100% probability that the robot will reach it regardless of its starting position.

Saturday, June 22, 2013
I've found a very useful approach to robot programming (concept) - Behaviors and Arbitrators. So I decided to give it a try, since it looked much more sophisticated than before.
So I've created a set of behaviors and an arbitrator to manage them. Functionality remains, the code looks much better. But...for reasons unknown, the behavior for ending the program (DestinationReached) does not work as it is supposed to. According to documentation arbitrator returns only in case that none of behaviors managed fulfills its takeControl(), therefore no behavior is entitled to take an action. But that doesn't work - not for me...

Gallery and code

[1] gallery on the school server [2] source code