John Newcombe

Products, ideas and other geeky nonesense.

Pigeon English for Applications: Towards a Natural Language

My recent wanderings in the world of Artificial Intelligence (AI) recently had me looking at Natural Language Processing (NLP). My aim was to try and get a machine to understand natural language (in this case English) and convert it to some useful comuter function. Obviously the machine never understands as such, but there are simple techniques such as simplification, tokenising and templating that can be employed to give the effect of machine understanding. However, it becomes quite clear very quickly that once we step out of a single problem domain, things get quite tricky.

For example, getting a machine to understand my own language, English, in order to perform a search seems a reasonable task. The problem domain in this scenario is Search. This means that the machine only has to have knowledge of search terms in order to determine what to do. If we add other problem domains such as personal organisation or communications, the complexity increases significantly.

Part of my work over the last couple of weeks has been to evaluate the Prolog computer programming language for natural language tasks in comparison with a language such as C#. I reported on which language I thought was best suited to the task. This idea of determining the best approach for a particular task is a common one. However, it struck me that where AI and NLP are concerned, we are taking the opposite approach.

We as humans are very capable of understanding different languages, far better than any machine I know of. Therefore, why waste time getting a machine to understand our language when it is far more efficient for us to learn its language. I guess what I am saying is that if we follow the best suited for the task paradigm, we as humans should learn the computers language and leave the computer to do something it is good at. Naturally, I appreciate that for all sorts of reasons this is either not always possible or desirable. However, maybe there is a compromise to be had.

Whilst I write this I am in Bulgaria on a skiing trip. There is an interesting parallel here, if you excuse the pun. Like the majority of skiers I ski the piste, I am rubbish at off piste so I meet the mountain half way. I learn to ski the piste and the mountain presents its pisted runs for me to have a go at. The intermediary, between me and the mountain, is the piste.

What is needed is an intermediary language between English and Computer. We have a few to choose from already. We have programming and scripting languages, we have built in functions e.g. Unix or DOS commands. We have applications with their own command syntax and of course we have technologies such as ActiveX. However, these are all disparate approaches to computer control which, from an NLP perspective, represent multiple problem domains.

A common solution to handling disparate entities is to abstract those entities. In the case under discussion we would could create a common extensible intermediate language that sits somewhere between English and the disparate varieties of Computer language. This language would need to be open and extensible in order to encompass any new application or hardware device, and should be sufficiently complete that it could be used to easily control all aspects of computing regardless of platform. In an ideal world the hardware and software manufacturers would provide the intermediate language extensions with their products.

Taking this a step further, once we have an intermediate language that sits somewhere between English and Computer, any natural language processing we require can be built on top of this abstraction. This helps us in all sorts of ways, none least the ability to use different international languages, English, Russian, etc. In addition, those of us that are happy to learn this new, intermediate, computer language, will have a common language to make use of outside of NLP.

So what would this intermediate language look like? A formal tokenised language that makes use of common expressions and well known abbreviations may be a good starting point for discussions. However, the important factor is that manufacturers and software engineers sign up, and commit to supporting a hierachial intermediate language namespace.

In many respects we are all used to tokenised language. We see this already with todays text and email languages. Imagine a language that was simple enough to read and yet complex enough to control any computer application on any computing platform. I guess what I am imagining is a sort of object based Pigeon English for Applications (PEA). Sounds like a possible MSc Project to me. Comments?

Waymex GPS Library for .Net now on CodePlex

The GPS Library is a single .Net 4.0 Assembly designed to provide a simple object based interface to both the Garmin and Magellan range of GPS devices. In addition the GPS Library will support NMEA devices.

The GPS Library was originally sold as the Waymex GPS Library for .Net. Waymex IT Ltd no longer exists and the rights to this software now lie with me, the original author. The project, including latest version and source code is now available on CodePlex (http://gpslibrary.codeplex.com) under the unrestricted BSD licence.

The GPS Library started life back in the late 90s as an experimental product written for the Aboriginal Land Management Office. They had a lot of land that needed mapping and their approach was to spend several weeks driving around the perimiter in a Land Rover, carrying a Garmin GPS. Following the success of this experiment, the component was opened up for general sale.

The code, originally written in VB6, was ported to .Net 1.1 and then converted from VB.net to C# in 2003. It was upgraded to .Net 4.0 in 2010. Despite the fact that the code was written before Generics, Linq, Lambdas and all the other features we know and love today, and Patterns and Practices were not what they are now, the product has performed well for many customers over many years. It continues to be used in applications around the world today.

Having said that, the resources required to maintain, develop and support this product in a decreasing market is simply not viable any longer. Waymex as a company no longer exists and I have for sometime been involved in other products and technologies. Understanding the needs of Waymex GPS Library customers, to support their own customers and projects, the GPS Library for .Net has been moved to CodePlex.
Enjoy!

Project Chess

This week I was reminded of the program Microchess.

Microchess was probably the first software package to sell in large numbers (50k+) it was written for the small hobbyists computer called a KIM-1. Microchess is probably, albeit indirectly, responsible for the success of Apple, the success Microsoft and the success of the IBM PC.

Microchess was written by Peter Jennings who founded the company Personal Software which later became known as VisiCorp. Personal Software was responsible for publishing the Software Arts title VisiCalc. VisiCalc was the first spreadsheet program and the first ‘killer app’. It was originally written for the Apple II and it turned that machine from a hobbyists toy to a true business machine. It was also bundled with the early IBM PC’s.

Microchess played a pivotal role in the success of Apple simply because Steve Jobs gave Personal Software a heavily discounted Apple II computer in order that they could port Microchess to the Apple II. In owning this machine they were able to persuade the authors of VisiCalc not to develop for DEC but for the Apple instead, a decision that ensured the success of Apple. It was the success of this application that helped convince Microsoft to produce end user software rather that just software for developers.

VisiCalc was ported to the PC when that turned up. However, competition on the PC platform became fierce with products such as MultiPlan, SuperCalc and later on, Lotus123. Once Microsoft wrote Excel for the Apple (yes, it was originally written for Apple), the writing was on the wall. The rights to VisiCalc eventually ended up with Lotus.

So there you have it, a small program called Microchess that was distributed on cassette tape was probably responsible for the success of Apple and Microsoft and the birth of the IBM PC. Interesting then, that the project that produced the IBM PC was called ‘Project Chess’.

Creating GPS iPhone and iPad Applications

I recently wrote an OS grid based GPS application for the iPhone and thought it may be helpful to describe an approach that I have used several times now.

Many books and documents will describe how easy it is to implement GPS by using the Core Location delegates and so on. Typically, this would be done in a view controller or perhaps the application delegate. Many of you will have discovered that it can get quite messy if you have more than one view conroller requiring location data. This is especially true when there are a whole raft of calculations to be done on the data, perhaps to change coordinate systems or create projections etc. The other difficulty is testing, as there is no GPS simulation in the IOS Simulator.

An approach I use is to encapsulate all of the GPS functionality into a singe ‘Location Manager’ class, and use Notifications to send a new ‘Location’ data object to any view controllers that need location data. The code in the view controllers and app delegate classes is reduced to a couple of lines, and all calculations and transformations can be done, in one place.

The encapsulation of the Core Location functionality allows the new ‘Location Manager’ to calculate heading and speed whilst at the same time accounting for the fact that the accuracy of the given location is constantly changing. These sort of calculations are essential in order to make the raw data from Core Location, useable. For example, imagine I am standing still and position data is sent from the device. If the accuracy of this new data is different that that of the previous data, it will, quite correctly, update my position to the new value. However, from a heading and speed point of view I appear to have moved when in fact I am standing still.

The ‘Location Manager’ has been built in to our AIF Frameworks IOS library and is used for all of our location based solutions. We also have a whole collection of coordinate, ellipsoid and projection classes within the library. This allows us to implement complex location based solutions in a simple and coherent manner. The addition of a GPS simulator build into the ‘Location Manage’ is the icing on the cake, making the Notification model a very elegant solution.

Web is for Mediocrity

Those that have spent time with me lately will know that I have been harping on about the mobile phone being used in preference to the web in the not too distant future. This has been hard to swallow for many, including myself.

I have spent the last 10 years developing reasonably large scale web sites using Microsoft technologies, in particular, ASP.Net. The idea of having to start at the begining with a mobile platform is daunting. With this in mind it is easy to see why many developers and IT departments tend to talk about mobile web apps being the way forward. Their desire to have a standard code base that suits all devices, browsers and the like, is a reasonable one. However, in my view, it is missing the point.

We are moving towards a new era. The dreams of a standard code base for use with a multitude of devices, either through web based services or otherwise, should be forgotten. We need to shift our emphasis back to device specific code in order that we can harness the full potential of each device.

Microsoft recently launched their new, Windows Mobile 7, phone. At around the same time they shifted their emphasis regarding their Silverlight product. Microsoft have given us all a clear indication that trying to maintain Silverlight for a multitude of web browsers and devices is not practical. Instead I believe they are shifting their emphasis away from the web and towards Mobile development. The development framework of choice for the Windows Mobile 7 devices is Silverlight.

So where does that leave us as developers? That’s easy, pick a device, learn the skills necessary, and get on with it. If you’re still not convinced consider my experience last Friday. I am sat at home watching my latest ‘Love Film’, I see a trailer advertising another film. Do I get my laptop out of its bag, switch it on, log on to Love Film and add it to my list? or do I open the Love Film app on my iPhone and add it there and then, it’s a no brainer. A few iPhone key presses later, not only have I added the film to my list but I have also ordered, from Amazon, the draught excluder I need to cut down the drafts in my Grade II listed windows.

For me, and I suspect many, Mobile apps deliver a better user experience and can leverage the location and mobile functionality not available on the web, even mobile web. As I said, Web is for mediocrity.

Einstein’s 7 Inches

On this day in 1879 Albert Einstein was born. As we all know Alb, through his Special Theory of Relativity, introduced us to time travel, well sort of….

He stated that nothing could travel faster than the speed of light and was considered a pretty cool chap by many. The trouble is that Newton stated that the effects of gravity were instant i.e. if you suddenly turned up with a planet, the gravity this produced would be felt instantly no matter how far away you were. This kind of blew the ‘faster than light’ bits of Al’s theory away.

However, Al was no slouch and developed his theory into the General Theory of Relativity, which as we all know introduced the concept of curved space time and poked one in the eye for Newton.

Its hard not to like Al but this relativity stuff can be a pain in the arse for the likes of a GPS developer due to the positional error it can cause. The theory then for those who have forgotten… Imagine two clocks set to the same time, one is placed in a moving body (remember that space ship we built earlier this year) the other remains stationery (actually there is no such thing as stationary but we will leave that for another day). To an observer holding the stationary clock, the moving clock would appear to be going slow. What’s weird is that an observer holding the moving clock would see the stationery clock going slow also. Even weirder is that for each individual looking at their own clock, things look perfectly normal.

In our GPS world we have two clocks and one is in a moving body (the satellite) the other on the ground. Therefore we have to calculate the errors incurred through this phenomenon. Now a few bright chaps around the world can do this sort of stuff in there heads. However, thankfully, the clock frequencies in the satellites are adjusted to compensate for the relativistic effect, so panic over. Without correction for relativity, the error can be as much as 18cm, 7 inches.

Just thought you’d like to know.

Detecting Lemons

This week my computational intelligence soiree introduced me to computer vision systems. This is all about computers recognising things by their attributes. Typically these could be a combination of colour size shape etc. and could involve a bit of AI and so on. To keep things simple I decided to see if I could get my Mac to detect a lemon.

So with a bit of jiggery pokery I managed to compile and link to the Open Computer Vision library (OpenCV). This simplifies things somewhat and allows us to capture images, manipulate them and display them.

A lemon detector turns out to be quite simple really. The steps we take are as follows;

  • capture a frame from a web cam;
  • copy this to a second image;
  • remove everything that isn’t yellow;
  • create a black and white (binary) image where white represents the lemon;
  • calculate the shape around the white bit (convex hull);
  • draw the shape on the original image.

Pretty simple really, oh… then we do it all again for the next frame and so on. The code is at the bottom of the post:

This worked like a charm. The video displays in realtime and, as long as it is in shot, the red line picks out the lemon even when thrown across the room.

OK so spotting lemons is not that useful, but what about something that can highlight that the person wandering off with your bike, is not the person who parked it? Similarly useful would be  a system that could identify people entering a railway station with luggage, and leaving without it? Of course these sorts of things are already being done and I suppose it is a step in the right direction being able to witness my bike being stolen, even if I still can’t catch the thief or get the bike back. Perhaps, an example of something more useful would be the latest Sony Playstation, with its ‘lemon topped’ controllers.

My interest of course is for Herbert my robot (see earlier post), this technology could give him some form of vision. Therefore it is my intention to build the lemon detector to run on an iPhone and attach this to Herbert. I am not sure where his search for lemons will take him but, should he get lost, at least he will be able to phone home.

The Code

/*
This program has been designed to recognise a Lemon. The program processes images captured from an attached camera a frame at a time. Each frame is copied (cvCopy) in order that manipulation can be applied to one image without affecting the original image.

The copied image is first converted to HSV colour space before being smoothed using a guassian filter. The resultant image is then restricted in range to the colour yellow and converted to a binary image.

Morthological operators are applied in order to clean the image further and the convex hull is determined. The convex hull is then drawn on the normal image.

Helper functions have been used to determine the convex hull an to display a convex hull on an image and care has been taken to release memory, both within the functions and within the main loop, once it is no longer required.

The option to display both the normal and binary image is given with the DISPLAY_BINARY definition.
*/

#include <cv.h>
#include <highgui.h>
#include <math.h>

//Set to 1 to show both the binary and normal image windows.
//Set to 0 to show the normal image only.
#define DISPLAY_BINARY 1

//declare functions
void DrawConvexHull(IplImage *dstImage, CvSeq *hull, CvScalar colour, int width);
CvSeq* GetConvexHullOfImage(IplImage* srcBinaryImage);

//main entry point int main(int argc, char *argv[]) {

//declarations
int key = 0;
IplImage* imageTemp;
IplImage* currentFrame;
IplImage* currentFrameHSV;
IplImage* currentFrameBinary;

//Create and Open camera window
char* windowTitleCamera = “Camera Image”;
char* windowTitleBinary = “Binary Image”;

cvNamedWindow(windowTitleCamera, CV_WINDOW_AUTOSIZE );

#if DISPLAY_BINARY
cvNamedWindow(windowTitleBinary, CV_WINDOW_AUTOSIZE );
#endif

//define the capture device
CvCapture* captureDevice = cvCaptureFromCAM(-1);

//initialise images
currentFrame = cvQueryFrame(captureDevice);
currentFrameHSV = cvCreateImage(cvSize(currentFrame->width, currentFrame->height) , IPL_DEPTH_8U, 3);
currentFrameBinary = cvCreateImage(cvSize(currentFrame->width, currentFrame->height) , IPL_DEPTH_8U, 1);

imageTemp = cvCreateImage(cvSize(currentFrameHSV->width, currentFrameHSV->height) , IPL_DEPTH_8U, 1);

//main loop
while (key != 27) {

//get the current frame from the capture device
currentFrame = cvQueryFrame(captureDevice);

//create a copy of the frame for manipulation
cvCopy(currentFrame, currentFrameHSV);

//use ‘inline’ function to convert to HSV
cvCvtColor(currentFrameHSV, currentFrameHSV, CV_BGR2HSV);

//usea guausian filter to help remove noise
cvSmooth( currentFrameHSV, currentFrameHSV, CV_GAUSSIAN, 7, 7 );

//convert the image to binary whilst setting the range to detect yellow
cvInRangeS(currentFrameHSV, cvScalar(20,100,100), cvScalar(30,255,255), currentFrameBinary);

//clean up the binary image
//use morthological operators (combination of erode and dilate) to clean the iamge somewhat

cvDilate(currentFrameBinary, currentFrameBinary, NULL, 5); cvErode(currentFrameBinary, currentFrameBinary, NULL, 5);

//could use something like this
//cvMorphologyEx(currentFrameBinary, currentFrameBinary,imageTemp, NULL, CV_MOP_GRADIENT, 1);

// Could add outlier removal here…
//

//use convex hull algorithm to find shape CvSeq *hull = GetConvexHullOfImage(currentFrameBinary);

//draw convex hull on to normal frame
if(hull) {
DrawConvexHull(currentFrame, hull, CV_RGB( 255, 0, 0 ), 2);

//tidy up
cvClearSeq(hull);

}

//show the normal captured image in a window
cvShowImage(windowTitleCamera, currentFrame);

#if DISPLAY_BINARY
//show the binary image in a window
cvShowImage(windowTitleBinary, currentFrameBinary);
#endif

//get any key presses
key = cvWaitKey(10);

}
}
}

