High School

Overview: 
Learn about timing issues in robotics programming.
Objectives: 

Understand the speed of program execution on a robot and what that means for your program. Understand how to write code that does not fail due to timing issues.

Content: 

When programming robots (or any other real-time system), it is very important to understand how the speed realm of the robot differs from your own. When we look at our robot program, we see the while loop that we use to perform the read-environment/make-decision/act repeating pattern. We tend to think of this loop as happening slowly or at least as we might think of going through these operations.

The reality is that the robot will execute the while loop in our program thousands of times per second. The robot operates much faster than you think. This can lead to bugs in your programs in some situations.

Consider the example code below. The purpose of the program is to perform two actions controlled by the gamepad buttons. The program will count each time your press button A and on each press of button B, toggle a boolean variable from true to false. Download the program in Android Studio and test it on your robot.

So what happened? When you pressed the A button the immediate result is the program counted hundreds or thousands of button presses. Why? Because while the A button press seemed to you to be quick, on the program's time scale the button was down for many repeats of the while loop, and it counted each loop. Same for the B button. The setting of the boolean value bButton seems erratic and definately not a toggle each time the button is pressed. Again, due to the fact that your idea of a button press and the program's idea of a button press are quite different.

What do we do about this? We have to write code to handle this situation and convert the many button presses seen by the while loop into one logical press and act only when the one logical press happends. Here is the example program modified to handle the timing problems:

Download this program into Android studio and try it out. You should see the button presses now handled correctly.

The use of the variables aButtonPressed and bButtonPressed to track the state of the button is called latching.

 

Navigation:

Overview: 
Explore the use of PID controllers to manage motors.
Objectives: 

Understand what a PID controller is and how to use one to control robot motors.

Content: 

With the test robot used to develop this course, there is a problem with the previous examples of turning under gyro or IMU control. When turning at a constant power setting and setting the power to zero when the target angle is reached, depending on motor configuration, gear ratio, robot weight and the turn power, the robot will most likely not stop quick enough to be on the desired angle. This is called overshoot. On our test robot, a 90 degree turn would end up being 110-120 degrees. Fixing this can be tricky to do manually but there is an automated way to better control the turn.

To do this we will use a software routine called a PID controller. PID stands for Proportional, Integral, Derivative. The idea behind a PID controller is to take the desired state value (90 degrees in our turn example), compare that to the actual (feedback) state value (the current gyro or IMU angle) and apply factors to the difference (called the error) that produce a proportional output value. So in our example we start out turning away from zero towards 90 degrees at the full power we specify. As the turn progresses, the angle of turn is fed to the PID controller routine which measures error and produces a value (the turn power) at or near the starting (full) power. As the turn gets closer to 90 degrees, the PID routine starts to return smaller and smaller values thus reducing the power being applied and slowing the rate of turn. In theory this reduction in power and slowing rate of turn will eliminate the overshoot. The PID controller can also apply a tolerance margin that indicates when the actual value is within some percentage of the target to further control robot motors.

A similar example is to use a PID controller to compute the power correction needed to make the robot drive in a straight line. Here the target is zero (gyro not deviating from direction we are traveling) and any change in the measured angle will result in a correction value calculated by the PID controller.

A PID controller can take a lot of tuning to get the desired result but once you get a feel for how they work you can tune them fairly quickly and by using all three of the PID factors you can get quite fine control over motors. 

There are many resources and discussions of PID online. Here, here and here are some resources to start with to investigate PID further. The FIRST forums on programming have extensive discussions of PID in robot applications.

The example below takes the previous DriveAvoidImu example and uses two PID controller instances to manage straight driving and the 90 degree turn on obstacle contact. The PID controller class itself is an inner class inside the example. It would be an obvious candidate to be moved to a utility class.

 

Navigation:

Overview: 
Learn about the REV Hub's built-in IMU or Internal Measuring Unit and how to use it.
Objectives: 

Understand the REV Hub's built-in IMU and how to use it.

Content: 

