Go Down

Topic: Fully Autonomous Golf Caddy (Read 5929 times) previous topic - next topic

bleedscarlet

and now if anyone feels like reversing the coordinate conversion, you can actually find out exactly where I am :p

andpe

Spending too much time on this..

bleedscarlet

#17
Nov 04, 2010, 10:50 pm Last Edit: Nov 04, 2010, 10:51 pm by bleedscarlet Reason: 1
not even close! wrong coast entirely haha

bleedscarlet

more pics
with improved wheel hubs and bag attached:





bleedscarlet

#19
Nov 09, 2010, 02:39 am Last Edit: Nov 09, 2010, 02:41 am by bleedscarlet Reason: 1
Added in some CYLON!!!

:D

Code: [Select]
void setup() {                
 pinMode(43, OUTPUT);    
 pinMode(45, OUTPUT);
 pinMode(47, OUTPUT);
 pinMode(49, OUTPUT);
 pinMode(51, OUTPUT);
 pinMode(53, OUTPUT);  
}

void loop() {
 for (int i=43;i<54;i++){
   digitalWrite(i+1, HIGH);
   delay(30);
   digitalWrite(i-1, LOW);
 }
 for (int i=54;i>42;i--){
   digitalWrite(i-1, HIGH);
   delay(30);
   digitalWrite(i+1, LOW);
 }
}


video coming as soon as youtube processes.

bleedscarlet

[media]http://www.youtube.com/watch?v=B2PMp5y32Qk[/media]

bleedscarlet

[media]http://www.youtube.com/watch?v=TvK04xJeoOA[/media]

bleedscarlet

#22
Nov 09, 2010, 05:23 am Last Edit: Nov 09, 2010, 05:24 am by bleedscarlet Reason: 1
it seems very jumpy, I just incorporated an exponentially weighted moving average for the compass heading and hopefully that will stabilize it a bit. Playing with it in house it seems much more stable, although it does lag behind about 200ms instead of 50ms now, which is less than desirable but it might be necessary for fluid motion.

With the jumpiness we can't get very accurate readings or smooth motion. I have lots of videos of the movement as is but it's kind of crappy.


it's 30 degrees out now so i'm going to continue testing some other time.

bleedscarlet

Quote

#include <String.h>
#include <ctype.h>
#include <Wire.h>

int compassAddress = 0x32 >> 1;
int heading = 0;
int tilt = 0;
int roll = 0;
int ledPin = 13;
int rxPin = 0;
int txPin = 1;
int byteGPS=-1;
char linea[300] = "";
char comandoGPR[7] = "$GPRMC";
int cont=0;
int bien=0;
int conta=0;
int indices[13];
char CurrentXascii[9];
char CurrentYascii[10];
float CurrentX;
float CurrentY;
float CurrentHeading;
float CurrentHeading1;
float CurrentHeading2;
float CurrentHeading3;
byte responseBytes[6];
int GPStimer=0;
double DeltaX=0.000;
double DeltaY=0.000;
int Instance=0;
int InstanceSize=0;
int buttonState=0;
int buttonPin = 22;
int lastButtonState=0;
int buttonPushCounter=0;
float DesiredHeading=0.0;
int LeftSpeed=0;
int RightSpeed=0;
double ParkingLotX[3] = {4031.24554, 4031.24116, 4031.23294};
double ParkingLotY[3] = {-7427.58914,-7427.57996,-7427.5853};
void setEngineSpeed1(signed char cNewMotorSpeedH)
{
  unsigned char cSpeedVal_Motor1 = 0;
  if(cNewMotorSpeedH==0)
  {
    Serial3.print(0,BYTE);
    return;
  }  
  cSpeedVal_Motor1 = map(cNewMotorSpeedH,-100,100,1,127);
  Serial3.print(cSpeedVal_Motor1, BYTE);
}

void setEngineSpeed2(signed char cNewMotorSpeed2)
{  
  unsigned char cSpeedVal_Motor2 = 0;
  if(cNewMotorSpeed2 == 0)
  {
    Serial3.print(0,BYTE);
    return;
  }  
  cSpeedVal_Motor2 = map(cNewMotorSpeed2,-100,100,128,255);
  Serial3.print(cSpeedVal_Motor2, BYTE);
}

