msgbartop
I will happily conduct a FREE basic web security scan for any genuine organization interested in my services to point out whether or not I can find vulnerabilities in your application. Just contact me.
Need a PHP Programmer, PHP staff or project manager? Contact me now.
msgbarbottom

26 Dec 08 The Linux Robot – Progress, Software & a Video

Over the past week I’ve made a couple of hardware improvements, as well as building the majority of the software library, a TCP server and making a good start on a client.

The camera draws over 350mA@12V and there’s no reason why I need it permenantly on. I’ve connected one of the Phidget Kit’s outputs to a simple transistor/resistor/LED circuit, with a 12V supply passing into the transistor’s collector pin, through the transistor, relay input and resistor. Then I’ve connected the camera’s power over the relay’s output. The power on and off for the camera/LED are now through setting the board’s digital output 0 to 1 and 0 respectively. Power consumption with no movement has now dropped from 1.25A to just under 0.90A. I’ve also put all essential USB hardware on one usb hub and all optional hardware on another (USB to TTL adapters, sound adapter) on the other. The optional hub is also on a relay now on the opposite side of the robot, and this now reduces idle power consumption from 0.90A to about 0.50A which I’m happy with.


I’ve spent a while working on the software site of things. I’ve written a ‘library’ in C which interfaces with the various hardware that we’re interested in. The library provides a number of functions, I’ve listed the useful ones here, and they’re hopefully pretty self explainatory:

int motor_open_port(const char *path, struct termios *newopts, struct termios *oldopts);
Opens the port and sets things up ready for access. ‘newopts’ is a pointer to our termios struct which after this function is finished will contain our new port options. oldopts is a pointer to another termios struct which will be used to hold our current port settings. We’ll pass these to motor_close_port later. The function returns a file descriptor.

int motor_move(unsigned char controller, unsigned char outbyte);
Takes a 1 or a 0 to indicate the controller we’re talking to, and a single byte ‘outbyte’ to send to that controller.
int motor_close_port(int fd, struct termios *oldopts);
Close our serial port connection. Closes the port and restores our old termios settings.

int motor_move_simple(int fd, int fd2, unsigned char direction, unsigned char speed);
I’m not entirely sure that this should be part of the library itself but anyway – no harm done. It’s a wrapper to motor_move. We pass the two file descriptors or our open serial connections two the function, and then a direction from 0 to 6, being halt, left, forward, right, back, rotate left, rotate right, and speed being between 0 to 4, being halt, slow, medium, fast, faster.

int phidget_open_port(CPhidgetInterfaceKitHandle *ifKit, CPhidgetInterfaceKitHandle *ifKit2);
We provide new ifKit and ifKit2 variables by reference and phidget_open_port hopefully returns us our two phidget kits.

int phidget_close_port(CPhidgetInterfaceKitHandle *ifKit, CPhidgetInterfaceKitHandle *ifKit2);
Closes the above opened ifKit and ifKit2 descriptors.

int phidget_read(CPhidgetInterfaceKitHandle *ifKitTmp, unsigned char sensor, int *sensorvalue, unsigned char t);
Read from the phidget board, ifKitTmp being our handle, sensor being a sensor between 0 and 7, sensorvalue holding the result, and t being 1 or 0 depending on whether we want the interpreted or the raw value.

int phidget_set(CPhidgetInterfaceKitHandle *ifKitTmp, int sensor, int outputState);
Set an output high or low. ifKitTmp is our interface kit pointer, sensor is the output number between 0 and 7, outputState is a 1 or 0 for an on or off.

int phidget_read_input(CPhidgetInterfaceKitHandle *ifKitTmp, int sensor, int *result);
This reads the digital inputs.

int lcd_open(const char *title);
Prepare the LCD and return a file descriptor. title is the starting title.

int lcd_close(int fd);
Close the LCD connection

int lcd_write(int fd, int line, const char *t);
Write to the LCD, fd being our connection descriptor, line being a line from 1 to 4, and t being our output text.

int speak(const char *t, int block);
Speak! Using espeak. ‘t’ being our text, and block being a 1 or a 0 depending on whether we want to halt until speech is finished before continuing.

