03/15/15 – The ides of March!
It’s been a while since I’ve posted on the progress of our wall-following robot project. The last post talked about some significant remodeling goals, and most of those have been accomplished. The 4 AA batteries have been replaced by 2ea Sparkfun 3.7V 2000mAH Li-ion batteries, the motor driver board was moved to the top of the robot platform, and the front ping sensor was installed on the ‘new front’ (remember, I turned the robot around when I discovered the side-mounted ping sensors were causing regenerative feedback?). However, I didn’t install the two additional side-mounted ping sensors as planned – at least not yet. Here are some photos of the remodeled robot.
One significant change that came out of the remodeling effort was the decision to abandon the idea of having Wall-E recharge itself. It was pretty clear from results so far that getting Wall-E into a precise enough position/orientation to engage a charging plug was going to be very difficult, even with some sort of guide-in rails. Plus there was the problem of getting Wall-E disengaged and going again at the end of the charging cycle. So, a new plan was hatched to have Wall-E ‘yell for food’ with some sort of audible signal. Since I’m an ex-Ham Radio operator, I immediately thought of adding a Morse code capability to the robot, and it turned out Danny was interested in Morse code too, so… Now all we had to do was figure out how to get Wall-E to speak Morse, along with everything else it was doing. Our first try at this used Arduino’s non-blocking tone(pin, frequency, duration) function to generate the dots and dashes, but it turned out the duration of each tone wasn’t anywhere near accurate enough for this. Wall-E sounded like a very drunk radio operator with dots sounding like dashes and dashes running on forever. The solution to this was to change to the blocking version of tone(pin, frequency)/noTone(pin), but this meant Wall-E couldn’t be moving while sending Morse – bummer! As it turned out though, I had been playing around with Adafruit’s Trinket microprocessor as a possible replacement for the Arduino Micro in our Enders Game Flashgun project, so I decided to try and use a Trinket as an auxiliary Morse code processor. After the normal amount of muttering and teeth-gnashing, the Trinket, along with a Sparkfun RedBot Buzzer wound up working pretty well! +Vbatt for the Trinket is supplied through one of the Arduino’s digital I/O pins; when the Arduino senses that the battery voltage is getting too low, it simply powers up the Trinket and parties on, and the Trinket does the ‘Yell for food’ stuff independently.
After re-installing the front ping sensor on the new front end of the robot, I had to decide how to sense the ‘stuck’ condition. Originally I was doing this by detecting the condition where sequential front ping distances were identical – i.e. the robot wasn’t moving (at least not in the forward direction). This worked, but there were problems. First, I had to exclude ping distances of zero, as zero is also returned when the ping distance is greater than the maximum (200cm in my case). This meant that if Wall-E got stuck with it’s snout right up against an obstacle, the real distance could be zero, and then the ‘stuck’ condition would never be detected. In addition, there was the problem of integer truncation int the ping distance return value from ping(). If Wall-E is moving slow enough, or the pings happen fast enough, then two identical distance values could happen naturally – oops! I could address the adjacent ping/speed issue by spacing out the front distance checks in time so that any reasonable robot speed would produce at least 1cm travel, but there didn’t appear to be any way to address the real-zero-distance problem. So, I decided to change the ‘stuck’ detection logic to simply declare ‘stuck’ whenever Wall-E got within some minimum distance (10cm to start) of an obstacle. This turned out to be much simpler to implement, more robust, and maybe even extensible to more complex situations in the future.
After running some wall-following and obstacle avoidance trials (see first movie below), it appeared that Wall-E was doing so well that it might be time to try a ‘tail trial’ or two to see what the cats thought of a mobile prey animal. Turned out that Yori (the outgoing cat) was right on top (literally) of the situation, but Sunny (the wall-flower cat) ignored the whole thing – see the second movie below.
One of the things I noted from recent runs is that Wall-E will occasionally break out of wall-following mode and nose-dive into the nearest wall. After seeing this happen a number of times, I’m beginning to believe this is another unintended consequence of having the side ping sensors so far ahead of the axis of rotation. When first we visited this saga, I had just discovered that the side ping sensor placement behind the center of rotation was setting up a regenerative feedback loop that caused Wall-E to over-correct wildly. Moving the sensors ahead of the axis of rotation (actually what I did was simply redefine Wall-E’s ‘front’ and ‘back’) changed the feedback loop from regenerative to degenerative allowing Wall-E to successfully follow walls. However, it turns out that this ‘fix’ isn’t quite as clean as I had thought. For the first few degrees of rotation around the axis, the near-side ping sensor moves directly toward the wall, giving the required negative feedback. However, if the rotation goes beyond about 30 degrees, then the distance returned by the near-side ping sensor may start to go back up, as the point on the wall pointed to by the ping sensor moves away from the perpendicular. I speculate this acts like a variable phase shift, and at some point it shifts enough so the loop feedback sign changes – oops! The fix for this is to either move the left/right ping sensors nearer to the axis of rotation and/or incorporate additional left/right sensors at the axis of rotation to provide a distance term that doesn’t change significantly with robot rotation.
Another thing that I saw from this last round of trials is that I need to add some wheel covers to Wall-E, to prevent the wheels from hanging up on chair legs. Not quite sure how to do this yet, but…