Introduction and request for Help - Motors "go crazy" at end of a mpr() command

7 replies [Last post]
RiverValley_Joe
Title: NooBot
Joined: 10/13/2012
Posts:
BotPoints: 19
User offline. Last seen 9 years 24 weeks ago.

Howdy community - I am new advisor to a team, and am testing the equipment we inherited from last year's team. Oh, and learning about KISS IDE, and everything! I have experience as C coder, from 20 years embedded software work, but am new to this particular IDE, the CBC, and associated lingo. While I have experience with embedded Linux (HardHat), I do not expect this year's team of bright and energetic rookies to go beyond using the KISS library functions. But watch out, these students are having fun!

Um, by way of "introduction", I live in East San Diego county, am retired, and love this "programming robots" stuff. I also like to grow vegetables.

Our team has no "veterans" returning from precious year, so we (I) am likely going to be here with many questions. I would appreciate pointers to where answers to my often basic questions could be found! I researched this "chattering" issue, and have found nothing, so far.

What I am finding is after an mrp, such as: mrp(1,100, 400); the motor often (most of the time) chatters or oscillates for a while, sometimes seems like it will not even stop ratcheting. The red/blue forward/reverse LEDs flash back and forth!

The behavior happens on all ports (well 1,2,& 3, as port 0 has broken-off connection thing), and all motors.

Perhaps it is seeking an exact position? mav() commands seem to work OK, with a slight hesitation at particular points as they turn.

Here is test code:
int test_motor(int n, int speed, int offset)
{
mrp(n,speed, offset);
bmd(n);
sleep(1);
ao();
printf("did mrp(%d, %d, %d), have position: %d\n", n, speed, offset, get_motor_position_counter(n));
}

int main()
{
test_motor(1,100, 500);
test_motor(2,100, -400);
test_motor(3,100, 400);
printf("all off, done\n");
}

Best regards,
Joe

Jeremy Rand
Jeremy Rand's picture
Title: Botball Youth Advisory Council
Joined: 04/03/2009
Posts:
BotPoints: 1168
User offline. Last seen 7 years 18 weeks ago.

Hi Joe, welcome to the Botball Community!

I've seen this happen occasionally as well. Probably the best way to see what's happening is to look at the CBOB motor controller source code: https://github.com/kipr/cbc/blob/master/bob/firmware/boblib/motors/motors.c

If you look at the MotorPositionControl function:

  1. int MotorPositionControl(int motor)
  2. {
  3. int diffPosition = g_TargetPosition[motor] - g_MotorCounter[motor];
  4. int speed = 0;
  5.  
  6. // is the difference in position within the threshold values
  7. if((diffPosition > -g_MotorThreshold[0]) && (diffPosition < g_MotorThreshold[0]))
  8. {
  9. g_MotorIError[motor] = 0;
  10. g_MotorInMotion &= ~(1<<motor); // clear the Motor in motion bit
  11. //g_MotorCtrlType[motor] = 0; // turn motor position control off
  12. }
  13. else
  14. {
  15. speed = (diffPosition);
  16. if(speed > g_TargetTPC[motor]) speed = g_TargetTPC[motor];
  17. else if(speed < -g_TargetTPC[motor]) speed = -g_TargetTPC[motor];
  18.  
  19. speed = PIDSpeedControl(motor, speed - g_MotorTPC[motor]);
  20. }
  21.  
  22. return speed;
  23. }

As you can see, it's checking whether the current position is within a threshold (set to 100 by default) of the goal position. If it is, then it stops moving the motor; otherwise it will actively try to get it within that threshold, resulting in the oscillation you're seeing.

Unfortunately, there is no easy way to change this threshold unless you recompile the CBOB firmware, which is sufficiently dangerous that I don't recommend it. However, there are some other things you can try. First off, you can try putting a heavier load on the motor, which may make it oscillate less. The other thing you can try is setting the PID gains (I think there's documentation in the KISS-IDE manual on this) to something lower, which will also reduce oscillation. The end goal is to reduce oscillation sufficiently that it will pass through the threshold without bouncing from one side of it to the other.

If none of the above works, a somewhat more hacky solution is, instead of using bmd(), simply call get_motor_position_counter and check whether it's close to the goal position you gave; if it is, move onto the next command (or call the off() function). This will let you choose your own threshold, but be warned that it will be less responsive than bmd() because the Chumby's Linux kernel will introduce lag.

Hope all this helps.

EDIT: The 100 threshold is in CBOB units, which can be calculated by multiplying the ticks displayed on the CBC GUI by 44. So the threshold is approximately within 2 ticks of the target position.

