Lesson: Sample Robot in more Detail

Explore the Sample Robot source code in more detail.

Understand in more detail how the Sample Robot project works and how you can expand it to do more.


Lets examine the Sample Robot project in more detail.

Looking at Robot.java the first thing we see is the package created for us by the WPILib plugin based on our team number.

Next we see some reference variables defined. These are for a RobotDrive object and a Joystick object. These objects are part of the WPILib API. The RobotDrive object gives you many ways to control the motors in a robot drive system.  The Joystick object gives you access to the inputs (deflection and buttons) available from a joystick.

Next we see the Robot class constructor. Here we initialize the myRobot and stick variables to instances of their classes and specify the port numbers these devices are attached to. In the case of the myRobot instance, the motors are assumed to be plugged into the RoboRio PWM ports 0 and 1. For the stick instance, it is assumed to be plugged into a driver station USB port and mapped to port 0 in the driver station app. This initialization could be performed in the robotInit() method and that is probably the best place as there are minor differences between the constructor and the robotInit() method.

After the constructor is completed, the robotInit() method will be called. In our example we have nothing to initialize in that method so nothing happens.

After the robotInit() method completes, the disabled() method is called as the robot is considered to be in the disabled state right after your code is loaded. disabled() is also called when either autonomous or operatorControl periods end. Here you would have code to make sure your robot is in the correct state and prepare for transition to the next mode.

The autonomous() method is called when the autonomous period is started. In our example we do a simple drive forward by using a method of the myRobot object (myRobot.drive) to set motor power (this particular method sets both motors) to 50% with no turn angle. This will cause the motors to turn on. We then wait for 2 seconds and then call the same myRobot.drive method to turn the motors off. We then exit the method and that is the end of our autonomous function. Note that the minus sign on the myRobot.drive power argument. Plus and minus indicates forward and backward. Forward and backward are relative to the robot, motor and gearing design of the robot and will need to be determined experimentally. The example assumes minus turns the motors so the robot moves in the forward direction. 

The operatorControl() method is called when the teleop period is started. In our example, we want to use the joystick to drive the robot in arcade (one joystick) style. We use the arcadeDrive() method of the myRobot instance of the RobotDrive class to do the driving. We pass the stick instance variable directly to the arcadeDrive() method and it will get the joystick deflection and set the motor speed and direction for us. We want to continue driving so we wait a short time before looping back and setting the motor power again. We want to keep doing this until the teleop period is over, so we condition the while loop by looking at two methods that are available to us from our parent SampleRobot object. The isEnabled() method returns true if the robot is enabled and we also check the isOperatorControl() method to make sure the period has not changed. Note that if our autonomous code might run to the full time of the autonomous period, we need to employ these same kind of checks (using isAutonoumous) to make sure our code stops when the period is over.

Further note that the wait function we use is Timer.delay(.020). Timer.delay is a special wait function that will stop our code but not interfere with motor control activities. We select 20 milliseconds because that is approximately how fast the joystick data updates are sent from the DS to the RoboRio.

The last thing we want to look at is Motor Safety. The RobotDrive class has a built-in feature that is intended to prevent runaway robots. This is called motor safety. A timer is automatically started on a RobotDrive object and if there is no input supplied to the RobotDrive instance in the time allowed, the motors associated with the RobotDrive object will be stopped. In our example we set the timeout to 100 milliseconds which should be good as we plan to update the motor power setting every 20 milliseconds. If our code crashed or looped and we failed to update the myRobot instance for 100ms then our motors would be stopped.

Note that in autonomous mode there is no joystick so once we set power in this example, there is no further motor input for our 2 seconds of run time. Obviously the motor safety feature would stop our robot, so we turn motor safety off for the autonomous period. But this does mean you have to be careful with your code as there is no runaway protection. When we go to the teleop period, we make sure that motor safety is turned back on. When I said no runaway protection, I meant automatic protection. The DS disable button will stop a runaway robot, so when testing your code you should always be ready to click the disable button if things go wrong.

Note that we use System.out.println to implement a simple execution trace. The println output goes to the RoboRio console. You can view this console output using one of the console viewers.

That completes our review of the Sample Project. Obviously a real robot would have more functionality and more physical hardware to control. We will look at more complex examples next.

Here is the top level of the Java specific on-line documentation. 

Here is the detailed documentation of the Robot API classes contained in the WPILib for you to use.

Additionally, the attached PDFs contain valuable documentation and examples even if they are a bit dated.

To really program the RoboRio control system, you will need to read and be familiar with the information in these resources.