User Tools

Site Tools


Functions and random behavior

During this class we used pan/tilt-servo-setups to explore putting animated behavior in functions of our own, that we then could call randomly and thereby get a behavior that looks intelligent, and at the same time have code that is easy to overview and change.


We started with the example from the arduino webpage called Sweep which turns a servo from 0 degrees to 180 and back again. Each direction is animated by setting up a for-loop going from one number to the other and for each increment/decrement we move the servo one degree with the command myServo.write(pos) where pos contains the new direction.

We took each of those for-loops and put into a function of our own, called left() and right(), which could look something like this:

void left()
  for(pos = 0; pos < 180; pos++)  // goes from 0 degrees to 180 degrees 
   {                                  // in steps of 1 degree 
     myservo.write(pos);              // tell servo to go to position in variable 'pos' 
     delay(15);                       // waits 15ms for the servo to reach the position 

Now wherever we write “left();” the full movement of the for-loop will be performed before the code moves on.

We did similar things for the other servo called up() and down() thinking the first servo turns us around, and the other looks up or down.

Random behavior

Once we have a few functions we can add the randomness to it. By using random() we can get a random number to use to select one of our prepared movements. It can look something like this:

 int action = random(4);
  if(action == 0)
  else if (action == 1)
  else if (action == 2)
  else if(action == 3)

Notice that there are no curly brackets in the code above. There is a special case with if that says that if you're only doing ONE thing in the if-statement, you can skip the curly brackets. It makes it easier to read, but also might make you forget to put in brackets if they SHOULD be there.

By having the actual specifics of the movement defined in functions outside of loop, and in loop only have this structure of which animation to do at what time, the code becomes a lot easier to read. And if you want to tweak something, it's a lot easier to find the part of the code that's relevant.

Extra tidbits

We defined an ÜBER movement function that would take an angle as input and turn to it regardless of if that angle would be to the left or right of the servo:

void front(int angle)
  if (pos > angle) //is the servo to far to one side?
    for (; pos > angler; pos--)
  else //or the other?
    for (; pos < angle; pos++)

This example introduces two other neat things. 1) Sending a value through when calling the movement, for example “front(75);” and also 2) by not setting a start condition in the for-loop, we avoid the servo swinging crazy from an end angle to a start angle, and just goes from wherever it happens to be.

“for (; pos < angle; pos++)”

For our robot-head to not seem like it's a hyperactive psychopath we might want to make one function just to pause from time to time as well.

Chris played around with trigonometry to move the head in a circle and noticed that if you use this simple calculation, you get a nice gradual start and end of movement.

for (int i = 0; i <= 360; i++) {
    float x = 20 * (cos ((PI * i) / 180)) + 90;
    float y = 20 * (sin ((PI * i) / 180)) + 60;
courses/intro.prototyping.spring.2016.apr12.txt · Last modified: 2016/04/14 01:54 by rickard