Jump to content

Photo

Maze Solving Robot (AKA Sushi shows off at work)


  • Please log in to reply
39 replies to this topic

#1 SushiKitten

SushiKitten

    Coffee Cat

  • Members
  • 1,916 posts
  • LocationCanada

Posted 19 February 2013 - 08:44 AM

I wasn't actually sure where to put this, I figure here.

So I thought it might be fun to show off some of the things I do at work.



Sorry that the camera seems to go out of focus. I took the video on my tablet so the dimensions of the video would be right, but it seems the camera on there isn't the best.

But anyway, the source code for the maze following is here, for anyone who wants a looksie: http://www.pololu.com/docs/0J21/8
And the robot I am using is here: http://www.pololu.co...log/product/975

The key differences between my code and the source code is I chopped up my program into functions, as requested by my supervisor. I also added beeps whenever the robot turns or finds the end of the maze. And I made another function called follow_segment_solved() that just increases the speed. It's called once the robot finishes the maze the first time.

So the point of my job is to experiment with this robot and create a set of labs to be used in the first year programming course. Since all this is online, I have to come up with a way to change the objective of the lab just a bit so the students can't just find the code online and get marks for it. I'm thinking they have to go to certain places before the black dot.

#2 Affray

Affray

    Knower of things

  • Members
  • 5,753 posts
  • LocationThe Great White North

Posted 19 February 2013 - 08:50 AM

That is neat.
Robots are neat.
You are neat.

When you grab the robot after it solves the maze it creeped me out a little.
You slowly reach up on it, then quickly nab it off the table.
Like a predator nabbing a chipmunk.

It is perfectly acceptable to fear and admire a being you could not possibly understand.


#3 SushiKitten

SushiKitten

    Coffee Cat

  • Members
  • 1,916 posts
  • LocationCanada

Posted 19 February 2013 - 08:55 AM

That is neat.
Robots are neat.
You are neat.

When you grab the robot after it solves the maze it creeped me out a little.
You slowly reach up on it, then quickly nab it off the table.
Like a predator nabbing a chipmunk.


Ahah, that was actually me getting a bit confused, I was looking at the screen to get the robot (holding a big tablet with one hand is difficult), but it wasn't where I thought it was, so I just took my eyes off the screen to get it instead.

#4 Guest_ElatedOwl_*

Guest_ElatedOwl_*
  • Guests

Posted 19 February 2013 - 09:17 AM

How much on-board memory does that little guy have access to?

#5 SushiKitten

SushiKitten

    Coffee Cat

  • Members
  • 1,916 posts
  • LocationCanada

Posted 19 February 2013 - 09:30 AM

How much on-board memory does that little guy have access to?


It's got about 32 KB of flash program memory, and 2KB of RAM to work with.

It's very similar to Arduino, but they took out the bootloader for extra memory. To program it, you need an AVR programmer that basically just serially programs the thing for you.

#6 Guest_ElatedOwl_*

Guest_ElatedOwl_*
  • Guests

Posted 19 February 2013 - 09:41 AM

Man, 2KB is pretty small. o-o; I'd envisioned storing all the junctions in memory with each possible path so it could actually like map out the maze but I don't think anything beyond a small maze could fit.

#7 SpleenBeGone

SpleenBeGone

    Deer Leader of the Goriest Revolution

  • Administrators
  • 14,951 posts
  • LocationHouston

Posted 19 February 2013 - 09:47 AM

That's pretty awesome. I need one. >.>
nmjUGDL.jpg

#8 Dasherman

Dasherman

    Megabyte

  • Members
  • 496 posts
  • LocationAzeroth and Sanctuary, simultaneously by using quantum powers

Posted 19 February 2013 - 09:58 AM

