FRC Java Beta Testing

Document Sample
FRC Java Beta Testing Powered By Docstoc
					FRC Java Beta Testing Overview for Teams Considering Java Development Team 1279 ColdFusion

1 The NetBeans Development Environment
The NetBeans IDE is a great full featured development environment for Java. It is widely used and free, so if you have any interest in Java definitely take a few minutes to get it and take a look. The NetBeans site is, there are a wide variety of resources beyond just the downloads we need. Same for the official Sun Java site

1.1 Getting NetBeans & Java
From the NetBeans and Java pages there are links to downloads, you want to make sure that you download a package with Java ME (micro edition), at the moment it is bundled with the SE package and a few other things. SE (standard edition) will give you things to play with while waiting for FIRST to release the robot plug-ins for ME. You can go from the top-level page to Java SE (on the right hand side) or directly to: The exact version of the JDK and NetBeans changes regularly, download the 6.7.1 NetBeans and JDK 6 Update 17 at the moment.

Select your OS and download speed on the next page, and press continue

You are offered a chance to login, but you can press 'skip this step'.

Depending on the security settings of your browser you may need to acknowledge a security warning to allow downloads.

The package is 136MB, download took 5m 18s over a Comcast cable connection.

1.2 Installing NetBeans
We have installed NetBeans and the JDK on computers running Windows XP, Vista, and Ubuntu Linux. Note that as of this time:  Windows 7 is not supported  You will need at least one Windows machine to run the LabView imaging tool. Install time was roughly the same on each platform, and much quicker than installing with LabView from DVD.

When you install you may get a security warning about the digital signature

You have to continue.

Accept the license agreement.

Accept or change the install directories

Register and agree to provide usage data if desired.

1.3 Configuring for FRC
Please note that we are required by our NDA with FIRST not to publish the Programming Guide or other beta documents. Hopefully FIRST will be making them available in early December again this year, I strongly recommend you work with NetBeans while waiting and add the FIRST plugins as soon as they become available. When you first open NetBeans it will also ask you to register. To configure for FRC use go to Tools->Plugins and choose the Settings tab. Use the button 'Add' to add the path to the current set of plugins. This path has changed during Beta so that people can go back and forth between versions.

Important:  'Check for updates automatically' only checks, you must install them yourself!  Development machines must be connected to the internet at least when you want to update. After entering this information select the 'Available Plugins' tab. You will see the available plugins, you want all the FRC ones. Then click 'Install'. You will need to accept the license agreement, ignore the fact they aren't signed, and then restart the IDE.

Helpful Hint: if you deselect everything but FRC it will show only those plugins and you don't have to scroll looking for them. Then go to Tools->Options and select the Miscellaneous category and FRC Options tab to enter your team number.

Helpful hint: note where the WPILibJ is stored, it is not with the rest of your source code.

1.4 Updates
So far new cRIO images and Driver Station SW have required updated plugins, but there have been plugin updates that don't need new images. I suggest that someone check daily. (last year there was a mandatory C++ update the week before our first regional and I was doing it at the last minute because I hadn't paid attention) To do this just check the 'Updates' tab periodically. You will also need to keep an eye on the FIRST and WPI websites, if they change the URL of the plugins you will need to change it in settings, the IDE won't know about it. So far changes have only been replacements, not additions to the current plugins.

2 Project Creation and Download
2.1 Creation from a Sample
After installing the plugins there will be several sample projects available. Select File->New Project and you will see several folders. The Robot projects are under FRC Java, and there are additional samples under Samples/FRC Java, notably the vision code sample. We are going to derive a project from the SimpleRobotTemplate project.

Click next and name your project and first class. Helpful hint: note the directories where things are being stored to make it easy to find files to e-mail, backup, etc..

Open the project source tree in the project pane and double click on the .java file to open it in the editing pane.

2.2 Editing
The editor options, under Tools->Options, are many. Some very helpful, some a bit annoying, but most people will disagree which is which. In general it has syntax highlighting, autocompletion, the ability to jump to problems, and generally good suggestions when you run into trouble. I did run into one serious problem with copying over large blocks of C code. If the IDE freezes you need to open a file browser and copy your source files elsewhere before killing it. It did zero out a file on me in the aforementioned situation.

