Middle School

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:

Overview: 
Explore programming Servos.
Objectives: 

Understand Servos and how to program them.

Content: 

Now lets look at using servos to control robot functions. The wheel motors we used in the previous exercises simply run at whatever power level they are set at. Servos are different in that they have a defined range of motion and you control them by setting the location in that range you want the servo to move to. Once in that position, servos resist movement. Servos are typically used for arms and grippers.

Servo positions range from 0 to 1 representing 100% of the servo's range of motion. When you build your robot, you will have to experimentally determine how the position values map to the arm and gripper servos in terms up up/down and open/closed.

Note that there are also continuous servos which run just like regular motors. You set the power and direction and the servo runs in that mode until set to something different.

In this exercise, we will have three servos on our robot, one will raise and lower an arm. In our hardware configuration we name this servo "arm_servo". At the end of the arm is a simple gripper which is opened and closed by a second servo named "grip_servo". The third servo is a continuous servo named "cont_servo". We use buttons on the controller to move the servos. Lets extend our Tank Drive example to operate these servos:

Copy and paste this code into a new OpMode called DriveWithGripper and demonstrate servo control on your robot.
 
We operate the regular servos by adding or subtracting a small amount to the servo position when a gamepad button is depressed. We have to montior the position and not go over or under the servo min/max. For the continuous servo we just set the power with appropriate sign to rotate the servo in response to the left and right D-pad buttons.
 
Note that the increment and decrement of the servo position variables show the two different ways to add or subtract with a numeric variable.
 
Here is more detailed information about servos on the Modern Robotics website.
 
When you test this code you will see that displaying double or float values may result in a very large number  being displayed due to the nature of these data types in Java. By default, if a double or float has places right of the decimal point, all of those places will be displayed. We can trim that down using the format function of the String class. Here we call String.format(formatstring, variable) where the format string tells Java we will be displaying a floating point number and we only want to show 2 places right of the decimal point. You can comment out the original lines and uncomment the lines with String.format() to see how this works. Finally, addData() has built in support for formatting the message so you don't have to use String.format(). Try all 3 ways. Here is a detailed discussion of formatting variables into strings for output.
 

Navigation:

Overview: 
Explore adding logging of debugging information to a file on the controller phone and then pulling that file back to the PC for examination.
Objectives: 

Add the provided logging utility source code to your project and then understand how to use logging in your programs.

Content: 

We are now going to take a look at logging (also called tracing) as a tool to debug our robot programs. Logging is recording useful information from the robot program to a disk file on the EV3 controller. You can then download that file to your PC and examine it. It can be very useful to record information while your robot is running during a match so you can look at it afterwards and see what took place. If you have not read the general lesson on Logging, you should do that now.

To get started, we need to get the provided logging code into your robot controller project. In the teamcode package, create a new class called Logging. Click here to open the logging class code. Copy the code and paste it into the new Logging class you just created. This adds the logging class to your project and makes it available for use in your OpModes.

Now we are going to copy the DriveCircleTouch example and add logging to it. Create a new class in the teamcode package called DriveCircleLogging. Copy the code below into that class.

Now lets discuss the changes made to implement logging. We added a constructor method to this class and in that method call Logging.Setup(). This initializes the logging system. We then write a message to the log file with the Logging.log() method. We then added other messages recording the progress of the OpMmode.

The logging class will write the messages to a file called Logging.txt in the top directory of the controller phone. You can use ADB (Android Debug Bridge) to download that file from the phone. Open the terminal window at the bottom of Android Studio. Copy and paste  this command into the terminal window and press enter:

adb pull //storage/sdcard0/Logging.txt c:\temp\robot_logging.txt

This will pull the file from the phone into the PC directory specified. You can then view the file with Notepad.

Run the program 3 times, once letting it run the 5 seconds and stop on timeout. Then  run again and press the touch button before the 5 seconds passes. Last, run it and click the Stop button on the Driver Station before time runs out. Then pull the Logging.txt file back to your PC and take a look. It should look like this:

