Labels

Saturday, March 30, 2013

Rethinking the Blackboard Control

Well, I'm back on the Blackboard problem.  I had put together a home-brew blackboard system for another project and will be utilizing some of the patterns and development I did there.  For one thing, I was able to have the matcher portion of the system be able to be built from definitions that were contained in an xml file.  In fact, part of the process was to create new source code from xml file elements.  So I had a way of prototyping using xml, and when something became proved out I would then be able to use the same program to bootstrap new source code that could then be combined with the previous source code and compiled.  In this way, I simplified the testing that needed to be accomplished especially in the case that the problem that was being solved was not completely spelled out, i.e. the requirements were not fully thought out.

In the process of putting the home-brew blackboard together, I had not given much thought to the control issue.  The proper way of adding control to a blackboard system is to allow the control to be modified along with execution of the domain knowledge sources.  The blackboard system is then divided into two areas, one for the domain knowledge sources and one for the control plans.  The idea is to now have control knowledge sources that compete for run-time with the domain knowledge sources.  So how am I supposed to be able to get this new found control problem to work?  My thought is that I need to start with a simple control knowledge source that executes a simple control plan and places initial knowledge sources to be executed.  As the problem progresses, the elements of control and domain will play out as changes to the blackboard occur.

I am a great proponent of utilizing already proven designs, such as the concept of design patterns.  In the POSA1 book, there is a chapter on Blackboard.  I will be using this along with a design pattern paper entitled, "Two complementary patterns to build multi-expert systems" by Philippe Lalanda.  This paper was the first time that I had encountered the control and domain separation of blackboard execution.  I have later learned that BB1 was the first blackboard system to have used the idea.  I have been reading a number of papers on the subject and I am warming to the idea that this would be the way to go.  Right now my express purpose is to use this blackboard architecture to control my robot and in the process learn some things about control processing that I can reflect back into the previous project.

So if the Blackboard is utilized by the Domain knowledge sources and the Control Plan is utilized by the Control knowledge sources, how is the basic Control structure to run?  Looking at the paper I see that the Control reads both the Blackboard and Control Plan.  The knowledge sources (KS) themselves (both domain and control) will activate the Control as necessary.  The Domain knowledge sources (DKS) operate on the Blackboard and the Control knowledge sources (CKS) operate on the Control Plan.  In the original Blackboard pattern, the Control element executed a loop, determining the nextSource to execute by examination of the Blackboard and then going through the different KS which determine if they have something to offer.  Those KSs that have something to offer are placed on a list for execution and when the nextSource routine ends, the Control loop then executes each of the KS in the list.  The execution through this list, either first come first serve, or by priority, or by some other mechanism can be thought of as the control plan.

My home-brew blackboard system used a rather simplified control plan, always executing the same sequence of DSs based upon whether they had something to offer or not.  An incoming message was the trigger event that caused the whole sequence to be executed.  The incoming messages were then as a result queued for execution.  So the whole sequence, even though it was somewhat non-deterministic, ended up being an event driven case statement with matching patterns that executed as necessary.  I really did not have the concept of multiple hierarchical levels on the Blackboard such as what is in BB1.  This does not give the capability for more complex problem solving.  I need to change this capability in order to move on.

Stupid RPi Tip #4 - write it down!

If you are an experimenter like me, you try all kinds of crazy things.  More often than not, you will have more than one experiment going on at a time.  The nice thing about the Raspberry Pi is that it is so easy to change out one to do a different experiment with by simply replacing the SD Card.  This also means that sometimes you loose your place in what you were doing before and trying to remember something that you were working on two weeks ago becomes a challenge.  Answer to the dilemma, write what you do down.  I am speaking of keeping a notebook or a journal or an online notepad of some sort.  Anything that will give you the chance to regain your thoughts on where you were six months ago on a project.  Obviously this means that you need to be able to put down more than 160 characters at a time.  Think of the things you can do:

1. you can record what your ultimate goal is and what path you hope to use to accomplish that goal
2. you can record what prompted you to try this very thing
3. you can record what things you learned, and what resources you used (like SD Card numbers)
4. you can record if this particular time you were successful or not - even Thomas Edison failed over a 1000 times before he got the right combination of components to make a lightbulb, his notebooks were very handy to keep him from redoing what already didn't work
5. you can record what you hope to do in the next iteration
6. if you become famous the notes are very valuable for your memoirs and if you patent something the notes will hold up in a court of law

