Creating a Lego Mindstorm Navigation Robot
Length: 1614 words (4.6 doublespaced pages)
Rating: Excellent
Open Document
Lego Navigation System Abstract My project was to create a robot out of a Lego Mindstorms construction set that was capable of “knowing” where it was. The robot would head out on a random path, remember and update its location, and return to its origin on a straight line. The challenge of this project was not so much a matter of constructing the robot, but of creating a working program in the week and a half time limit. The project goal was met on the last day, thus showing that a Lego navigation system is possible. Background A war zone is a dangerous place, especially for the infantry. Any advantage, technological or otherwise is welcome, and any technology that spares soldiers’ lives is invaluable. Recently, one such technology has made its way to the battlefield; remote controlled robots. These robots can take realtime video, maneuver inside and out, and move hazardous materials out of the way of troops. Two of the leading manufacturer’s of these robots are iRobot and the US Marine Corps. IRobots’ PackBot EOD uses a camera/grabber, multiple sensors, and a unique tread system capable of climbing stairs in order to execute the majority of its tasks. It also has GPS. The US Marine Corps’ Dragon Runner is a rugged, fourwheeled machine with a camera and other sensors safely encased in the body. The Dragon Runner weighs roughly 16 pounds, while the PackBot is just over twice that much weight. While these robots are a great help in a war zone, the navigation system could be improved. If the robot could navigate by itself, the soldiers that previously had to operate the robot would be free to do more important tasks. By implementing a Cartesian coordinate system, I believe that these robots be programmed with a simple selfnavigation system. Procedure The physical design of NavBot is very simple. It follows the basic design of TankBot, as described in David Baum’s Definitive Guide to Lego Mindstorms. I chose this design as the basis of my robot due to its simplicity and ease of construction. While it follows the basic TankBot design, it has its variations, because I didn’t want to hunt down all of the “required” pieces. When I first built the body and tested it, I found that the robot tended to drift to the right. This was easily fixed by changing the power level of the left motor from 7 (highest) to 4. Aside from a few decorations (wings, camel head, smiley face), the physical aspect of NavBot was complete. The more important, as well as complicated, problem was how to program Need Writing Help?Get feedback on grammar, clarity, concision and logic instantly. Check your paper »How to Cite this Page
MLA Citation:
"Creating a Lego Mindstorm Navigation Robot." 123HelpMe.com. 25 Feb 2018 <http://www.123HelpMe.com/view.asp?id=154118>.
Keywords:
NavBot with a navigation system. Early on, I had decided to use a Cartesian
coordinate system, since that was familiar to me. I also decided on using time as the unit of measure because it was convenient and would work no matter what robot the code was placed in. After deciding on the navigation system I would be using, it was time to start programming. The robot would start off at the origin of the coordinate system, then head forward for a random time up to three seconds, then turn to face one of four directions (left, right, reverse, or forward). This going forward and then turning could be repeated as many times as the user desired. I’d originally planned to repeat the process ten times, but decided on five after ten created problems in that it covered an area larger than the room I tested it in. All of the turns had to be at right angles, since anything else would require trigonometry. I had originally planned to have NavBot turn in any direction, but I soon found out that NQC did not support trig (or other important mathematical operations, as I later found out). This would cause other problems later on in the project. To find the location of NavBot, the program took into account the time it moved forward, what direction it was facing, and the previous coordinates. The new location was calculated after each straight movement. Once NavBot had repeated the process of moving and turning the desired number of times, the program had to turn to face the origin, and head back the correct distance. First, NavBot decided in which quadrant it was in, based on it’s x and y coordinates. It could also tell if it was on either the x or y axis. It then turned to face downward if it was above the y axis, and upward if it was below (in the case that it was on either axis, it simply faced the origin). This was so that I only had to program how to face the origin with NavBot facing one direction, as opposed to any of four directions. This is where some of the trigonometry problems really came into play. I’d planned to program how far to turn to face the origin by using trigonometry, but since that wasn’t in option, I had to come up with an alternate strategy. I tried using the Taylor series to approximate the inverse of the tangent function (the only function I needed) , but I later discovered that it was incredibly inaccurate (off by up to forty degrees even when NavBot was less than three seconds from the origin). I then considered using #define to define all of the inverse tangent definitions, but those definitions used decimals, and NQC can only handle fractions. I would have converted the decimals to fractions, but I didn’t want to spend an eternity typing these out only to find that NQC can’t tell that 1/2 and 5000/10000 are the same number. Finally, I decided to use the slope of the line between NavBot’s location and the origin to approximate the angle needed to return to return to the origin. If the slope was between that of two predefined slopes, It would turn a specific angle. While this wasn’t extremely accurate, it was the only solution I could see. If I had more time, I could have created more slopes between which there is a specific “return slope” and corresponding angle. Another problem with the lack of math functions in NQC was the omission of square root capability. This was made programming the time to return to the origin difficult, since the distance formula requires the use of square roots. However, I created an approximation through trial and error. The only other problem that arose was the fact that NQC cannot deal with numbers greater than 1600. This is a tiny number for computer programs, and since my distance formula squared times, which are measured in .001 seconds (i.e. 1 second=100), 16,000 was nowhere near sufficient. I worked around this by dividing times by 100, plugging them into my distance formula, then utilizing the smaller numbers by using a repeat loop that repeated the motor’s turning on for the smaller time 100 times. Results After many tests and efforts to debug the program, it finally worked consistently on the final workday. There is a copy of the code, complete with programming notes, in the appendix. Conclusion The results of this project prove that it is possible to create a navigation system for the Lego Mindstorms construction kit. If I were to continue work on this project, I would research an alternative programming language to NQC in which trigonometry and square roots are supported. References Baum, D. (2000). Definitive Guide to Lego Mindstorms. New York: Apress. [Internet] Crane, D. (March 21, 2005). “More Robotic Infantry Soldiers Headed to Afghanistan and Iraq” Retrieved (July 20): http://www.defensereview.com/modules.php?name=News&file=article&sid=711 Appendix //final project //alex mcauley #define LEFT OUT_A #define RIGHT OUT_C #define ALL OUT_A+OUT_C #define RIGHTTURN 85 #define LEFTTURN 90 #define FULLTURN 165 int x=0,y=0,time=0,d=0,forward=3,return_angle; task main()//goes straight then turns  repeats 10 times { SetPower(LEFT,4); repeat(5) { Fwd(ALL); straight(); turn(); repeat(forward) { PlayTone(700,10); Wait(30); }} quad();//plays what quadrant NavBot's in home(); } // void straight()//goes straight for random amount of time { time=(Random(300)); OnFor(ALL,time); if(forward==0) { x+=time; } if(forward==1) { y=time; } if(forward==2) { x=time; } if(forward==3) { y+=time; }} // void turn()//turns 1 of 4 (0,1,2,3) directions { d=Random(3); if(d==1)//if d is 0, don't turn at all. if d is 1, turn right { Rev(RIGHT); OnFor(ALL,RIGHTTURN); Fwd(ALL); } if(d==2)//turn completely around { Rev(RIGHT); OnFor(ALL,FULLTURN); Fwd(ALL); } if(d==3)//turn left { Rev(LEFT); OnFor(ALL,LEFTTURN); Fwd(ALL); } forward+=d; if(forward>=4) { forward=4; } } // void home() { int z=(((x/100)*(x/100))+((y/100)*(y/100)))/(8/3); _return_angle(); if(x>0 && y>0)//NavBot's in quadrant 1 {//First, turn so that NavBot faces downward if(forward==0) { Rev(RIGHT); OnFor(ALL,RIGHTTURN); Fwd(ALL); } if(forward==2) { Rev(LEFT); OnFor(ALL,LEFTTURN); Fwd(ALL); } if(forward==3) { Rev(RIGHT); OnFor(ALL,FULLTURN); Fwd(ALL); } Rev(RIGHT); OnFor(ALL,(RIGHTTURN*return_angle/90)); Fwd(ALL); } if(x<0 && y>0)//NavBot's in quadrant 2 {//First, turn so that NavBot faces downward if(forward==0) { Rev(RIGHT); OnFor(ALL,RIGHTTURN); Fwd(ALL); } if(forward==2) { Rev(LEFT); OnFor(ALL,LEFTTURN); Fwd(ALL); } if(forward==3) { Rev(RIGHT); OnFor(ALL,FULLTURN); Fwd(ALL); } Rev(LEFT); OnFor(ALL,(LEFTTURN*return_angle/90)); Fwd(ALL); } if(x<0 && y<0)//NavBot's in quadrant 3 {//First, turn so that NavBot faces upward if(forward==0) { Rev(LEFT); OnFor(ALL,LEFTTURN); Fwd(ALL); } if(forward==1) { Rev(RIGHT); OnFor(ALL,FULLTURN); Fwd(ALL); } if(forward==2) { Rev(RIGHT); OnFor(ALL,RIGHTTURN); Fwd(ALL); } Rev(RIGHT); OnFor(ALL,(RIGHTTURN*return_angle/90)); Fwd(ALL); } if(x>0 && y<0)//NavBot's in quadrant 4 {//First, turn so that NavBot faces upward if(forward==0) { Rev(LEFT); OnFor(ALL,LEFTTURN); Fwd(ALL); } if(forward==1) { Rev(RIGHT); OnFor(ALL,FULLTURN); Fwd(ALL); } if(forward==3) { Rev(RIGHT); OnFor(ALL,RIGHTTURN); Fwd(ALL); } Rev(LEFT); OnFor(ALL,(LEFTTURN*return_angle/90)); Fwd(ALL); } if(x==0 && y>0)//On posy axis {//First, turn so that NavBot faces origin if(forward==0) { Rev(RIGHT); OnFor(ALL,RIGHTTURN); Fwd(ALL); } if(forward==2) { Rev(LEFT); OnFor(ALL,LEFTTURN); Fwd(ALL); } if(forward==3) { Rev(RIGHT); OnFor(ALL,FULLTURN); Fwd(ALL); }} if(x==0 && y<0)//On negy axis {//First, turn so that NavBot faces origin if(forward==0) { Rev(LEFT); OnFor(ALL,LEFTTURN); Fwd(ALL); } if(forward==1) { Rev(RIGHT); OnFor(ALL,FULLTURN); Fwd(ALL); } if(forward==2) { Rev(RIGHT); OnFor(ALL,FULLTURN); Fwd(ALL); } } if(x==0 && y>0)//On posx axis {//First, turn so that NavBot faces origin if(forward==0) { Rev(RIGHT); OnFor(ALL,FULLTURN); Fwd(ALL); } if(forward==1) { Rev(RIGHT); OnFor(ALL,RIGHTTURN); Fwd(ALL); } if(forward==3) { Rev(LEFT); OnFor(ALL,LEFTTURN); Fwd(ALL); }} if(x==0 && y>0)//On negx axis {//First, turn so that NavBot faces origin if(forward==1) { Rev(LEFT); OnFor(ALL,LEFTTURN); Fwd(ALL); } if(forward==2) { Rev(RIGHT); OnFor(ALL,FULLTURN); Fwd(ALL); } if(forward==3) { Rev(RIGHT); OnFor(ALL,RIGHTTURN); Fwd(ALL); }} PlayTone(600,100); repeat(100) { OnFor(ALL,z); } PlayTone(700,100); } // void _return_angle() { if(abs(y/x)>0 && abs(y/x)<(2/3)) { return_angle=72; } if (abs(y/x)>=(2/3) && abs(y/x)<=(3/2)) { return_angle=45; } if(abs(y/x)>(3/2)) { return_angle=18; }} // void quad()//Plays what quadrant NavBot's in. { Wait(100); if(x>0 && y>0) { repeat(1) { PlayTone(700,10); }} if(x<0 && y>0) { repeat(2) { PlayTone(700,10); Wait(50); }} if(x<0 && y<0) { repeat(3) { PlayTone(700,10); Wait(50); }} if(x>0 && y<0) { repeat(4) { PlayTone(700,10); Wait(50); }} } 