int stt(const char *model, int sec);
This is the start of the speech to text engine. Using CVoiceEngine. ‘model’ is a .cvc voice model file built using model_editor from CVoiceEngine. ‘sec’ is the number of seconds we’re going to wait for a command. The function returns a value which will either be -1 if nothing was matched, or a value from 0 and up which we set using model_editor for the recognised voice pattern.

On top of this library, I’ve built a TCP server largely based on Beej’s multiperson chat server example. For the moment, the protocol is simple. Issue a command and receive a response.

MM12  will move the motors, direction ’1′ (left) speed 2 of 4
MD0127 will send byte ’127′ to motor controller 0
PO101 will set the output of phidgets kit 1, sensor number 0, state 1 (this is how we turn the camera on/off)
PO100 will turn the above output to state 0 again
PI00 will return the state of input 0 on phidget kit 0
PS06 will read the interpreted value of sensor 6 on phidget board 0
PR05 will read the raw value of sensor 5 on phidget board 0
LW1{Test} will write ‘Test’ to the LCD line 1
AS0{Test} will speak ‘test’ and block
AH{yesno.cvc} will open voice model yesno.cvc and return a value of any text matched
Q1 shuts my connection
Q2 shuts closes open descriptors, and shuts the server software down gracefully
Q3 issues Q2 above and then a graceful halt to the system
Q4 runs kill -9 -1 instantly

With this toolkit software can be created rapidly in just about any language. I chose PHP for my first application. I call it ‘eyes’:

voyage:/mnt/usb/dev/client# wc -l functions.inc.php eyes.php
84 functions.inc.php
173 eyes.php

Code really is minimal yet powerful. ‘Eyes’ outputs lots of interesting statistics to the LCD read from various sensors. I have two light dependant resistors which I use as inputs. This software is set to run a full cycle at about 700Hz. The software is configured to take a running average of 3 consecutive readings from each sensor. The software will compare the results from both left and right light dependant resistors. I have allowed for a 12.5% DIFFERENCE_THRESHOLD and a 30% LOWER_THRESHOLD in calling the results ‘equal’. The logic is simple. If either the left or the right sensor is showing both above ‘LOWER_THRESHOLD’ and above DIFFERENCE_THRESHOLD to the other sensor, the light is brighter on that side, turn towards it. As soon as both sensors are ‘equal’ taking into account DIFFERENCE_THRESHOLD move straight. This simple logic allows the robot to follow the light. I’m using a bright LED torch. Here’s a video!

I haven’t published the library code, a) because it needs a lot of improvement, it’s a bit of a mess at the moment and b) I’m not sure that the bespoke code would serve much use to anyone but if anyone does want it, just drop me a line and I’ll post it.

Edit: Code can now be downloaded below.
Disclaimer:
1. I take no responsibility for any damage you do with this code or that this code does to you.
2. Parts of this code are licenced. Please respect the licence.
This code is hacky/very unstable. It needs a lot of work/tidying up. A lot of code specifically for UDP/TCP communications is from Beej and has been annotated as such. Please respect the licence of his code. This code is really not ready for public viewing. If anyone can submit bug fixes/improvements, that would be good. Otherwise, when I get some more time, I will release 0.1b which will be largely cleaned up and more stable.

http://www.adamsinfo.com/wp-content/custom/arobot-dev-31Dec08-0.1a.tgz [MD5: d3c74295e7c5268c5cf7a7b512e2cdbe]

Tags: , , , , , , , , , , , , , , , , , , , , , ,



Reader's Comments

  1. |

    drop it. you’ll never know if anyone wants it if you don’t do it. give it a license like GPL that will protect it and then you’re done

  2. |

    Interesting, I noticed when you started this project but didn’t consider that it would be a large robot, I’d assumed it would be like a desktop robot.

    Next you’ll need a petrol engine :)

  3. |

    [...] The Linux Robot – Progress, Software & a Video [...]

  4. |

    Thanks Lee! I did consider a small petrol engine but only briefly as it wouldn’t be so nice inside :)

    João: I have edited the original post with source code.



Leave a Comment

You must be logged in to post a comment.