Society of Robots - Robot Forum

Software => Software => Topic started by: Jdog on January 10, 2009, 12:55:09 AM

Title: Stampy Edge Detection For Axon
Post by: Jdog on January 10, 2009, 12:55:09 AM
I've been trying to use the stampy edge detection algorithm on the Axon microcontroller. I don't know hot to program very well. I added Axon.c, Hardware.c, and Control.c to my avr studio source files, and I added Sor_Utils.h to my header files. I have added
#define ir_servo( position )               servo(PORTE,5,position)
and
long int ir_servo=600;
to my hardware.c code.
I added
ir_servo(ir_servo);
to control.c
I'm using the Sharp GP2D12.
I have a few questions.

1. Can I just copy the stampy code and paste it into control.c and then make a few minor modifications?
2.When/If I do copy and paste the stampy code, what do I have to leave in control.c, and what are those modifications?
3. Where do I add
int sharp_IR_interpret_GP2D12(int value)
   {
   return 1384.4*pow(value,-.9988);
   }
as given in the sensors.c?
Title: Re: Stampy Edge Detection For Axon
Post by: Jdog on January 11, 2009, 06:43:38 PM
Can someone please help me, has anyone done this before?
Title: Re: Stampy Edge Detection For Axon
Post by: Jdog on January 12, 2009, 09:36:45 PM
Ok, Forget all of the stuff I said I changed in the code in the first post. I now copied the c file from the provided stampy code, and I' trying to convert it to be usable on the axon.

I'm trying to make it usable without utils.h and cereb.h so that the makefile will configure it also.

First I got rid of all of the led_green or whatever stuff like that because I didn't need it, and the Axon doesn't have a multi-coler led.
Then I got rid of

//initializing all Cerebellum routines
cereb_init(0);
pwm_init();

//allow short capacitor charge up time
delay_us(5000);

because it doesn't apply to the Axon, and that stuff is in Axon.c.

I changed all of this stuff:

//movement actions
   if (scan_angle > 85)//if target is too far on right
      {
      servoRight();//turn towards target
      set_led(YELLOW, 0);
      set_led(GREEN, 1);
      scan_angle-=1;//scanner turns left while robot turns right
      }
   else if (scan_angle < 50)//if target is too far on left
      {
      servoLeft();//turn towards target
      set_led(YELLOW, 1);
      set_led(GREEN, 0);
      scan_angle+=1;//scanner turns right while robot turns left
      }
   else //centered on target
      {
      servoForward();//drive straight
      set_led(YELLOW, 1);
      set_led(GREEN, 1);
      }
   }

to
   //movement actions
   if (scan_angle > 85)//if target is too far on right
      {
       wheel_left=850;
       wheel_right=800;//turn towards target
      scan_angle-=1;//scanner turns left while robot turns right
      }
   else if (scan_angle < 50)//if target is too far on left
      {
      wheel_left=550;
      wheel_right=550;//turn towards target
      scan_angle+=1;//scanner turns right while robot turns left
      }
   else //centered on target
      {
      wheel_left=800;
      wheel_right=550;//drive straight
      }
   }

I also added
#define ir_servo( position )               servo(PORTE,5,position)
to hardware.c

I changed this delay:
delay_us(2500);//so it doesnt change states too fast //2500 works
to:
delay_cycles(65500);//so it doesnt change states too fast

How do I control the ir_servo angle and tell the program that scan_angle is the ir_servo angle?
Also what do I do about this stuff:
   output_bit(PIN_D2, 1);//139 center
   long_delay_us(130+scan_angle);
   output_bit(PIN_D2, 0);
And this stuff:
printf("angle: %ld distance: %u\r\n", scan_angle, target_distance);
And this stuff:
while(analog(A3) < 100) {printf("%u\r\n", analog(A3));}; //hand swipe to activate robot

I have included a .zip file of my current hardware.c, control.c, and axon.c if that can help you understand what I just explained.
Also if you have a kind soul and feel like seeing if I left anything else out that would give me an error, I would greatly appreciate it.
Title: Re: Stampy Edge Detection For Axon
Post by: Jdog on January 14, 2009, 03:03:31 PM
I also changed the scan actions to
{
   //swap scan directions
   
   /*psuedocode
   while object is detected
      scan left while object detected
   while object not detected
      scan right until object detected*/
   
   target_distance = analog(A3);//check sensor
   
   if (target_distance > distance_thresh)//object detected
      {
      if (ir_servo>250) //overflow protection
         ir_servo-=1;//scan left
      }
   else //object not detected
      {
      if (ir_servo<1000) //overflow protection
         ir_servo+=1; //scan right
      else //if scanned all the way, this forces it to start over
         ir_servo=250;
      }
and I changed the movement code to
//movement actions
   if (ir_servo > 750)//if target is too far on right
      {
       wheel_left=850;
       wheel_right=800;//turn towards target
      ir_servo-=1;//scanner turns left while robot turns right
      }
   else if (ir_servo < 650)//if target is too far on left
      {
      wheel_left=550;
      wheel_right=550;//turn towards target
      ir_servo+=1;//scanner turns right while robot turns left
      }
   else //centered on target
      {
      wheel_left=800;
      wheel_right=550;//drive straight
      }
   }
