LIDAR-Lite Rotates!

Posted 5/29/15

In previous posts I described a couple of LIDAR alternatives to my original ultrasonic ping sensor system for Wall-E’s navigation capabilities, and the challenges I faced in implementing them.  The LIDAR-Lite module is easily interfaced to an Arduino controller via the I2C interface and there is  plenty of example code for doing this.  However, in order to use it as the primary navigation sensor, it needs to spin at a controlled 1-5 RPS (60-300 RPM) and there has to be a way to determine  the rotational  angle associated with each distance measurement.  In a previous post (http://gfpbridge.com/2015/05/dc-motor-speed-control-using-optical-tachometer/) I described my experiments with one of Wall-E’s wheel motors to implement speed control using an IR LED/photodiode/toothed-wheel tachometer.

After successfully implementing speed control on Wall-E using the right wheel motor, I next turned my attention to implementing a drive train to connect the wheel motor to the LIDAR Lite unit.  I couldn’t just connect the LIDAR module to the motor shaft, as the LIDAR wiring would simply wrap itself to death as soon as the motor started turning.  I had previously acquired the  slip ring module  (described in  http://gfpbridge.com/2015/04/robot-of-the-future-lidar-and-4wd/) shown below

Adafruit Slip Ring with 6 contacts

Adafruit Slip Ring with 6 contacts

So I needed a way to connect the rotating part of the slip ring to the LIDAR module, and the non-rotating part to the robot chassis and (via a drive belt) to the motor shaft.

In TinkerCad, I designed a grooved pulley with a rectangular cross-section axial hole to fit over the motor shaft, an  adapter from the rectangular LIDAR mounting plate to the cylindrical slip ring rotating side, and a chassis mounting bracket that would allow the non-rotating side of the slip ring to be adjusted toward and away from the motor shaft pulley to properly tension the drive belt.  The drive belt is a standard rubber O-ring from McMaster Carr.

Now that I have motor speed control working and the LIDAR spinning, I need to connect the LIDAR electrically to the Arduino Uno controller and see if I can actually collect angle-specific LIDAR distance data (distance from the LIDAR, angle from the wheel speed tachometer control software).  Stay Tuned!

Frank

 

LIDARMountChassisBracket LIDARMountChassisSlipRing LIDARMountLIDARBracket LIDARMountMotorPulley

Spinning LIDAR drive assembly and LIDAR unit.  Note O-ring drive belt.

Spinning LIDAR drive assembly and LIDAR unit. Note O-ring drive belt.

 

DFRobots ‘Pirate’ 4WD Robot Chassis

Posted 5/28/15

A while back I posted that I had purchased a new 4WD robot platform from DFRobot (http://www.dfrobot.com/), and it came in while I was away at a bridge tournament. So, yesterday I decided to put it together and see how it compared to my existing ‘Wall-E’ wall-following platform.

The chassis came in a nice cardboard box with everything arranged neatly, and LOTS of assembly hardware.  Fortunately, it also came with a decent instruction manual, although truthfully it wasn’t entirely necessary – there aren’t that many ways all the parts could be assembled ;-).  I had also purchased the companion ‘Romeo’ motor controller/system controller from DF Robot, and I’m glad I did.  Not only does the Romeo combine the features of an Arduino Leonardo with a motor controller capable of 4-wheel motor control, but the Pirate chassis came with pre-drilled holes for the Romeo and a set of 4 mounting stand-offs – Nice!

So, at this point I have the chassis assembled, but I haven’t quite figured out my next steps.  In order to use either the XV-11 or PulsedLight LIDAR units, I need to do some additional groundwork.  For the XV-11, I have to figure out how to communicate between the Teensy 2.0 processor and whatever upstream processor I’m using (Arduino Uno on Wall-E, or Arduino Leonardo/Romeo on the Pirate).  For the LIDAR-Lite unit, I have to complete the development of a speed-controlled motor drive for rotating the LIDAR.  Stay tuned!

Frank

Parts, parts, and more parts!

Parts, parts, and more parts!

Motors installed in side plates

Motors installed in side plates

Side plates and front/back rails assembled

Side plates and front/back rails assembled

Bottom plate added

Bottom plate added

Getting ready to add the second deck

Getting ready to add the second deck

Assembled 'Pirate' chassis

Assembled ‘Pirate’ chassis

Side-by-side comparison of Wall-E platform with Pirate 4WD chassis

Side-by-side comparison of Wall-E platform with Pirate 4WD chassis

Over-and-under comparison of Wall-E platform with Pirate 4WD chassis

Over-and-under comparison of Wall-E platform with Pirate 4WD chassis

Optional 'Romeo' motor controller board.  Holes for this were pre-drilled in the Pirate chassis, and mounting stand-offs were provided - Nice!

Optional ‘Romeo’ motor controller board. Holes for this were pre-drilled in the Pirate chassis, and mounting stand-offs were provided – Nice!

Fun with the NEATO XV-11 LIDAR module

Posted 05/23/15

In my last post (DC motor speed control using optical tachometer) I described my effort to implement  a speed controller for one of Wall-E’s wheel motors so I could use it as the drive for  a spinning LIDAR  system using theLIDAR-Lite unit from  PulsedLIght (http://pulsedlight3d.com/products/lidar-lite).  Although I got the speed controller working, delivery of the 4WD robot chassis I had ordered to carry the LIDAR-Lite system was delayed so I couldn’t fully implement the system.  In the meantime, I decided to play with the NEATO LIDAR unit I had acquired from eBay.

The NEATO XV-11 unit is a very cool self-contained spinning LIDAR unit intended for use in the NEATO robot vacuum cleaner.  I find it interesting and amusing that such a  technically elegant and useful module was developed for what is essentially a luxury toy, and  that it is available to hobbyists for a reasonable price!  The bad news is that the XV-11 emits a binary data stream that requires a fair bit of processing to make useful.  Fortunately for us mere mortals, Get Surreal (http://www.getsurreal.com/) produces a Teensy-based XV-11 controller (http://www.getsurreal.com/product/xv-lidar-controller-v1-2) that does most of the work; it has connectors to mate with the XV-11 on one end, and a USB connector on the other for data retrieval/control.  All that is required is an upstream USB  device with a serial monitor of some sort.  In my case, I used my laptop  and the RealTerm serial monitor (http://sourceforge.net/projects/realterm/) to do the job.

As an experiment, I placed the XV-11 in a 14 x 14 inch cardboard shipping box, and connected it up.  After capturing some processed data  using my laptop and RealTerm, I sucked the processed data into Excel 2013 for analysis.  The data transmitted by the Get Surreal Teensy controller is formatted as colon and space delimited (angle, distance, SNR) triplets.  Angle is in integer degrees, distance is in mm, and SNR  is an integer in parentheses with 0 representing missing data, and large numbers indicating high SNR.  At the end of each 360-degree set of data, the XV-11 reports the elapsed time (in integer millisec) for the previous data set.  The screenshot below shows the last few lines of a complete 360 degree dataset, along with the elapsed time value.

Last few items in a complete dataset, along with the elapsed time report

Last few items in a complete dataset, along with the elapsed time report

Excel – at least the 2013 version – is a very cool data analysis program.  Not quite as cool as MATLAB (which I used a  lot as a research scientist at Ohio State), but still pretty good, and nowhere near as expensive (it was free for me at the university, but it is very expensive for civilians).  Excel’s graphing routines are amazingly powerful and easy to use – much better IMHO than MATLAB’s.  In any case, I used Excel to graph some of the XV-11 data I had just captured.  I started with Excel’s stock polar graph (it’s called a Radar plot in Excel), and got the following plot with absolutely no effort on my part (other than selecting the Radar plot type)

Stock Excel Radar Plot for 360 degree data set.

Stock Excel Radar Plot for 360 degree data set.

This appears to be an excellent representation of the actual box, with a few data points missing (the missing points had SNR values of zero, so I could easily have gotten Excel to disregard them).  Although I had physically placed the XV-11 in the box in such a way as to be parallel with the sides of the box, the data shows a tilt.  This is due to the way that the XV-11 reports data – 0/360 degrees is  not the physical front of the device – it is offset internally by about 11 degrees (no idea why)

As my original Wall-E robot was conceived as a wall-following device, I was interested in using the LIDAR data to do the same thing – follow the walls.  So, I converted the polar (angle/radius) data into X/Y coordinates to see if I could condense the data down to something I could use for wall guidance.  The next plot is the same dataset as in the above plot, but converted to X/Y coordinates.

XV-11 Dataset converted to X/Y coordinate system

XV-11 Dataset converted to X/Y coordinate system

This, although perfectly understandable given the box environment, wasn’t really helpful as a possible wall-following algorithm, so I decided to look at the line slope instead of just the raw X/Y coordinates.  This gave me the next Excel plot, shown below.

Calculated line slope m = dY/dX for XV-11 dataset

Calculated line slope m = dY/dX for XV-11 dataset

This plot was interesting in that it definitely showed that there were only two slopes, and they were the negative reciprocals of each other, as would be expected from a box with two sets of parallel sides perpendicular to each other.   Also, having only two values to deal with vastly simplifies the task of making left/right steering decisions, so I thought maybe I was on to something for LIDAR Wall-E.

As I drifted off to sleep that night, I was reviewing my results so far when it occurred to me that I was thinking of the problem the wrong way – or maybe I was trying to solve the wrong problem.  I was trying to use LIDAR data to follow walls a la Wall-E, but what I really wanted to do was have the robot navigate typical indoor layouts without getting stuck anywhere. I had chosen a wall-following algorithm because that’s what I could do with ultrasonic ping sensors.  Another possible way to solve the  problem is to have the robot move  in the direction  that offers the  least restriction; i.e. in the ‘most open’ direction.  This would be very difficult to accomplish with ping sensors due to their limited range and inherent multipath and fratricide problems.  However, with a LIDAR that can scan the entire 360 degrees in 200 msec, this becomes not only possible, but easy/trivial.  So, the new plan is to mount the XV-11 LIDAR on Wall-E, and implement the ‘most open in the forward direction’ algorithm.  This  should result in something very like wall-following in a long hallway, where the most open forward direction would be along the length of the hall.  When the robot gets near the end of the hall, then either the left or right perpendicular distance will become ‘the most open’ direction which should cause Wall-E to make a hard right or left turn, followed by another same-direction turn when it gets close to the other wall. After the two right-angle turns, Wall-E should be heading back down the hall in the opposite direction.

Stay tuned…

Frank

 

DC motor speed control using optical tachometer

Posted 04/13/15

In my last post I described my plans for upgrading Wall-E (my Wall-following Robot) with a LIDAR package of some type, and my thought that I might be able to use such a package to not only replace the existing front-facing ping sensors, but (with a bit of rotating magic) the side sensors as well.

In order to replace *all* the sensors, the LIDAR package would have to rotate fast enough so that it could produce front, left, and right-side distance readings in a timely enough fashion to actually implement wall-following.  I’m not sure exactly what the requirements for wall-following are, but I think it’s safe to say that at least the measurements to the followed wall must be in the several-per-second range, or Wall-E could run into the wall before it figures out it is getting too close.  The other side, and the front could be taken at a more relaxed pace if necessary, but the wall being tracked has to be done correctly.

In order to rotate a unit such as the LIDAR-Lite from PulsedLight, I would  need a speed-controlled motor of some kind.  I considered  both stepper motors and direct-drive DC motors.  Since I already had two DC motors (the left and right wheel motors on Wall-E) and they came with ‘tachometer sensors’ (plastic disks with slots for optical wheel motion sensing), I thought I’d give this a try.  Earlier in my robot startup phase, I had obtained  some IR LED/Photodiode pairs, so I had at least the basic building blocks for a tachometer system.  I was  already speed-controlling Wall-E’s wheel  motors for steering using PWM from the Arduino Uno, so that part was already in place.  ‘All’ I had to do was couple the input from a tachometer into the already-existing PWM speed control facility and I would have a closed-loop speed-controlled rotating base for my LIDAR system – cool!

OK, so now I have all the parts for a speed-controlled motor system – I just have to assemble them. First up was a way of mounting the IR LED and IR detector in such a way that the slots in the tachometer wheel would alternately make and break the light path between them.  In the past when I had to do something like this, I would carve or glue something out of wood, or bend up some small pieces of aluminum.  However now I have a very nice 3D printer and the TinkerCad design package, so I could afford to do this a different way.  The confluence  of hobby robotics and 3D printing allows so much more design/development freedom that it almost takes my breath away.  Instead of dicking around for a while and winding up with something half-assed that is used anyway because it is way too much trouble to make another  -better – one, a 3D printer based ‘rapid iteration’ approach allows a design to  be evolved very quickly, with each iteration so cheap as to be literally throw-away.    To illustrate the approach, the image below shows the evolution of my IR LED/IR detector bracket, along with the original 20-slot tachometer wheel that came with the motors and a 10-slot version I printed up as a replacement (the tach signal-to-noise ratio was too low with the 20-slot original).

Evolution of an IR tach sensor bracket, along with the original and a custom-printed tach wheel

Evolution of an IR tach sensor bracket, along with the original and a custom-printed tach wheel

The evolution proceeded from left to right in the image.  I started with just a rectangular piece with a horizontal hole to accommodate the IR LED, and a threaded hole in the bottom to affix it to the robot chassis.  Then the design evolved a ‘foot’ to take advantage of a convenient slot in the robot chassis, for physical stability/registration purposes.  Then I added a second side with a slot in it to accommodate the  IR detector, with the tach wheel passing between the two sides.  This basic two-sided design persisted throughout the rest of the evolution, with additional material added on the IR LED side to accommodate the entire length of the IR LED.  Not shown in the photo are some internal evolutionary changes, most notably the width of the slot that allows IR energy from the LED to fall on the detector – it turns out that the detector opening should be about 1/2 the width of a tooth slot for best signal.  Each step in the above evolution cost me about 30 minutes of design time in TinkerCad, and a few pennies worth of filament.  Moreover, once I have the end design, printing more is essentially free.  Is that cool, or what?

Wall-E's right motor being used as my tachometer test bed

Wall-E’s right motor being used as my tachometer test bed.  Note the piece of scotch tape on the wheel, used for manually timing RPM.

Tachometer sensor bracket, showing IR LED and tach wheel

Tachometer sensor bracket, showing IR LED and tach wheel

Tachometer sensor bracket, showing slot for the IR detector

Tachometer sensor bracket, showing slot for the IR detector

Since I was already controlling the speed of Wall-E’s motors with an Arduino Uno (albeit for steering), I simply modified the wall-following program to act as a test driver for the tach feedback system.  The output of the IR detector was connected to an analog input, and the analog readings were captured and imported into an Excel spreadsheet for analysis.

The first test showed that I wasn’t getting enough signal swing between the slot and non-slot (plug) states of the tach wheel (less than 100 out of a possible 1024 levels), and this led me to start experimenting with different IR detector apertures.  As shown in the second plot below, constricting the aperture provided a marked improvement in SNR (about 3 times the peak-peak variation).

First test of the tach sensor system.  Note the not-impressive variation between wheel slot and plug readings

First test of the tach sensor system. Note the not-impressive variation between wheel slot and plug readings

Paper barrier with a small slot placed in front of detector aperture

Paper barrier with a small slot placed in front of detector aperture

The above results led directly to the final round of evolutionary changes to the tach sensor bracket, where the detector aperture was changed from a large circle (same diameter as the IR LED) to a small slit.  In addition, to further improve the SNR, the tach wheel itself was redesigned from 20 slots to 10  with  the slots and plugs equal area.  In addition one slot was removed to create an absolute wheel position ‘index mark’.  After these changes, the tach sensor test was redone resulting in the following plot.

IR Detector response with a narrow slit aperture and a 10-tooth wheel.

IR Detector response with a narrow slit aperture and a 10-tooth wheel.

Now the signal varies from 0 to 800, allowing easy and reliable ‘off’ to ‘on’ state detection, and index mark detection.

After incorporating the physical changes noted above, an Arduino program was developed to test whether or not the motor could be accurately speed controlled.  Rather than trying to manually threshold-detect the above waveform, I simply used  Mike Schwager’s very cool EnableInterrupt Library (see  https://github.com/GreyGnome/EnableInterrupt) and set the Tach signal analog input to trigger an interrupt on each signal change.  This resulted in two interrupts per slot position, but this was easily handled in the software.

After getting the program working,  I found that I could control the motor such that, when set to 60 rpm, 20 wheel revolutions (as measured by counting the scotch tape on the wheel) took exactly 20 seconds.

Well, I’m not quite sure where I’m going from here.  Now I have demonstrated that I can control a typical hobbyist/robot motor for use as a LIDAR turret.  However, I’m not entirely convinced that a spinning LIDAR can produce wall distance measurements fast enough for successful wall following, and it will be a major PITA to modify Wall-E sufficiently to find out.  For one thing, I can’t really use one of Wall-E’s drive wheels as the LIDAR turret motor without giving Wall-E an unacceptable ‘limp’  (If I did that, I guess I would have to change his name from ‘Wall-E’ to ‘Quasimodo’ ;-)).  For another, to mount the LIDAR and turret on the current Wall-E chassis would be a major project by itself, as Wall-E’s real estate is already heavily populated with ‘stuff’.

So,  I think I’m going to wait until my new 4WD robot chassis arrives (it was unfortunately delayed for a week or so), and then build it up from scratch as a LIDAR-only platform. I can then use one of the motors from Wall-E as the turret motor for the PulsedLight LIDAR-Lite system.  In the meantime, I think I’ll try and mount the NEATO XV-11 spinning LIDAR on Wall-E, as it doesn’t require any additional motors (it has its own motor built in), and see if I can successfully follow a wall using only LIDAR.

Stay Tuned…

 

Frank

 

 

Robot of the future – LIDAR and 4WD

Posted 04/29/15

In a whole series of posts over this last month, I described the results of my efforts to solve the ‘stealth slipper’ problem, where Wall-E gets stuck on my wife’s fuzzy blue slippers and can’t seem to reliably detect this condition.  I ran a large number of experiments which eventually convinced me that the ultrasonic sensors I have been using for wall-following  and ‘stuck’ detection just aren’t up to the task. Even the use of  two forward-looking ping sensors, which I thought was going to be a really cool and elegant solution, didn’t do the job.  There is just too much data corruption due to multipath and ‘friendly fire’ corruption between ping sensors to reliably discriminate the ‘stuck on stealth slippers’ condition.

Slipper turned 90 degrees  clockwise

Slipper turned 90 degrees clockwise

So, its time to consider other, more radical, alternatives.  First and foremost, it is clear that ultrasonic sensing will not work for ‘stealth slipper’ detection/avoidance.  Other possible sensing modes are:

  • IR Ranging:  This has the advantage of being pretty cheap, but hobbyist IR ranging options like the Sharp IR Range Sensor (shown below) are fairly short range, slow, and have just an analog output with limited accuracy.

    Sharp IR Range Sensor

    Sharp IR Range Sensor

  • LIDAR:  This technology is fast, can be very long range, and can provide very accurate ranging information.  Unfortunately these sensors tend to be heavier and much more expensive than either the ultrasonic or IR sensor options.  The CentEye/ArduEye laser range finder using the Stonyman vision chip was a really cool, light weight and cheap solution, but it is unfortunately out of production and unavailable :-(.  The best of the lot for now appears to be the LIDAR-LITE sensor or the fully-assembled LIDAR package that is part of the NEATO robot vacuum cleaner.
    PulsedLight LIDAR-Lite unit

    PulsedLight LIDAR-Lite unit

    Neato Robotic Vacuum LIDAR module

    Neato Robotic Vacuum LIDAR module

  • Optical parallax vision processing:  This is really the same as the LIDAR option, but with separate  laser, receiver, and parallax computation modules.  This is what the now-unobtainable Stonyman chip/Laser/Arduino solution did, but there are other, less attractive, ways to do the same thing.  One is a combination of a cheap laser diode and the Pixy CMU Cam.  The Pixy module handles a lot of the vision pre-processing necessary for parallax range determination, and the laser diode would provide the bright, distinct spot for it to track.Pixy CMU Cam module

After looking through the available options, it occurred to me that something like the LIDAR-Lite might allow me to  not only replace the forward-looking sensor on WallE, but maybe even the side ones as well.  The LIDAR-Lite is fast enough (20 msec/reading) that I should be able to use it for all three directions (left, right, forward).  In fact, if I mounted it on a servo motor using something like the Adafruit slip ring component shown here, I could implement a cool 360-degree LIDAR

Adafruit Slip Ring with 6 contacts

Adafruit Slip Ring with 6 contacts

It also occurred to me that while I’m in the process of making radical changes to WallE’s sensor suite, I might want to consider changing WallE’s entire chassis (I think this is the robot equivalent of ‘repairing’ a car by lifting up the radiator cap and driving a new car under it).  The 2-wheel plus castering nose wheel arrangement with the current WallE leaves a lot to be desired when navigating around our house.  Too often the castering nose wheel gets stuck at  the transition from the kitchen floor to the hall carpet or the area rugs.  In addition the nose wheel axle/sleeve space tends to collect dirt and cat hair, leading to the castering nose wheel acting more like a castering nose skid than a wheel ;-).  After some more quality time with Google, I came up with a very nice 4-wheel drive DFRobot 4WD Arduino Mobile Platform  robot chassis from DF Robots, along with the companion ‘All In One Controller‘.

DFRobot 4WD Arduino Mobile Platform

DFRobot 4WD Arduino Mobile Platform

DFRobot Romeo V1 All-in-one Microcontroller (ATMega 328)

DFRobot Romeo V1 All-in-one Microcontroller (ATMega 328)

Adventures with Wall-E’s EEPROM, Part VI

Posted 04/26/15

In my last post I showed there was a  lot of variation in the data from Wall-E’s  ping sensors – a lot more than I thought there should be.  It was apparent from this run that my hopes for ‘stuck’ detection using variation (or lack there of) of distance readings from one or more sensors were futile – it just wasn’t going to work.

At the end of the last post, I postulated that maybe, just maybe, I was causing some of these problems by restricting the front sensor max distance to 250 cm.  It was possible (so I thought) that opening up the max distance to 400 cm might clean up the data and make it usable.  I also hatched a theory that maybe motor or movement-related vibration was screwing up the sensor data somehow, so I ran some tests designed to investigate that possibility as well.

So, I revised Wall-E’s code to bump the front sensor max distances to 400 cm and made a couple of runs in my test hallway (where the evil stealth slippers like to lurk), to test this idea.  The code adjustment had a bit of a ripple effect, because up til now I had been storing the distance data as single bytes (so could store a distance reading of 0-255 cm), and storing 2-byte ints was going to take some changes.  Fortunately a recently released update to the EEPROM library provide the put() and get() methods for just this purpose, so I was able to make the changes without a whole lot of trouble.

Results:

First, I ran a number of tests with the front sensor max distance still set at 255 so I could stay with the single-byte storage system, with and without the motors engaged, and with and without mechanically induced vibration (tapping vigorously on the side of the robot chassis) while moving it toward and away from my bench wall.

Test bench run with motors disabled, without any external tapping

Test bench run with motors disabled, without any external tapping

Test bench run with motors enabled, but no external tapping

Test bench run with motors enabled, but no external tapping

Test bench run, motors enabled, with external tapping

Test bench run, motors enabled, with external tapping

From these runs, it is clear to see that having the motors engaged and/or having an external disturbance does not significantly affect the sensor data quality.

Next, I enabled 2-byte EEPROM storage and a 400 cm max distance for the two front sensors. Then I did a bench test to validate that EEPROM storage/retrieval was being done properly, and then ran another field test in the ‘slipper’ hallway.

Field test with all sensors and motors enabled, 400 cm max distance on front sensors

Field test with all sensors and motors enabled, 400 cm max distance on front sensors

The front and top-front sensor data still looks very crappy, until Wall-E gets within about 100 cm of the far wall, where it starts to look much better.  From this it is clear that opening up the front max distance from 255 to 400 cm did absolutely nothing to improve the situation.  Meanwhile, the offside side sensor readings are all over the place.

So, I have eliminated motor noise, mechanical vibration, and inappropriate max distance settings as the cause of the problems evident in the data.  After thinking about this for a while, I came to the conclusion that either there was still some intra-sensor interference, and/or the hallway itself was exhibiting multipath behavior.  To test both these ideas, I disabled the motors and all but the top-front sensor, and ran a series of 4 tests, culminating in a run in the ‘slipper’ hallway where I moved the robot by hand, approximating the somewhat wobbly path Wall-E normally takes.  The results are shown below.  In the first two tests I moved the robot toward and away from my test wall a number of times, resulting in a sinusoidal plot.  In the two long range tests, I started approximately 400 cm away from the wall, moved close, and then away again, back to approximately 400 cm.

Test run in my lab and in the  'slipper' hall, top front sensor only (400 cm max distance).

Test run in my lab and in the ‘slipper’ hall, top front sensor only (400 cm max distance).

The first two tests (‘Bench 1’ and ‘Bench 2’) validated that clean data could be acquired, and the ‘Lab Long Range’ test validated that the ping sensor can indeed be used out to 400 cm (4 meters).  However, when the field test was run, significant variation was noted in the 150-350 cm range, and there doesn’t seem to be any good explanation for this other than multipath.  And, to make matters worse, if one sensor is exhibiting multipath effects, it’s a sure bet that they  all are, meaning the possibility (probability?) of multiple first, second, and third-order intra-sensor interference behavior.

After this last series of tests, I’m pretty well convinced that the use of multiple ping sensors for navigation in confined areas with multiple ‘acoustically hard’ walls is not going to work.  I can probably still use them for left/right wall-following, but not for front distance sensing, and certainly not for ‘stuck’ detection.

So, what to do?  Well, back to Google, of course!  I spent some quality time on the web, and came up with some possibilities:

  • The Centeye Stonyman Vision Chip and a laser diode. This is a  very cool setup that would be perfect for my needs.  Very small, very light, very elegant, and (hopefully) very cheap laser range finder – see  https://www.youtube.com/watch?v=SYZVOF4ERHQ.  There is only one thing wrong about this solution – it’s no longer available! :-(.
  • The ‘Lidar Lite’ laser range finder component available from Trossen Robotics (http://www.trossenrobotics.com/lidar-lite).  This is a complete, self-contained LIDAR kit, and it isn’t  too big/heavy, or  too expensive (there might be some argument about that second claim, but what the heck).
  • The Pixy CMUCam, also available from Trossen (http://www.trossenrobotics.com/pixy-cmucam5).  This isn’t quite as self-contained as it  needs a separate laser and some additional programming smarts, but it might be a better fit for my application.

So, I ordered the LIDAR-lite and the CmuCAM products from Trossen, and they will hopefully be here in a week or so.  Maybe then I can make some progress on helping Wall-E defeat his nemesis – the evil stealth slippers!

Stay tuned…

Frank

Adventures with Wall-E’s EEPROM, Part V

 

Posted 04/22/15

In my last post I analyzed  a stuck/un-stuck scenario where Wall-E got stuck on a coat rack leg, and then got himself unstuck a few seconds later.  This post deals with a similar scenario, but with the evil stealth slippers instead of the coat rack, and this time Wall-E didn’t get away :-(.

 

 

EEPROM data from Wall-E slipper run.  Note large variations on all four channels.

EEPROM data from Wall-E slipper run. Note large variations on all four channels.

Last 50 records, showing large amount of variation on all four channels.

Last 50 records, showing large amount of variation on all four channels.

Analysis:

  • T = 09: Wall-E hits his nemesis, the evil Stealth Slippers
  • T + 37: Wall-E signals that it has filled the EEPROM.  No ‘stuck’ detection, so no sensor array data.
  • My initial impression of the 4-channel EEPROM record was “Geez, it’s just random garbage!”.  There does not appear to be any real structure to the data, and certainly no stable data from the left and right side sensors.  Moreover, the top front sensor – the one that was supposed to provide nice stable data even in the presence of the stealth slippers – appears to be every bit as unstable as the others – ugh!
  • In order to more closely examine the last few seconds of data, I created a new plot using just the last 50 or so records.  From this it is clear that both the left and right side sensor data is unstable and unusable – both channels show at least one max-distance (200 cm for the side sensors) excursion.  The front and top-front data doesn’t fare much better, with 4-5 major excursions per second.
  • The only bright spot in this otherwise panoply of gloom is that the front and top-front sensor data shows a lot of intra-sensor variation, meaning that this might be used to effect a ‘stuck’ declaration.  In the last 50 records, there are 4 records where ABS(front-topfront) > 85 (i.e. > MAX_FRONT_DISTANCE_CM / 3).  Looking more closely at the entire EEPROM record, I see there are 18 such instances – about one instance per 50 records or so, or about 1 per second.  Unfortunately, at least 6 of these occur in the first third or so of the entire record, meaning they occur  before  Wall-E gets stuck on the slipper.  So much for  that idea :-(.

Despite the gloom and doom, this was actually a very good run, in that it provided high-quality quality data about the ‘stealth slipper detection’ problem.  The fact that the data shows that one of my ideas for detection (the intra front sensor variation idea) simply won’t work, as that variation is present in  all the data, not just when Wall-E is stuck.  At least I don’t have to code the detection scheme up and then have it fail! ;-).

It is just barely possible that I have caused this problem by restricting the max detection distance for the front sensors to 250 cm in an effort to mitigate the multipath data corruption problem.  So, I’m going to make another run (literally) at the slippers but with the max front distance set out to 400 cm versus the existing 255 cm limit.  However, this will cut the recording capacity  in half, as I’ll have to use 2 bytes per record.  I can compensate for this by not storing the left and right sensor data, or by accepting a shorter recording time, or some combination of these.  One idea is to store the left & right sensor data as bytes, and the front sensor data as ints.  This will require modifying the EEPROM readout code to deal with the different entry lengths, but oh well….

Stay tuned…

Frank

 

 

Adventures with Wall-E’s EEPROM, Part IV

Posted 04/22/15

In my last post, I showed some results from Wall-E’s EEPROM data captures, including a run where Wall-E got stuck on the wife’s evil stealth slippers – and then unexpectedly got ‘unstuck’.  I couldn’t explain Wall-E’s miraculous recovery from the captured EEPROM sensor data, so I was left with two equally unpalatable conclusions; either I didn’t understand Wall-E’s program, or Wall-E was ‘seeing’ something besides what was captured in the EEPROM.

So, I decided to modify Wall-E’s programming to capture additional data when/if Wall-E got stuck – and then unstuck – on future runs.  The mods were described in the last post, but basically the idea was to capture the contents of both the 50-point front and top front sensor data arrays, along with the current values of all four sensors.  To do this I re-purposed  the first 100  EEPROM locations to store the sensor array data, figuring that the earliest points would be the least likely to be relevant for post-run analysis.

After making the mods, and testing them on the bench in debug mode, I took Wall-E out for another field trial, hoping he would do the same thing as before – namely getting stuck and then un-stuck on/from the evil stealth slippers.

As it turned out, Wall-E’s next run produced good news and bad news. The good news is that Wall-E did indeed get stuck and then un-stuck, providing some very good decision data.  The bad news was that it got stuck on a coat rack leg (an easier problem for Wall-E) instead of the stealth slippers.  Still, it  did provide an excellent field validation of the new data collection scheme, as shown below.

Remaining EEPROM Contents at the point where Wall-E declares 'Stuck'.

Remaining EEPROM Contents at the point where Wall-E declares ‘Stuck’.

Top and Top Front Sensor Array Contents at the point where Wall-E declares 'Stuck'

Top and Top Front Sensor Array Contents at the point where Wall-E declares ‘Stuck’

Analysis:

  • T + 13:  Wall-E gets stuck on a coat rack leg.  He got stuck because I  hadn’t yet updated the left front bumper to the new non-stick style, but this was a good thing ;-).  Just before Wall-E hits the leg, the left sensor distance reading changes rapidly from about 40 cm to about 20, as the left sensor picks up the coat rack leg on its left.
  • T + 13-15: Wall-E tries to drive around the coat rack leg it is stuck on, causing it to turn about 45 degrees to the left. During this period the right, front, and top-front sensor readings vary wildly, but the left sensor reading stays quite stable (almost certainly  reading the distance to the coat rack leg on the left).
  • T + 16:  Wall-E has stopped moving, and consequently the top and top-front  sensor readings settle down.  Interestingly, the right distance sensor readings  don’t  settle down, even thought there are no obstacles within the max detection distance (200 cm) on that side – no idea why.
  • T + 20: Wall-E declares the ‘stuck’ condition.  This is almost certainly due to  the total deviation of the current contents of  the front sensor reading arrays falling below the threshold (5 cm in this case).  From the data, the front sensor array deviation is 4 cm, while the top-front deviation is still high (161) due to a 209 value that hasn’t quite yet fallen off the end.

So, the captured for this run is entirely consistent with the stuck condition and recovery, with the possible exception of the anomalous right sensor readings that should show a constant 200 cm but doesn’t for some unknown reason.

Next up – another try at getting Wall-E stuck on the stealth slippers, with (hopefully) a ‘stuck’ condition’ detection to boot!

Stay tuned…

Frank

 

 

 

Adventures with Wall-E’s EEPROM, Part III

 

Posted 04/19/15

In my last post I described how I might be able to use the Arduino Uno’s onboard EEPROM to see the world from Wall-E’s point of view, at least for a few seconds at a time.  So, now that I’m back home from the Gatlinburg, Tn duplicate bridge tournament, I decided to try my luck at this.

First, I had to make some additional modifications to Wall-E’s program:

  • Revised the sensor data retrieval routines to substitute  MAX_FRONT_DISTANCE_CM for any zero reported from either  front sensor, and to substitute MAX_LR_DISTANCE_CM for any zero reported from either the left or right sensor. This takes care of the problem of sensor readings abruptly transitioning from a near-maximum reading to zero, and back again.
  • Revised the EEPROM storage routine to store readings from all four sensors instead of just the two front ones.  Data will be recorded until the EEPROM is full, at which point Wall-E will blink all four taillight LED’s twice.  Wall-E will continue to run, but won’t store any more data.
  • Revised the separate EEPROM readout program to properly read out all four sensor values, instead of just the two front ones.

After making the modifications (and fixing the inevitable bugs), I set Wall-E loose on the world with it’s new EEPROM-storage capabilities.  I video’d the run so I would later be able to correlate the EEPROM data with what Wall-E was actually doing at the time.  The first run went very well, with Wall-E behaving ‘normally’ (whatever ‘normal’ means for a robot!).  I videoed the run until Wall-E blinked its tail-lights to signify it was done recording, and I noted that the run had lasted about 30 seconds (which was too bad, because Wall-E got stuck on a coat rack leg  just after running out of storage space! ;-).

The video and the Excel plot are shown below, followed by my post-run analysis

 

EEPROM data from Wall-E's first instrumented run

EEPROM data from Wall-E’s first instrumented run

Analysis:

  • The very first thing I noticed about the Excel plot is that there is something badly wrong with the first part  of the data,  up to about point 400; it’s way too constant.    After about 400, it looks like Wall-E collected ‘good’ data, although a lot of it looks pretty frightening!
  • I thought Wall-E started out tracking the wall on the right, but the data doesn’t support that – it appears it was tracking on the left wall from the get-go.
  • from the video it looks like Wall-E’s tracking period is between  one and two seconds, and from the plot this corresponds to about 50 points.  This correlates reasonably well with the observation that it takes about 30 seconds to fill the 1024-byte EEPROM.  1024 divided by 30 gives 34 points/sec, so 50 points would give a period of about 50/34 = 1.5 seconds.  This is actually quite good news, because it means that the 50-point array I was using earlier as part of the ‘stuck’ detection routine can probably capture an entire tracking period.  The amplitude of the tracking response appears to be about 8-10 cm in ‘free space’ and about half that when Wall-E’s castering nose wheel was hitting the rug edge after about point 580.
  • From the plot, it appears the front and top-front sensors were reporting obstacles in view even though there weren’t any, at least not for the first part of the initial wall-tracking phase of the run.  This is probably due to the fairly large heading deviations made by Wall-E even while wall tracking, possibly coupled with some multipath effects.  This is actually good news as  there should be significant variation in front sensor readings during normal operation, even if there is no dead-ahead obstacle within sensor range.   Also, it is clear that once Wall-E  came within about 60-75 cm of the door, it ‘captured’ the attention of both the front and top-front sensors, which then tracked the door very nicely all the way down to the 10 cm avoidance threshold.  The same thing happened with the side wall, although because Wall-E was moving slower, the distance reversal happened a bit earlier.
  • After turning away from the side-wall obstacle, Wall-E tracked the same wall, but in the opposite direction and at a larger distance (about 60 cm vs about 40 on the way in).  It is interesting to note that the reported distanced from the front sensors also went up, presumably due to the longer slant-distance to the wall and back during the toward-wall heading excursions (and also probably because Wall-E’s heading excursions weren’t as large due to being slower on the carpet)
  • The ‘off-side’ (right sensor on the way in, and left sensor on the way out) showed very large variations – large enough to hit the stops (200 cm max distance) occasionally on the way in, and on almost every heading swing on the way out.  The measured distance from Wall-E’s average position on the way out to the far wall is about 150 cm, so a 45 degree heading variation would create a slant range distance of over 200 cm.  Smaller heading deviations would also likely create a situation where most of the  left sensor’s ping energy bounced away from the sensor, creating a ‘nothing in view’ response.

Posted 04/20/15

Today I made another run with the EEPROM enabled.   This time I was fortunate enough to have Wall-E encounter my wife’s stealth slippers, while still in the EEPROM collection window, so I may have captured that data.  Unfortunately, Wall-E was uncharacteristically smart enough to figure out he was stuck, and so backed away from the dreaded robot-eating slippers!

 

Sensor plot from Run 2. Wall-E triumphs over the ‘stealth slippers’ at the end!

Analysis:

  • This plot shows the same disconcerting initial section where the data just doesn’t look correct.  However, this time I know where it comes from; Wall-E’s normal running code is configured (now – not for Run 1) to zero out the EEPROM contents before the run starts, and this happens in setup().  When I want to read the information back out again, I need to load an entirely different program, and to do that, I have to connect the USB connector to the Arduino.  Unfortunately, this action also powers up the Arduino and sets Wall-E’s normal program running – and practically the first thing it does is start zeroing out the EEPROM.  Fortunately it only got through the first couple of hundred data points before being halted by the bootloader, but this is the reason for the initial group of zeros in the plot for Run 2, (and the initial group of too-stable data for Run 1).  In the future, I think I’ll incorporate a switchable delay  into Wall-E’s programming, maybe using the now-existing pushbutton, so that no data will be zeroed out or overwritten.
  • Between point 336 and 358 the front and top-front sensor readings ‘come off the stop’ of 250 cm as they start ‘seeing’ the doorway at the end of the hall.
  • T + 24: Wall-E hits the wall to the left of the doorway at point 628 after a hard left turn, and immediately backs up and recovers.  The hard left turn occurs when Wall-E’s right sensor picks up the short wall stub to the near right and then, after making an initial correcting left turn, picks up the door itself and ‘wall-follows’ it.  This is clearly shown in the data, as the right sensor (red) readings drop below the left ones at that point.  Wall-E is programmed to use the nearer wall for wall-following.
  • T + 27: Wall-E barely misses the end of the short wall stub.  It has been  ‘wall-following the door and then short wall on its left side this entire time.  Interestingly, between the t + 24 hit and this  near miss, the top-front sensor readings vary wildly, but the front sensor ones look fairly smooth.  My guess is that the upper sensor was alternately ‘seeing’ the wall stub approaching and the wall well beyond that point, while the lower one was just getting the wall stub.
  • T+ 29: At point 684, Wall-E hits the other wall and recovers.
  • T + 33: After recovering from the second wall hit, Wall-E runs into the stealth slippers and gets stuck – yay!!
  • T + 37: Wall-E gets away!!  After 4 seconds, Wall-E manages to figure out that it is ‘stuck’ and backs away from the evil stealth slippers!  The sensor data in this 4-second period is extremely interesting, as this is the first time I’ve been able to see what Wall-E is ‘seeing’ when he gets stuck on the evil stealth slippers.  As previously assumed (but never confirmed until now!) the left sensor readings show very little variation, making the ‘stuck’ condition very easy to distinguish (at least from the human eyeball viewpoint), but the readings from the other three sensors aren’t so easy to interpret.  Contrary to expectations, and my ‘test range’ results,  both the front and top-front sensor readings show significant variations (as does the readings from the ‘off-side’ side sensor.  The problem is, I have no clue as to why Wall-E got away from the slippers.  The current code uses only the top and top front sensor readings to determine the stuck condition, and I can’t see anything in the last 50 records that would cause that determination to succeed.    There are two criteria for a ‘stuck’ declaration; if neither the front or top front sensors show significant variation for the last 50 points, or if the difference between the front and top front sensors exceeds more than half the max front sensing distance (255 cm for this run) at any time.  There are actually two points within the last 50 that satisfy the second of these criteria (the top front sensor reading goes to 255 but the front sensor reading stays at 120 and 80 respectively), but these don’t trigger a ‘stuck’ declaration – Wall-E stays glued to the slippers for another 2-3 seconds.  So, either I don’t understand what my own code is actually doing, or I don’t understand what is actually going into the 50-point deviation tracking arrays, or the EEPROM data isn’t what Wall-E is actually seeing, or some combination of all the above  (or something else entirely!).
  • Last 50 records before EEPROM recording ended.  Somewhere in  here is something that Wall-E used to declare the 'stuck' condition.

    Last 50 records before EEPROM recording ended. Somewhere in here is something that Wall-E used to declare the ‘stuck’ condition.

  • T + 39: EEPROM recording ends.

Well, I think I’m making some progress toward understanding Wall-E’s point of view (or maybe it’s his ‘point of hear’ instead?), especially with respect to how Wall-E manages obstacles like the evil stealth slippers.  I’m not there yet, although I am encouraged by how stable the left (near wall) sensor data looked while Wall-E was stuck on the slipper.  If that behavior can be confirmed by further observations, then it might be an easy and definite way of ‘stuck’ detection.

So, I have modified Wall-E’s code yet again as follows:

  • Moved the EEPROM initialization code until after the LED light startup sequence, thereby (hopefully) giving the compiler/load/bootloader code time enough to stop Wall-E’s main program before it wipes out the EEPROM data from the previous run.
  • Modified my ‘IsStuck()’ stuck detection function so that if it ever does detect a ‘stuck’ condition, it will
    • write the contents of the front and top-front 50-point history arrays to the the EEPROM (either after the newly collected sensor data if there is room, or by overwriting the initial set of sensor readings if there isn’t)
    • Light all 4 LEDs
    • Shut down the motors
    • Enter an infinite loop

By having Wall-E shut down and go to sleep, I can ensure that the ‘stuck’ detection is the very last thing Wall-E does, which should  mean that the captured array and sensor data is what Wall-E was using to make the detection.

Then I modified the EEPROM read-out program to print out the array contents in single columns  for ease of plotting, with a line in between the array contents and the remaining sensor readout values.

 

 

Stay tuned….

Frank

 

Adventures with Wall-E’s EEPROM, Part II

Posted 04/17/15

I haven’t had much time to work on the ‘stuck detection’ problem lately, as I have been playing duplicate bridge every day at the ACBL regional tournament here in Gatlinburg, Tennessee.  However, my pick-up partner for the morning session didn’t show, so I’m using the free time to think about the problem some more.

In my last post I showed that Wall-E gets confused in certain circumstances when what I believe to be multipath effects corrupt the data collected by the two front-facing ultrasonic sonar sensors.  My current ‘stuck detection’ algorithm relies on at least the top sensor getting good clean distance data, even if the lower one is completely or partially blocked (the ‘stealth slipper’ scenario).  When the data from  both sensors is corrupted, I’m screwed.  In my last post I showed some data I collected from a ‘stuck’ scenario using Wall-E’s on-board EEPROM, and this data made it crystal clear that both sensors were getting bad data.  So, what to do?  Time to go back to the drawing board and devise a new, improved ‘stuck detection’ algorithm that takes in to account the new information.

Excel plot of the front and top-front sensor data while Wall-E was stuck on the base of a cat tree

Excel plot of the front and top-front sensor data while Wall-E was stuck on the base of a cat tree

Here’s what we have:

  • The ‘stealth slipper’ scenario, where the lower sensor is partially or completely blocked, while the upper one is not.  In this case, the upper sensor may report a real distance if there is an obstacle  within the set MAX_DISTANCE_CM parameter, or it may report zero if there isn’t .  The lower sensor can sometimes also report zero when it is blocked by the fuzzy slippers, as the slippers absorb or deflect enough of  the ultrasonic energy to make the sensor think there’s nothing there.  The ‘stuck’ detection algorithm handles this case in a two-step process.  First, if both sensors report very little variation  over time (meaning the distance to the next obstacle isn’t changing) then a ‘stuck’ condition is declared.  Or, if the deviation over time of the bottom sensor is different than the variation  over time of the top sensor (the bottom sensor is partially blocked by the slipper, and reports widely varying distance readings), then a ‘stuck’ condition is declared.  A potential flaw in this algorithm is that either or both sensors can report a constant zero even if Wall-E is moving normally, but there simply isn’t anything within the set  MAX_DISTANCE_CM parameter.  In the current algorithm, this is addressed by setting the  MAX_DISTANCE_CM parameter to 400 cm for the front sensors, on the theory that in a normal wall-following scenario, there is always something within 4 meters (13 feet or so).
  • The  normal wall-following scenario, where (hopefully) the front sensors report a steadily declining distance, with enough variation over time to avoid triggering a ‘stuck’ detection.  In this mode, the side sensor reporting the smaller distance will be  used for primary left/right guidance.
  • The multipath scenario, where the physical geometry is such that the front sensors report widely varying distances, sometimes the same, and sometimes different.   The present ‘stuck detection’ algorithm fails completely here, as the top sensor reports enough variation over time  to pass the first test, and there isn’t enough variation difference between the top and bottom sensors to satisfy the second one.  I don’t think there is anything to be done about the problem with the first test, as the presence of variation over time is the  only  reliable indicator of movement.  However it seems to me that the second test (differential variation between the two sensors) can be improved.  The differential variation test essentially compares the average variation in the top sensor to the average variation in the bottom one, and this clearly doesn’t work for the multipath case.  But, if I compared the two sensor readings on a point-by-point basis over a few seconds, I should be able to detect the mutipath case.  Maybe a running count of differences that exceed a set threshold (from the plot, it looks like a 10 cm distance threshold would work)?  Then if the count/sec exceeds some other threshold, declare a ‘stuck’ condition?

Anyway, I’m starting to think there may be some hope for Wall-E after all; maybe he won’t wind up stuck forever under a cat tree somewhere.  In any case, I think it would be wise to use my new-found EEPROM powers to collect some more ‘real-world’ data before I leap too far to a conclusion.  I think I might even want to include the side sensors in the reporting, so I can see what is actually happening during a typical wall-following sequence, as well as when Wall-E is actually stuck.  I think I can probably get at least 10-20 seconds of data without running out of EEPROM space, so we’ll see.

Stay tuned,

Frank