2014 FRC Robot C++ and JAVA Two languages saying the same thing but differently!!!! Presented By: Frank Larkin Lansdale Catholic Robotics, Team 272 Philadelphia PA, Dec. 2014 Goals • Get a good understanding of what the new control system can and cannot do. • Get a good understanding of how to program in C++ and JAVA – Be able to create your own classes to allow multiple threads for development. • See different programming designs for the FRC robot. • Learn how to get autonomous working How will we do it? • Eat donut holes and then lunch! • Discuss C++ and JAVA – No rat holing on theory. – Exchange cards, get phone numbers and email • Review online resources – Forums, Wiki, bla bla • Review beta code to explore possibilities – Get many flavors of the same thing. – Touches many of the approaches available to you – See how other accomplished – Shamelessly steal their stuff. • Thought Games – I ask, you figure it out. Fun!!!! • Hands On – Play until it is time to leave. FRC Robot Hardware • Google:FRC robot control system picture • https://decibel.ni.com/content/d ocs/DOC-30419 • http://team358.org/files/progra mming/ControlSystem20152019/ C++ and JAVA • Both languages are similar… – Both are somewhat human readable. – Both follow a very similar syntax. – Both are object oriented • Both allow you to declare variables – Integer, long, short, float, double • All numbers that reserve different amounts of space. – Character, string • A way to store letters and words. Not really used too much in robots but we can. – Google: [language] operators • A million Internet sites discuss this topic. • Both are extensible and use something called a class – Bundle all of a things, things into a single thing. – A class’s “things” can be public or they can be private. If private you use public methods to set values to them or get values from them. – Classes can inherit other classes Programming Lexicon • Object – Objects are definitions of things you can use in programming you robot. All objects have state and behavior. They define behavior with the outside world through methods. • Class – A class is the blueprint from which individual objects are created. • Inheritance – Different kinds of objects often have a certain amount in common with each other. Object-oriented programming allows classes to inherit commonly used state and behavior from other classes. • Interface (Java only) (just another class in C++) – In its most common form, an interface is a group of related methods with empty bodies. • Variable – A way to associate some information with a name that we can use in our programs. Some variables are created as static and once created cannot be changed. • Package (Java only) (header file (.h) in C++) – A package is a namespace that organizes a set of related classes and interfaces. Conceptually you can think of packages as being similar to different folders on your computer. Class Inheritance • One class can “inherit” everything from another class • People are several inherited classes. • class mammal – Methods: GetAge(), SetAge(), GetHeartBeat(“bpm”) • class human extends mammal – Methods: GetName(), SetName() • class student extends human – Methods: SetGrade(), GetGrade() – Human.GetAge() still works. How Many Classes? • http://www.wbrobotics.com/jav adoc/index.html?edu/wpi/first/w pilibj/package-summary.html • http://wpilib.screenstepslive.co m/s/3120/m/7912 FRC Class Example Joystick Question?????? • What “things” would you expect from an object called a joystick? FRC Class Example Joystick • What “things” would you expect from an object called a joystick? – Buttons • Trigger • Top • Other user buttons – Various Axis controllers • X = side to side • Y = forward and back • Z = twist or variable level KISS • Class variables – Public – Everyone can get to them. – Private – You decide who gest to them using set and get. …a dazzling triumph for aerospace designer and maverick genius Burt Rutan. ... SpaceShipOne' s "pressuriza- tion" system is essentially a couple of corks. Motor Basics: Java Examples import edu.wpi.first.wpilibj.Jaguar; import edu.wpi.first.wpilibj.Victor; import edu.wpi.first.wpilibj.Relay; // creating a Jaguar reference Jaguar motor1 = new Jaguar(1); // default digital module, channel 1 // setting the desired speed (range of -1.0 to 1.0) motor1.set(0.5); // creating a Victor reference Victor motor2 = new Victor(2); // default digital module, channel 2 // setting the desired speed (range of -1.0 to 1.0) motor2.set(0.25); // creating a Relay reference // allowing forward direction only // default digital module, channel 1 Relay motor3 = new Relay(1, kForward);; // setting the motor to on and off motor3.set(kOn); motor3.set(kOff); Motor Basics: C++ Examples #include “WPILib.h”; #include <Jaguar.h>; #include <Victor.h>; #include <Relay.h>; // creating a Jaguar reference // default digital module, Jaguar *motor1 = new Jaguar(1); //channel 1 // setting the desired speed (range of -1.0 to 1.0) motor1->Set(0.5); // creating a Victor reference Victor *motor2 = new Victor(2); //channel 2 // setting the desired speed (range of -1.0 to 1.0) motor2->Set(0.25); // creating a Relay reference, // allowing forward direction only // default digital module Relay *motor3 = new Relay(1, Relay::kForward); // channel 1 // setting the motor to on and off motor3->Set(Relay::kOn); motor3->Set(Relay::kOff); Sensor Basics: Java Examples import edu.wpi.first.wpilibj.AnalogChannel; import edu.wpi.first.wpilibj.DigitalInput; // Create a reference to an analog sensor // default analog module, channel 1 AnalogChannel sensor1 = new AnalogChannel(1); // Get the average voltage from the analog sensor double voltage = sensor1.getAverageVoltage(); // Create a reference to a digital sensor // default digital module, channel 1 DigitalInput sensor2 = new DigitalInput(1); // Get the value from the sensor boolean value = sensor2.get(); Sensor Basics: C++ Examples #include <AnalogChannel.h> #include <DigitalInput.h> // Create variable pointers for sensors AnalogChannel *sensor1; DigitalInput *sensor2; // Initialize the analog sensor // default analog module, channel 1 sensor1 = new AnalogChannel(1); // Get the average voltage from the analog sensor float voltage = sensor1->GetAverageVoltage(); // Create a reference to a digital sensor // default digital module, channel 1 sensor2 = new DigitalInput(1); // Get the value from the sensor UINT32 value = sensor2->Get(); Differences between C++ and JAVA • Java – Import • Brings in external packages or classes to make it available to your code. • C++ – #include • Preprocessor directive that brings in external definitions to make them available to your code • Actual code is recompiled into libraries and linked in later – C++ Variables must be declared and then initialized (2 steps) – What is this ?? • -> C++ • Pointers vs Local Declarations – Pointers – References to things in memory • Possibly looks cleaner • How most examples are being done. – Declarations – The things in memory • No need for pointers but a little more complicated – Why do I care? • You will see code described both ways. Do not be afraid embrace them. • Declaration Section: class IterativeDemo : public IterativeRobot { // Declare variable for the robot drive system Servo *p_servo; } Note: * means this is a pointer! • Initialization Section: IterativeDemo(void) { printf("IterativeDemo Constructor Started\n"); p_servo = new Servo(5); } • Usage: p_servo->Set(.50); p_servo->Set(p_leftStick->GetZ()); Declared Example • Declaration Section: class IterativeDemo : public IterativeRobot { // Declare variable for the robot drive system Servo m_servo; Joystick m_leftStick; Joystick m_RightStick; Joystick m_OperatorStick; } • Initialization Section: IterativeDemo(void) : servo(5), leftStick(), rightStick(), operatorStick() { } • Usage: m_servo.Set( leftStick.GetZ() ); • How do I keep it all straight? – Liberal use of variable prefixes can help. • • • • • p_servo, p_leftJoystick; = pointers i_count = integer (not a pointer) ip_speed = integer pointer (may never see this). f_motorPower = floating point variable M_stuff = member variable (used in many beta examples) – This should scare you….. • p_servo.Set(5); Death By Pointer • Java uses pointers under the covers. http://javadude.com/articles/passbyvalue.htm Java makes sure you cannot hurt yourself. • What happens if you do it wrong? – – – – It will compile The Driver Station will show Ok It will not run. “Slow Blinking LED of Doom!” Death By Pointer • Startup of program on cRIO Exception current instruction address: 0x012eb5c8 Machine Status Register: 0x0000b032 Data Access Register: 0x537fb81b Condition Register: 0x20000048 Data storage interrupt Register: 0x40000000 Task: 0x1307e98 "FRCRobotTask" 0x1307e98 (FRCRobotTask): task 0x1307e98 has had a failure and has been stopped. 0x1307e98 (FRCRobotTask): fatal kernel task-level exception! Welcome to LabVIEW Real-Time 8.5.1 Indicator Mode changed... Slow Blink • Driver Station shows correctly • Do not panic over the slow blink of death! – May be a pointer issue. Do a code review looking for illegal use of pointers. p_servo.Set(0.0); // p_ indicates pointer!!! p_servo->Set(0.0); // correct Good Boot Up • Startup of program on cRIO Resync command from DS... Resync command from DS... Enabled! Booting watchdog! Indicator Mode changed... Steady On WPILib was compiled from SVN revision 1330:1345 Spawned FRCRobotTask (0x12f7b70) RobotIterativeBase Constructor Start RobotIterativeBase Constructor Finish IterativeDemo Constructor Started IterativeDemo Constructor Completed RobotIterativeBase StartCompetition() Commenced Teleop_Init() completed Welcome to LabVIEW Real-Time 8.5.1 Making It All Work Inputs with Java // Declaration and Initialization in one step DriverStation m_Dstation = new DriverStation.getInstance(); Joystick m_DriverStick = new Joystick(1); Joystick m_OperatorStick = new Joystick(2); // Use float f_DYAxis = m_DriverStick.getY(); float f_DXAxis = m_DriverStick.getX(); float f_DTrigger = m_DriverStick.getTrigger(); int i_AutoMode = m_Dstation.getAnalog(1); Making It All Work Inputs with C++ // Declaration DriverStation *p_DStation; Joystick *p_DriverStick; Joystick *p_OperatorStick; int i_AutoMode; float f_DYAxis, f_DXAxis; f_DTrigger; // Initialization p_DriverStick p_OperatorStick = new Joystick(1); = new Joystick(2); // Use f_DYAxis = p_DriverStick->GetY(); f_DXAxis = p_DriverStick->GetX(); f_DTrigger = p_DriverStick->GetTrigger(); i_AutoMode = p_Dstation.GetAnalog(1); Later inputs are fed to outputs. Making It Work • Floating point power ranges – Percentage of power • Stated as range is -1.0 to 1.0 with 0.0 being stop. – Forward and Back are relative • 2 motors side by side set to (1.0) are running at full power. But what direction? – All relative to the motors position, gearing, wheels surface top vs. bottom – Joysticks Y axis • Backwards to what you might think? • Push forward get a value of -1.0. • Pull back get 1.0 Inputs to Outputs • Inputs are fed to outputs – JAVA m_LeftDriveMotor.set(f_DYaxis) – C++ p_LeftDriveMotor->Set(f_DYaxis) • What about the right motor? Inputs to Outputs • Right Motor – opposite side of the robot – Will normally have to go in opposite direction to match left motor. – JAVA m_LeftDriveMotor.set(f_DYaxis) m_RightDriveMotor.set(-f_DYaxis) – C++ p_LeftDriveMotor->Set(f_DYaxis) p_RightDriveMotor->Set(-f_DYaxis) Cooking The Inputs • Sometimes we “cook” the inputs – Joystick gives us percentage of power. 1.0 to -1.0 float tmp = my_joystick.getY(); – Squaring: multiply input by itself driverY = tmp * tmp; – Qubing: multiplying input 3 times driverY = tmp * tmp * tmp; • What will this do? Cooking The Inputs Discoveries • Simple math is your friend! • Joystick “twist” comes in a GetZ() – Range 1.0 to -1.0 – What does this do? my.f_Power = ( (-my.p_LeftDriverStick->GetZ() / 2) + 0.5); • Use excel to help figure out value ranges Robot Class Types • SimpleRobot – A simple robot base class that knows the standard FRC competition states (disabled, autonomous, or operator controlled). – You can build a simple robot program off of this by overriding the robotinit(), disabled(), autonomous() and operatorControl() methods. – The startCompetition() method will calls these methods (sometimes repeatedly). depending on the state of the competition. – Alternatively you can override the robotMain() method and manage all aspects of the robot yourself. • Google: frc2168 FRC robot Robot Class Types • IterativeRobot (JAVA) – implements a specific type of Robot Program framework, extending the RobotBase class. – The IterativeRobot class is intended to be subclassed by a user creating a robot program. This class is intended to implement the "old style" default code. import edu.wpi.first.wpilibj.IterativeRobot; public class MyRobot extends IterativeRobot { public void robotInit() { … } public void disabledInit() { … } public void disabledContinuous() { … } public void disabledPeriodic() { … } public void autonomousInit() { … } public void autonomousContinuous() { … } public void autonomousPeriodic() { … } public void teleopInit() { … } public void teleopContinuous() { … } public void teleopPeriodic() { … } } Robot Class Types • IterativeRobot (C++) class My2011Robot : public IterativeRobot { // data member declarations … public: MyRobot(void) { // constructor } void RobotInit() { // initialization } void DisabledInit() { … } void DisabledContinious() { … } void DisabledPeriodic() { … } void AutonomousInit() { … } void AutonomousContinious () { … } void AutonomousPeriodic() { … } void TeleopInit() { … } void TeleopContinious () { … } void TeleopPeriodic() { … } // team-specific methods … }; START_ROBOT_CLASS(My2011Robot); Robot Class Types • IterativeRobot – FMS tells code which mode be in at any time, disabled, autonomous or teleop. – Code runs in fast loop • Too fast for sensors • Continuous routines are called in every loop, good or bad? – 50 times per second code drops into appropriate Periodic function. (Called polling) • F-117 only polls 40 times per second! – When FMS switches state, init function is run only once. – When robot first boots up what state are we in? LC Approach • Variables – Put all your variables into structure (C++) or a class (Java). – input – All your input variables – sensors – All non-driver station sensors – fbw – Fly by wire. Inputs are manipulated and saved in bfw structure – Output – all outputs • Major Code sections – GetDSInputs() • Read in and cook DS variables into fbw variables – GetRobotSensorInputs() • Read in all non DS sensors – Robot Think() • Decide what to do. Manipulate inputs to FBW variables – ProcessOutputs() • Update outputs with fbw variables LC Approach Teleoperated void LC2013::TeleopPeriodic(void) { // feed the user watchdog at every period GetWatchdog().Feed(); GetDSInputs(); GetRobotSensorInputs(); RobotThink(); ProcessOutputs(); // increment the number of teleop periodic loops completed tele_periodic_loops++; } LC Approach Autonomous void LC2013::AutonomousPeriodic(void) { // feed the user watchdog at every period GetWatchdog().Feed(); m_autoPeriodicLoops++; autoStatus.i_AutoLoops++; ZeroDSInputs();// zero out inputs GetRobotSensorInputs();// ask the robot what it sees // figure out and run what auto program to set fbw values AutoDispatcher(); RobotThink();// allow processing of settings just like normal ProcessOutputs();// set the outputs PrintDiag(1);// force diag to show autonomous. } Look At Other’s Code • Google: frc399 james-bot – Many classes – Autonomous Batch Files • Use batch files to quickly change computer ethernet connection. – You must know what your connection is called. netsh Command • netsh – used to set network parameters Command: netsh /? To see parameters • Example: Set interface to Crio @echo off echo Setting the Ip to CRIO network 10.2.72.6. netsh interface ip set address name="Local Area Connection" static 10.2.72.6 255.0.0.0 pause Note: In the example above the netsh command is on the same line! Many batches • Set to camera netsh interface ip set address name="Local Area Connection" static 10.2.72.3 255.0.0.0 • Set to DHCP netsh interface ip set address name="Local Area Connection" dhcp Note: All the above commands are set on the same batch line. Final Thought Unlike baseball crying is allowed in software development… but … …when you’re done, get back and make it work!