Go Down

Topic: Help with nested loops (Read 2 times) previous topic - next topic

wildbill

for (i=7;i>=0;i--) would do the trick

For the master array, which looks like your forward today, but with more rows, what I was thinking was that each row of the array represents an action the robot can make as part of its walking sequence e.g. extend front legs. So each one is a basic walking operation. So the forward, backward commands etc could be thought of as a little sequence (program) of robot walking op codes:

byte forward[] = {3,5,6,9,12};

Which means set servos to the positions at row 3 of the master array, then 5, then 6....

Then you can have a function that you call like this:

DoWalkingSequence(forward,sizeof(forward)/sizeof(byte));

This function just iterates through the array it was passed, forward in this example, and sets the servos to the positions from the appropriate row of the master array

Then you can use the same 'walking opcodes' in several different sequences to achieve the movements you want, but allowing each opcode to be specified only once to keep memory usage down.

Consts, enums, #defines can make it more readable, but that's the basic idea.

breagle

So if I use the DoWalkingSequence() function, it will use less memory because it wont have to load the whole master array? It just loads the specific rows? And it also uses less memory because of the byte type variable? Also, how does the function fit into a loop? I have briefly looked over enums and #defines. I am still reading on them. When I started this project, I knew when my sketch got to a certain level, it would become too complex for me to understand by just reading to learn. That is why I choose to use this method of locomotion. I would love to use some kind of inverse kinematics to move the robot. But I am finding it difficult to learn it by the internet.

If I can use the DoWalkingSequence() in a loop it would work very well for what I am doing. Thank you for the advice and help.
Bob

breagle

Can you please show me how the DoWalkingSequence() function is wrote? I am not understanding how to use it?
I am not sure how this: DoWalkingSequence(forward,sizeof(forward)/sizeof(byte));
works.Such as the sizeof area, and what would change if i wanted to go backward. Thanks again for all the help.
Bob

wildbill

Here's what I had in mind: You have a master array of servo positions, each of which is what you earlier described as a picture. I assume that when moving, you will use these pictures in more than one movement. So, you can add an extra level of indirection and have an array I've called forward, which is a list of indexes of pictures that make up forward motion and other arrays for other movements. Like this - compiles, not tested though:
Code: [Select]

#include <Servo.h>

#define number_of_servos 24

byte Master[][number_of_servos]=
{
{135  ,45  ,135  ,45  ,45   ,90  ,45  ,90,  180  ,180 ,180  ,180 ,0    ,90  ,0   ,90,  180  ,90  ,180  ,90  ,0    ,180 ,0   ,180}, // set servos to the first position
{35  ,95  ,135  ,45  ,45   ,90  ,45  ,90,  180  ,180 ,180  ,180 ,0    ,90  ,0   ,90,  180  ,90  ,180  ,90  ,0    ,180 ,0   ,180}, // set servos to second position
{135  ,45  ,135  ,45  ,45   ,9  ,45  ,90,  180  ,180 ,180  ,180 ,0    ,90  ,0   ,90,  180  ,90  ,180  ,90  ,0    ,180 ,0   ,180}, // set servo to next position
{135  ,25  ,135  ,45  ,45   ,90  ,45  ,90,  180  ,180 ,180  ,180 ,0    ,90  ,0   ,90,  180  ,90  ,180  ,90  ,0    ,180 ,0   ,180},// set servo to next position
{15  ,45  ,135  ,45  ,45   ,90  ,45  ,90,  10  ,180 ,180  ,180 ,0    ,90  ,0   ,90,  180  ,90  ,180  ,90  ,0    ,180 ,0   ,180},// set servo to next position
{135  ,45  ,135  ,45  ,45   ,90  ,45  ,90,  180  ,180 ,180  ,180 ,0    ,90  ,0   ,90,  180  ,90  ,180  ,90  ,0    ,180 ,0   ,180},// set servo to next position
{135  ,45  ,135  ,45  ,45   ,90  ,45  ,90,  180  ,180 ,180  ,180 ,0    ,90  ,0   ,90,  180  ,90  ,180  ,90  ,0    ,180 ,0   ,180},// set servo to next position
{135  ,45  ,135  ,45  ,45   ,90  ,45  ,90,  180  ,180 ,180  ,180 ,0    ,90  ,0   ,90,  180  ,90  ,180  ,90  ,0    ,180 ,0   ,180}// set servo to next position
};

byte Forward[]={3,4,0,7};
byte OtherMovement[]={1,2,0,5};

Servo Servos[number_of_servos] ;

void setup()
{
// Do attach and other setup
}

void loop()
{
DoWalkingSequence(Forward,sizeof(Forward)/sizeof(byte));
DoWalkingSequence(OtherMovement,sizeof(OtherMovement)/sizeof(byte));
}

void DoWalkingSequence(byte *Movements,int NumMovements)
{
for (int i=0;i<NumMovements;i++)
  {                                                             // this is each step for the picture
  for (int servo_number=0;servo_number<number_of_servos;servo_number++)
    {
    Servos[servo_number].write(Master[Forward[i]][servo_number]);       // writes to servo   
    }
  delay(1000);                                           //delay for servos to move
  }

}


gerg

If you wanna get really geeky on this, here's something to consider. What you're doing is known as key frame animation. You only need your servo positions for each key frame animation. From there, you can interpolate and tween your entire robotic movement. Taking this approach means you need only key frame your specific animations and the tweening would allow you to mix them as you desire. So for example, you could tween a walking and hand waving motion without explicitly coding that combination. Rather, you would have key frames for walking and key frames for waving.

Your master loop would then only care about a relative reference clock and the specific animations you wish to animate. So for example, a forward walk would likely look something like four to eight key frames and a backward walk would be the reverse sequence. The fact is was walking, versus any other movement, would be completely arbitrary, aside from the named association with that specific set of associated key frames.

If you look, you can find lots of coding examples of interpolation, and tweening. Of course, the complexity rises with the provided flexibility.
http://maniacalbits.blogspot.com

Go Up