I attached the new control.c, the hardware.c, and the axon.c again for a better understanding.
Title: Re: Stampy Edge Detection For Axon
Post by: Admin on January 15, 2009, 08:48:06 AM
Use the code from here:
http://www.societyofrobots.com/robot_50_robot_sharpIR.shtml

Basically its the Stampy algorithm implemented on an ATmega similar to the Axon. My comments are easier to understand.

Have a look and let us know if its still confusing for you.
Title: Re: Stampy Edge Detection For Axon
Post by: Jdog on January 15, 2009, 02:12:43 PM
Oh wow, forgot about that. I'm now using the one for the 50$ robot and I'm still having problems.
Title: Re: Stampy Edge Detection For Axon
Post by: Admin on January 15, 2009, 07:34:33 PM
Its better to just start with the Axon files. (use v1.01, the latest version is broken right now)

All the Stampy code you'll need is in 50_robot_sharpIR.c.

For example add this at the top of control.c:

Code: [Select]
//global variables
int sharp_IR_reading=0;

int scan_thresh=0;//threshold value of scanning sensor

int scan_angle=30;//position of scanner, in units of servo command
int max_scan_angle=56;//maximum position scanner can rotate to (57)


//this function causes scanning servo to center on edge of object
void scan(void)
{
//lower (-) goes right
//higher (+) goes left
//30 far right, 50 straight, 56 far left (until it jams)

/*psuedocode
object is detected
scan right object detected
object not detected
scan left until object detected*/

sharp_IR_reading=a2dConvert8bit(3);

if (sharp_IR_reading > scan_thresh)//object detected
{
if (scan_angle>41) //overflow protection
scan_angle-=2;//scan right
}
else //object not detected
{
if (scan_angle<=max_scan_angle) //maximum servo angle
scan_angle+=2; //scan left
//else //if scanned all the way, this forces it to start over
// scan_angle=30;
}

//servo scan code
servo_scan(scan_angle);
}


//automatically calculates threshold value before run
void autocalibrate(void)
{
scan_thresh=a2dConvert8bit(3);//sensor reading
}

And put this in your while loop:
Code: [Select]
scan();

//object on left
if(scan_angle > 57)
robot_turn_left();

//object on right
else if(scan_angle < 41)
robot_turn_right();

//object is centered
else
robot_go_straight();

delay_cycles(400);//a small delay to prevent crazy oscillations

Of course, I'll leave it up to you to figure out how to do robot_turn_left();, etc :P

You'll also have to tweak the scan_angle. Values around 300 to 500 would be more reasonable.
Title: Re: Stampy Edge Detection For Axon
Post by: Jdog on January 15, 2009, 07:59:23 PM
Firstly, don't I have to add
#define servo_scan( position )               servo(PORTE,5,position)
to hardware.c?

Then, I replaced all of the simplified operations like robot_left with
wheel_left=800;
wheel_right=800;

Then Rather than having 700=center, 250=left, 1150=right like in the photovore code, you had 50=center 30=right, and 56= left. So I did the math finding out that for every 1 value in how you defined them there was worth roughly 19 in how I was used to seeing it for the axon. Then I changed all of the servo stuff to the values I was used to seeing.
For Example:
if (scan_angle>56) //overflow protection
scan_angle-=2;//scan right
became:
if (scan_angle<529) //overflow protection
scan_angle+=38;//scan right
For a better understanding, look at the code I'm using.

When I tried to build it, everything failed utterly:

Compiling: Axon.c
avr-gcc -c -mmcu=atmega640 -I. -gstabs   -O0 -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=Axon.lst  -std=gnu99 -Wp,-M,-MP,-MT,Axon.o,-MF,.dep/Axon.o.d Axon.c -o Axon.o
In file included from control.c:20,
                 from Axon.c:21:
