Sunday, 2 December 2018

How To Train Your Robot

Somehow we managed to miss a blog update in November - how time flies. 

November was all about software. The saws, screwdrivers, crimping tools and sellotape were put away, and out came the laptop. 

One of the aims of building this robot was for me to learn Python. After a couple of weeks, I was threatening to name this blog '10 things I hate about Python' but I persevered and am beginning to forgive it. 

I decided to keep it simple and implement a single, multi-threaded application, rather than trying to have multiple processes. I drew out a simple design - just to keep me on track using UMLet. This is the best free tool I've found for sketching out rough designs really quickly. This was just to give me a rough idea about the classes and what needs to know about what.. 

Initial Class Diagram

The actual software design has evolved somewhat during implementation, but the basic class structure is still there, so this diagram is still a useful reference. 

It took me a while to implement the serial comms between the Arduino and the Pi, but it was a useful learning exercise. The Arduino is connected to the ultrasonic sensors, so once this was done Sputnik could start sensing its environment. At the moment it's just one way comms - the Arduino reads the distances from the 5 sensors and pumps the data to the serial port. Once the Pi is up and running, it reads from the serial port and stores the distances in memory for the automated robot modes to use.

So - then on to implementing the first automated mode .....

The Straight Line (Speed) Test 

The first challenge to look at was the straight line speed test. I know the wording of the challenge says it won't be completely straight - but little steps and all that. 

I wrote a quick class to monitor the distances on the left and right and work out the rate of change of the robot as it approaches or moves away from either the left or right walls. It then adjusts the speed of the wheels slightly to try and keep going straight and then repeats the monitoring process. 

The initial attempt was actually quite good - except that sometimes it got confused and turned straight into the wall. Also - it didn't always stop at the end of the run on its own. I found that the ultrasonic sensors occasionally gave out erroneous zero results, so I added a filter to reduce the impact of these. 

Here's the results: 

It's difficult to see, but the robot does actually stop automatically at the end before it hits the door. It's early days, but we're happy. 

Things learned from this development:

  1. Working with a scripting language like Python takes some getting used to. Coming from a C++ and Java background, it's frustrating to have the code running, only for it to go down a path and come up with silly syntax errors. I've since learned to compile it first. I'll also looking into some other python syntax checking apps. 
  2. I didn't appreciate that Python applications are limited to a single core. I understand that it tries to keep it simple so you don't have to worry too much about using locks, or making variables volatile, but it is quite limiting. One of the points of writing multiple threads is to make use of several cores. I don't think it'll be an issue - but I may need to revisit the design if we start running out of processor bandwidth.
  3. Importing python modules and classes make my head hurt. I keep getting confused between a module and a class name and can take ages trying to work out what the issue is. 
  4. Watching a robot drive itself is pretty cool. 
Next steps - think about how to handle possible kinks in the course. Start coding the minimal maze mode. 


No comments:

Post a comment