I have mounted a sonar on a servo and am scanning let/right (a la Stampy Edge detection) and storing the distance values in an array - which I later examine to move in the direction 'of least resistance'.
So this leads to a number of issues/challenges:
1 - If the robot is going 'full steam ahead' then the values from left to right aren't comparable, because if there's a wall dead ahead and at right angles to the 'bot, and we use the sonar to read left to right, then the readings don't take into account that the robot is moving. So scanning from left to right then the left value thinks the wall is further away than the right value - as by the time we take the right reading then the robot is closer to the wall. This error is therefore linear to the speed of the robot.
2. If the robot is very close to something then I make it spin on itself. Since you are spinning then the left to right values are quickly out of date unless you spin'a'bit, re-scan from left to right and then decided what to do. So the error is linear to the rotation of the robot.
So the total error is a function of the forward velocity and the speed of rotation.
Of course you could spin the sonar servo faster than the wheels so that these problems disappear (ie one step fwd, stop, re-scan sonar left to right, repeat) but it doesn't feel correct and will make the bot into a slug where the sonar does all the work. Bear in mind there is a max sampling rate for the sonar so as to avoid ghost echoes - ie the the cycle time to scan all positions from left to right can take a few 100ms.
So it seems that 2 things lead to errors:
1 - Forward velocity (as the time to scan from left to right will mean that the robot has moved so the sonar values become out-of-date)
2 - Speed of rotation (if the robot is spinning on its own axis then the current sonar values are quickly out-of-date)
So there is a link between 'forward velocity' and 'speed of turn' as both of these quickly invalidate your scan of the world ahead. Yes - you can fix this by stopping, resampling the world ahead, etc but this will severely restrict the overall speed. ie if the sonar can be pinged every 50ms (as any quicker may cause ghost echoes) and you have 7 positions (from extreme left to extreme right) then thats 350ms to which you have to add the delay it takes to move the servo holding the sonar to each of these positions.
No - I don't have an encoder on the wheels so I can't alter the values between sonar readings by knowing how far I have traveled since the last reading.
Does this error matter? Well - maybe? Lets assume we are heading straight at a wall at 1cm per reading and we are using sonar to scan from left to right we might get readings of:-
10 09 08 07 06
So we decide to head left since that says the wall is furthest away (10cm).
But on the next scan the sonar is now going from right to left and we are still heading for the wall. So now we get:-
06 05 04 03 02
So now we decide to go right(06cm).
Repeat the two steps and the robot makes a perfect S shape straight into the wall !!
So how do we fix this (without encoder hardware)?
Only solution I can think of is to somehow massage the figures based on what we ASKED the motors to do via software (as opposed to what they DID do via an encoder). ie if we have a rough idea of how fast the robot is meant to be going forward then we can sort of fudge the values to represent values at a given time interval.
Still think this may mean S'ing into the wall if it's not correct. (Is S'ing a new swear word!).
Over to you more clever folk for an obvious and easy answer