SoR_Utils.h:46: error: redefinition of 'configure_ports'
SoR_Utils.h:47: error: previous definition of 'configure_ports' was here
SoR_Utils.h:142: error: redefinition of 'delay_cycles'
SoR_Utils.h:143: error: previous definition of 'delay_cycles' was here
SoR_Utils.h:153: error: redefinition of 'LED_off'
SoR_Utils.h:154: error: previous definition of 'LED_off' was here
SoR_Utils.h:155: error: redefinition of 'LED_on'
SoR_Utils.h:156: error: previous definition of 'LED_on' was here
SoR_Utils.h:161: error: redefinition of 'reset_timer_0'
SoR_Utils.h:162: error: previous definition of 'reset_timer_0' was here
SoR_Utils.h:167: error: redefinition of 'reset_timer_2'
SoR_Utils.h:168: error: previous definition of 'reset_timer_2' was here
SoR_Utils.h:177: error: redefinition of 'button_pressed'
SoR_Utils.h:178: error: previous definition of 'button_pressed' was here
SoR_Utils.h:192: error: redefinition of 'angtable'
SoR_Utils.h:192: error: previous definition of 'angtable' was here
SoR_Utils.h:195: error: redefinition of 'cos_SoR'
SoR_Utils.h:196: error: previous definition of 'cos_SoR' was here
SoR_Utils.h:203: error: redefinition of 'sin_SoR'
SoR_Utils.h:204: error: previous definition of 'sin_SoR' was here
SoR_Utils.h:213: error: redefinition of 'tan_SoR'
SoR_Utils.h:214: error: previous definition of 'tan_SoR' was here
In file included from Axon.c:21:
control.c: In function 'scan':
control.c:60: warning: implicit declaration of function 'servo_scan'
control.c: At top level:
control.c:73: warning: data definition has no type or storage class
control.c:73: warning: type defaults to 'int' in declaration of 'autocalibrate'
control.c:73: warning: function declaration isn't a prototype
control.c:73: error: conflicting types for 'autocalibrate'
control.c:66: error: previous definition of 'autocalibrate' was here
control.c:75: error: expected identifier or '(' before 'while'
control.c:104: error: expected identifier or '(' before 'return'
control.c:105: error: expected identifier or '(' before '}' token
Axon.c: In function 'main':
Axon.c:92: warning: implicit declaration of function 'control'
make: *** [Axon.o] Error 1
Build failed with 27 errors and 5 warnings...
Title: Re: Stampy Edge Detection For Axon
Post by: Admin on January 15, 2009, 09:36:48 PM
The best way to debug the code is start with something that works (default Axon code).

Then just add one thing at a time and compile. If it doesn't compile, you know exactly what code you added that caused it to break.

Looking at your errors, it appears you made two mistakes. First, you included some #include files too many times. Second, you improperly initialized your functions.

Play around with it and after awhile if you're still stuck, let us know.
Title: Re: Stampy Edge Detection For Axon
Post by: Jdog on January 15, 2009, 10:25:09 PM
I started from step one doing what you said. After I added the servo scanning part of the code and tried to build it, I got this error:

Axon.o: In function `main':
Axon.c:92: undefined reference to `control'
make: *** [Axon.elf] Error 1
Build failed with 1 errors and 1 warnings...

They're talking about this line:
      control();//use this for your code

Do you know how I could fix this?
Title: Re: Stampy Edge Detection For Axon
Post by: Admin on January 15, 2009, 11:12:51 PM
It compiles perfectly when you don't add servo scanning? Is the only modification what you made in control.c?
Title: Re: Stampy Edge Detection For Axon
Post by: Jdog on January 16, 2009, 02:53:51 PM
I fixed that problem. I forgot to add in the control function.(Sorry if that's the wrong terminology, I'm new to programming)
void control(void)
somewhere.
I added:
Code: [Select]
void control(void)
     {
      scan();
     }
and it compiled fine.
Then I tried to replace scan() with this while loop:
Code: [Select]
void control(void)
{
while(1)
{
scan();

//object on left
if(scan_angle < 570)
{//go left
wheel_left=800;
wheel_right=800;
};

//object on right
else if(scan_angle > 1000)
{//go right
wheel_left=550;
wheel_right=550;
};

//object is centered
else
{//go straight
wheel_left=800;
wheel_right=550;
                                                }
                 }
                }
and I got these 6 errors:
control.c:65: error: 'wheel_left' undeclared (first use in this function)
control.c:65: error: (Each undeclared identifier is reported only once
control.c:65: error: for each function it appears in.)
control.c:66: error: 'wheel_right' undeclared (first use in this function)
control.c:70: error: 'else' without a previous 'if'
control.c:77: error: 'else' without a previous 'if'
make: *** [Axon.o] Error 1
Build failed with 6 errors and 0 warnings...