<0>02:43:46:360 DriveCircleLogging.<init>(DriveCircleLogging.java:25): Starting Drive Circle Logging
<1>02:43:46:377 DriveCircleLogging.runOpMode(DriveCircleLogging.java:41): waiting for start
<1>02:43:47:286 DriveCircleLogging.runOpMode(DriveCircleLogging.java:49): running
<1>02:43:53:299 DriveCircleLogging.runOpMode(DriveCircleLogging.java:68): timeout
<1>02:43:53:301 DriveCircleLogging.runOpMode(DriveCircleLogging.java:81): out of while loop
<1>02:43:53:312 DriveCircleLogging.runOpMode(DriveCircleLogging.java:91): stopFlag=true, i=3, d=3.750000
<1>02:43:53:314 DriveCircleLogging.runOpMode(DriveCircleLogging.java:93): done
<0>02:43:54:647 ========================================================================
<0>02:43:54:650 DriveCircleLogging.<init>(DriveCircleLogging.java:25): Starting Drive Circle Logging
<2>02:43:54:662 DriveCircleLogging.runOpMode(DriveCircleLogging.java:41): waiting for start
<2>02:43:55:305 DriveCircleLogging.runOpMode(DriveCircleLogging.java:49): running
<2>02:43:57:456 DriveCircleLogging.runOpMode(DriveCircleLogging.java:74): button touched
<2>02:43:57:464 DriveCircleLogging.runOpMode(DriveCircleLogging.java:81): out of while loop
<2>02:43:57:480 DriveCircleLogging.runOpMode(DriveCircleLogging.java:91): stopFlag=true, i=3, d=3.750000
<2>02:43:57:483 DriveCircleLogging.runOpMode(DriveCircleLogging.java:93): done
<0>02:43:59:727 ========================================================================
<0>02:43:59:733 DriveCircleLogging.<init>(DriveCircleLogging.java:25): Starting Drive Circle Logging
<3>02:43:59:755 DriveCircleLogging.runOpMode(DriveCircleLogging.java:41): waiting for start
<3>02:44:00:937 DriveCircleLogging.runOpMode(DriveCircleLogging.java:49): running

Note the log message that uses format specifiers to merge variable data into the log message. You can read more about formatting here.

One final thing to note. Looking at the trace, we can see that when we pressed the Stop button on the DS, the trace ends immediately and the code after the while block is not executed. Yet it is when we end on timeout or button touch. The reason is that when the Stop button is pressed, the built in controller app code that runs your code throws an exception. That exception stops OpMode execution. This is done to make sure your OpMode does not run after the Stop button is pressed. However, this prevents your code from doing anything after the Stop button is pressed. There might be some clean up or perhaps logging that you would like to do before your OpMode ends. If so, you can run code after the while block by wrapping the while block in a try/catch block:

Catching the exception allows you to execute code after the OpMode has been signaled to stop. Note that if you do this, you are responsible for making sure your OpMode performs no action that could be construed as gaining an advantage in the game and you should make sure your code does end in a timely manner.

 

Navigation:

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

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

Content: 

Lets look a using sensors by starting with the simple touch sensor. This is simply a button that can be used to signal your code that something has happened by pushing the button. We will add a Modern Robotics Touch Sensor to the robot and plug it into digital port 0 on the Device Interface Module. We modify our controller phone configuration to identify digital port 0 as a touch sensor and name it touch_sensor. We will take the earlier DriveCircle exercise and modify it to use the touch sensor to determine when to stop driving:

Copy and paste this code into a new OpMode class called DriveCircleTouch and demonstrate your robot driving in a circle. It should keep driving until you press the touch sensor button or 5 seconds pass. Note the use of the while loop to run the robot while watching for 5 seconds to pass and also watching for the touch sensor button press. The TouchSensor isPressed() function returns false when not pressed and true when pressed. For us to continue to run while not pressed, we invert the result of the isPressed() function by preceeding it with the ! (invert) operator.

When using the REV Robotics touch sensor, there is no specific touch sensor class. The sensor is treated as a simple digital (input) device. Here is the above code sample modified to use the REV sensor:

Connecting the touch sensor or other digital device to the REV Hub has some nuances. Be sure to read the discussion here.

 

Navigation:

Pages