// Clean up cvDestroyWindow(windowTitleCamera);
cvDestroyWindow(windowTitleBinary);

//need to release images and memory storage here cvReleaseImage(&currentFrame);
cvReleaseImage(&currentFrameHSV); cvReleaseImage(&currentFrameBinary);

return 0;

//Simple function to create a connvex hull of an image.
//The caller is responsible for releasing the memory of the returned CvSeq. CvSeq* GetConvexHullOfImage(IplImage* srcBinaryImage) {

//use convex hull algorithm to find shape CvPoint point; CvMemStorage
*pointStorage = cvCreateMemStorage(0); CvSeq *ptseq = cvCreateSeq( CV_SEQ_ELTYPE_POINT|CV_32SC2,sizeof(CvContour), sizeof(CvPoint), pointStorage );

//wander through the image identifying points that are set to 1
for(int i=0;i<srcBinaryImage->width;i++) {
for(int j=0;j<srcBinaryImage->height;j++) {
if(((uchar*)(srcBinaryImage->imageData + srcBinaryImage->widthStep*j))[i] == 255) {

//we have a pixel set to 1 point.x = i; point.y = j;
cvSeqPush(ptseq, &point);

}
}
}

//create the hull
CvSeq *hull = cvConvexHull2(ptseq, 0, CV_COUNTER_CLOCKWISE, 0 );

//tidy up
cvClearMemStorage(pointStorage); cvClearSeq(ptseq);

return hull;

}

//Helper function to draw a convex hull on an image
void DrawConvexHull(IplImage *dstImage, CvSeq *hull, CvScalar colour, int width) {

if(hull) {

CvPoint pt0 = **CV_GET_SEQ_ELEM( CvPoint*, hull, hull->total – 1 );

//wander through the hull drawing from point to point
for( int i = 0; i < hull->total ; i++ ) {

CvPoint pt = **CV_GET_SEQ_ELEM( CvPoint*, hull, i );
cvLine(dstImage, pt0, pt, colour, width);
pt0 = pt;

}
}
}

All Things Fuzzy

For the last few months I have been looking at Fuzzy Logic and Fuzzy Sets. These things are great, they allow you to build software systems that are based on linguistic rules such as , “If the car in front is close, then brake”. The fuzzy bit is the term ‘Close’, what is close? Certainly my idea of close is different to many others on the road.

It’s this ability to program for vaguness that’s cool. Following this I started looking at Type 2 Fuzzy Logic systems, this adds a third dimension to the processing and to be honest gets a bit silly in the amount of computing power its uses, but there are simplifications that make it workable. Ok so where is this leading, to be honest I have no idea, I shall just enjoy the ride.

