wiki:ControlSystems/SoftwareTeam/Training/GettingStarted/IntroRobotJava

Version 1 (modified by David Albert, 6 years ago) (diff)

--

Java for FRC Robotics

Writing Java programs to control a robot is similar to the Java programming you've already learned; there are three key differences:

  1. The program you write must be transferred to the robot's computer (the roboRIO) where it will run
  2. FIRST and WPI provide a framework that your robot program must run within; the framework manages many aspects of the robot for you.
  3. WPI also provides a rich library of pre-written classes called WPIlib that makes robot programming faster and easier.

We write robot software in VSCode just as we did for Java, but we'll make use of the WPILib extensions to create, build, and run our robot programs. The WPILib extension is available via the W icon in the toolbar. Click on the icon and then:

  • Select Create a new project
  • Select Project Type->Template->java->Iterative Robot
  • Select a New Project Folder and select (or create and then select) Documents\Robot Projects
  • Enter project name: Xbox1
  • Enter team number: 2537
  • Press Generate Project
  • At the dialog select Yes (Current WIndow)

The WPILib extension then creates a new Robot project for you. The project contains many files and they're listed and organized in the left tree. The file we're intersted in is src->main->java->Robot.java open that file by double-clicking on it.

The Robot.java class that was created for you contains the minimal set of functions required for a robot program operating in the WPIlib framework. The functions include:

  • robotInit() - called once when the robot starts
  • robotPeriodic() - called periodically (e.g. every 20ms)
  • autonomousInit() called one when the robot first enters autonomous mode
  • autonomousPeriodic() - called periodically (e.g. every 20ms) while the robot is in autonomous mode
  • teleopPeriodic() - called periodically while robot is in teleoperated mode
  • testPeriodic() - called periodically while robot is in test mode

You will put your setup code in the Init() functions and the code that should run repeatedly in the Periodic() functions.

Modify the newly created program as follows:

  • Add import edu.wpi.first.wpilibj.XboxController; to the imports
  • In the Class definition where variables are defined, add private XboxController xbox;
  • In the function robotInit() add: xbox = new XboxController(0);
  • In the function robotPeriodic() addd: SmartDashboard.putNumber("Left Joystick X", xbox.getX());

Use the WPILib icon to build your new program: W->Build Robot Code

Start with an example

The best way to learn about robot programming a robot is to start with a simple example program, run it, study what it does, and incrementally expand its functionality. The WPILib software you installed includes example programs that you can compile and run on a RoboRIO. Review how to use VSCode and then try creating a new robot project.

  • WPILib provides 3 frameworks for building robot programs. Build your first program using the TimedRobot (previously had been IterativeRobot) framework as described here.
  • Connect your laptop to the RoboRIO USB port
  • Connect your joystick or xbox controller to another USB port on your laptop
  • Launch the NI Driver Station Software. For details see here
  • Confirm that the software detects your joystick/controller and responds to button presses and stick movement
  • Use Microsoft Internet Explorer (not Chrome or Firefox) to connect to the RoboRIO's web interface (usually at http://172.22.11.2) and confirm that you have connectivity with the RobORIO
  • Create a test project and follow these instructions to build, load, and run it on your RoboRIO/Robot