Wow, that's actually very cool.
It's one of those, 'if only I had the time' things :( I'm jealous xd
Quis custodiet ipsos custodes?
(//MihiPotestasSit\\)

#9 SushiKitten

SushiKitten

    Coffee Cat

  • Members
  • 1,916 posts
  • LocationCanada

Posted 19 February 2013 - 10:14 AM

Man, 2KB is pretty small. o-o; I'd envisioned storing all the junctions in memory with each possible path so it could actually like map out the maze but I don't think anything beyond a small maze could fit.


That's what I thought it would do when I first started playing with the maze solving program. What it actually does is when it comes across an intersection, take note of which way it went in a small array, every time it has to go back, it discards that route and keeps doing that until it's left with the fastest way to the dot. So it has no idea of the length of the lines or what the map looks like, it only knows to turn whatever way the array tells it to when the sensors see an intersection.

#10 Guest_ElatedOwl_*

Guest_ElatedOwl_*
  • Guests

Posted 19 February 2013 - 10:42 AM

That's what I thought it would do when I first started playing with the maze solving program. What it actually does is when it comes across an intersection, take note of which way it went in a small array, every time it has to go back, it discards that route and keeps doing that until it's left with the fastest way to the dot. So it has no idea of the length of the lines or what the map looks like, it only knows to turn whatever way the array tells it to when the sensors see an intersection.

I'm assuming it would get stuck if the maze did any kind of loop, then?
For example,
Posted Image

#11 SushiKitten

SushiKitten

    Coffee Cat

  • Members
  • 1,916 posts
  • LocationCanada

Posted 19 February 2013 - 10:48 AM

It'd definitely get stuck on that. I'm not sure how to go about that problem. That will probably be my next project. Adding a loop in there and telling students to edit the source code to accommodate it would be a good lab, if it's not too difficult.

#12 Guest_ElatedOwl_*

Guest_ElatedOwl_*
  • Guests

Posted 19 February 2013 - 11:10 AM

You'd need a 2-dimensional resizable array of floats to map out x, y coordinates and to keep track of current position as it moves.

Whether or not you can fit that with everything else into 2kb I do not know.

#13 Guest_ElatedOwl_*

Guest_ElatedOwl_*
  • Guests

Posted 19 February 2013 - 11:34 AM

My curiosity got the better of me. x:

I'd have two arrays like this
[
    [x, y],
    [x, y]
]
[
    [id, id, id, etc.]
]
The first array is the array of all junctions and has an entry for their x, y position
the second array is a relational array (ie, 0th item in the first array is the 0th item in the second array) and has all the directly connecting nodes to it.

I'm assuming no junction would ever have more than 4 possible connecting nodes and there is never going to be more than 255 nodes and that floats are 4 bytes,

each junction (at max) ends up taking 8 bytes for coordinates, 2 bytes for the pointers (I think? not positive on how 2 dimensional arrays are handled in C), and 4 max bytes for all connecting nodes. Assuming we don't want to take up more than 1kb on the map you can support (1024/14) 73 junctions.

#14 SIlhouette

SIlhouette

    Megabyte

  • Members
  • 383 posts

Posted 19 February 2013 - 11:57 AM

I would have done it differently to emo, I would have just had it time between turns if it makes more then 4 turns in the same direction (4 consecutive right turns), then if it comes across two parallel turns that are approximately equal then it is looping, have to make sure it measures all sides in sets of 2 so that it can calculate where it came into the loop and where it needs to exit the loop...

I think his method may be better although I think mine could save more memory space.

Edit (Add) Damn it doesn't work if the intersections are at odd angles... Only works at 90 degree turns.

#15 Guest_ElatedOwl_*

Guest_ElatedOwl_*
  • Guests

Posted 19 February 2013 - 01:27 PM

I would have done it differently to emo, I would have just had it time between turns if it makes more then 4 turns in the same direction (4 consecutive right turns), then if it comes across two parallel turns that are approximately equal then it is looping, have to make sure it measures all sides in sets of 2 so that it can calculate where it came into the loop and where it needs to exit the loop...

I think his method may be better although I think mine could save more memory space.

Edit (Add) Damn it doesn't work if the intersections are at odd angles... Only works at 90 degree turns.

I'm totally confused on your logic - I made a diagram if you have the time to go through it step by step.
Assume the top is north.
Posted Image
As far as mine goes,
start
	set currentPos to 0, 0
	set currentNode to 0
	while(whatever)
		does my current position exist in the map?
			yes: continue
			no: create new node and continue
		set boolean array of paths, in order of N, E, S, W (ie, if theres a path north and west the array would be [true, false, false, true])
		declare allExplored = true
		for(i=0;i<connectedNodes[currentNode].length;i++)
			if(bool && connectedNodes[currentNode][i] != null)
				allExplored = false;
				path unexplored, turn to face
		if(allExplored)
			all paths were explored, some logic here later to determine how to get to an uncharted path
		while(no junction)
			move forward
end

output would end up looking like

0,0
0,1
0,2
0,3
-1,3
-1,2
-1,-1
2, -1
2, 1
2, 2
2, 3
3, 3

find closest unexplored path to be 2,2 headed west

go to 2,2

1, 2
0, 2
-1, 2

find closest unexplored path to be 0, 1 headed east

go to 0, 1

1, 1
1, 2

find closest unexplored path to be 1, 1 headed east

go to 1, 1

2, 1
3, 1


#16 SpleenBeGone

SpleenBeGone

    Deer Leader of the Goriest Revolution

  • Administrators
  • 14,951 posts
  • LocationHouston

Posted 19 February 2013 - 02:36 PM

You've made me interested in just what can be stored in 2kb. >.>
nmjUGDL.jpg

#17 Coconut Man

Coconut Man

    Gigabyte

  • Members
  • 798 posts
  • LocationThe latest Smash Major

Posted 19 February 2013 - 03:07 PM

Is it possible to make a 3 dimensional maze and then make the robot solve it (I mean using ramps n stuff)?

fl9Uov4.gif


#18 Diabolical_Jazz

Diabolical_Jazz

    Gigabyte

  • Members
  • 959 posts

Posted 19 February 2013 - 04:17 PM

Just remember: When it eventually turns to you, beeps, and asks, "Does this unit have a soul?"

Don't kill it. :mellow:

Anyway, awesome! ^__^
I don't think he needs to be immortal. I think all he needs to do is to write the right story. Because some stories do live forever.

#19 Coconut Man

Coconut Man

    Gigabyte

  • Members
  • 798 posts
  • LocationThe latest Smash Major

Posted 19 February 2013 - 04:55 PM

It won't if you give it a red wig.

fl9Uov4.gif


#20 SIlhouette

SIlhouette

    Megabyte

  • Members
  • 383 posts

Posted 19 February 2013 - 11:12 PM

I'm totally confused on your logic - I made a diagram if you have the time to go through it step by step.
Assume the top is north.
Posted Image
As far as mine goes,

start
	set currentPos to 0, 0
	set currentNode to 0
	while(whatever)
		does my current position exist in the map?
			yes: continue
			no: create new node and continue
		set boolean array of paths, in order of N, E, S, W (ie, if theres a path north and west the array would be [true, false, false, true])
		declare allExplored = true
		for(i=0;i<connectedNodes[currentNode].length;i++)
			if(bool && connectedNodes[currentNode][i] != null)
				allExplored = false;
				path unexplored, turn to face
		if(allExplored)
			all paths were explored, some logic here later to determine how to get to an uncharted path
		while(no junction)
			move forward
end

output would end up looking like

0,0
0,1
0,2
0,3
-1,3
-1,2
-1,-1
2, -1
2, 1
2, 2
2, 3
3, 3

find closest unexplored path to be 2,2 headed west

go to 2,2

1, 2
0, 2
-1, 2

find closest unexplored path to be 0, 1 headed east

go to 0, 1

1, 1
1, 2

find closest unexplored path to be 1, 1 headed east

go to 1, 1

2, 1
3, 1


Yours would not work either since it doesn't discern distance, If it traveled from (-1, 2) to (-1, -1) it would actually assume it was at (-1, 1) what I propose is a timer which times the time taken between turns.

Attached File  Maze Example.png   2.64K   2 downloads

If it started at the right and traveled to the left then headed to the end and turned left then followed the loop for 3 more turns so it is back at the start of the loop. My logic is it then starts the loop again and times the turns, it would read 1.5, 1, 1.5, 1 since parallel lines on a rectangle have the same distance it would now have the information to know that it has traveled the entire rectangle since all parallel sides were equal It could then go to the turn stored after the loop and know where to leave.

I haven't done coding in about 7 years so forgive this...

If turn left.counter = 4 then
turn left(starttimerloop)
Else delete left.counter


Starttimerloop

get time.a
turn left
get time.b
turn left
get time.c
turn left
get time.d

If Time.a = Time.c and Time.b = Time.d then
travel a + b
Turn right or straight until time.e =/= time.a or time.b................. et cetera





As I said before, sorry about my lack of syntax for this. I can't see any logic errors though and this code assumes there is a certain logic in the robots methodology for figuring out the maze, which it can return to one a loop has been flagged it also assumes a geometric world of 90 degree angles. Once a loop is flagged it can delete the information from the loop and just remember the second L turn.

From what Sushi said I gather it just has a 1D array simply stating L, R, S, S, L ,R for its solved path when it finds a dead end it inverses the last turns made until it reaches another branch and deletes that information. My method uses its old framework but just adds a timer after storing a L, L, L, L or R, R, R, R so it becomes L(1.5), L(1), L(1.5), L(1).

Edit (Add) After watching the video it confirmed my theory that it "keeps its right hand on the wall" as its method for solving the maze, that is it prioritizes R over L until it discounts that area then it travels backwards along the incorrect path and inverts the R to L or L to R then discounts that branch and continues prioritizing R over L. Mine could be used under this existing framework assuming the robot has a timer function.