Update: Design review

We spent this past week working on our plans for the code that will be implemented in our final version of Homer including working on the last bits of menu, odometry and localization code. We’ve learned a lot over the past several months (that we’ll apply to our next autonomous robot project) and realize there are a couple of really important considerations when designing and building a robot, especially an autonomous robot.

In our opinion, two of the most important are power requirements and digital and analog input/ output constraints. As an example, Pins 5,6,7,8 on the Rover are already used by the motors so we’re limited on digital IO available.

We also intentionally loaded Homer with many different sensors so I and the boys could gain experience with a lot of hardware and get a lot of practice with the Arduino libraries and it’s version of “c” but we realize this is a little impractical.

We now think that a minimal design is probably better. To much “stuff” will limit battery life as well.

So, we’ve decided to reduce the number of obstacle avoidance sensors to one; the ping sensor, mounted on a pan and tilt assembly. We’re thinking we’d like the movement of the pan & tilt assembly to be smooth and fast as it will have to scan quickly (side to side and down (for edge detection)) so we’ll likely let the Nano manage this and communicate serially with the Rover’s Duemilanove. We also discovered (after spending several evenings over the past week) that the latest servo library disables interrupts which interferes with many other libraries (like the ping). Having the servos on a separate micro-controller eliminates this problem.

Since we’re now really close to having Homer completed, we’ve decided, this past week to review our design and see if we could improve it based on what we’ve learned for the completed build.

Here’s a few design ideas we’re going to apply in our final implementation of Homer.

1. Although the Rover kit comes with a built in micro-controller based on the Arduino Duemilanove we believe including a second micro-controller (like an Arduino Nano) is a good idea.  In addition to more I/O, you’ve another “brain” to split up some of the work load. Of course, since both micro-controllers need to communicate, a mechanism will need to be decided as there are a couple of choices. We decided upon serial communications. The “NewSoftSerial” library http://arduiniana.org/libraries/newsoftserial/ was extremely easy to get working (code example below). I’ll include a bit of this code at the end of this journal entry.

2. Using a Centeye Rox1, Tam2 or 4  for odometry (velocity) and a compass will give any type of robot significantly better localization accuracy based on dead reckoning. Since Homer is a track based platform where wheel encoders are just not reliable (after all, on track systems it’s called “slip drive”) this was a significantly better choice. The time we’ve spent experimenting with various methods of measuring speed… especially optical flow,  has really benefited this project and our future projects.

3. As explained above, we’re reducing the number of sensors down to one, the ping, mounting on a micro pan & tilt assembly. The pan & tilt servos will be controlled by a dedicated Nano micro-controller.

4. The menu will have three options:

a. Manual (needed for tuning sensors, drives and motors)

b. Wandering (just for fun)

c. Localization (this will be automated - initial and  target coordinates will be driven to manually and a “fix” selection will mark in memory.)

5. We’re not certain we’ll need the LCD or keyboard now.  We may choose a smaller LCD … still considering …

Ok .. so that’s it for this week ..

Here’s the code … two Arduino’s communicating …. this is pretty cool stuff, by the way.

This is the test code for the Rover’s Duemilanove. It receives the scan position information from the Nano.

#include <NewSoftSerial.h>

#define rxPin 3  // pin 3 connects to other arduino TX
#define txPin 2  // pin 2 connects to other arduino RX
NewSoftSerial mySerial =  NewSoftSerial(rxPin, txPin);
int  serIn; //var that will hold the bytes in read from the serialBuffer

void setup()
{
  Serial.begin(38400);
    // set the data rate for the NewSoftSerial port
  mySerial.begin(38400);

}

void loop()                     // run over and over again
{

  if (mySerial.available()) {
      Serial.println("Reading Nano");
      while (mySerial.available()>0){
        serIn = mySerial.read();	//read Serial
        Serial.print(serIn, BYTE); 	//prints the serialbuffer
     }
      Serial.println();
  }
}

And this is the Nano test code.  The Nano is moving the pan & tilt servos and communicating

angular position  to the Rover .

(there are 4 in the scan and one tilt down) in the sequence.

#include <NewSoftSerial.h>
#include <Servo.h>

# define PinPanServo 10
# define PinTiltServo 9

#define rxPin 2  // pin 2 connects to other arduino TX
#define txPin 3  // pin 3 connects to other arduino RX
NewSoftSerial mySerial =  NewSoftSerial(rxPin, txPin);

Servo servoPingPan;
Servo servoPingTilt;

void setup()
{

//prepare to chat with Rover

  Serial.begin(38400);
  mySerial.begin(38400);
  mySerial.println("Hello Homer");

// Setup Pan and Tilt Servos

servoPingPan.attach(PinPanServo); //64 is center
servoPingPan.write(64);

servoPingTilt.attach(PinTiltServo); //92 is level
servoPingTilt.write(92);

}

void loop(){

          servoPingPan.write(64); //center pan
          delay(200);
          servoPingTilt.write (46); //position tilt sensor down for 500ms
          delay(500);   

          //signal master to fire ping and check for edge
          mySerial.println("Down");
          Serial.println("Down");
          servoPingTilt.write(92); //point tilt level

        //----------------------
        //scan
        int i;
        int positions[] = {13,48,83,117}; //scan through 4 positions

        for (i=0;i<4;i++){
        servoPingPan.write(positions[i]);

        /* signal master at each position "i" to fire ping 
        to determine "best" direction */

        mySerial.println(positions[i]);
        Serial.println(positions[i]);

        delay(500); //pause a each position to take a measurement
        }

        servoPingTilt.write(92); //point tilt level

} //loop
Follow

Get every new post delivered to your Inbox.