Robot Serial Interface Protocol

Based upon a serial interface description that I found at http://forums.trossenrobotics.com/tutorials/how-to-diy-128/complete-control-of-an-arduino-via-serial-3300/, I have decided to try doing the interface in a like manner. I could use firmata but I do not want to program the RPi in python. Here is what I have come up with so far:

Robot Interface Protocol (Serial)
1 - write
    1 - digital pin write
        "pin number"
        "1 for LOW, 2 for HIGH" --> sets pin to value, returns OK
    2 - analog pin write
        "pin number"
        "frequency (0-255)" --> sets pwm on pin to value, returns OK
    3 - LCD panel error display
        "error number"

2 - read
    1 - digital
        "pin number" --> returns digital pin value (0 or 1)
    2 - analog
        "pin number" --> returns analog pin value (0 - 1024)

3 - servo (via Maestro)
    1 - read
        "servo number" --> returns pwm value
    2 - write
        "servo number"
        "pwm value" --> sets servo to pwm value, returns OK

4 - IR distance sensor (GP2D12 and servo)
    1 - set sweep range
        "low sweep pwm value (4000 - 8000)"
        "high sweep pwm value (4000 - 8000)"
        "sweep speed (0.25 us / 10 ms)"
        "sample rate in ms" --> returns OK
    2 - set IR distance servo
        "pwm value" --> returns OK
    3 - sample IR distance sensor (raw) --> returns "IR", raw value
    4 - sample IR distance sensor (computed) --> returns "IR", computed value
    5 - start continuous sample
        -->starts sweep back and forth; returns "IR", pwm, computed,
            raw at sample rate
    6 - stop continuous sample --> returns OK
    7 - get statistics at current pwm
        "number of samples" --> returns "IR", pwm, mean, sd of computed, mean, sd of raw
    8 - display samples on LCD panel
        1 - start --> returns OK, starts showing samples on LCD panel
        2 - stop --> stops showing samples, clears LCD panel, returns OK

5 - Ultrasonic distance sensor (HC-SR04 and servo)
    1 - set sweep range
        "low sweep pwm value (4000 - 8000)"
        "high sweep pwm value (4000 - 8000)"
        "sweep speed (0.25 us / 10 ms)"
        "sample rate in ms" --> returns OK
    2 - set Ultrasonic distance servo
        "pwm value" --> returns OK
    3 - sample Ultrasonic distance sensor (raw) --> returns "UL", raw value
    4 - sample Ultrasonic distance sensor (computed) --> returns "UL",
        computed value
    5 - start continuous sample
        -->starts sweep back and forth; returns "UL", pwm, computed,
            raw at sample rate
    6 - stop continuous sample --> returns OK
    7 - get statistics at current pwm
        "number of samples" --> returns "UL", pwm, mean, sd of computed, mean, sd of raw
    8 - display samples on LCD panel
        1 - start --> returns OK, starts showing samples on LCD panel
        2 - stop --> stops showing samples, clears LCD panel, returns OK

6 - camera pan and tilt servos
    1 - set sweep range for pan
        "low sweep pwm value (4000 - 8000)"
        "high sweep pwm value (4000 - 8000)"
        "sweep speed (0.25 us / 10 ms)" --> returns OK
    2 - set sweep range for pan
        "low sweep pwm value (4000 - 8000)"
        "high sweep pwm value (4000 - 8000)"
        "sweep speed (0.25 us / 10 ms)" --> returns OK
    3 - set camera pan and tilt servos
        "pan pwm value"
        "tilt pwm value" --> returns OK
    4 - start continuous sweep
        -->starts sweep back and forth; returns OK
    5 - stop continuous sweep --> returns OK

7 - reset all to setup conditions

Friday, March 29, 2013

Distance sensor data gathering

So I was able to start gathering sensor data last night.  I wanted to start gathering information on the two distance sensors in order to be able to calibrate the system.  I have enough errors propagating around, I just wanted to understand a little more about the IR and Ultrasonic Distance Sensors themselves and how they behave and how well they measure distance.
In the picture below, you can see the IR distance sensor (GP2D12).  I was able to modify the Arduino code to give me values output on the LCD display.  My measurements were from the front of the sensor housing, that means that I will need to add the offset from the front of the sensor housing to the center of the servo rotation point to get an accurate reading on the measurements.