Congratulations, you've just built and run your first robot program.

  • Create another WPILib project based on the TimedRobot framework
    • Study an example program. This is a simple program for one of our test robots: Peanut 2.
      • 2-wheel-drive (2WD) robot with two CIM motors driving plaction wheels
      • Motors are controlled by Talon SRX smart motor controllers; these are networked to the roboRIO (robot control computer) using CAN bus and are at addresses 3 (left motor) and 4 (right motor)
      • An ultrasonic sensor for forward collision avoidance connected to roboRIO digital I/O pins (DIO) 0 and 1
      • A USB camera so you can drive even when you can't see the robot
      • The driver controls the robot using the two analog sticks on an X-box game controller
    • Copy the program below over the default Robot.java created by the framework
    • Use the WPILib->Manage Vendor Libraries->Install New Libraries Offline->select the CTRE Framework
      package frc.robot;
      
      // Import the classes of objects you will use
      import edu.wpi.first.wpilibj.TimedRobot;
      import edu.wpi.first.wpilibj.XboxController;
      import edu.wpi.first.wpilibj.GenericHID.Hand;
      import edu.wpi.first.wpilibj.Timer;
      import edu.wpi.first.wpilibj.drive.DifferentialDrive;
      import com.ctre.phoenix.motorcontrol.can.*;
      import edu.wpi.first.wpilibj.Ultrasonic;
      import edu.wpi.first.wpilibj.CameraServer;
      
      import edu.wpi.first.wpilibj.livewindow.LiveWindow;
      
      import edu.wpi.first.wpilibj.smartdashboard.SendableChooser;
      import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard;
      
      /**
       * The VM is configured to automatically run this class, and to call the
       * functions corresponding to each mode, as described in the TimedRobot
       * documentation. If you change the name of this class or the package after
       * creating this project, you must also update the build.gradle file in the
       * project.
       */
      public class Robot extends TimedRobot {
        // Create instances of each object
        private static final String kDefaultAuto = "Default";
        private static final String kCustomAuto = "My Auto";
        private String m_autoSelected;
        private final SendableChooser<String> m_chooser = new SendableChooser<>();
        private XboxController xbox;
        private Timer timer;
        private WPI_TalonSRX m_rearLeft;
        private WPI_TalonSRX m_rearRight;
        private DifferentialDrive m_drive;
        private boolean    f_safetyStop;
        private Ultrasonic f_ultrasonic;
      
        /**
         * This function is run when the robot is first started up and should be
         * used for any initialization code.
         */
        @Override
        public void robotInit() {
          // initialize the objects and connect them to their underlying hardware
          m_chooser.addDefault("Default Auto", kDefaultAuto);
          m_chooser.addObject("My Auto", kCustomAuto);
          SmartDashboard.putData("Auto choices", m_chooser);
          xbox = new XboxController(0);
          timer = new Timer();
          m_rearLeft = new WPI_TalonSRX(4);
          m_rearRight = new WPI_TalonSRX(3);
          m_drive = new DifferentialDrive(m_rearLeft, m_rearRight);
          f_ultrasonic = new Ultrasonic(1,0); // ping, echo
          f_ultrasonic.setAutomaticMode(true);
          f_ultrasonic.setEnabled(true);
          CameraServer.getInstance().startAutomaticCapture();
      }
      
        /**
         * This function is called every robot packet, no matter the mode. Use
         * this for items like diagnostics that you want ran during disabled,
         * autonomous, teleoperated and test.
         *
         * <p>This runs after the mode specific periodic functions, but before
         * LiveWindow and SmartDashboard integrated updating.
         */
        @Override
        public void robotPeriodic() {
        }
      
        /**
         * This autonomous (along with the chooser code above) shows how to select
         * between different autonomous modes using the dashboard. The sendable
         * chooser code works with the Java SmartDashboard. If you prefer the
         * LabVIEW Dashboard, remove all of the chooser code and uncomment the
         * getString line to get the auto name from the text box below the Gyro
         *
         * <p>You can add additional auto modes by adding additional comparisons to
         * the switch structure below with additional strings. If using the
         * SendableChooser make sure to add them to the chooser code above as well.
         */
        @Override
        public void autonomousInit() {
          m_autoSelected = m_chooser.getSelected();
          // autoSelected = SmartDashboard.getString("Auto Selector",
          // defaultAuto);
          System.out.println("Auto selected: " + m_autoSelected);
          timer.reset();
          timer.start();
        }
      
        /*public void teleopInit() {
      
        }*/
      
        /**
         * This function is called periodically during autonomous.
         */
        @Override
        public void autonomousPeriodic() {
          if (timer.get() < 2.0) {
            m_drive.curvatureDrive(0.1, 0.0, false);
          }
          else
          {
            m_drive.curvatureDrive(0.0, 0.0,false);
          }
          switch (m_autoSelected) {
            case kCustomAuto:
              // Put custom auto code here
              break;
            case kDefaultAuto:
            default:
              // Put default auto code here
              break;
          }
        }
      
        /**
         * This function is called periodically during operator control.
         */
        @Override
        public void teleopPeriodic() {
      
          // Use front-mounted ultrasonic sensor to stop robot
          // if it gets too close to an obstacle
          double f_range = f_ultrasonic.getRangeInches();
          if (f_ultrasonic.isRangeValid()) {
             if ((f_range < 15.0) && !f_safetyStop) {
                System.out.println("Safety stopped due to front obstacle");
                f_safetyStop = true;
             } else if (f_range >= 15.0 && f_safetyStop) {
                System.out.println("Resuming...");
                f_safetyStop = false;
             }
          }
      
          // Use controller joysticks to set drive speed, but
          // safety stop if too close to an obstacle
          double leftSpeed  = -0.5*xbox.getY(Hand.kLeft);
          double rightSpeed = -0.5*xbox.getY(Hand.kRight);
          // If there's an obstacle in front of us, don't
          // allow any more forward motion
          if (f_safetyStop && 
              (leftSpeed > 0.0) && (rightSpeed > 0.0)) {
             m_drive.stopMotor();
          } else {
            // otherwise, set motors according to joysticks
             m_drive.tankDrive(leftSpeed, rightSpeed);
          }
          Timer.delay(0.01);
        }
      
        /**
         * This function is called periodically during test mode.
         */
        @Override
        public void testPeriodic() {
          // LiveWindow.run();
        }
      }
      
      
  • Sample code for Hazelnut (peanut robot) is here
  • A sample program to use ultrasonic sensors is here
  • A sample program to use xbox controllers is here
  • You can learn more about FRC robot programming here
  • You can learn more about game controllers here
  • Note: you can also program and operate a peanut robot wirelessly:
    • Find the Peanut's WiFi access point and connect to it; the default password is "password"
    • From within VSCode, choose WPILib->Deploy Robot Code
    • Launch the Driver Station
    • Enable and then start driving!
  • Note: the sample program assumes two !TalonSRX motor controllers at IDs 3 and 4. You can set them using the CTRE Phoneix Tuner
  • Note: the !RoboRIO web web interface is available via browser at 10.25.37.2

Attachments (2)

Download all attachments as: .zip