void readSensor()

  Wire.beginTransmission(compassAddress);
  Wire.send(0x50);
  Wire.endTransmission();
  delay(2);
  Wire.requestFrom(compassAddress, 6);
  if(6 <= Wire.available())
  {
    for(int i = 0; i<6; i++) {
      responseBytes = Wire.receive();
    }
  }
  heading = ((int)responseBytes[0]<<8) | ((int)responseBytes[1]);
  tilt = (((int)responseBytes[2]<<8) | ((int)responseBytes[3]));
  roll = (((int)responseBytes[4]<<8) | ((int)responseBytes[5]));
  CurrentHeading3 = heading/10;
  CurrentHeading2=(CurrentHeading3+CurrentHeading2)/2;
  CurrentHeading1=(CurrentHeading2+CurrentHeading1)/2;
  CurrentHeading=(CurrentHeading+CurrentHeading1)/2;
  


void readGPS()
{
  GPStimer=0;
  do{
    byteGPS=Serial2.read();
    if (byteGPS == -1)
    {
      delay(100);
    } 
    else {
      linea[conta]=byteGPS;
      conta++;
      if (byteGPS==13){
        digitalWrite(ledPin, LOW);
        cont=0;
        bien=0;
        for (int i=1;i<7;i++){
          if (linea==comandoGPR[i-1]){
            bien++;
          }
        }
        if(bien==6){
          for (int i=0;i<300;i++){
            if (linea==','){
              indices[cont]=i;
              cont++;
            }
            if (linea=='*'){
              indices[12]=i;
              cont++;
            }
          }
          Serial.println("");
          Serial.println("");
          Serial.println("---------------");
          for (int i=0;i<12;i++){
            for (int j=indices,k=0;j<(indices[i+1]-1);j++,k++){
              switch(i){
              case 2 :
                CurrentXascii[k]=linea[j+1];
               break;
              case 4 :
                CurrentYascii[k]=linea[j+1];
                break;
              }
            }
          }
          CurrentX=atof(CurrentXascii);
          CurrentY=-atof(CurrentYascii);
        }
        conta=0;
        for (int i=0;i<300;i++){
          linea=' ';            
        }                 
      }
    }
    GPStimer++;
  }
  while(GPStimer<300);
}

bleedscarlet

#24
Nov 09, 2010, 05:25 am Last Edit: Nov 09, 2010, 05:31 am by bleedscarlet Reason: 1
Quote

void setup()

  delay(500);
  Wire.begin();
  Wire.send(0x82);
  delay(500);
  Serial.begin(9600);
  pinMode(13, OUTPUT);  
  digitalWrite(13, HIGH);
  Serial2.begin(4800);
  for (int i=0;i<300;i++){
    linea=' ';
  } 
  Serial3.begin(9600);
  delay(2000);
  setEngineSpeed1(0);
  setEngineSpeed2(0);
  Instance=0;