For the ultrasonic distance sensor (HC-SR04) the measurements will be the same.  I will measure from the front of the sensor housing to the target and will add the distance from the front of the sensor housing to the center of the servo rotation point.



Wires: now that I have everything hooked up on the Lexan plate, the wire jumble on the top of the Arduino breadboard is pretty much a mess.  I am thinking of getting a proto board and putting headers on it in order to not have the jumble on top.  You can see what I mean by the picture below.



When I took the values from the IR distance sensor, I was surprised to notice how much the value changed with each sample.  The measurements are as follows:

Distance Measure1 Measure2 Measure3
2 7.24 7.22 7.26
2.25 6.76 6.72 6.72
2.5 6.84 6.91 6.82
2.75 7.54 7.64 7.68
3 8.23 8.66 8.57
3.25 9.23 9.18 9.15
3.5 9.97 9.97 9.36
3.75 10.95 10.92 10.85
4 11.39 11.32 11.46
4.25 12.28 12.24 12.24
4.5 12.84 13.05 12.84
4.75 13.72 13.72 13.72
5 14.39 14.29 14.24
5.5 15.67 15.73 15.67
5.75 16.63 16.26 16.5
6 17.08 17.14 17.08
6.25 17.96 17.89 17.89
6.5 18.47 18.4 18.18
6.75 19.01 18.7 19.01
7 19.9 20.15 19.98
7.25 20.33 20.24 20.33
7.5 21.52 21.42 21.42
7.75 21.81 21.71 21.9
8 23.26 23.04 23.04
9 25.9 25.51 26.03
10 28.63 28.79 29.11
11 32.89 32.29 33.5
12 36.64 36.4 35.92
13 35.92 31.92 36.4
14 40.65 40.65 40.65


Even though I took three measurements at each distance, the values pretty much vary pretty wildly.  A simplified graph of these measurements are as follows:

Actually, I should probably try and swap the x and y axis.  The x axis is the distance and the y axis is the measured values.  True to the data sheet, values that approach around 2 inches from the front of the sensor will change up and values over about 12 inches seem to start varying wildly.  In between, from 2 to 12 inches, the values seem to be steady and are almost linear given the formula in the sampling routine.  The values that return from the Ultrasonic sensor seem to vary even more crazily (see video below).

What I am learning from this is that I might have to rethink how the robot will follow the wall with the sensor data that I am seeing.



Thursday, March 28, 2013

Distance Calibration and Angle of Same

Ok, here are the current issues:

1. I have two distance sensors on the Lexan plate.  One is a GP2D12 ir distance sensor that is supposed to measure some short range distances.  The other is a HC-SR04 ultrasonic distance sensor that measures somewhat larger distances.  Each of these distance sensors have non-linearity in the values they return.

2. Each of the distance sensors are mounted on servos on either side of the Lexan plate, meaning that the center of rotation is off center from the iRobot Create.

3. When the servos were mounted, I noticed that they were not completely perpendicular to the Lexan plate, nor is the Lexan plate oriented in a perpendicular manner when mounted to the iRobot Create.  That means that the angle of rotation needs to be adjusted.  In addition, the Lexan plate is somewhat offset from the center of the iRobot Create and may have a rotation effect.

4. There is an area on the plate where each of the distance sensors can rotate to and an area where they cannot, a sector of a circle if you will.  There will need to be adjustments to the sweep for each of the distance sensors so that the values they return will be acceptable.

5. Servos have issues in that there are discrete steps that they make rather than a continuous movement.  Also, there needs to be a correlation between the pwm value and the angle of rotation for the servos, which may be different in each servo.

The above issues make it difficult to relate the measured values with what is really out there.  This post is an attempt to define those issues and point to a solution.  The overall requirement is to have measurements be absolute to a specific point, in this case the centroid of the iRobot Create.  In order to do this I will have to deal with a number of coordinate systems.  To simplify everything, I am going to assume an XY plane (i.e., no Z axis involved here), however I will retain XYZ coordinates for purposes of being able to add them in later.  In this case translation is only in the XY plane, rotation is only about the Z axis, and the Z value is always 0.  Note that I will assume no scaling.  I will use matrix algebra to translate everything into iRobot Create coordinates (assuming that 0,0 is at the center of the Create).  So when I take a measurement of a point, it can be translated into the iRobot Create coordinates.  So to make it easier we have rotation around the Z axis at an angle psi with translation in the X (Tx) and Y (Ty).  Note that normally the translation in Z (Tz) would be zero.