The REV Expansion Hub has a built-in IMU, or Intertial Measurement Unit. This is a sensor that can measure acceleration (movement) in several axis. It can be used in place of an external gyro. The IMU is not used in quite the same way as the gyro but is similar. Note: you must configure the IMU on I2C channel 0, port 0. Here is the DriveAvoid example converted to use the IMU in place of the MR gyro.

 

Navigation:

Overview: 
Explore using the Gyroscope Sensor device to gather information about the robot's environment.
Objectives: 

Understand how to use the Gyroscope Sensor to gather information about the robot's environment.

Content: 

Modern Robotics has an gyroscopic sensor designed for use with the Tetrix control system. This sensor can return heading and rate of rotation information. Here is a detailed discussion of the Gyro sensor on the Modern Robotics website. There are links on the page to programming information. This is recommended viewing.

Below is a simplified sample program that uses a gyro to drive in a straight line and avoid obstacles by backing up from contact with an obstacle and turing 90 degress and resuming driving in the new direction. You can paste it into AS and experiment with it.

 

Navigation:

Overview: 
Explore using the Compass Sensor device to gather information about the robot's environment.
Objectives: 

Understand how to use the Compass Sensor to gather information about the robot's environment.

Content: 

Modern Robotics has an Compass sensor designed for use with the Tetrix control system. This sensor can read the magnetic heading of the sensor, acceleration and tilt. The FTC SDK has a sample program you can use to experiment with the Optical Distance sensor. In AS, open the path FtcRobotController/java/[first package]/external.samples/SensorMRCompass. You can enable this program and work with it but any changes you make will be overwritten at the next update of the SDK. You can copy the class in the teamcode area so any changes you make will be retained.

Here is a detailed discussion of the Compass sensor on the Modern Robotics website. There is a link on the page to programming information. This is recommended viewing.

Navigation:

Overview: 
Explore using the Optical Distance Sensor device to gather information about the robot's environment.
Objectives: 

Understand how to use the Optical Distance Sensor to gather information about the robot's environment.

Content: 

Modern Robotics has an Optical Distance sensor designed for use with the Tetrix control system. This sensor can read the distance to a surface when the surface is within 15 centimeters of the sensor. The FTC SDK has a sample program you can use to experiment with the Optical Distance sensor. In AS, open the path FtcRobotController/java/[first package]/external.samples/SensorMROpticalDistance. You can enable this program and work with it but any changes you make will be overwritten at the next update of the SDK. You can copy the class to the teamcode area so any changes you make will be retained.

Here is a detailed discussion of the Optical Distance sensor on the Modern Robotics website. There is a link on the page to programming information. This is recommended viewing.

Navigation:

Overview: 
Explore using the Color Sensor device to gather information about the robot's environment.
Objectives: 

Understand how to use the Color Sensor to gather information about the robot's environment.

Content: 

Modern Robotics has a color sensor designed for use with the Tetrix control system. This sensor can read the color of a surface when the surface is within a few centimeters of the sensor. The FTC SDK has a sample program you can use to experiment with the color sensor. In AS, open the path FtcRobotController/java/[first package]/external.samples/SensorMRColor. You can enable this program and work with it but any changes you make will be overwritten at the next update of the SDK. You can copy the class to the teamcode area so any changes you make will be retained.

Here is a detailed discussion of the color sensor on the Modern Robotics website. There is a link on the page to programming information. This is recommended viewing.

This example shows an interesting technique. It gains access to the user interface elements of the FtcRobotController app and uses that access to change the background color of the controller app to match the color detected by the sensor. How this is done and the many other possibilities this opens are beyond the scope of this lesson, but the ability to access and use features of the controller phone is something to be aware of.

 

Navigation:

Overview: 
Explore using the Range Sensor device to gather information about the robot's environment.
Objectives: 

Understand how to use the Range Sensor to gather information about the robot's environment.

Content: 

Modern Robotics has a range sensor designed for use with the Tetrix control system. This sensor can read the distance to a surface when the surface is between 5 and 255 centimeters of the sensor. The FTC SDK has a sample program you can use to experiment with the range sensor. In AS, open the path FtcRobotController/java/[first package]/external.samples/SensorMRRangeSensor. You can enable this program and work with it but any changes you make will be overwritten at the next update of the SDK. You can copy this class to the teamcode area so any changes you make will be retained.

Here is a detailed discussion of the range sensor on the Modern Robotics website. There is a link on that page to programming information. This is recommended viewing.

Navigation:

Overview: 
Explore using the IR Seeker device to gather information about the robot's environment.
Objectives: 

Understand how to use the IR Seeker to gather information about the robot's environment.

Content: 

Modern Robotics has a IR beacon sensor (called IR Seeker V3) designed for use with the Tetrix control system. This sensor can detect the IR beacons used for some FTC games and provide information about the location of the beacon relative to the robot. The FTC SDK has a sample program you can use to experiment with the IR Seeker. In AS, open the path FtcRobotController/java/[first package]/external.samples/SensorMRIrSeeker. You can enable this program and work with it but any changes you make will be overwritten at the next update of the SDK. You can copy that class to the TeamCode area so any changes you make will be retained. Right click the SensorMRIrSeeker class and click copy. Then right click on the teamcode package in the TeamCode area and click paste. AS will copy the example class into the TeamCode area and adjust the package name.

Here is a discussion of the IR Seeker on the Modern Robotics website.

 

Navigation:

Overview: 
Explore the use of encoders to create feedback control of motors.
Objectives: 

Understand how to use encoders to better control motors by measuring their operation.

Content: 

So far we have been controlling the distance the robot travels with elapsed time. A more accurate way to control movement is with encoders. Encoders attach to or are integrated into the drive motors and count the revolutions of the motor shaft either optically or magnetically. The DcMotor object has support for using encoder counts to control how long the motor will run when turned on. In the example code we will run forward for 5000 encoder counts and stop. Then we will run backwards to zero encoder counts to the starting point. You will need to add encoders to both of the drive motors. Note that encoders don't count revolutions directly but count partial rotations to allow you to process small movements. A US Digital E4P encoder (in the Tetrix kit) will report 1440 counts for one revolution of the motor shaft. Each type of encoder will have a different counts per revolution value so you need to consult the specs for each encoder you use.

We set the target position of 5000 encoder counts. Nothing happens until we set the power level on the motors, then they start running and will run until the encoder count reaches 5000 and then stop on thier own. Note we still need to set power to zero when the movement is done.

Our code needs to wait while the motors are running to the target position. The example shows two ways to do that, one watching the DcMotor.isBusy() function (true while motor has not reached the target) and the other compares the current motor position to the target position. You could also determine the amount of time needed to complete the movement and wait for that time to pass. In either case, since we selected the motor run mode as RUN_TO_POSITION, the motor will stop on it's own with brakes on.

Run mode RUN_WITH_ENCODER does not stop on it's own. You have to manage that yourself. RUN_WITH_ENCODER tries to run the motor at a constant speed, which is a percentage of the max speed of the motor. You set the percentage just as you do with percentage of power using the setPower() function. When you set a power level, the speed of the motor will be influenced by the battery power level and will slow down as power fades. When you set a speed level, the motor will adjust it's power to maintain a constant speed, to the extent there is battery power available to accomplish that.

If your program calls for you to run your motors without using encoders after you use encoders, you must set the motors to run without encoders using the enum DcMotor.RunMode.RUN_WITHOUT_ENCODER. Running without encoders just means the motor will take no automatic action, but the encoder is still counting. As shown in the example, you can monitor encoder counts yourself and decide when stop instead of having the motor do it automatically. Having the motor stop automatically is more accurate.

Create a new class called DriveWithEncoder and copy/paste the example code. Demonstrate your program using encoder counts.

In practice, you can determine the number of encoder counts needed to complete a movement experimentally by displaying the counts reported by the motors and manually moving/driving the robot through the movement. You can also measure the number of encoder counts that translate to actual distance in inches or feet and then set your movement in those units, converting to counts. The number of counts to a unit of distance will be a function of wheel size and the gears used between the motor shaft and wheel shaft. Modify the example to move a selected distance in feet. Make the code that converts distance into counts into a function that can be reused.

Here is more detailed information about encoders on the Modern Robotics website.

Here is a quiz on using encoders.

 

 

Navigation:

Pages