Comparing Sonar and InfraRed Data

Of course, it was an illusion that I would be able to get straight back to the robot after vacation, there were a few other jobs waiting like the Dyalog’13 Conference Programme (the DyaBot will be making a couple of appearances, of course!). However, it appears I have now made enough flour to be able to remove my nose from the grindstone for a bit and spend more time with the robot, so I expect to be back to posting every week or so from now on, as we prepare to demonstrate an autonomously navigating robot at the conference!

Anyhow, here is a chart with the first recorded data from the LV-EZ4 ultrasonic sensor (sonar) – using RainPro, as demonstrated in the post on visualising sensor data. Many thanks to Stefano Lanzavecchia for help with the math required to generate the co-ordinates of a rectangle in a polar chart:

sonar-and-ir-data

The robot was placed in my kitchen (the setting for several robot videos), about 80cm from the back wall, 240cm from the front, and roughly halfway between the sides. The green rectangle labelled “actual” above shows the location of the walls relative to the bot. It was commanded to rotate through 360 degrees, recording the readings from the IR (red line) and Sonar (blue) sensors, which were both pointing straight ahead. Ideally, the blue line should have traced an identical rectangle. The red line essentially traces an 80cm circle plus noise, this is because SHARP GP2Y0A21YK0F infrared sensor has a maximum range of 80cm.

Sonar Issues

The ultrasonic sensor has a range of at least 6-7m, and is our choice for long-range distance measurements. However, what I believe the graph shows, is that we have a serious problem with reflections. Essentially, it appears that when the sonar beam hits a wall at certain angles, there is very little direct return; instead the beam is reflected. The return signals that we are getting from roughly 60 and 315 degrees look like reflections of the back wall – these reflections may be enhanced by the fact that there is a refrigerator at 60 and a dishwasher at 315 (metal surfaces). The signals at 135 and 220 degrees could be reflections of the robot itself, the beam having been reflected twice in a corner of the room.

Another thing that is not immediately evident from the above image, but took me by surprise studying the data sheet, was that the sonar beam is a quite a bit wider than I expected – as much as 30 degrees at close range, getting narrower as the distance increases (see the data sheet). In other words, we have some work to do in order to generate accurate maps of the universe based on the current set of sensors.

Will we succeed? To be continued …

Return to the Robot

DSC_0016

The Anna Elise

It has been more than a month since my last blog post, and you’d be forgiven for thinking that I’d lost interest in robots. It *is* true that I have been rather distracted by customers, including a trip to the USA. It is also holiday season, and I have been to a music festival. However, except for last week when I was skipper and this week when I am chillng out on the Anna Elise, the robot has been in my suitcase on every trip, and I have actually been working hard on it. I just haven’t been able to get anything new to work until very recently.

One problem was that robots do not travel particularly well. Put them in a suitcase every 3-4 days and bits quickly start falling off (if you have ever looked out the window of your plane and watched a baggage handling crew at work, that should be no surprise). I now have both 220v and 110v soldering irons (Thank You RadioShack!), and have so far been able to put humpty dumpty together again on arrival. But my last desperate attempt to collect some sonar data that I could publish before going sailing ended like this:

Rewriting the Raspberry Pi – Arduino Comms Program

The BIG reason for the lack of visible progress is that I decided that the time had come to rewrite the control program for the Arduino. The robot uses a Raspberry Pi running Dyalog APL as the main “brain”, but because a high-level language on a Pi isn’t a “real time” programming environment, we are using an Arduino to control the I/O pins. The idea is that, by implementing a very simple “front-end processor” on the Arduino, we will have a tool that APL can control at a high level, leaving timing-dependent work like controlling pulse-width-modulated output pins, which need to be continuously updated, to the Arduino.

The old control program had a number of limitations; most importantly, it was only really possible to monitor a single input pin. This was good enough until the sonar was added to the infra-red sensor. The program also contained hard-coded information about how pins were being used. Finally, it was quite simply a badly-written piece of Arduino C, subject to intermittent timing-related glitches because the original authors were unaware of certain limitations of the Arduino.

So I decided to write about 5 pages of new C code, and it took me a month and a bit to get back to blogging. Apart from the distraction of having to pretend to still be the CTO of Dyalog Ltd, the real problem is that I am not (usually) a C programmer. C is a rather unforgiving language. Or rather, it is a VERY forgiving language – it allows you to write code that will compile without warnings but just not work, because you unwittingly asked it to do odd things like truncate the content of a variable that you have used in a context which assumes a shorter type (etc, etc, and etc).

