Pages: [1] 2   Go Down
Author Topic: Roving robot  (Read 3721 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Full Member
***
Karma: 1
Posts: 223
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I built a roving robot, I call it "Marvin" since it just drives around and not do anything apart from occasionally colliding into stuff.

It uses a ultrasonic sensor for distance, two converted servos for driving the wheels, and another servo for rotating the sensor.

Here's a picture:



And a video clip of it in action with an old navigation algorithm:

Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 5
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi i need your help ... do u have any example codes to move a servo up n down ? like if i press A the servo will go UP n when i press S the servo will go down ... Thnx
Logged

0
Offline Offline
Full Member
***
Karma: 1
Posts: 223
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I can give you the code, but I think this explains it better than my uncommented code:

http://todbot.com/blog/wp-content/uploads/2006/10/arduino_spooky_projects_class3.pdf

I also read somewhere in the forum that someone posted a way of driving two servos with the PWM pins, but I can't seem to find the post. Search servo in the forum see if you can find it.

-Z-

Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 56
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Could you give more information about the servors and the sensor that you use for your robot ?
Logged

Sweden
Offline Offline
Newbie
*
Karma: 0
Posts: 27
Arduino really rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Yeah! Nice work man! Im building robots aswell so it's great to see someone else that does here too. I like how the robot feels so alive and active when it moves. It's not a rigid kind of movement.

Quote
Could you give more information about the servors and the sensor that you use for your robot ?

Lets see if i can help you...

The sensor is an ultrasonic sensor. It provides the robot a range sensing and gives a higher input the farer away the detected oblect is.

The servos seems to be of standard size, where the two driving servos have been modified to be continous driving. An unmodified servo is restricted to about 180 degrees movement and can be positioned in a specific degree.

What else do you need to know?
« Last Edit: August 15, 2007, 08:17:30 am by Fredrik_Andersson » Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 56
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Lets see if i can help you...

The sensor is an ultrasonic sensor. It provides the robot a range sensing and gives a higher input the farer away the detected oblect is.

The servos seems to be of standard size, where the two driving servos have been modified to be continous driving. An unmodified servo is restricted to about 180 degrees movement and can be positioned in a specific degree.

What else do you need to know?
It should be ok. I will try to do that and I will post the result later.
Logged

0
Offline Offline
Full Member
***
Karma: 1
Posts: 223
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Sorry I've been too busy with my uni project to browse the arduino forums lately.

Fredrik, thanks for the answer, you are exactly right!

I bought my ultrasonic sensor here:
http://www.sparkfun.com/commerce/product_info.php?products_id=639

I've connected the analog output directly to an analog-in to read the distance.

Good luck!

-Z-
« Last Edit: August 20, 2007, 04:42:12 pm by zitron » Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 5
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The ultrasonic sensor on a servo is an awesome idea. I just my steal it someday  :-*
Logged

0
Offline Offline
Full Member
***
Karma: 1
Posts: 223
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
The ultrasonic sensor on a servo is an awesome idea. I just my steal it someday  :-*


It wasn't my idea, I stole it from someone else smiley.
Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 56
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

what is the type of servo motor ? Do you have the schema of your circuit ? What is the goal of the capacitor ?  
Logged

0
Offline Offline
Full Member
***
Karma: 1
Posts: 223
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
#define LeftWheelPin 6
#define RightWheelPin 5
#define ArmServoPin 4
#define SonarPin 0

#define runningLED 2
#define errorLED 7

short ArmAngle, dAngleMax,dAngleMin, dAngleMaxTemp, dAngleMinTemp;
short ArmAngleRange, ArmAngleTarget;
short LeftSpeed;
short RightSpeed;
short ArmTrim = 0;
int distance, dmax, dmin, dmaxtemp, dmintemp;

unsigned long lastPulseL;
unsigned long lastPulseR;
unsigned long lastPulseA;

int i, k;
unsigned short refreshTime = 15;
unsigned long timeLast, timeLastFast;
unsigned long timeLastSlow;
unsigned int timeStart;

// --------------------------------------------------- LED flashing
void flashLED(short pin, short times) {
  for (i = 0; i<=times; i++) {
    digitalWrite(pin, HIGH);
    delay(100);
    digitalWrite(pin, LOW);
    delay(500);  
  }
}

// ---------------------------------------------------- Refreshes all servo pulses
void updateServos() {

  if (millis() - lastPulseL >= refreshTime) {
    digitalWrite(LeftWheelPin, HIGH);
    delayMicroseconds((LeftSpeed+90)*11+500);
    digitalWrite(LeftWheelPin, LOW);
    lastPulseL = millis();
  }

  if (millis() - lastPulseR >= refreshTime) {
    digitalWrite(RightWheelPin, HIGH);
    delayMicroseconds((-RightSpeed+90)*11+500);
    digitalWrite(RightWheelPin, LOW);
    lastPulseR = millis();
  }

  if (millis() - lastPulseA >= refreshTime) {
    digitalWrite(ArmServoPin, HIGH);
    delayMicroseconds((ArmAngle+ArmTrim+90)*11+500);
    digitalWrite(ArmServoPin, LOW);
    lastPulseA = millis();
  }

} // end updateServos

// ----------------------------------------------------- Rover move and turn function
void move(int speed, int turnSpeed) {
  //LeftSpeed = speed - turnSpeed;
  //RightSpeed = speed + turnSpeed;

  if (LeftSpeed < 30 && LeftSpeed < (speed - turnSpeed)) {
    LeftSpeed++;
    //LeftSpeed = ((LeftSpeed*10)+1)/10
  }
  else if (LeftSpeed > -30 && LeftSpeed > (speed - turnSpeed)) {
    LeftSpeed--;
    //LeftSpeed = ((LeftSpeed*10)-1)/10;
  }

  if (RightSpeed < 30 && RightSpeed < (speed + turnSpeed)) {
    RightSpeed++;
  }
  else if (RightSpeed > -30 && RightSpeed > (speed + turnSpeed)) {
    RightSpeed--;
  }

  //if (speed == 0 && turnSpeed == 0) {
  //  LeftSpeed = 0;
  //  RightSpeed = 0;
  //}
}    // End move

// -------------------------------------------------- Update ArmAngle
void armturn() {

  if (ArmAngle < 90 && ArmAngle < ArmAngleTarget) {
    ArmAngle = ArmAngle ++;
  }
  else if (ArmAngle > -90 && ArmAngle > ArmAngleTarget) {
    ArmAngle = ArmAngle --;
  }
}

// ------------------------------------------------- sonar distance function
long ping() {
  long raw;

  raw = analogRead(SonarPin)+analogRead(SonarPin)+analogRead(SonarPin)+analogRead(SonarPin);
  raw = raw/4;
  return raw + raw*123/512;
}


// -------------------------------------------------- Main navigation function
void roving() {
  int speed, turn;
  randomSeed(millis());
  
  if (dmax > 300 && abs(dAngleMax) < 10) {
    ArmAngleRange = 15;
    speed = 20;
    turn = -dAngleMax;
  }    
  else if (dmax > 60) {
    ArmAngleRange = 60;
    speed = 16;
    turn = -dAngleMax/4;
  }  
  else if (dmax > 30) {
    ArmAngleRange = 70;
    speed = dmax/5 - 6;
    turn = -dAngleMax/24;
  }
  else if (dmax <= 30) {
    ArmAngleRange = 80;
    speed = 0;
    turn = -dAngleMax/20;
    digitalWrite(runningLED, HIGH);
  }
  if ((dmin <= 19)&&(abs(dAngleMin)<60)) {
    ArmAngleRange = 80;
    digitalWrite(errorLED, HIGH);
    speed = -4;
    if (dAngleMin !=0) {
      turn = dAngleMin/20;
    }
    else {
      if (random(0,1)) {
        turn = -2;
      }
      else {
        turn = 2;
      }
    }
  }
  /*
  else {
    move(0,0);
    flashLED(errorLED,5);
  }
  */
  move(speed, turn);
}  


void setup() {
  pinMode(LeftWheelPin, OUTPUT);
  pinMode(RightWheelPin, OUTPUT);
  pinMode(ArmServoPin, OUTPUT);
  pinMode(errorLED, OUTPUT);
  pinMode(runningLED, OUTPUT);
  pinMode(SonarPin, INPUT);
  Serial.begin(9600);

  LeftSpeed = 0;
  RightSpeed = 0;
  ArmAngleRange = 80;
  ArmAngleTarget = 80;
  distance = 50;
  dmaxtemp = 20;
  dmintemp = 1000;

  flashLED(runningLED,5);

  timeStart = millis();

  move(0,0);
}

// -------------------------------------------------- Main Loop
void loop() {

  digitalWrite(errorLED, LOW);

  if (millis() - timeLast > 100) {
    distance = ping();
    
    
    if (distance < dmintemp) {
      dmintemp = distance;
      dAngleMinTemp = ArmAngle;
    }
    if (distance > dmaxtemp) {
      dmaxtemp = distance;
      dAngleMaxTemp = ArmAngle;
    }
    roving();  
    timeLast = millis();
    updateServos();
  }

  if ((millis() - timeLastSlow > 500) && (abs(ArmAngle) >= abs(ArmAngleTarget))) {
    if (ArmAngleTarget > 0) {    
      ArmAngleTarget = ArmAngleRange*-1;
    }
    else {
      ArmAngleTarget = ArmAngleRange;
    }
    dAngleMax = dAngleMaxTemp;
    dAngleMin = dAngleMinTemp;
    
    dmax = dmaxtemp;
    dmin = dmintemp;
    dmaxtemp = 10;
    dmintemp = 1000;
    
    /*
    Serial.print("Angles: ");
    Serial.print(dAngleMax,DEC);
    Serial.print(", ");
    Serial.print(dAngleMin,DEC);
    Serial.print(" - Distances: ");
    Serial.print(dmax,DEC);
    Serial.print(", ");
    Serial.println(dmin,DEC);
    */
    timeLastSlow = millis();
    updateServos();
  }

  if (millis() - timeLastFast > 4) {
    armturn();
    timeLastFast = millis();
  }


  //updateServos();
  //Serial.println(distance,DEC);
  digitalWrite(runningLED, LOW);

  updateServos();
}

Logged

0
Offline Offline
Full Member
***
Karma: 1
Posts: 223
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

This code is more "advanced" than the one used in the video. Basically every time the sonar servo completes a sweep, the angle for the direction with the maximum distance is determined, and the robot tries to turn in that direction. The direction with the minimum distance is also determined, and the rover tries to turn away from that direction.

-Z-
Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 56
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
This code is more "advanced" than the one used in the video. Basically every time the sonar servo completes a sweep, the angle for the direction with the maximum distance is determined, and the robot tries to turn in that direction. The direction with the minimum distance is also determined, and the rover tries to turn away from that direction.

-Z-
How do you do to synchronize the servo of your sensor ? After few seconds, the angle of mine is not respected... It starts to go more on the right a little bit and it difficult to calibrate it. After three minutes, it is not anymore in the good direction.
Logged

0
Offline Offline
Full Member
***
Karma: 1
Posts: 223
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Quote
This code is more "advanced" than the one used in the video. Basically every time the sonar servo completes a sweep, the angle for the direction with the maximum distance is determined, and the robot tries to turn in that direction. The direction with the minimum distance is also determined, and the rover tries to turn away from that direction.

-Z-
How do you do to synchronize the servo of your sensor ? After few seconds, the angle of mine is not respected... It starts to go more on the right a little bit and it difficult to calibrate it. After three minutes, it is not anymore in the good direction.


What do you mean? The servo driving the sonar is just a normal servo controlled through PWM, I've never needed to calibrate it. I check the angle of the sonar just by knowing the angle I'm telling the servo to point. The angle is probably not 100% accurate, but the robot only needs a rough idea which direction is clear of stuff.

-Z-
Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 56
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ok I know why I have a problem with my servo. My servo has a continuous rotation.  So it is difficult to know exactly  where is the servo after few moments.
Logged

Pages: [1] 2   Go Up
Jump to: