I cannot thank George Gillard from New Zealand enough for creating and making available his Beginner’s Guide to RobotC, Volume 1 and Volume 2. These documents are professionally organized and laid out, with clear writing and examples to demonstrate the concepts offered. Here are a few concepts from Volume 2.

EasyC users: You can make use of these concepts exactly the same way that RobotC users can; the code below can very easily be adapted to work in the EasyC user interface.

Stopping in Autonomous

As many people have probably experienced in autonomous mode, when you tell the chassis motors to stop after xx-encoder-clicks or xxx milliseconds, the motors do turn off when you ask them to, but the robot still obeys the laws of physics and rolls forward some additional amount from its own inertia.

Mr. Gillard introduces a concept that I had not considered before, which is applying the breaks—for a very short time. Yes, this is hard on your motors, and should not be over-used or used at high speeds (well, if you value your motors, anyway). Here’s a function from his manual for driving forward and stopping quickly:

void driveForward( int time, int speed ) {
   motor[leftDrive] = speed;
   motor[rightDrive] = speed;

   motor[leftDrive] = -10;   // Brake
   motor[rightDrive] = -10;  // Brake
   wait1Msec(50);            // for a really short time

   motor[leftDrive] = 0; 
   motor[rightDrive] = 0;

We have tried this on our autonomous code, and are very pleased with the results—it really does stop on a dime. Depending on the weight of your robot and its drive speed, you might find that you need to vary either the breaking time or the breaking power to get the outcome you need.

Button Commands in One Line

Our standard code for connecting buttons to motors looks something like this:

if Button6U == 1, set motor5 to 100 power
else if Button6D == 1, set motor5 to -100 power
else set motor5 to 0

But there’s an all-in-one way to do this, that I think is pretty elegant:

motor5 power = (Button6UButton6D) * 100;

If a button is pressed, it returns a value of 1; if it is not pressed, it returns a value of 0. Looking at the formula above, we have the following:

  • If Button 6U is pressed (and 6D is not), then we’ll get (1 – 0) * 100 = 100 power.
  • If the reverse is true (6D is pressed/6U not), then we have (0 – 1)*100 = -100 power.
  • If neither button is pressed, then we have (0 – 0) * 100 = 0 power.

Pretty nifty!

  • However, if both buttons are pressed, then we have (1 – 1) * 100 = 0 power. This scenario (0 power) is probably not what’s really desired—you’d probably still want the motor to do something based on what’s more important to the robot’s functionality—so you could code some extra functionality for this possibility, or you can tell your drive team, “Hey! Don’t press Up and Down buttons at the same time.”

Slowing Down as You Approach Your Target

This topic can be usefully applied to any kind of movement that’s being controlled by sensor readings: arm movement with potentiometer, driving with ultrasonic sensor, or driving with shaft encoders. This functionality helps reduce the likelihood that one will overshoot the target sensor value. With an arm and potentiometer, some simplistic code could look like this:

int desiredHeight, difference;

while( sensorValue(armPotentiometer) < desiredHeight ) {
   difference = desiredHeight  sensorValue(armPotentiometer);
   motor[arm] = difference;

The power delivered to the arm motor, when the arm is far away from the target, will default to the maximum of 127 power. As it gets closer and the gap between actual and desired height narrows, the power to the arm will get smaller and smaller until the power is set to 0 when the arm reaches its target. To make the arm move more smoothly, the difference variable could be multiplied by a constant fraction, and one could also include a threshold on the desiredHeight to allow for some “slop” in the arm’s action—but this here is the basic concept; customize as needed.

♦        ♦        ♦

I hope you find these concepts as helpful as I have!