void loop()
{
  buttonState = digitalRead(buttonPin);
  if (buttonState != lastButtonState) {
    if (buttonState == HIGH) {
      buttonPushCounter++;
    }
    lastButtonState = buttonState;
  }
  Instance=buttonPushCounter;
  readSensor();
  Serial.print("Heading: ");
  Serial.print(CurrentHeading);
  Serial.print("\t Tilt: ");
  Serial.print(tilt / 10, DEC);
  Serial.print("\t Roll: ");
  Serial.println(roll / 10, DEC);
  delay(50);
  readGPS();
  Serial.print("Current X Value: ");
  Serial.print(CurrentX, 10);
  Serial.print("\t");          
  Serial.print("Current Y Value: ");
  Serial.println(CurrentY, 10);
  Serial.println("---------------");
  do{
    readGPS();
    DeltaX=ParkingLotX[Instance]-CurrentX;
    DeltaY=ParkingLotY[Instance]-CurrentY;
    if (DeltaY<0){
      if (DeltaX<0){
        DesiredHeading=270-atan(DeltaY/DeltaX)*180/3.14159265;
      }else if (DeltaX>0){
        DesiredHeading=180-atan(DeltaY/DeltaX)*180/3.14159265;
      }
    }else if (DeltaY>0){
      if (DeltaX<0){
        DesiredHeading=360-atan(DeltaY/DeltaX)*180/3.14159265;
      }else if (DeltaX>0){
        DesiredHeading=90-atan(DeltaY/DeltaX)*180/3.14159265;
      }
    }
    readSensor();
    if (((DesiredHeading-CurrentHeading) < 15)&&((DesiredHeading-CurrentHeading)>6)){
      LeftSpeed=40;
      RightSpeed=30;
    }else if (((DesiredHeading-CurrentHeading) <= 30)&&((DesiredHeading-CurrentHeading)>15)){
      LeftSpeed=40;
      RightSpeed=20;
    }else if (((DesiredHeading-CurrentHeading) <= 60)&&((DesiredHeading-CurrentHeading)>30)){
      LeftSpeed=40;
      RightSpeed=10;
    }else if (((DesiredHeading-CurrentHeading) <= 360)&&((DesiredHeading-CurrentHeading)>60)){
      LeftSpeed=40;
      RightSpeed=-40;
    }else if (((DesiredHeading-CurrentHeading) <= -6)&&((DesiredHeading-CurrentHeading)>-15)){
      LeftSpeed=30;
      RightSpeed=40;
    }else if (((DesiredHeading-CurrentHeading) <= -15)&&((DesiredHeading-CurrentHeading)>-30)){
      LeftSpeed=20;
      RightSpeed=40;
    }else if (((DesiredHeading-CurrentHeading) <= -30)&&((DesiredHeading-CurrentHeading)>-60)){
      LeftSpeed=10;
      RightSpeed=40;
    }else if (((DesiredHeading-CurrentHeading) <= -60)&&((DesiredHeading-CurrentHeading) >- 360)){
      LeftSpeed=-40;
      RightSpeed=40;
    }else if (((DesiredHeading-CurrentHeading) <= 6)&&((DesiredHeading-CurrentHeading) >= -6)){
      LeftSpeed=40;
      RightSpeed=40;
    }
    setEngineSpeed1(LeftSpeed);
    setEngineSpeed2(RightSpeed);
    Serial.print("LeftSpeed: ");
    Serial.print(LeftSpeed);
    Serial.print("\t");
    Serial.print("RightSpeed:");
    Serial.print(RightSpeed);
    Serial.print("\t");
    Serial.print("DesiredHeading:");
    Serial.print(DesiredHeading);
    Serial.print("\t");
    Serial.print("CurrentHeading:");
    Serial.print(CurrentHeading);
    Serial.print("\t");
    Serial.print("CurrentX:");
    Serial.print(CurrentX, 4);
    Serial.print("\t");
    Serial.print("CurrentY:");
    Serial.print(CurrentY, 4);
    Serial.print("\t");
    Serial.print("Y:");
    Serial.print(ParkingLotY[Instance], 4);
    Serial.print("\t");
    Serial.print("X:");
    Serial.print(ParkingLotX[Instance], 4);
    Serial.print("\t");
    Serial.print("Instance:");
    Serial.println(Instance);
   delay(50);
  }while((abs(DeltaX)>0.0001)&&(abs(DeltaY)>0.0001));
  setEngineSpeed1(0);
  setEngineSpeed2(0);
}



bleedscarlet

in case anyone's wondering about the strange coordinates, this is how to convert it:

GPS outputs in XXYY.ZZZZ where XX is degrees YY is minutes and ZZZZ is fractional minutes

google maps works XX.FFFFFFFFFF where F is simply fractional degrees

so this coordinate: 40.520576, -74.45974

take the decimals, .520576, .45974 and multiply by 60
31.23456, 27.5844
append to the degrees
4031.23456, -7427.5844

and that's how the GPS speaks. It's kind of annoying that the gps doesn't just output as fractional degrees but whatever, we've gotten used to the converting back and forth now and it's not so bad.

bleedscarlet

added in a exponential moving average smoothing for the motor control too, smoothen out those jumps a little, I lessened the smoothing for the compass because the lag was too much.

Boffin1

With my 8 weeks experience of programming, can I ask - are you really holding the golf bag up with one frictional gripping pivot at the bottom ??  :D

bleedscarlet

For the time being, we're not doing any actual testing with it as i'm sure you've realized that shit will not hold up if I breathe on it hard enough.

We're working on implementing a magnet system to click grip it and a strap that goes around the stem to the golf bag's grip, we may incorporate a small "basket" for it on the bottom, we've already designed and built the basket but it looks ugly so we're looking at alternative methods.

Good eye!

Boffin1

Just kidding, I'm so impressed with the scale of the project, well done

Go Up