while(counter<20)//allows for recycling until robot is found { x=0; y=0; while(x<6 || y<6)//while the map hasnt been fully scanned{//if this location is a wall or the goal, just ignore itif (map[x][y] != wall && map[x][y] != goal){//a full trail to the robot has been located, finished!if (min_surrounding_node_value(x, y) < reset_min && map[x][y]==robot){printf("Finished Wavefront:\n");print_map();//tell robot to start moving down pathreturn min_node_location;}//record a value in to this nodeelse if (minimum_node!=reset_min)//if this isnt here, 'nothing' will go in the locationmap[x][y]=minimum_node+1;}//go to next node and/or rowx++;if (x==6 && y!=6){y++;x=0;}} printf("Sweep #: %d\n",counter); print_map(); counter++; } return 0;}

//this function looks at a node and returns the lowest value around that nodeint min_surrounding_node_value(int x, int y){minimum_node=reset_min;//reset minimum

//go to next node and/or rowy++;if (y==6 && x!=6){x++;y=0;}and I have since been unable to reproduce that strange error again. I have no idea why, and I suspect that the error is still hiding in there somewhere . . .

hey Admin,so i'm too tired to dig into your code too much right now but there does seem to be a definite pattern in the output.it appears that as the program gets to the end of each line, it is overlapping into the first value of the next line.

strange that you are not getting the same symptoms now you have changed the scan order.what about if the goal is above the robot on the map?

heh. i feel your pain.i was faced with a similar problem a few months ago with my inter ic network protocol.it turned out to be a buffer overflowing in a certain set of conditions.perfectly obvious one i had worked out what was going on but brain melting trying to spot where it was happening in the first place.

Quote

I can give you all the code to play around with the map if you want . . .

heh, i'll be too busy with my own mapping algorithm soon.i finally have my latest bot's hardware and firmware as i want it.it all becomes a programming challenge from here on which is nice considering how little time i'm at home to work on it.

There are 2 mistakes in your code which are both required for the problem to appear:

1. An array defined like this: int map[6][6] should be accessed like this: map[y]

= 5;

In other words, the "most significant" coordinate should be first. I can tell that in your case, the most significant coordinate is y, by the way you print your array - when printed it looks the same way it does when it's defined. This means the horizontal (x) coordinate is less significant, and the vertical (y) coordinate is more significant (for every single y, there are 6 x's). So you should access your array like this: map[y]

= 5. Not the other way around.

2. You wrote "while (x != 6 || y != 6)". || stands for logical OR. You probably need to replace it with && which is AND.In your loop, when y becomes 5, x goes from 0 to 5, and then x returns to 0, and y becomes 6. But then the condition is still met, because one of the two coordinates is not 6. So the loop continues when it shouldn't, with y=6. Because we agreed in 1 that you handle your coordinates in reverse, it is actually the horizontal coordinate (which you call "y" by mistake) that becomes 6. In memory, the 6th coordinate in a line is next to the 5th in that line, but it is also the 1st coordinate in the NEXT line. So in the function that looks for a local minimum you look at the 6th coord in a certain line, and place some value in it (because of what's in the 5th coord), but actually you placed that value in the 1st coord of the next line.When you changed the order of the loop and advanced x instead of y, you no longer see the problem because the 6th position of x (the vertical coord) is completely outside the array (which is still bad).

So, in short, wherever you access the array (except in the print_map function which seems to be fine) you should access it with y first (map[y]

). And change the || condition into a && condition. It doesn't matter in what order you advance the coords.

I wrote all the details above because I spent a few minutes figuring out the problem, and it would be a shame if I just told you how to correct it and you'd have to spend more time trying to understand why it works, when I've already done it.

You wrote "while (x != 6 || y != 6)". || stands for logical OR. You probably need to replace it with && which is AND.

Thanks! That fixed it! Man, Im a moron . . . That error was also causing my robot software to completely fail outside of simulation, so this also fixed the robot too!

Quote

heh. i feel your pain.i was faced with a similar problem a few months ago with my inter ic network protocol.it turned out to be a buffer overflowing in a certain set of conditions.perfectly obvious one i had worked out what was going on but brain melting trying to spot where it was happening in the first place.

I knew something like this would happen, which is why Im simulating it on my computer before transferring the code to the robot . . .

Quote

heh, i'll be too busy with my own mapping algorithm soon.

What kind of mapping algorithm?(do tell!)

This current wave front algorithm Im working on requires encoders on my robot, but in the future I want to design it so no encoders are required . . . some form of simplified SLAM.

I should have a tutorial with source code on the wavefront algorithm in like a week or so. The very first one to be written for the entire internet (Im trying to feel special right now).

Thank you for even more great tutorials! Cant wait to get my parts so I finally can start some basic stuff to get me started.

I have a few very simple questions about the path finding: How do you create the grid? I can see how it could be easily created from a camera above, but how is it done with a IR sensor mounted so low? How do you give it a destination to go to? Is it instructed to simply go 5 units straight ahead or is there something more behind it?

How do you create the grid? I can see how it could be easily created from a camera above, but how is it done with a IR sensor mounted so low?

I put an empty matrix (in this case, a 6 x 6 map) in its memory. When it detects an object with a scan, it adds it to the map in memory. Then it recalculates a new path.

Quote

How do you give it a destination to go to? Is it instructed to simply go 5 units straight ahead or is there something more behind it?

I preprogrammed the goal into the map in memory. In reality, the proprogrammed location could be a can of beer in your fridge You could also preprogram multiple goals, and have it chose a particular goal for whatever reason. The source code easily allows this (check the tutorial).

Quote

Does it stop to scan or to calculate?

Both. The scan takes up to a second (depending on what it sees). The calculation takes like .1 seconds. For larger maps it would take longer. I didnt make the wavefront efficient . . . was too lazy . . . whats .1 seconds anyway?

Thanks for explaining it. One last thing, can the robot move outside the 6x6 matrix? If so, how does it do it? I assume you dont use C, so you dont have direct access to the fast vector structure for example

Not yet . . . mostly been too lazy. I probably should though . . . Ill get on it in the next few days I think. If I dont, it will just sit in the corner until I forget how the code works like all my other old robots . . .

Quote

Is matrix manipulation very costly to do?

So in a typical 6x6 map it sorts through the matrix about 20-30 times per calculation. It depends a lot of obstacle locations, goal location, and start location. I would assume a map with 4x the node number would on average take 4x as long. Perhaps half a second at most?

I didnt implement another method that would halve computational time, but I could.

About the 90 vs 45 degree angle thing... Look up Field D* by Fergusun and Stentz. There is also a multi-resolution Field D* that helps with memory and speed requirements in sparse environments. Also, from what I understand D* will be faster at re-planning in large environments but is trickier to implement.

Use a dynamic array (a vector).. build a compass into your robot and let it run around the house, dynamicly resizing the array (using the sensor and a simple algorithm) when it:

sees an open spot

is at the border of the pre-programmed array

Build in a small information storeage to remember the information and it last known position. Heck, build in an algorithm to find it's location based on its readings (for example (0 = open, 1 = not-open) : If this is the array, and the robot is at R, make it drive left, check position... 4 steps right, check position, one up check position, two left check positions. If they're all 1, the robot knows where it is...

I think it'd be easier if I just create one giant matrix and just fill in the map as the robot goes. Knowing the size of my bot and the size of my house, I can calculate how big I need the matrix to be. Nothing wrong with using all the memory on a microcontroller if I dont need it all.

Any area on the matrix that is marked as an obstacle requires is basically ignored by my algorithm so as obstacles get added, it will take less and less processing power . . .

Ill try this out the next chance I get . . . Ill try to improve dead-reckoning and operate the bot only on hardwood floors to improve the encoder accuracy.

Here is a question . . . so when the robot cannot find a clear path I have it delete its entire map to start over. This works really well for small maps. But for large maps this is bad because travel/scan time is expensive . . . anyone can think of an intelligent way to rescan previously blocked areas efficiently? A scan takes between .3 and 2 seconds . . . I can think of a few ideas but they all have flaws . . .

Question 1:Can you use some external flash or EEPROM memmory on these MCUs? Maybe buy the now cheap 1Gb thumb drives, rig it to work with the MCU, and bingo! Near limitless (relatively ) memmory for your bot... would something like that work?

Question 2:Can MCUs handle 3D arrays? Add a height plain to the equation? That would be sweet.

This is the whole problem I'm having in my design (it's a problem in any map building algorithm)Adding is easy but to take away intelligently.... that is an issue. I'm on my lunch break so I don't havetime to explain what I'm planning but it will definitely not work on a normal micro on the scale I'm workingbut... after work I'll do some explaining...

Here is a question . . . so when the robot cannot find a clear path I have it delete its entire map to start over. This works really well for small maps. But for large maps this is bad because travel/scan time is expensive . . . anyone can think of an intelligent way to rescan previously blocked areas efficiently? A scan takes between .3 and 2 seconds . . . I can think of a few ideas but they all have flaws . . .

i haven't implemented this yet but i intend to mark each positive sensor hit with a value dependant on the reliability of the sensor "seeing" it.i will then degrade all the values over time so eventually the bot will forget about objects it has not seen for a long time.

if a sensor thinks an area is clear where in the past there was an object that positions value will be degraded by an amount depending on the reliability of the sensor.

in this way it may take a few sensor readings that show a position has become clear before a bot trust's it's sensors.

this way of doing things has the nice bonus of helping with the problem of accumulative error in the bot's position. if correctly calibrated the map will fade as the error relative to those points builds up.

dunk, your idea wont work well for really large maps . . . the forget delay would need to be a function of map size, but i can see cases where:

A) the delay time is guessed/tweaked by the programmerB) control oscillations from new paths suddenly appearing because of forgetting obstaclesC) moving objects near the robot (highest probability of error) would be the freshest in memoryD) very large maps would need a very long forget delay - or the robot would forget the first half of the map while it explores the second half

Perhaps the solution is not a software thing, but I just need a much faster/better scanning algorithm . . . or maybe i should use beacons so the bot can occasionally realign the map to the world . . .