I don't see how wheel_left and wheel_right are undeclared when I declared them in hardware.c.
Also for the else problems there are ifs before them so I don't know what it is talking about.
Also, do you know if there is a way to show the line numbers in avr studio, because it's kind of annoying to open the file in textedit whenever I get an error.
Once again the code I'm using is at the bottome of the page.
Title: Re: Stampy Edge Detection For Axon
Post by: Jdog on January 16, 2009, 07:32:39 PM
Woohoo, everything compiles and uploads, now I have to get it to do what I want. First of all, why in the provided code is a servo's movements controlled between 30 and 70 whereas in the photovore code, servo motions are between 250 and 1150? Also When I upload this code,
Code: [Select]
/****************************************************************************
*
*   Copyright (c) 2008 www.societyofrobots.com
*   (please link back if you use this code!)
*
*   This program is free software; you can redistribute it and/or modify
*   it under the terms of the GNU General Public License version 2 as
*   published by the Free Software Foundation.
*
*   Alternatively, this software may be distributed under the terms of BSD
*   license.
*
****************************************************************************/

//Add your code here

//global variables
int sharp_IR_reading=0;

int scan_thresh=30;//threshold value of scanning sensor

int scan_angle=1000;//position of scanner, in units of servo command
int max_scan_angle=529;//maximum position scanner can rotate to (57)
long int wheel_left=600;
long int wheel_right=600;

//this function causes scanning servo to center on edge of object
void scan(void)
{
//lower (-) goes right
//higher (+) goes left
//30 far right, 50 straight, 56 far left (until it jams)

/*psuedocode
object is detected
scan right object detected
object not detected
scan left until object detected*/

sharp_IR_reading=a2dConvert8bit(3);

if (sharp_IR_reading > scan_thresh)//object detected
{
if (scan_angle<529) //overflow protection
scan_angle+=38;//scan right
}
else //object not detected
{
if (scan_angle<=max_scan_angle) //maximum servo angle
scan_angle-=38; //scan left
//else //if scanned all the way, this forces it to start over
// scan_angle=30;
}

//servo scan code
servo_scan(scan_angle);
}
void control(void)
{
while(1)
{
scan();
//object on left
if(scan_angle < 570)
{//go left
wheel_left=800;
wheel_right=800;
}

//object on right
else if(scan_angle > 830)
{//go right
wheel_left=550;
wheel_right=550;
}

//object is centered
else
{//go straight
wheel_left=800;
wheel_right=550;
}
  }
}


//automatically calculates threshold value before run
void autocalibrate(void)
{
scan_thresh=a2dConvert8bit(3);//sensor reading
}

my wheels don't spin, my ir servo goes all the way to the right, and it doesn't go left when I put my hand in front of it.

Also, I want to throw a printf in there, so would this be right?
rprintf("Sharp_IR=%d, IR_Servo=%d%d, L_wheel=%d%d, R_wheel=%d%d\r\n",Sharp_Ir_Reading, servo_scan, wheel_left, wheel_right);

Sorry for all of the questions.
Title: Re: Stampy Edge Detection For Axon
Post by: Admin on January 16, 2009, 08:01:33 PM
Quote
When I upoaded it, it said program succesful, verify succesful, CRC-error.
So, I rebuilt the code, and tried uploading it again and got the same results. I changed the + and the - signs back, and everything uploaded fine. How does changing the + to a - mess up the uploading process?
What is CRC?
Thats odd . . . put the signs back to normal and see if it happens again. Did the robot work?

CRC means Cyclic Redundancy Check, which basically is the method of which to find errors in the code.
Title: Re: Stampy Edge Detection For Axon
Post by: Jdog on January 16, 2009, 08:39:17 PM
I switched them back and they worked, and now the uploading is fine, I don't know what happened.
Now I have problems with the code as stated above.
Title: Re: Stampy Edge Detection For Axon
Post by: Admin on January 16, 2009, 09:02:17 PM
Jdog, its better that you make a new post, instead of erasing an old post for a new question. Now everyone will be confused why I talked about CRC :P

That being said, the Axon has a much faster processor than the $50 Robot. Since a cycle takes much less time, you need more cycles. All numbers for servos should now be between 300 and 1200.
Title: Re: Stampy Edge Detection For Axon
Post by: Jdog on January 16, 2009, 09:20:29 PM
Sorry, I was just posting all of the problems I was having with this issue on this, I'll make a different post.