Chief Delphi

Chief Delphi (http://www.chiefdelphi.com/forums/index.php)
-   Robotics Education and Curriculum (http://www.chiefdelphi.com/forums/forumdisplay.php?f=66)
-   -   Autonomous Code Example (http://www.chiefdelphi.com/forums/showthread.php?t=22693)

Sachiel7 14-11-2003 17:26

Oh, well, I suppose you could easily implement something like that. You could have it jump around based on specific timing values or such, if that's what you mean. Or if you just want event driven code (a sub for each function) that can be done as well. The main problem with Sub-Based auto modes is that you need a sub for each function you want to perform. You need to define a way to count how long it should last, and you need a way of defining the pattern it should take. This can easily begin to eat up your program and variable memory. My first auto program was set up to do this, and after it *worked* but it didn't do quite what it was supposed to, It took me a long time to tweak/fix it.
The main thing is, with this, you don't need to write any extra code, or anything. Just go to the start of the program and insert your array. That's it.
Since it's a pretty adaptive *little* program (not the excessive use of **'s :D) it doesn't take much at all to tweak. I can write out 15 different auto modes and have the program compiled within less than 5 minutes using this code.
Another thing about using arrays is that it's not Bot-specific. Basically you could have a prototype eduBot that performs a certain thing, but you'd need to change your speed/time variables for the larger one. Using the array method, you can just click and It's set for your full bot.
Anyway, I still like the idea of Sub-Structured Auto Modes, but I'm stickin' with my array code this year.
BTW, nobody's tried to guess what the sample array I posted earlier does...
Take a wild guess!

GregTheGreat 14-11-2003 17:29

Quote:

Originally posted by Sachiel7
Oh, well, I suppose you could easily implement something like that. You could have it jump around based on specific timing values or such, if that's what you mean. Or if you just want event driven code (a sub for each function) that can be done as well. The main problem with Sub-Based auto modes is that you need a sub for each function you want to perform. You need to define a way to count how long it should last, and you need a way of defining the pattern it should take. This can easily begin to eat up your program and variable memory. My first auto program was set up to do this, and after it *worked* but it didn't do quite what it was supposed to, It took me a long time to tweak/fix it.
The main thing is, with this, you don't need to write any extra code, or anything. Just go to the start of the program and insert your array. That's it.
Since it's a pretty adaptive *little* program (not the excessive use of **'s :D) it doesn't take much at all to tweak. I can write out 15 different auto modes and have the program compiled within less than 5 minutes using this code.
Another thing about using arrays is that it's not Bot-specific. Basically you could have a prototype eduBot that performs a certain thing, but you'd need to change your speed/time variables for the larger one. Using the array method, you can just click and It's set for your full bot.
Anyway, I still like the idea of Sub-Structured Auto Modes, but I'm stickin' with my array code this year.
BTW, nobody's tried to guess what the sample array I posted earlier does...
Take a wild guess!

I will take a guess, is it a bunch of 360's?

-Greg The Great

Sachiel7 14-11-2003 17:41

Not quite....
This program writes something...
I built a small edu with just 2 motors and a marker in the middle...

GregTheGreat 14-11-2003 17:49

Quote:

Originally posted by Sachiel7
Not quite....
This program writes something...
I built a small edu with just 2 motors and a marker in the middle...

Well i see the inputs, I see the straight line.. I am thinking it is either your team number, or The Claw?

-Greg The Great

Sachiel7 14-11-2003 18:12

Not quite...
Think "Typical intro program"...
The 1st array element is the left drive, and since the motor is backward, 0 if "forwards" for the robot. the second element is the right drive, 254 is forward for it. the final element is the timer, the number of cycles the first two elements are outputted. Try drawing it (sorta) or "cracking the code"
It's not that hard...
BTW-The first code like this I wrote was to write "RAPTAR" and it had 82 steps. Try coding THAT in sub-form! (BTW, I did, and I couldn't compile for some reason...lack of mem?)

GregTheGreat 14-11-2003 23:46

I dont understand this input, is it a aliasis?

if (counter > Func01[F_Count][2])

-Greg The Great

Sachiel7 15-11-2003 00:20

counter > counts the program cycles
F_Count > The Function Counter. If F_Count was 3 then your third array elements in Func would be performed.
For example:
F_Count = 5

Func[6][3] = {

{1,1,10},
{3,2,50},
{2,2,30},
{4,5,10},
{7,2,20},
{8,9,50}

};

F_Count means that we're looking at the fifth strand (7,2,20)
Func[F_Count][1] = Left Drive Variable
Func[F_Count][2] = Right Drive variable
Func[F_Count][3] = Wait until counter equals this before going on.
When Counter => Func[F_Count][3] then the counter is reset to 0 and F_Count is increased by one (++)
If F_Count = MAX_FUNC (The number of Functions, 6 in this case) then either loop or stop.

NOTE to those reading this post, particularly anyone not versed in C, C starts counting from 0 up as far as arrays are concerned.
ie: x[5] = {1,2,3,4,5}
The actual arrays of x are x[0]-x[4], while x[0]=1 and x[4] =5
That's why MAX_FUNC is the number of functions, it's checking to see if we've done everything before looping or stopping.

GregTheGreat 16-11-2003 21:11

Quote:

Originally posted by Sachiel7
counter > counts the program cycles
F_Count > The Function Counter. If F_Count was 3 then your third array elements in Func would be performed.
For example:
F_Count = 5

Func[6][3] = {

{1,1,10},
{3,2,50},
{2,2,30},
{4,5,10},
{7,2,20},
{8,9,50}

};

F_Count means that we're looking at the fifth strand (7,2,20)
Func[F_Count][1] = Left Drive Variable
Func[F_Count][2] = Right Drive variable
Func[F_Count][3] = Wait until counter equals this before going on.
When Counter => Func[F_Count][3] then the counter is reset to 0 and F_Count is increased by one (++)
If F_Count = MAX_FUNC (The number of Functions, 6 in this case) then either loop or stop.

NOTE to those reading this post, particularly anyone not versed in C, C starts counting from 0 up as far as arrays are concerned.
ie: x[5] = {1,2,3,4,5}
The actual arrays of x are x[0]-x[4], while x[0]=1 and x[4] =5
That's why MAX_FUNC is the number of functions, it's checking to see if we've done everything before looping or stopping.

Alright, I give up, I need to know what it is.

-Greg The Great

Sachiel7 16-11-2003 22:59

The example I posted writes "HI" sorta like the typical "Hello, World!" programs. Here's A Breakdown:

{84, 170, 40}, //forward 5 inches
{170,170,60}, //Turn left 180 degrees
{84,170,20}, //forward 2.5 inches
{170,170,30}, //turn left 90 degrees
{84,170,20}, //forward 2.5 inches
{170,170,30}, //turn left 90 degrees
{84,170,20}, //forward 2.5inches
{170,170,60}, //turn left 180 degrees
{84,170,40}, //forward 5 inches
{170,170,30}, //turn left 90 degrees
{84,170,20}, //forward 2.5 inches
{170,170,30}, //turn left 90 degrees
{84,170,40} //forward 5 inches

I'll try and find some of the sheets it wrote on and post it here.

seanwitte 21-11-2003 10:02

If you use the gyro and a shaft encoder then you can make your commands simpler AND scalable. Break it down into three commands: Drive, Turn, and Stop. Drive will move forward a certain number of encoder ticks and turn will rotate a certain number of degrees. Here is a sample:

Code:

#define CMD_TURN 0
#define CMD_DRIVE 1
#define CMD_STOP 3
#define FORWARD 227
#define REVERSE 27
#define NEUTRAL 127

typedef struct {
  unsigned int step;
  unsigned char cmd;
  int progress;
  int target;
  unsigned char prev_encoder;
} command;

void command_turn(command *cmd, unsigned int gyro);
void command_drive(command *cmd, unsigned char encoder);
void command_stop(command *cmd);
void command_run(command *cmd);
void command_next(command *cmd);

//rotate in place until target gyro "ticks" have
//passed. A gyro tick will be the difference between
//the value read and 512. Positive values are
//clockwise and negative are anti-clockwise.
void command_turn(command *cmd, unsigned int gyro)
{
  //add current rotational velocity to progress
  cmd->progress += gyro;
  cmd->progress -= 512;

  //clockwise
  if (cmd->target < 0)
  {
      //got to the next command when target radians have passed
      if (cmd->progress <= cmd->target)
      {
        command_next(cmd);
      }
      else
      {
        drive_r = REVERSE;
        drive_l = FORWARD;
      }
  }
  else
  {
      //got to the next command when target radians have passed
      if (cmd->progress >= cmd->target)
      {
        command_next(cmd);
      }
      else
      {
        drive_r = FORWARD;
        drive_l = REVERSE;
      }
    }
}

//drive forward until target ticks have passed
void command_drive(command *cmd, unsigned char encoder)
{
  //increment progress when encoder goes from 0 to 1
  if ((cmd->prev_encoder == 0) && (encoder == 1))
  {
      cmd->progress++;
  }
 
  if (cmd->progress >= cmd->target)
  {
      command_next(cmd);
  }
  else
  {
      drive_l = FORWARD;
      drive_r = FORWARD;
  }
  cmd->prev_encoder = encoder;
}

//stop the robot
void command_stop(command *cmd)
{
  drive_r = NEUTRAL;
  drive_l = NEUTRAL;
}

//run this function against the command
//variable each time through the program
//loop. it will figure out which command to
//execute
void command_run(command *cmd)
{
  if (cmd->cmd == CMD_TURN)
  {
      command_turn(cmd, analog1);
  }
  else if (cmd->cmd == CMD_DRIVE)
  {
      command_drive(cmd, IO16);
  }
  else
  {
      command_stop(cmd);
  }
}

void command_next(command *cmd)
{
// you can fill this in
// look at the current step number in cmd
// and get the next command from your
// storage array.
}

With this system you can use a 2-D array of commands and target values instead of trying to work out the timing. You'll have to play around with the values to see how many gyro "ticks" there are in 90 degrees.

Say that 20000 gyro ticks is 180 degrees. Assume your wheel is 4" in circumference with 4 transitions that the encoder can see. You want to drive 8", rotate 180 degrees clockwise, drive 8", then turn 180 degrees anti-clockwise. Your commands will be:

CMD_DRIVE, 8
CMD_TURN, 20000
CMD_DRIVE, 8
CMD_TURN, -20000
CMD_STOP, 0

I don't know that the code will work, its just off the top of my head. Just trying to give you another angle on the same problem.


All times are GMT -5. The time now is 23:38.

Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright © Chief Delphi