Hack Notes CVA 090423

From Noisebridge
Jump to navigation Jump to search

Today's hack notes will be just a snip of the motor timing code I did a little work on:

int cycles_per_second = 23; //board and compass specific - must measure
int activity = 100;

(Added two new vars.)

  //Turn on the appropriate motor while keeping track of time
  curr_motor = CalcMotor(8, angle);
  if (curr_motor != prev_motor) { //if we changed angle enough
    TurnOnMotor(curr_motor);      //turn on the new motor
    counter = 0;                  //reset counter
    if (activity < 200){
    activity = activity + 1;      //increase activity level
    }                             //mav val = 200
  } else {
    if (counter < (activity / 10) * cycles_per_second) {  //only keep
      TurnOnMotor(curr_motor);    //same motor on for
    } else {                      //less than cycles * activity level
      TurnOnMotor(0);
    }
    counter++;                    //increment counter
    if (counter > (600 * cycles_per_second) / activity ){
      counter = 0;                //reset counter
      if (activity > 10){         //lower activity level
      activity = activity - 10;   //max val(s) 0-9
      }
    }
  }
  prev_motor = curr_motor;

  Serial.print("counter: ");
  Serial.print(counter);
  Serial.print(" activity: ");
  Serial.println(activity);

And here's what's going on up there:

  1. There is a counter of processing cycles - a fuzzy but good enough approximation of the passage of time.
  2. Every cycle compares the current motor that the compass tells us to activate to the motor that was on in the previous cycle.
    • If the motor has changed, we reset the counter.
    • If the motor has not changed, we see if the counter is under a certain range. If it is, we keep the motor on.
    • If the motor hasn't changed and the counter is past a certain range, we turn that motor off.
  3. After a certain number of cycles, we reset counter. This will cause the motor to turn on again for another interval.
  4. (This is what's new:) There is a variable to keep track of the amount someone is turning.
  5. As this activity level goes up, the length of time we keep the motor on increases and the length of time between counter resets decreases, and vice-versa.
  6. One problem with this is when you are at just the right angle that the compass reading switches back and forth between motors very rapidly the activity level will shoot up. A decent solution - other than moving one's foot half a degree to leave that zone - would be to add some signal smoothing to the code so this situation is less common.

There are some relative constants involved in this process that will need lots of tweaking through experimentation:

  1. The maximum and minimum activity levels are 0 and 200.
  2. A motor stays on for 1/10 the current activity level (times the number of cycles per second). At that value, a motor's on interval will never be longer than about 20 seconds (though it can be followed immediately by another on interval). The on interval can be as short as 0 seconds (because activity level can be < 10 and we're doing division of ints).
  3. The interval until the counter is reset (whether a motor is off or not) is 600 ( * cycles/sec ) divided by the activity level. The longest possible interval is thus six minutes (though at that activity level of 1 there would be no motor activation after six minutes and it would be effectively off until you start moving again!) and the shortest possible interval is 3 seconds.
  4. The rate at which the activity level increases is 1 per change of motor.
  5. The rate of decrease is 10 per counter reset interval.
    • As activity decreases, the counter reset interval increases and the activity level subsequently decreases less quickly.
      • This means the activity level increases linearly, but decreases logarithmically (or would this be exponentially??).
      • I kinda think that this should be neat, but all those bold numbers still have to change until they match up in some magic way to get it to work Just Right.