Skip to content

Robot Develeopment with FlashFRC

Tom Tzook edited this page Apr 27, 2022 · 7 revisions

Robot Control

Before starting with our robot software, we need to learn how our robot software is going to be managed and controlled. That is because planning and writing a robot software works a lot differently than applications for personal computers.

Robot Main Class

A robot software contains a primary class, which serves as the base for the code and is responsible for integrating all the robot code into a single manageable place. The class will contain the objects which control our electronics, or perform algorithms and methods which use those objects.

Robot Systems

A robot is usually divided into systems, each responsible for performing different actions, and together they perform tasks. A system can be the robot's drive train, which includes the motors which move the robot. Another example can be an arm which is controlled by one or more actuators. All in all, a system is can be whatever we decide, as long as it makes sense.

Because our robot is divided into systems, we would usually divide the software similarly. Although not a must, we recommend making each robot system a different class. Those classes will have properties which will include objects and variables for controlling the system, and methods which will allow us to control the system from our main robot class. Once ready, we would create one object for each system in our main class and control those systems from there.

Read further here.

Electronics

Controlling a robot is basically controlling electronic devices on the robot which are connected to the robot computer. Those devices include actuators like motors or servos, as well as sensors like gyroscopes and ultrasonics.

To interact with those device our software needs to able to read and write into IO ports on the robot computer. This is possible thanks to WPILib which provides IO ability for roboRIO.

Operation Modes

FRC robots work in certain modes during the competition. This is reflected in the code, allowing programming to depend on the specific mode used.

There are several modes of operation:

  • disabled: a safety mode in which the robot is meant to do nothing. Operation of electronics is automatically disabled.
  • operator control (or teleop): for when the robot is meant to be directly controlled by a human operator using controllers (joysticks).
  • autonomous: for when the robot is meant to operate independently without human operators. In here, programmers have to designate an algorithm which operates without human intervention (based entirely on sensors).
  • test: this mode doesn't have any specific usage other then testing robot operations outside of competition. Especially useful when wanting to avoid touching other modes to test parts of the code.

Robot Control Loop

Unlike desktop programs or applications, robot software is built iteratively, meaning that our robot is managed by a loop. FlashLib provides robots with a loop which runs while the robot is operational, and from this loop user code is called. The loop takes care of different operation modes and allows our robot to operate without a stop.

Driver Station

The FRC DriverStation is a desktop program capable of communicating with the robot to control its operations. It is capable of controlling the operation modes of the robot and providing some feedback.

Getting Started

Before starting to write any code we must first prepare a project. WPILib uses gradle as it's preferred build system and has most of the things required already prepared for use. But we still have to create the project and configure it correctly. Instead of doing so manually, we will be using a pre-made template, which may be acquired here. Simply download it and open it in your preferred IDE.

The template is filled with quite a few files. But for now we only care about Robot.java (located under src/main/java/frc.team3388.robot).

package frc.team3388.robot;

import com.flash3388.flashlib.frc.robot.FrcRobotControl;
import com.flash3388.flashlib.frc.robot.base.iterative.IterativeFrcRobot;
import com.flash3388.flashlib.robot.base.DelegatingRobotControl;

public class Robot extends DelegatingRobotControl implements IterativeFrcRobot {

    public Robot(FrcRobotControl robotControl) {
        super(robotControl);
    }

    @Override
    public void disabledInit() {

    }

    @Override
    public void disabledPeriodic() {

    }

    @Override
    public void teleopInit() {

    }

    @Override
    public void teleopPeriodic() {

    }

    @Override
    public void autonomousInit() {

    }

    @Override
    public void autonomousPeriodic() {

    }

    @Override
    public void testInit() {

    }

    @Override
    public void testPeriodic() {

    }

    @Override
    public void robotPeriodic() {

    }

    @Override
    public void robotStop() {

    }
}

Implementing Methods in Robot

There are quite a few methods to implement in the Robot class, each with a different purpose.

The constructor public Robot(FrcRobotControl robotControl) is called on robot startup and is meant to be used to initialize the different parts of the robot. Things like electronics and such.

public void robotPeriodic() is called every ~20ms while the robot is operational. Can be used to monitor and update things periodically.

Operation Modes

Each operation mode, as provided by the Driver Station has several related methods:

  • init (e.g. disabledInit): called once when entering this mode to perform initialization logic related to this mode.
  • periodic (e.g. disabledPeriodic): called every ~20ms to perform periodic logic in the mode. Basically acting like a loop and can contain the main logic of the mode.
  • exit (optional) (e.g. disabledExit): called once when exiting this mode and switching to another mode.

We can view the execution of code in a specific mode as following this pseudo-code:

init()
while inMode()
    periodic()
    doInternalStuff() // for 20ms or so
exit()

Accessing Robot Resources

There are several resources provided for our usage in controlling the robot. These are exported via the RobotControl interface and accessible directly in the robot class (or globally with RunningRobot.getControl()).

Some notable ones among them are:

  • HidInterface: provides access to Human Interface Devices (joysticks, gamepads) which are connected to the Driver Station.
  • Logger: for logging information either to a file or directly to the Driver Station.
  • Clock: provides current timestamp according to the on-board FPGA clock.
  • Scheduler: responsible for scheduling operation of Actions (we'll talk about those later).

Building and Deploying

The robot project is based on the gradle build system, with configurations to properly build the code and how to deploy it. To work with gradle we need to open a command-line in the directory of the project. Some IDEs may have a built-in one.

To build, run the command:

gradlew build

When building, some dependencies may be needed and will be automatically downloaded. This will require to be connected to the internet, or it will fail. The downloads are cached and will only be needed once-in-a-while.

Once the code is built, connect the computer to the robot (either via cable or wifi) and run:

gradlew deploy

The code should now start running on the robot. Note that the code will be saved on the robot even after a restart, so no need to upload it each time, only after modifying it.

Example

Let's write a simple robot code that writes to the log when starting and when entering a mode. Download and open the template (as mentioned previously) and open the Robot.java file.

We'll simple add some uses of the robot logger.

package frc.team3388.robot;

import com.flash3388.flashlib.frc.robot.FrcRobotControl;
import com.flash3388.flashlib.frc.robot.base.iterative.IterativeFrcRobot;
import com.flash3388.flashlib.robot.base.DelegatingRobotControl;

public class Robot extends DelegatingRobotControl implements IterativeFrcRobot {

    public Robot(FrcRobotControl robotControl) {
        super(robotControl);

        getLogger().info("Hello World");
    }

    @Override
    public void disabledInit() {
        getLogger().info("Hello Disabled");
    }

    @Override
    public void disabledPeriodic() {

    }

    @Override
    public void teleopInit() {
        getLogger().info("Hello Teleop");
    }

    @Override
    public void teleopPeriodic() {

    }

    @Override
    public void autonomousInit() {
        getLogger().info("Hello Autonomous");
    }

    @Override
    public void autonomousPeriodic() {

    }

    @Override
    public void testInit() {
        getLogger().info("Hello Test");
    }

    @Override
    public void testPeriodic() {

    }

    @Override
    public void robotPeriodic() {

    }

    @Override
    public void robotStop() {

    }
}

You can now build and upload this to your robot. Open Driver Station and watch the log console. Now play with the modes (switching between them) and see the prints from the log.