Notice that if there is no rotation, i.e. psi is zero, then cos psi is 1.0 and sin psi is 0.0 which is just a standard identity matrix with the translation parameters imposed. Where to begin:

a. Assume center of Lexan plate is the Lexan plate origin.  The centroid of the plate should be an easy calculation, assume normal XY coordinates - measurements should be consistent (i.e., in inches).

b. Assume center of servo rotation is the servo origin.  Distance measurements from each distance sensor should be to the servo origin.  This simplifies the remaining transformations.

c. Servo -> Lexan coordinates: translate servo origin to Lexan center, rotate about Lexan center to compensate for Servo angle offset, scaling values should be equal to one (no scaling).  It should be easy to measure the servo origins in relation to the plate and figure out the translation values.  The servo angle offset may be more difficult, in the initial for simplification we can assume 0 degrees.

d. Lexan -> Create coordinates: translate Lexan origin to iRobot Create origin to compensate for plate offset, rotate about iRobot Create origin to compensate for plate rotation offset, scaling values should be equal to one (no scaling).

e. Create -> World coordinates: translate Create origin to World origin, rotate about World origin to get final World coordinates correct. No scaling, probably set the first matrix to an identity matrix for no effect.

Following the normal convention for such things, the final form of the equation is:


Fiddling with a full setup on the Arduino

I decided to go ahead and put together a complete setup of software in the Arduino.  I have been developing the interfaces to the servos, ir distance sensor, ultrasonic distance sensor, and LCD serial panel.  In the course of the changes, I decided to move the read of the ir distance sensor to the Arduino rather than read it through the Maestro.  I may end up changing my mind later.  So my setup in the IDE looks something like this:

// Pololu Mini-Maestro 18 Serial Servo Controller
// Power 9v Seperate power supply from Arduino
// GND to GND on the Arduino
// SSC RX pin to Arduino TX pin Pin04
// SSC TX pin to Arduino RX pin Pin03
// Channel 0 - Ultrasonic Distance Sensor Servo
// Channel 2 - Camera Pan Servo
// Channel 4 - Camera Tilt Servo
// Channel 6 - IR Distance Sensor Servo

// GP2D12 IR Distance Sensor
// Power 5v from the Arduino
// GND to GND on the Arduino
// GP2D12 Sensor analog Rx pin to Arduino Analog pin 0

// Parallax 2x16 Serial LCD Panel
// Power 5v from the Arduino
// GND to GND on the Arduino
// LCD Rx pin to Arduino TX pin Pin06

// HC-SR04 Ultrasonic Distance Sensor
// Power 5v from the Arduino
// GND to GND on the Arduino
// HC-SR04 Trig to Arduino TX pin Pin13
// HC-SR04 Echo to Arduino RX pin Pin12


This setup ends up forcing a number of pin definitions as so:

// Define constants
// Serial pins
const int tx_ToSSC=4; ///< Tx pin going to SSC
const int rx_ToSSC=3; ///< Rx pin coming from SSC
const int tx_ToLCD=6; ///< Tx pin going to LCD panel
const int rx_FrmLCD=5; ///< Rx pin coming from LCD panel(nc)
// Digital pins
const int digtx_ToUltraTrig=12; ///< Tx pin going to ultrasonic sensor trig
const int digrx_FrmUltraEcho=13; ///< Rx pin coming from ultrasonic sensor echo
// Channels on SSC
const int chan_ultraservo=0; ///< Channel 0 - Ultrasonic Distance Sensor Servo
const int chan_camerapanservo=2; ///< Channel 2 - Camera Pan Servo
const int chan_cameratiltservo=4; ///< Channel 4 - Camera Tilt Servo
const int chan_irdistservo=6; ///< Channel 6 - IR Distance Sensor Servo
// Analog pins
const int rx_irdistanalog=0; ///< IR Distance Sensor analog Rx



I have gleaned from several sources the code that I need to access each of these items.  First up, is my interfaces to the two serial connections needed for the SSC (Maestro) and the LCD panel:

// initalizing serial connections
SoftwareSerial SSC_Serial = SoftwareSerial(rx_ToSSC, tx_ToSSC);
SoftwareSerial LCD_Serial = SoftwareSerial(rx_FrmLCD, tx_ToLCD);