To stack the odds further against me, the default Arduino environment has no real debugger. In addition, the I2C bus that we are using to communicate between the Pi and the Arduino is very timing-dependent, which means that any attempt to step through the code will necessarily cause it to fail. Even the standard Arduino practice of monitoring diagnostic messages written to the serial interface cannot be used as it alters the timing enough to cause many I2C requests to fail. So after 2-3 weeks of wailing and gnashing teeth, I implemented my own simple logging mechanism to return diagnostic info via I2C and finally managed to move very slowly forward and complete the new control program. And I even RTFM and a few web pages written by people who had done this kind of thing before – in particular, this post by Wayne Truchsess was extremely helpful.

I was hoping to be able to publish some results of using the new Sonar, but I tried to do this on a jet-lagged Sunday morning sandwiched between returning from the USA and heading off to sail, and absolutely everything I did went wrong. The batteries died in the middle of my data collection and, to make the day perfect, when I found a new set of batteries, a wheel fell off (see the video above)…so I won’t be able to blog about the sonar data until I am back from the sailing trip at the end of July. However, I would like to talk a bit about the new control program.

I2CArduinoComm v0.2

As previously mentioned, we have a piece or Arduino C code (available on GitHub), which supports a simple command language which APL on the Raspberry Pi uses to issue instructions to set or read I/O pin values. The BIG difference compared to the old version is that ALL code that either reads or sets pin values has been moved to the loop() function, which (if my understanding is correct) is dispatched by the Arduino “operating system” when the O/S is not busy with other tasks. The old program would read and update pins immediately upon receipt of I2C messages. The I2C bus is quite critical with respect to timing, and the old code was spending too much time reading pin values when a data request arrived – so we were missing the timing window for getting a response back in time – and possibly interfering with other timing-dependent activities on the Arduino. The new program constantly maintains arrays containing the latest input values (done in the “loop” function), so all an I2C read request needs to do is to transmit the current values.

Command Language Extensions 

From a functional point of view, the main improvement is that the pin usage is completely configurable using a new “setup” command. At a lower level, the command language has been made more flexible. We no longer use a fixed command length; instead the first byte transmitted declares the length of the command (the first byte of all results is also the length of the response). The following commands are supported:

Command
Character
Command Name Description / Comments
I Identify Returns two bytes containing the major and minor version number of the ArdCom program (currently 0 2), followed by two bytes per defined pin (pin #, pin type).
R Reset Clears all pin definitions.
S Setup Declares pin types. Following the command character, triplets of (pin#, pin type, additional info) for each pin (see the pin type table below for details). “S” can be called several times in succession if the overall length of the command would otherwise exceed 32 bytes).
W Write Sets pin values: the command char is followed by pairs of (pin#, value).

Pin Setup

Each pin declaration included in a setup command consists of a triplet of bytes, containing the pin#, type character, and “additional info”. Only the “p” pin type currently makes use of the additional info – for other pin types this value is ignored.

Pin Type
Character
Type Name Description / Comments
A Analogue output Uses the analogWrite function to set the value.
D Digital output Uses digitalWrite.
S Servo output Uses Servo.write to update the pin value.
a Analogue input Uses analogRead.
d Digital input Uses digitalRead.
p Pulse input Uses pulseIn to read a pulse-width modulated input. If “additional info” is set, then this should be a digital pin number which is given a 10ms HIGH signal to tell the device to provide an input pulse.

See the Arduino Reference for descriptions of analogWrite, digitalWrite and the other functions mentioned above.

Reading Input Values

When an I2C read request is made (by APL on the Pi), the current values for all pins defined as inputs (in ascending order) are returned in a single transmission. The data stream contains two bytes (Most Significant Byte followed by LSB) for each input pin. If the control program wants to return diagnostic information, then the first data byte will have the value 254 and the rest of the transmission will be textual “log” data. 254 is an impossible value for the MSB of any input, because the maximum input value is 1023, which has an MSB value of 3. 254 was chosen rather than 255, which frequently occurs when there are transmission failures or other errors.

The ArdCom Class

A new APL class has been written to communicate with the new Arduino code. You can find the source code in the file ArdCom.dyalog in the GitHub repository. The DyaBot class has been updated to make use of the ArdCom encapsulation, the new version can be found in the Exampes folder in the repository. I will describe the in detail in my next blog post – probably not for another week, as the weather forecast looks superb for the next few days (probable route Faaborg-Aabenraa-Augustenborg-Gråsten-Flensburg-Sønderborg-Ærøskøbing).

Sonar Arrives for the Robot

Following the release of Dyalog APL for the Raspberry Pi came a hectic week with no time to play… But now the next sensor has arrived, so it is time to power the robot back up. In the video below, we practice turning it through 180 degrees using APL.

The big day will be the day after tomorrow, when the three mice (who were once blind) are bringing a bag of robot parts and coming to play with us. Jason and I will help them solder things together and get APL code up and running. We’ll work on getting our own sonar operational – and Jasons LCD display, if we can figure it out.

APL at work in Africa

My dad is originally from the Cape, and I grew up in Botswana, so hopefully I can be forgiven for feeling that it is very cool to find Dyalog APL at the core of a project which aims to increase financial literacy and support the financial stability of small and medium-sized enterprises in South Africa, by delivering a “cash flow optimizer” on phones and tablets:

More Links:

CF04i Home Page
Article in the Financial Mail Corporate Essentials
Riskflow Blog

Elementary Cellular Light-Emitting Automaton

In response to an earlier post on driving an 8-bar LED using the Raspberry Pi, Roger Hui commented that 8 lights should be sufficient to display the output of a 1-d Game of Life. The code snippets displayed in this post are based on some working code that Roger was also kind enough to forward to me.

The following two functions provide the basic building blocks for the computation of the next generation of a 1-d cellular automaton:

bits←{(8⍴2)⊤⍵}           ⍝ Encode a number as 8 binary bits
neighbors←{↑¯1 0 1∘.⌽⊂⍵} ⍝ Map vector => 3-row matrix with neighbors

These allow us to perform the following transformations:

      bits 5
0 0 0 0 0 1 0 1
      bits 110
0 1 1 0 1 1 1 0
      neighbors b←0 1 0 0 1 1 1 1
1 0 1 0 0 1 1 1
0 1 0 0 1 1 1 1
1 0 0 1 1 1 1 0
      2⊥neighbors b ⍝ base-2 decode of each column
5 2 4 1 3 7 7 6

With these, it is now easy to define a function to compute the next generation of a pattern for a given Wolfram Code (and test it with a couple of arguments):

      wc←{(bits ⍺)[8-2⊥neighbors ⍵]}
      110 wc b
1 1 0 1 1 0 0 1
      110 wc 110 wc b ⍝ 3rd generation
0 1 1 1 1 0 1 1

We subtract the result of the base-2 decode from 8, because the least significant bit (bit 0) is the 8th element of the vector returned by the bits function. Next, we define an operator which returns a matrix containing a number of generations:

    ∇ r←gens(rule wcgm)pattern;i
[1] ⍝ Wolfram Code Generations
[2]
[3] r←(gens,⍴pattern)⍴pattern
[4] :For i :In 1↓⍳gens
[5]    r[i;]←rule wc r[i-1;]
[6] :EndFor
    ∇

    5 (110 wcg) b ⍝ 5 generations of code 110
0 1 0 0 1 1 1 1
1 1 0 1 1 0 0 1
0 1 1 1 1 0 1 1
1 1 0 0 1 1 1 1
0 1 0 1 1 0 0 0

Finally, we can add 1 to the boolean matrix and use it to index into a 2-element character vector, to get better “visualization” of the result (10 generations of Wolfram code 20):

      '-*'[1+10 (20 wcgm) b]
-*--****
-**-----
---*----
---**---
-----*--
-----**-
-------*
*------*
-*------
-**-----

The function also works with longer inputs – in the example below a random input of length 60 (20 generations of Wolfram code 18, this time using just blank and asterisk for the display):

     ' *'[1+20 (18 wcgm) 1=?60⍴2]
*****    * ***** *** ** *  * ***    *  *** *  ***  ** ***** 
     *  *                **     *  * **     **   **         
    * ** *              *  *   * **    *   *  * *  *        
   *      *            * ** * *    *  * * * **   ** *       
  * *    * *          *        *  * **        * *    *      
 *   *  *   *        * *      * **    *      *   *  * *     
* * * ** * * *      *   *    *    *  * *    * * * **   *    
              *    * * * *  * *  * **   *  *        * * *  *
*            * *  *       **   **    * * ** *      *     ** 
 *          *   ** *     *  * *  *  *        *    * *   *   
* *        * * *    *   * **   ** ** *      * *  *   * * *  
   *      *     *  * * *    * *       *    *   ** * *     **
* * *    * *   * **     *  *   *     * *  * * *      *   *  
     *  *   * *    *   * ** * * *   *   **     *    * * * **
*   * ** * *   *  * * *          * * * *  *   * *  *        
 * *        * * **     *        *       ** * *   ** *      *
    *      *      *   * *      * *     *      * *    *    * 
   * *    * *    * * *   *    *   *   * *    *   *  * *  * *
* *   *  *   *  *     * * *  * * * * *   *  * * * **   **   
   * * ** * * ** *   *     **         * * **        * *  * *

 

Finally, we can light the lights using the BarLED class from our GitHUB repository – and the Quick2Wire interface board and LED Bar – see the original post for an explanation. The video below shows the output resulting from the following APL expressions

      ]load /home/pi/BarLED
      bl←⎕NEW BarLED ⍬
      0.2 bl.Play ↓50(20 wcg) 0 1 0 0 1 1 1 1
      0.2 bl.Play ↓50(18 wcg) 0 1 0 0 1 1 1 1

Many thanks to Roger for the inspiration to take this one step further (and the code)! For a 2-dimensional implementation of Conway’s classic Game of Life, see the video by John Scholes at http://www.youtube.com/watch?v=a9xAKttWgP4.

Dyalog APL v14.0 Tech Preview

And now, as they say, for something completely different. Our robot is running Dyalog APL version 13.2 for the Raspberry Pi, which was released on our major platforms (Windows, Linux, AIX) in January 2013. The next release of Dyalog APL will be version 14.0, which currently has a tentative delivery date of “sometime in the 1st half of 2014”.

We are in the final stages of the design of a number of new language features, and would like to invite interested parties to install and test the “v14.0 Tech Preview” – or download and review the Release Notes. Some of the features may be controversial, so we welcome your feedback – whether you are a user of Dyalog APL or not. The key features that we hope to validate through the release of the preview include:

  1. New primitive operator rank (identical to the SHARP APL implementation and the ISO/IEC 13751 Extended APL Standard)
  2. New primitive operator key (similar to the J definition)
  3. New primitive function tally (identical to the J definition)
  4. Function trains (similar to trains of length 3 in J)
  5. An extension to dyadic index of (iota), to work on higher-rank arrays (for example, to search for rows of a matrix)
  6. An extension to mix with axis, providing greater compatibility with IBM APL2
  7. New user commands to control boxed / truncated session output
  8. Experimental changes to the binding of function definitions

A number of these new features were discussed by John Scholes and Roger Hui at the Dyalog’12 conference – the video can be viewed on the Dyalog Conference YouTube feed, and is also embedded below (but beware, some of the design details have changed since this recording was made):

“Tech Preview II”

The current invitation is in fact for the second release of the preview; the first release was distributed to a small number of well-known (and loved) troublemakers, and has already resulted in one important change to the definition of the proposed Key operator. I would like to thank Phil Last and Paul Mansour for feedback which has resulted in the operand function being passed the relevant key value as a left argument on each invocation.

Note to users of the first preview version: The default “loco” (1060 I-Beam) setting is 2 (trains, “late” binding) in this release, as this is the setting that we are most keen to have applications tested with. It was 0 (no trains, traditional binding) in the first preview.

How You Can Help

If you are able to commit to setting some time aside to test the new language features and providing us with feedback, please write to sales at dyalog dot com and let us know why YOU should be included in the evaluation team. It would be particularly valuable to us if you have time to run an existing application on v14.0; one of the proposed language extensions is a change to name binding, which will impact the behaviour of certain language constructs. Although most of these would be labelled “exotic”, there is a chance that they are used in existing applications, and we are very interested in learning about the degree to which these changes actually cause problems for existing applications. If serious “adverse reactions” are experienced, we may be forced to abandon some of the new features.

If you do not have time to install and test the preview, you are welcome to read the Release Notes and write to us with feedback, either in response to this blog post or by writing to language at dyalog dot com.

Thanks in advance to everyone who is able to participate!