But what does it do?

I have been looking at behavioural robotics these last few weeks and the result, Herbert, has been wandering around our living room, much to the amusement of our family and friends.

Herbert is made of Lego and doesn’t really do too much. He wanders around the room avoiding obstacles and, when he finds some food, or more acurately something green on the floor, he slows down as if to eat it. The point of course, is that it is an exercise in programming not one of application. For me, this exercise in programming has taken me back to basics. This week for example, Herbert been used to demonstrate the effectiveness of the ‘finite state machine’.

Finite state machines are incredibly simple to code and very effective. They go something like this:

Herbert

//(pseudo code)
while(true){
  switch(currentState)
  {
  case stateForward:
    if(obstacleDetected)
    {
      setReversingTimer()
      currentState = stateReversing
    }
    else
    {
      forward()
    }
  case stateReversing:
    if(reversingTimeElapsed)
    {
      setTurningTimer()
      currentState = stateTurning
    }
    else
    {
      reverse()
    }
  case stateTurning:
    if(turningTimeElapsed)
    {
      currentState = stateForward
    }
    else
    {
     turn()
    }
  }
}

Ok so now we have a state machine handling our robots meandering. We can easily add extra states e.g. ‘Feeding’ and so on. However, as all of the wandering and avoiding is done on a single thread of execution, what we could do is add the extra behaviours to additional threads. This way we end up with a whole stack of state machine controlled behaviours all accessing the same motors and sensors. We need a bit of arbitration to control access to the motors and sensors but this approach (Subsumption; Brooke, 1986) is great for our Herbert.

The thing is that should anyone ask how he works, I can answer by describing the above with large helpings of geekish enthusiasm. The trouble is that all I ever get asked is ‘What does it do?’ In which case I end up replying, ‘Not much really’.

Can anyone draw me some 4D shapes?

I was listening to Simon Coupland recently. He has come up with a way of simplifying the task of finding the centroid of a 3D shape.

Its all to do with his work on fuzzy logic controllers and to be honest it was tad boring until he got his robot out.

Simon is clearly an amazing guy, his ideas to simplfy the maths involved, are to cover the 3D shape with triangles and use geometric calculations. If none of this makes sense, don’t worry all it means is that instead of needing a computer the size of a planet, I can now work out this stuff on my Blackberry. But that’s not all, there’s more.

Simon pointed out that his approach should work with 4D shapes and in fact 5D and 6D shapes, and so on. We can easily get a computer to draw all of the triangles and see if he is making a reasonable attempt to represent a 3D shape. However, I have no idea how to test for 4D or 5D as I have no idea what a 4D or 5D shape looks like.

So if you are any good at drawing could you send me some 4D shapes to play with, many thanks.

Follow

Get every new post delivered to your Inbox.

Join 27 other followers