Next up, I have the procedure interface to the SSC that sets a servos pwm value:

// Send a Set servo pwm command to the Maestro.
// Target is in units of quarter microseconds
// so the normal range is 4000 to 8000.
void ssc_cmnd_pwm(unsigned char servo, unsigned int target)
{
    SSC_Serial.write(0xAA); //start byte
    SSC_Serial.write(0x0C); //device id
    SSC_Serial.write(0x04); //command number
    SSC_Serial.write(servo); //servo number
    SSC_Serial.write(target & 0x7F);
    SSC_Serial.write((target >> 7) & 0x7F);
}


Next, I have a few routines for writing information out to the LCD panel:

// display two strings on the LCD panel
void lcd_display_2_str(String myvalue1, String myvalue2) {
  delay(100);
  LCD_Serial.write(12); // Clear            
  LCD_Serial.print(myvalue1); // First line
  LCD_Serial.write(13); // Form Feed
  LCD_Serial.print(myvalue2); // Second line


// display string and int value on one line, string on second line on the LCD panel
void lcd_display_2_str_int(String myvalue1, int myvalue, String myvalue2) {
  delay(100);
  LCD_Serial.write(12); // Clear            
  LCD_Serial.print(myvalue1); // First line
  LCD_Serial.print(myvalue, DEC);
  LCD_Serial.write(13); // Form Feed
  LCD_Serial.print(myvalue2); // Second line


// display integer value on the LCD panel
void lcd_display_int_val(int myvalue) {
  delay(100);
  LCD_Serial.write(12);                 // Clear            
  LCD_Serial.print("val: ");
  LCD_Serial.print(myvalue, DEC);  // First line
  LCD_Serial.write(13);                 // Form feed


Next, I deal with the gp2d12 ir range detector (along with a test):

/*
 read_gp2d12_range
 Function that reads a value from GP2D12 infrared distance sensor and returns a value in centimeters.

 This sensor should be used with a refresh rate of 36ms or greater.

 BY: Javier Valencia 2008

 float read_gp2d12_range(byte pin)

 It can return -1 if something gone wrong.

 */

float read_gp2d12_range(byte pin) {
    int tmp;

    tmp = analogRead(pin);
    if (tmp < 3)
        return -1; // invalid value

    return (6787.0 /((float)tmp - 3.0)) - 4.0;
}

void test_irdistance()
{
  float myval;
  myval = read_gp2d12_range(rx_irdistanalog);
  Serial.print("ir val: ");
  Serial.println(myval);
//  LCD_Serial.write(12);                 // Clear            
//  LCD_Serial.print("ir val: ");
//  LCD_Serial.print(myval, DEC);         // First line
//  LCD_Serial.write(13);                 // Form feed
}


Next, I deal with the Ultrasonic distance sensor (HC-SR04):

/*
  HC-SR04 Ping distance sensor
  VCC to Arduino 5v, GND to Arduino GND
  Echo to Arduino pin 13, Trig to Arduino pin 12
  more info at: http://goo.gl/kJ8G1
  */

float grab_ultrasonic()
{
  int duration;
  float distance;
  digitalWrite(digtx_ToUltraTrig, LOW);
  delayMicroseconds(2);
  digitalWrite(digtx_ToUltraTrig, HIGH);
  delayMicroseconds(10);
  digitalWrite(digtx_ToUltraTrig, LOW);
  duration = pulseIn(digrx_FrmUltraEcho, HIGH);
  distance = (duration/2) / 29.1;

  return distance;
}

void test_ultrasonic()
{
  float mydist;
  mydist = grab_ultrasonic();
  if (mydist >= 200 || mydist <= 0){
    Serial.println("Ultra: Out of range");
//    LCD_Serial.write(12);                 // Clear            
//    LCD_Serial.print("Out of range");
//    LCD_Serial.write(13);                 // Form feed
  } else {
    Serial.print("Ultra: ");
    Serial.print(mydist);
    Serial.println(" cm");
//    LCD_Serial.write(12);                 // Clear            
//    LCD_Serial.print("Out of range");
//    LCD_Serial.print(mydist, DEC);
//    LCD_Serial.print(" cm");
//    LCD_Serial.write(13);                 // Form feed
  }
}


In order to utilize these, I have the following setups:

// run once, when the sketch starts
void setup()
{
  // setup pins for serial interface to SSC
  pinMode(rx_ToSSC, INPUT);
  digitalWrite(tx_ToSSC, HIGH);
  pinMode(tx_ToSSC, OUTPUT);
  // set SSC serial interface speed
  SSC_Serial.begin(9600);

  // setup pins for serial interface to LCD
  pinMode(rx_FrmLCD, INPUT);
  digitalWrite(tx_ToLCD, HIGH);
  pinMode(tx_ToLCD, OUTPUT);
  // set LCD serial interface speed
  LCD_Serial.begin(9600);
  // initial clear and backlight for LCD
  LCD_Serial.write(12); // Clear            
  LCD_Serial.write(17); // Turn backlight on
  delay(5);             // Required delay for response

  // set SSC servos to initial state
  ssc_cmnd_pwm(chan_ultraservo,6000);
  ssc_cmnd_pwm(chan_camerapanservo,6000);
  ssc_cmnd_pwm(chan_cameratiltservo,6000);
  ssc_cmnd_pwm(chan_irdistservo,6000);
 
  // set Ultrasonic Distance Sensor pins
  pinMode(digtx_ToUltraTrig, OUTPUT);
  pinMode(digrx_FrmUltraEcho, INPUT);
 
  // setup our serial monitor
  Serial.begin(9600);
 
  // wait for settling to happen
  delay(1000); 
}


Now that I have the initial software coded, I have time to try them out and start to build the interfaces between the Arduino and the sensors/servos.  Next up will be results of the testing, followed by dealing with the interface to the RPi.

Wednesday, March 27, 2013

Next Move - Get Arduino SW Working

Connections are in place and now I can settle down to figuring out the software in the Arduino, the breadboard connections for same, and the interface software from the RPi.  I still have a number of interfaces that need to be tested:

1. the Ultrasonic Distance sensor needs to be wired up through the breadboard and the interface software needs to be written for the Arduino
2. the IR Distance sensor interface software needs to be written for the Arduino
3. the interface software for the two distance sensor servos needs to be written for the Arduino
4. the interface software for the two camera servos needs to be written for the Arduino
5. a control protocol, including response, needs to be thought up between the RPi and the Arduino and coded on both sides - ultimately this will be used by several Facades in the RPi software
6. a control protocol, including response, needs to be thought up between the RPi and the iRobot Create and coded in the RPi
7. afterwards I can concentrate on more higher level software, including the blackboard.

The connection diagram has changed

Now that I have come to the conclusion that I can move a lot of the hardware control down to the Arduino, I have redone the Test Setup connection diagram.



This diagram now shows the two ways that I have of controlling the iCreate, either through the Arduino or via a USB serial line.  In addition, I have added the IR and Ultrasonic Distance Sensors and their servos.  I changed out the SSC-32 for the Maestro, since that seems to be a better bet.  I have also added a temporary place holder for a Joystick/Button shield connected to an Arduino.  The purpose for this connection is to be able to use a Joystick controller to control movement and camera remotely, not something I want to have in the final model.

Was able to Setup Full Connection

Now that I have settled in on what the interfaces should be, I took the time to mount the Arduino and the Pololu Micro-Maestro onto the Lexan piece.  I did take advantage of the fact that the Lexan is not conductive, and just screwed the Maestro down onto the plastic without any kind of standoffs.




A close up of the connections is shown in the following picture.



I will say that I did at first have problems with the setup.  After I got everything mounted I tried out the Arduino test program that I had written, and I could not get it to work.  I started removing all kinds of wires and eventually got everything down to just the interface to the LCD panel and I got it to work.  What I did not realize was that when I turned on the power to the servos, I failed to turn on the master switch on the power platform.  That is why the servos would not operate, they did not have any voltage because I had removed the voltage jumper on the Maestro.  Once I figured that problem out I was able to get both the one servo and the LCD to respond.  Maybe I need a checklist.

Monday, March 25, 2013

Got Servo and LCD Panel to Work Together

I was wondering if the little Arduino would be able to keep up with a multiple number of tasks that I was giving it. I was able to program the Arduino UNO from my RPi to have two serial connections. One was to my Pololu Mini-Maestro and the other was to my Parallax 2x16 LCD display. I was able to get it to display what values I was sending to the Maestro. I did discover that turning off the backlight on the LCD took too much time. I also discovered that the servos that I am using respond better to 9 volts than they do to 6 volts. The serial connections were at a 5 volt level.

On the Maestro, I used the gnd, 5 volt, Rx, and Tx lines on the side and connected them to gnd, 5 volts, digital pin 4, and digital pin 3. This is the GND, VIN, RX, and TX pins on the left hand side of the board.  I removed the VSRV=VIN jumper and connected the 9 volt supply to the servo power on the bottom right.  During the test I had the servo connected to channel 0.



On the LCD panel, I used the gnd, 5 volt, and Rx lines and connected them to gnd, 5 volt, and digital pin 6. Fortunately, I was able to easily accommodate the different pins due to the fact that I was using the Parallax breadboard shield which breaks out each of these pins around the breadboard.

My main motivation in doing this experiment was to see how many things I could seasonably  attach to the Arduino that would be controlled independently.  This gives me hope for being able to move much of the hardware control down to the Arduino micro-controller.

Saturday, March 23, 2013

Starting Up Robot SW Build

Over the next few months I will be posting updates on what is going on with the Robot SW build.  I intend on building the software from a design at the top which will meet with some experimental software which drives different components at the bottom.  Hopefully, they will meet somewhere in the middle correctly.  The reason that I need to work on the bottom components is that I need to make sure that I have a sufficient set of facades that will talk to the hardware correctly.  I am excited about the prospects and from here on out will try to give a play by play description of what I am up to.  I will be using BoUML for the UML design and will document things by posting them here.

Saturday, March 16, 2013

Using the Arduino as a control head for the RPi

I am thinking that possibly I might use the Arduino as a control head for the RPi. I can get a two line LCD panel with a series of buttons and that is enough to have a menu system. I could connect either via Ethernet or by USB serial.

As part of prep for this experiment, I went by the MicroCenter near me and purchased a two line serial LCD panel; complete with an Arduino processor to control it. I also picked up a joystick shield for the Arduino to add some controls to it.

Just got a new Gertboard

I just received a new Gertboard for the RPi. It was home when I arrived from my trip to Florida. When I opened it up, I was expecting that there would be a ribbon cable amongst the items in the box. However, as I started looking through the user manual, it became apparent that I was wrong.




The Gertboard has a different connection when used with the RPi.




The Gertboard has a GPIO connector, but is turned away from the RPi. The kit does have standoffs, the assumption is that the combination sits on the table. I will now Need to determine if I can actually put a ribbon cable on the Girtboard and connect it to the RPi. The combination takes up a lot of real estate and is really not functional for use with the Robot HW that I am building up. I only have so much room on the piece of Lexan. What this will probably force me to do is use the Gertboard to make a circuit and then duplicate it on a breadboard. Then again, maybe I will use the Gertboard for other things.

Wednesday, March 6, 2013

Lower Level Classes for Experiments

In looking at the overall structure of what I want to do with experiments and such, I have come up with the following list of lower level classes that need to be developed:

1. SSC-32 Facade - [HW interface] this will be a collection of routines that will be able to get to the execution points for the SSC-32 servo controller.  Specifics:
a. include routines to open / close the connection(s)
b. include routines to read analog and I/O for the digital aspects of the controller
c. include routines to set / read the current pulsewidth of the servo control. since the controls may be made through the Arduino, this facade needs to make sure of being able to proxy the connection to the SSC-32, and this might involve going through the network

2. Pololu Mini-Maestro Facade - [HW interface] this will be a collection of routines that will be able to get to the execution points for the Pololu Mini-Maestro (18) servo controller. Specifics:
a. include routines to open / close the connection(s)
b. include routines to read analog and I/O for the digital aspects of the controller
c. include routines to set / read the current pulsewidth of the servo control
d. since the controls may be made through the Arduino, this facade needs to make sure of being able to proxy the connection to the Pololu Mini-Maestro, and this might involve going through the network

3. Arduino Facade - [HW interface] this collection of routines will utilize the Firmata protocol initially and later will reflect a home grown protocol later on.  The purpose is to be able to access most of the functionality of the Arduino through this interface.
a. general interfacing topics for the Arduino is at http://playground.arduino.cc/Main/InterfacingWithHardware.
b. the Firmata information is at http://firmata.org/wiki/Main_Page.

4. Video Facade - [HW interface] this collection of routines will focus on gathering a video stream and/or information about the video including snapshots and setting webcam parameters.

5. Robot Link Facade - [HW interface] this will be a collection of routines that will be able to move data between various CPUs within the Robot and will include connections to external PCs.  The reasoning for having this Facade is to be able to grab sensor information from a remote source as necessary.

6. Ultrasound Distance Sensor Proxy - since I will not know in advance of where I will connect the Ultrasound sensor, this will utilize the underlying Facades to control and gather information re the sensor.  I want to include calibration routines, setting the servos, reading the sensor, starting/ending sweeps, etc.

7. IR Distance Sensor Proxy - since I will not know in advance of where I will connect the IR distance sensor, this will utilize the underlying Facades to control and gather information re the sensor.  I want to include calibration routines, setting the servos, reading the sensor, starting/ending sweeps, etc.

8. Camera Pan/Tilt Proxy - since I will not know in advance of where I will connect the pan and tilt servos, this will utilize the underlying Facades to control the servos.  I would like to include setting the position of the servos and reading where the servos are, along with calibration routines.

9. Video Stream Proxy - this will pretty much be an interface point to the video stream, no matter where the webcam(s) are placed.  This would include such things as streaming the video between CPUs within the Robot space.

10. Robot Arm Proxy - since I will not know in advance of where I will connect the robot arm servos, this will utilize the underlying Facades to control the servos.  I would like to include setting the position of the servos, getting feedback on other sensors (pressure), and reading the servo positions, along with calibration routines.

I think this is a list that will keep me busy for a while getting ready for the main routines to execute the Robot software.

May Have Found an In-Between Code for Arduino

I had an interesting question for one of the engineers this morning.  I asked him if he knew of any remote control for the Arduino in which a command could be sent to the Arduino for execution in lieu of programming the Arduino for a specific purpose.  Interestingly enough, I found the Firmata project (http://firmata.org/wiki/Main_Page).  This appears to be a protocol based upon the Midi control signals and is geared for micro-controllers of which the Arduino is one.  There is a load for the Arduino for the protocol server, and a test program to run from a side computer.  All software is available for both sides.  In looking through the protocol, it looks like it might do everything that I need it to do for experimentation purposes.  Obviously, I would program the Arduino to do specific tasks after I figure out what I need it to do.

The Strange Process You Go Through

It might appear to be a little weird that I have been concentrating on the hardware aspects of experiments prior to concentrating on the software aspects.  The reasoning is that:

1. I have something in mind that I want to do,
2. I visualize what it would take to do it,
3. Since I am not that familiar with the hardware devices, I order some that look interesting,
4. When I get the hardware in, I assemble it into an experiment package knowing that I will need to try out a few things prior to getting the final product,
5. Write out software for the experiments and choose the best course of action for the final product,
6. Design the software for the final product,
7. Changeout the hardware to accomodate the final product,
8. Code and test the software for the final product

I have more of an experimenter's mindset when it comes to these things.  I want to learn and the best way to learn is to try things out and come to some sort of a conclusion.  You not only get experience but it helps later when you are trying to design something else.

Opened up a repository at GitHub

In light of my wanting to get ambitious, I have added a repository at GitHub (https://github.com/linuxweenie/rpiexperiments).  I will have the link for this repository to the right of the blog and will be adding software as it becomes available.

Sunday, March 3, 2013

Did some more setup

I spent a little time and finally got the servos and the new RPi mounted in the Lexan.


After looking at what I was able to do, it turns out that my servos are a little misaligned.  That means that I am going to have to calibrate the camera, all angles, the sweep motion, and other stuff in order to be accurate in any experiment that I might be doing.

Strange things you find out about

When I was at work last week, I talked to one of the other engineers and found out a few things about the Arduino, another single board computer. I found out that there is an IDE that you can use to compile and load new software into the Arduino. What I later found out was that the same IDE could be used to compile and load programs into the similar chip on the Gertboard. So I thought to myself why not start exploring the Arduino and find out some more about it, maybe I can use it in some of my experiments. Today I found out that you can put the Arduino IDE on the RPi as well as connect the Arduino and RPi together. So it looks like I will simplify my life somewhat and offload some of the tasking for watching the servos and distance sensors onto the Arduino. Yep, that's right, I went out and purchased one to use in my experimenters box.





That's a Ethernet shield on top, because I wasn't sure how I was going to get access to the Arduino from the RPi. Now we know.