Middle School

FIRST YSMClass: Clone of Robo Intro

FIRST YSMClass: Clone of NXT Parts Exploration

FIRST YSMClass: Clone of NXT Kit Overview

FIRST YSMClass: Clone of Introduction to NXT

FIRST YSMClass: Clone of What is a Robot?

Customization Description: 
Overview: 

This course is intended to introduce the Java programming language to students using the EV3 (FLL), Tetrix (FTC) and RoboRio (FRC) robotics platforms. For EV3, the course moves the student away from block based robot programming to using a text based programming language. For Tetrix and RoboRio, the course will provide more instruction in Java itself, which is missing in existing materials. The course will teach a basic competency in Java with a focus on robotics applications. Robot construction will not be covered in any depth as it is assumed the student will have or acquire hardware building skills separately. The course is targeted to beginners and there are no prerequisites.

Get started using this course by clicking the first Unit and then the first Lesson. The Lesson content will be displayed and next/previous lesson buttons will appear at the bottom of each lesson making it easy to move between adjacent lessons.

Education Level: 
Overview: 
Learn about Interfaces which are definitions of the fields and methods implementing classes must expose.
Objectives: 

Understand Interfaces and be able to use them when appropriate.

Content: 

Just as a class is a description of an object, an Interface is a description of a class. An Interface defines the fields (variables) and methods that a class must provide (public access) to users of the class. The Interface does not define how a class derives the value of a field or the result of a method, only that a class that implements an Interface must expose that Interface's fields and methods. As such, the Interface defines a public facing API that the class must provide. Interfaces are also called Contracts, in that the Interface defines a contract or agreement (in terms of the fields and methods exposed) between a class and users of that class. Classes may extend only one (parent) class but classes may implement any number of interfaces.

One power of Interfaces is that any class that implements an Interface can be used where ever that Interface is defined as a required data type. This concept is best explained by an example.

A simplifed view of the PIDController class in the FRC library shows a constructor that takes two classes as input, a PIDSource object and a PIDOutput object. PIDSource and PIDOutput are both Interfaces. Digressing for a moment, a simplified PIDController needs two things to perform its function. An input or process control value that will be used by the PIDController to compute an output value, which must be sent to some other class for action. Now in many cases the input value will come from an encoder (counts) and the output value will go to a motor (power). You could define the PIDController class constructor as Public PIDController(Encoder enc, Motor motor). There are two problems with this. First, the PIDController class and the Encoder and Motor classes have not agreed on how data will pass between the Encoder and PIDController class and how data will pass between the PIDController and Motor class. The second issue is that the PIDController as defined will only work with Encoders and Motors. What if we wanted to use some other classes as the input and output objects? Interfaces solve both of these problems.

The simplified PIDController class constructor actually looks like this: Public PIDController(PIDSource source, PIDOutput output). PIDSource and PIDOutput are Interfaces and they define what fields and methods are required for any class that wants to act as a PID source or PID output object. These Interfaces define the contract between the PIDController class and any class wanting to act as a PID source data provider or a PID output data consumer. The example Interfaces look like this:

A class implementing the PIDSource Interface must provide a method defined as double pidGet(). That method must return the current input value to be used by the PIDController. Since any class passed into the PIDController constructor for input must implement the PIDSource Interface, the PIDController now knows what method to call on the source object reference variable to get the input value. For instance, the Encoder class implements PIDSource and as such must provide the method pidGet() along with its other methods. When pidGet() is called, the Encoder returns the current tick count. So an Encoder object can be passed to the PIDController constructor. But so can any other class that implements PIDSource. A class implementing the PIDSource Interface would look like this:

Any class that implements PIDOuput must provide the pidWrite(double value) method. That method when called, will take the passed value and perform some action with it. The PIDController knows that any class implementing PIDOutput will have  the pidWrite() method and so it knows how to send the output value it has calculated from the input, by calling the pidWrite method on the output object reference variable. A class implementing the PIDOutput Interface would look like this:

For instance, the Motor class implements PIDOutput and provides the pidWrite(double value) method and sets it's motor power from the value. So a Motor object can be passed to the PIDController constructor as an output object. But so can any other class that implements PIDOutput.