-Jeremy Rand
Senior Programmer, Team SNARC (2012-2013), Norman Advanced (2010-2011), Norman HS (2008-2009), Norman North (2005-2007), Whittier MS (2003-2004)
2012-2013 VP of Tech, 2011 President, Botball YAC (2009-2013)
Mentor, Alcott and Whittier MS

RiverValley_Joe
Title: NooBot
Joined: 10/13/2012
Posts:
BotPoints: 19
User offline. Last seen 9 years 24 weeks ago.

Hi,and thanks, Jeremy, I do see set_pid_gains in "the Manual". I do not get any intuition or understanding of what "the p, i and d coefficients." means, so I am researching! I see many references on the Net, so Onward"! I expect to learn more before I tinker. I guess you can infer that I am not a hacker type, but prefer to learn more first!

You mention "...ticks displayed on the CBC GUI by 44". I did not see how to get that from the GUI, but I shall continue to poke at it.

Thanks again,
Joe

Jeremy Rand
Jeremy Rand's picture
Title: Botball Youth Advisory Council
Joined: 04/03/2009
Posts:
BotPoints: 1168
User offline. Last seen 7 years 18 weeks ago.

Yes, PID coefficients are somewhat complex a subject. A simple way to modify them is, if you cut all of the coefficients in half (e.g. by doubling the divisor arguments from the defaults), the PWM output to the motors will be cut in half for a given situation. This will make the motors less responsive but also oscillate less. Finding "optimal" coefficients is difficult, but simple trial and error can yield "good" results.

To see the position in ticks of the motors, if you go to the Sensors test screen, I believe it will show the four motor positions there. (I don't have a CBC handy to check right now, sorry.)

-Jeremy Rand
Senior Programmer, Team SNARC (2012-2013), Norman Advanced (2010-2011), Norman HS (2008-2009), Norman North (2005-2007), Whittier MS (2003-2004)
2012-2013 VP of Tech, 2011 President, Botball YAC (2009-2013)
Mentor, Alcott and Whittier MS

RiverValley_Joe
Title: NooBot
Joined: 10/13/2012
Posts:
BotPoints: 19
User offline. Last seen 9 years 24 weeks ago.

Thanks, I did just halve the numerators, seemed easy. The chatter is gone. Fine-tuning is for later!

Uh, the micro-servo seems to tend to chatter too, and do not see "PID" parameters for them, sigh!

I got a good sense of PID motor control from this link:
http://courses.csail.mit.edu/6.141/spring2011/pub/lectures/Lec03-MotorCo...

OK, onward,
--Joe

Jeremy Rand
Jeremy Rand's picture
Title: Botball Youth Advisory Council
Joined: 04/03/2009
Posts:
BotPoints: 1168
User offline. Last seen 7 years 18 weeks ago.

Happy to hear you got it resolved. And thanks for posting the link, it'll probably be helpful for other members of the Community. Unfortunately it's not possible to change gains on the servos; the only solution I can think of is to increase the load on the servo.

-Jeremy Rand
Senior Programmer, Team SNARC (2012-2013), Norman Advanced (2010-2011), Norman HS (2008-2009), Norman North (2005-2007), Whittier MS (2003-2004)
2012-2013 VP of Tech, 2011 President, Botball YAC (2009-2013)
Mentor, Alcott and Whittier MS

RiverValley_Joe
Title: NooBot
Joined: 10/13/2012
Posts:
BotPoints: 19
User offline. Last seen 9 years 24 weeks ago.

Are the micro-servos particularly sensitive to this chatter issue? (Seems like it...) And it seems to have to do with longer excursions. With smaller movements the micro's seem to be stable.

--Joe

Jeremy Rand
Jeremy Rand's picture
Title: Botball Youth Advisory Council
Joined: 04/03/2009
Posts:
BotPoints: 1168
User offline. Last seen 7 years 18 weeks ago.

I'm not particularly knowledgeable about the servo types (I was a programmer, not a builder), but I do know that we always found the micro-servo to be near-useless due to its low torque and high speed. I think the best use we ever found for it was to hit the Create's power button as a fail-safe in case a disconnect happened. Since they're very fast relative to their torque, I wouldn't be surprised if they're particularly vulnerable to the problem you're encountering.

-Jeremy Rand
Senior Programmer, Team SNARC (2012-2013), Norman Advanced (2010-2011), Norman HS (2008-2009), Norman North (2005-2007), Whittier MS (2003-2004)
2012-2013 VP of Tech, 2011 President, Botball YAC (2009-2013)
Mentor, Alcott and Whittier MS