2.3 Adding Classes
In Java classes (except internal classes within other classes) get their own files, so adding a class is done through the project pane. Right click on the project and select New->Java class. Name your class, and you will probably want it to be part of the same package.

In working with other developers I found it easiest to create empty classes and copy their files into my workspace.

2.4 Downloading to the cRIO
If you are connected to the robot you need only 'Run' or 'Debug' to transfer the code. What you download will start next power cycle. Many teams using wireless reported a variety of problems. We always used a wired connection and had no serious issues.

2.5 Looking at the WPILibJ
The WPILibJ source is very useful when trying to figure out just what was intended in particular classes. Be VERY careful if you modify anything and always make backups. Also, note any changes that you really like, they will disappear after updates, and if the bug is still open you will need to recreate your fix. To get to the library go to File->Open Project

You can then browse the source code for any class of interest. No matter how good the documentation there is no substitute for seeing the source code when questions or problems arise.

2.5.1 Generating Javadocs
Even if you have no intention of ever touching the library code the Javadocs are an invaluable resource. You can generate up-to-date documentation after each update by right clicking on the project and selecting 'Generate Javadoc'. It creates a searchable html reference that is convenient beyond words. Make a bookmark to the page,` you will go back often.

2.5.2 Changing Code
In the course of testing there were two items I felt should be different in the WPI library that have not been addressed as of the 11/8/09 update:

 

The Timer class has a microsecond and millisecond method, but only the microsecond is public. The DriverStation class has a getStickAxis method that returns 127/128 instead of 1.0 at the positive extreme.

Neither is earth-shaking, but both are easily changed and so I did. Only to find that you cannot then recompile the WPILibJ completely. The changed files recompile fine but the same half dozen other classes consistently fail a manual recompile. Fortunately the NetBeans IDE tries to compile all projects at start up and that compile always succeeds. This was supposed to be fixed but is still broken. So don't panic if suddenly don't compile after trying a manual recompile of the library.

3 Porting from C/C++
First off, don't be nervous, there is nothing that Java does that you couldn't code in C. If you create a structure that contains function pointers to the functions that are used to manipulate the structure members, and are rigorous about using only those, you have 90% of what Java tries to do for you. Java gives you 'free' what good programmers usually do for themselves anyway, careful range checking, consistent access methods to data, safe use of pointers and memory.

3.1 cRIO Image
You will not be able to use Java on your until FIRST makes the official cRIO image and loader available. One it is available, if you find you need to go back to last year's code you need to go back into the LabView 8.5 folders to find the original image and loader. If you have a critical need for a working robot you probably want to make sure you have a copy of the images, loader, and source code from last year archived.

To revert to the old image and code, go to the old LabView tool in:
\Program Files\National Instruments\LabView 8.5\project\CRIO Tool

run it, it should look like this:

Note there is no Java entry, so you know you are in the right place. Now download the LabView or C++ image as appropriate. Full instructions are in last year's documents, Control System section 5.1. Open last year's LabView or WindRiver project and download it as appropriate.

3.2 Naming Conventions
Java uses uppercase initial characters for class names and lower case for methods. This is slightly annoying in that almost every C++ function is available as a Java method, and differs by a single character in the name.

3.3 Replacing #define
Java doesn't use preprocessor statements like #define, but that is easily worked around. Within a class you can use a 'final' variable, e.g.:
public static final int BALL_FIRE_STICK = 1;

This isn't as efficient as preprocessor substitution, but works the same from a coding standpoint: it can be changed in one spot, it can't be changed at runtime, and it replaces a number with meaningful text. The problem is that it is only valid within the class where it is defined or derived classes. In the case of slots and channels it would be nice to have a single set of definitions across classes.

3.3.1 Your Own
Our solution to a consistent set of defines for things we want to be 'globally' consistent was to create an interface and have all of our classes implement it. See section 3.4.3 for an example.

3.3.2 WPILibJ's
The WPILibJ uses constants in many areas for instance:

This can be aliased as
public static final Relay.Direction R_BOTH = Relay.Direction.kBoth;

and used thus

I am not sure this is actually an advantage, as it hides the real type and its origin, but it is an option that reduces typing and adds to readability.

3.4 Uses of Java's Interface Type
3.4.1 WPILibJ Interfaces
WPILibJ interfaces can be identified in the javadocs listing, they are italicized. The interfaces most likely to be of interest to teams are PIDOutput/Source and SpeedController. CounterBase
Implemented by Counter, Encoder, and Geartooth. All common sensors to use this are implemented, but teams may find it useful if they use a custom sensor to count things like the number of balls picked up. DMAChannelDescriptors
Used by many lower level functions, it is unlikely that teams will need to implement this interface, it is included for the sake of completeness. ExpectedFPGASignature
Used by many lower level functions, it is unlikely that teams will need to implement this interface. It might possibly come in handy for teams with multiple cRIOs of different vintages that desire a single code base for all of them. It is included for the sake of completeness. NiRioConstants
Used by many lower level functions, it is unlikely that most teams will need to implement this interface, but it may be useful in debugging system level problems. It is mostly included for the sake of completeness. PIDOutput
Implemented by the Victor and Jaguar classes currently. This will be useful in PID programming. PIDSource
Implemented by the Accelerometer, AnalogChannel, Gyro, and Ultrasonic classes currently. This will be useful in PID programming. SortedVectorComparator
Implemented by SortedVector. A useful utility class and interface for sorting arrays of objects. SpeedController
This is actually a sub interface of PIDOutput. It is implemented by the Jaguar and Victor classes. Right now the Victors and Jaguars are identical, but that is almost certainly going to change; the Jaguars have many more capabilities. See the Runtime Binding section for an example of how this could come in handy.

3.4.2 For Runtime Binding
It is often necessary to change or adapt to some situation without re-downloading code to the robot. For instance, during beta testing we were also testing the new Black Jaguars. We were nervous, having blown a regular Jaguar up last year, so we wanted to be able to switch from Jaguar to Victor by flipping setting a rotary switch. In C/C++ you would typically use void pointers and cast them as necessary, e.g.:
void *Controller1 = NULL; Victor VictorController; Jaguar JagController; ... if (switch1 == VICTOR_PRESENT) Controller1 = &VictorController; else Controller1 = &JaguarController;

In Java you can do this:
//assign actual controllers to interface objects if (red_blueSW.getVoltage() > 2.5){ //autonomous 3-5 for Victors leftWheel = new Victor(1); rightWheel = new Victor(3); } else { //autonomous 0-2 for Jaguars leftWheel = new Jaguar(1); rightWheel = new Jaguar(3); }

Now there are some limitations, in the SpeedController interface currently only get() and set() methods are supported. But it does allow you to assign specific types late and pass them from class to class.

3.4.3 For Readability
Implementing an interface means you don't need to qualify the methods and variables, which can improve readability (possibly at the expense of clarity). For example we created a RobotConstants interface and implemented all of our classes with it, so code can look like this:
/** * * @author emily osmond */ public interface RobotConstants { ... public static final int DSC_LEFT_SLOT = 4; public static final int DSC_RIGHT_SLOT = 6; public public public public static static static static final final final final int int int int BALL_PICKUP_CHANNEL = 1; BOTTOM_SHOOTER_CHANNEL = 3; BALL_ELEVATOR_CHANNEL = 6; TOP_SHOOTER_CHANNEL = 5;

public static final int BALL_PICKUP_MOTOR = 1; public static final int BOTTOM_SHOOTER_MOTOR = 2; ... } /** * * @author gerard osmond */ public class BallHandler implements RobotConstants { ... private void initBallMechanism() { ballPickup = new Relay(DSC_LEFT_SLOT, BALL_PICKUP_CHANNEL); bottomShooter = new Relay(DSC_LEFT_SLOT, BOTTOM_SHOOTER_CHANNEL); ballElevator = new Victor(DSC_LEFT_SLOT, BALL_ELEVATOR_CHANNEL); topShooter = new Victor(DSC_LEFT_SLOT, TOP_SHOOTER_CHANNEL); ballPickup.setDirection(Relay.Direction.kBoth); bottomShooter.setDirection(Relay.Direction.kBoth); } ... }

rather than this:
private void initBallMechanism() { ballPickup = new Relay(RobotConstants.DSC_LEFT_SLOT, RobotConstants.BALL_PICKUP_CHANNEL); bottomShooter = new Relay(RobotConstants.DSC_LEFT_SLOT, RobotConstants.BOTTOM_SHOOTER_CHANNEL); ballElevator = new Victor(RobotConstants.DSC_LEFT_SLOT, RobotConstants.BALL_ELEVATOR_CHANNEL); topShooter = new Victor(RobotConstants.DSC_LEFT_SLOT, RobotConstants.TOP_SHOOTER_CHANNEL); ballPickup.setDirection(Relay.Direction.kBoth); bottomShooter.setDirection(Relay.Direction.kBoth); }

or, worse, this:
private void initBallMechanism() { ballPickup = new Relay(4, 1); bottomShooter = new Relay(4, 3); ballElevator = new Victor(4, 6); topShooter = new Victor(4, 5); ballPickup.setDirection(Relay.Direction.kBoth); bottomShooter.setDirection(Relay.Direction.kBoth); }

A small but convenient difference.

3.5 Creating Classes
Using Java's classes and interfaces can greatly smooth development. Because classes in Java are really independent compared to C++ (each class must be defined in a separate file, for instance) splitting development duties can be done easily and naturally.

3.5.1 Constructors
Constructors create new instances of objects, Java provides a default constructor that simply 'zeros' everything, that is sufficient for simple classes (e.g a class that just replaces a C/C++ structure). Often it is useful to create several constructors, for instance the standard constructors for cRIO channels that can use a slot argument when you have multiple modules of the same type or omit it when there is only one. For instance in our BallHandler class:

public BallHandler(){ ds = DriverStation.getInstance(); js = new Joystick(BALL_FIRE_STICK); initBallMechanism(); } public BallHandler(Joystick joystick) { ds = DriverStation.getInstance(); js = joystick; initBallMechanism(); } public BallHandler(DriverStation driverStation) { ds = driverStation; js = new Joystick(BALL_FIRE_STICK); initBallMechanism(); } public BallHandler(DriverStation driverStation, Joystick joystick) { ds = driverStation; js = joystick; initBallMechanism(); }

These multiple ways of instantiating object from the class allow great flexibility to use the methods and variables of the class in many different contexts. At the opposite end of things you may want to force only one instance of a class to ever be created, and everyone to access the same one. The WPI classes that have a getInstance() method use this approach. We don't do this but making your constructor private and calling it only once from the getInstance method can accomplish this:
public class MySingletonClass{ private static MySingletonClass theOnlyInstance = null; private MySingletonClass { //stuff everyone should refer to the same copy of //this can be used to provide the equivalent //of static variables across classes } public static MySingletonClass getInstance { if (theOnlyInstance == null) theOnlyInstance = new MySingletonClass; return theOnlyInstance; } }

When an object of MySingletonClass is needed it is simply assigned with getInstance rather than 'new'.

3.6 Try and Catch
Early in the robot construction cycle there may be things that don't work or aren't installed. Or there may be features of it, the Java VM, or underlying OS that don't always work, either from bugs or resource limitations. In cases where something fails often enough to be a concern you can use the try-catch pair of Java commands. For 1279 the cRIO and camera aren't always in the same place. If you try to do a getInstance() on your camera when it is not attached there is along time-out and then a cascade of errors. We have to live with the timeout, but there is an easy way to work without having to download different code to ignore the camera. In the constructor :
try { ac = AxisCamera.getInstance(); } catch(NIVisionException e) { ac = null; System.out.println("Camera not found! e=" + e);

} if (ac == null ) cameraPresent = true; else cameraPresent = false;

then in methods that depend on the camera
public Targeted findTarget(double volts){ if (!cameraPresent) return null;

4 Debugging Techniques
Under Java you can use 'Run' to download for normal purposes and you will be able to see the printlns you have put in the code in the output window. Or if not connected to NetBeans in the console. In order to connect the debugger you must choose debug, which downloads an image with hooks for the debugger.

4.1 println
The Java standard System.out.println() method is used almost exactly as you would use printf (except for the nice, if obtuse, format specifiers). There are a few downsides, the most important is that it is expensive. Write a 1000x loop that prints the time every loop. Then write one that prints the time before and after rather than during. You will not want leave any printlns active in your final code. Also there were problems seeing the printlns in the NetBeans output pane during early construction of the SimpleRobot derived class. I was measuring about a 1.5 second delay before output was redirected from the console to the TCP/IP port.

4.2 stdout stderr to files
File I/O is allegedly working right now, but I have not had a chance to check it. The created files would be ftp'ed back to your PC after a run for examination. Be careful if you use file logging to check and clean up your files. You don't want to fill up the filesystem at an inopportune moment.

4.3 Setting Breakpoints 4.4 Connecting the Debugger
Interactive debugging is very nice under NetBeans, the remote target can have conditional and nonconditional breakpoints, you can watch variables, step through and over method calls. In short, everything that you would expect from a host platform debugger you can do on the embedded target.     Make sure your project is the Main Project, or set it by right clicking on the project name. Set at least one break point (that will definitely trigger if conditional) Right click the project and select Debug. It will take about a minute for the debug image to fully load. When you see "Waiting for Connection from Debugger..." select Attach Debugger from the menu or toolbar.

Once connected you will see new icons on the toolbar to the right of the debug icon. Hovering the mouse will show what each does.

4.5 Watching a variable
When the debugger is attached you will see Variables and Breakpoints tabs have been added to the output pane. The bottom icon in the left hand column allows you to add watch expressions. These can be single variables or combinations or several. The value only updates in the display when a breakpoint is hit, but it is monitored constantly.

5 Pitfalls
5.1 Improvements
Read through as much of the docs and example code as possible and note things that are convenient and potentially useful. While porting I spent an hour writing code to do my own maintenance and sorting of 'hit lists' of ParticleAnalysisReports. I then happened across the getOrderedParticleAnalysisReports() function and realized they had improved much of the image handling code. Quite a bit of fiddling was replaced with essentially two lines of code. The Java image processing and camera functions seem better than last years C++ (I don't know if parallel improvements were made there as well). There are certain issues however. We initialize the Axis camera in one of our class constructors and if the camera is not connected the time out is quite long. Some teams reported this as a crash, but we found that if you wait long enough, and don't try to use the camera object later, that the rest of the code ran fine after timing out.

5.2 Timing and Overhead
We ran a number of timing tests and found a wider than expected (wider than last year's C++) variation in timing for our main teleoperated loop. The loops take longer, seem to vary more, and are I/O sensitive. That said, the actual performance of the robot in competition did not seem to suffer. Last year's robot was able to do all our main loop processing in less than 20ms with image processing rates of 25FPS. That would mean an image was processed every other loop. The Java code was modified to a 30ms main loop. At that rate is only broke real-time about once every two or three seconds.

I strongly recommend profiling the timing characteristics of your system if you have any integrations or measurements that might be sensitive to variations.

5.3 Using free()
Certain lower level functionality, including a lot of the image processing functions are handled outside the JVM in C. As a result the normal garbage collection process doesn't realize memory has been allocated and won't cause it to be automatically freed. An explicit call to free() on the object will result in the appropriate cleanup taking place. You should carefully check the documentation when using methods that return objects, and see if a free is necessary. When programming our image processing we ran out of memory in about 90 seconds. Here is the code, with the added free()s everything can run forever.
ColorImage cameraImage; if (ac.freshImage()) cameraImage = ac.getImage(); else return false; BinaryImage imageMask = null; imageMask = cameraImage.thresholdHSL(td.hue.minValue, td.hue.maxValue, td.saturation.minValue, td.saturation.maxValue, td.luminance.minValue, td.luminance.maxValue); if (cameraImage == null) return false; else; /* get largest particles that meet criteria */ /* GetLargestParticles fills out only the indices in the hitReport */ = imageMask.getOrderedParticleAnalysisReports(numberHitsRequested); if (imageMask == null) return false; else;

6 Q&A 7 Reference Material
Keep an eye on the various forums for comments and code by the various teams, some are doing very systematic examination of the environment, libraries, and JVM. We at 1279 are certainly indebted to all those whose comments and code helped us along the way.

7.1 Contact Info
Our Beta Testing Team was: Emily Osmond - mentor/parent Gerard Osmond - mentor/parent Jim O'Malley - mentor/parent Brian Osmond - student John Osmond - student Stephen Simon - student Peter Stadmueller - student With the gracious assistance of the rest of team 1279's mentors, parents, and students, our General Manager teacher Marika Foreman, and the administration and staff of Immaculata. Visit us at

You can contact us with programming questions at jamesomalley (-at-)

Shared By:
Jun Wang Jun Wang Dr
About Some of Those documents come from internet for research purpose,if you have the copyrights of one of them,tell me by mail you!