A simplified PIDController class would look like this:

An example of using these classes:

The key here is that the single implementation of the PIDController class can handle both the custom source and output classes as well as the standard encoder and motor classes.

Classes can implement more than one Interface along with any other fields or methods they wish. Interfaces are very powerful and allow a class expecting an Interface (like PIDController) to work with any number of other classes that implement that Interface.

Note that Interfaces only define the expected fields and methods to be exposed by the implementing class. The actual implementation (code) is contained in the class implementing the Interface.

Like many things in Java (and other languages), this is a basic introduction to Interfaces. There is a lot more to Interfaces which you can read about here. Here is a video on interfaces. This lesson should be enough to understand Interfaces and use them in your robot code.

 

Navigation:

Overview: 
Explore the concepts and details of using more than one Thread of execution in a program.
Objectives: 

Understand what Processes and Threads are and what it means to have multiple Threads active in Java program. Gain a basic understanding of how to use Threads.

 

Content: 

An executing Java program is called a Process. That process executes your instructions (program) sequentially following the path you created when you wrote your program. This single path is called a thread. As such, your program is only doing one activity (Java statement) at a time and working on one task (your programs list of statements) at a time. For most situations, this works fine. But there are times when you would like to have your program doing more than one thing at time. Using Java Threads it is possible to create additional threads or paths of execution that run in parallel with the main (or first) thread. The effect is that your program can be doing more than one thing (task) at a time. Doing robotics on our platforms you will not need additional threads (multi-threading) most of the time but there are some cases where multi-threading can be useful. Threads can be used to simplify the main path in your program or to perform repetitive tasks while the main thread is busy with something else, sleeping or waiting for some user action.

Like many aspects of programming in Java (and other languages), threads are simple in concept but potentially complex in implementation. There are several ways to do threading and multi-threading can create very interesting and hard to find bugs in your program. But it is possible to keep it simple and get benefit from multi-threading without getting into too much of the possible complexity. We are going to explore basic threading here and there will be example programs in each of the platform sections. It is probably best for you to go now to the section for your hardware platform and work through the examples until you come to the one on using Threads. Then return here to finish this lesson.

When creating a new thread of execution in a Java program, there are two ways to do it. You can use the runnable interface or you can extend the Thread class. We are only going to look at extending the Thread class.

When creating a new thread, the main thing we need to define is the code you want executed in that thread. When you create a new thread, you are telling the JVM here is a bit of code, start running it separately from the main thread and run it until the code path comes to an end. The thread code can have it's own private variables that exist only while the thread is running and the thread shares the class level variables of the class that creates the thread, assuming the thread class is an inner class. An inner class is a class within a class and doing threading with inner classes greatly simplifies things.

Lets look at a simple example:

Here the main thread prints the value of i every half second and the thread increments the value every second. You can see by the results of this code that the two threads run independently of each other.

The code we want to run in the thread is put in the run() method of the thread class. Threads are started with the start() method and stopped with the interrupt() method. When thread.interrupt() is called, the Thread class isInterrupted() method returns false. You should look for this to exit your thread code. If you happen to be in a blocking method when interrupted, sleep() in this case, the InterruptedException will be thrown. You normally just ignore that exception as it is just another signal to stop your thread code. The second catch statement catches and reports any errors that might occur in your code.

Here is this example in CodingPoint. Threads can be used in many ways and there are many methods on the Thread class for managing and coordinating threads. More complex threading is beyond the scope of this lesson and if you use threads it is best to keep it simple as shown here.

When doing multiple threads, you frequently need to share data between threads. Coordinating access to shared variables is called concurrency and is a complex and multi-faceted subject. Java contains many features to allow threads to coordinate write access to shared variables and objects by multiple thread. Again these features are beyond the scope of this lesson. To keep it simple and avoid concurrency issues, follow this rule: variables should only be updated by one thread. They can be read by several threads but only changed by one. In the above example, only the MyThread class changes the value of variable i.

Here is a simple tutorial and a video on multi-threading. Here is a more detailed tutorial including concurrency and here is the official Java documentation on threading.

 

 

Navigation:

Pages