by l3v3rz » Fri Jan 08, 2010 7:27 pm
by l3v3rz
Fri Jan 08, 2010 7:27 pm
In the Robobuilder C programming tutorial there is an application written in C to enable the robot to traverse a maze using the distance sensor. You have to compile it in AVR C and download to the RBC. To make this easier to do, I've converted it to L#/Lsharp.Net. A simple scripting language. It uses the lisp code explained here
http://robosavvy.com/forum/viewtopic.php?t=4800. (Or downloaded as a word document here :
http://robobuildervc.googlecode.com/files/final.doc )
You need final.lisp from here
http://robobuildervc.googlecode.com/files/Lisp.zip to connect to Robobuilder. The maze application code is available here
http://robobuildervc.googlecode.com/files/maze2.lisp
The code builds a map on screen of the maze as the robot moves around. It uses the distance sensor to identify the walls and then the following algorithm:
1. If there is no wall, move forward.
2. If the wall is detected, check left side.
3. If front and left side wall are detected, check right side.
4. If front, left and right side walls detected, go to opposite way.
You can run it in a simulate mode without the robot. Here's an example of it in action:
- Code: Select all
> (maze)
........
........
........
........
....^...
........
........
........
distance ?
: 20
LT90
Run motion 3
Run motion 3
Run motion 3
........
........
........
........
....<...
........
........
........
The program defines a number of simple primitive motions based on the built in motions:
- Code: Select all
(def leftturn90 () (prn "LT90") ( runMotion 3) (runMotion 3) (runMotion 3))
(def leftturn180 () (prn "LT180") ( runMotion 3) (runMotion 3) (runMotion 3) (runMotion 3) (runMotion 3))
(def rightturn90 () (prn "RT90") ( runMotion 5) (runMotion 5) (runMotion 5) (runMotion 5))
(def forward () (prn "FWD") ( runMotion 4) (runMotion 4) (runMotion 5) )
(def back () (prn "BACK") ( runMotion 10))
The maps is created using a simple string to represent 8x8 grid. And some functions that display and show the robot a simple character.
The function
maze then uses these routines to solve the maze, by walking the robot around, and measuring the distances to the nearest wall using the PSD.
The code is written so that it uses two key routines from final.lisp
runMotion that plays the motion turn left etc and
readdistance that reads the PSD sensor. These routines are initially defined in maze2.lisp to allow user to simulate by entering the distance and then printing the motion to be called - so it can be run without a robot attached.
To run fully all that is required is to load final.lisp which will redefine
runMotion and
readdistance to be the actual routines. Call (run_robobuilder) and connect the PC to robot. Select "Basic Posture" and then exit the menu. Now type (maze) and off it goes, showing its its progress on the map!
- Code: Select all
;maze algorithm
(def maze ()
(= px 4) (= py 4) ; assume center of maze
(= pd 0) ; facing up
(= pt '("^" ">" "v" "<")) ; maze turtle character
(= cs 0) ; current state = 0
(clrmap) ; reset map
(while true
(= pd (mod pd 4))
(putmap px py (nth pt pd)) (showmap)
(= d (readDistance))
(if (> 12 d) (back)
(and (is cs 0) (> 30 d)) (do (leftturn90) (= pd (+ pd 3)) (= cs 1))
(and (is cs 1) (> 30 d)) (do (leftturn180) (= pd (+ pd 2)) (= cs 2))
(and (is cs 2) (> 30 d)) (do (rightturn90) (= pd (+ pd 1)) (= cs 0))
(do
(= cs 0)
(forward)
; update map
(putmap px py "*")
(= pd (mod pd 4))
(if (is pd 0) (= py (- py 1))
(is pd 1) (= px (+ px 1))
(is pd 2) (= py (+ py 1))
(is pd 3) (= px (- px 1)))
(if (< px 0) (= px 0) (< py 0) (= py 0) (> px 7) (= px 7) (> py 7) (= px 7))
)
)
)
)
You may well have to tune the motion routines to optimise performance. You you could add a test to see if the robot has fallen over - and if it does, get it to stand up, reset the maze and start again.
Have fun!
In the Robobuilder C programming tutorial there is an application written in C to enable the robot to traverse a maze using the distance sensor. You have to compile it in AVR C and download to the RBC. To make this easier to do, I've converted it to L#/Lsharp.Net. A simple scripting language. It uses the lisp code explained here
http://robosavvy.com/forum/viewtopic.php?t=4800. (Or downloaded as a word document here :
http://robobuildervc.googlecode.com/files/final.doc )
You need final.lisp from here
http://robobuildervc.googlecode.com/files/Lisp.zip to connect to Robobuilder. The maze application code is available here
http://robobuildervc.googlecode.com/files/maze2.lisp
The code builds a map on screen of the maze as the robot moves around. It uses the distance sensor to identify the walls and then the following algorithm:
1. If there is no wall, move forward.
2. If the wall is detected, check left side.
3. If front and left side wall are detected, check right side.
4. If front, left and right side walls detected, go to opposite way.
You can run it in a simulate mode without the robot. Here's an example of it in action:
- Code: Select all
> (maze)
........
........
........
........
....^...
........
........
........
distance ?
: 20
LT90
Run motion 3
Run motion 3
Run motion 3
........
........
........
........
....<...
........
........
........
The program defines a number of simple primitive motions based on the built in motions:
- Code: Select all
(def leftturn90 () (prn "LT90") ( runMotion 3) (runMotion 3) (runMotion 3))
(def leftturn180 () (prn "LT180") ( runMotion 3) (runMotion 3) (runMotion 3) (runMotion 3) (runMotion 3))
(def rightturn90 () (prn "RT90") ( runMotion 5) (runMotion 5) (runMotion 5) (runMotion 5))
(def forward () (prn "FWD") ( runMotion 4) (runMotion 4) (runMotion 5) )
(def back () (prn "BACK") ( runMotion 10))
The maps is created using a simple string to represent 8x8 grid. And some functions that display and show the robot a simple character.
The function
maze then uses these routines to solve the maze, by walking the robot around, and measuring the distances to the nearest wall using the PSD.
The code is written so that it uses two key routines from final.lisp
runMotion that plays the motion turn left etc and
readdistance that reads the PSD sensor. These routines are initially defined in maze2.lisp to allow user to simulate by entering the distance and then printing the motion to be called - so it can be run without a robot attached.
To run fully all that is required is to load final.lisp which will redefine
runMotion and
readdistance to be the actual routines. Call (run_robobuilder) and connect the PC to robot. Select "Basic Posture" and then exit the menu. Now type (maze) and off it goes, showing its its progress on the map!
- Code: Select all
;maze algorithm
(def maze ()
(= px 4) (= py 4) ; assume center of maze
(= pd 0) ; facing up
(= pt '("^" ">" "v" "<")) ; maze turtle character
(= cs 0) ; current state = 0
(clrmap) ; reset map
(while true
(= pd (mod pd 4))
(putmap px py (nth pt pd)) (showmap)
(= d (readDistance))
(if (> 12 d) (back)
(and (is cs 0) (> 30 d)) (do (leftturn90) (= pd (+ pd 3)) (= cs 1))
(and (is cs 1) (> 30 d)) (do (leftturn180) (= pd (+ pd 2)) (= cs 2))
(and (is cs 2) (> 30 d)) (do (rightturn90) (= pd (+ pd 1)) (= cs 0))
(do
(= cs 0)
(forward)
; update map
(putmap px py "*")
(= pd (mod pd 4))
(if (is pd 0) (= py (- py 1))
(is pd 1) (= px (+ px 1))
(is pd 2) (= py (+ py 1))
(is pd 3) (= px (- px 1)))
(if (< px 0) (= px 0) (< py 0) (= py 0) (> px 7) (= px 7) (> py 7) (= px 7))
)
)
)
)
You may well have to tune the motion routines to optimise performance. You you could add a test to see if the robot has fallen over - and if it does, get it to stand up, reset the maze and start again.
Have fun!