Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.Sign up
Strongback is a new open source software library that makes your robot code lighter and stronger. You use it along with the WPILib library on your FIRST Robotics Competition robot's RoboRIO, but Strongback's APIs and functionality mean you need less code to do more. Plus, Strongback makes it easier for you to test your code without robot hardware and can record real-time data while you operate your robot for later post-processing.
Strongback offers the following features:
- Testable - Test more of your robot code on development machines without requiring any real robot hardware.
- Simple API - Uses powerful language features of Java 8 to reduce and simplify code while retaining flexibility.
- Useful frameworks - Strongback offers several separate frameworks that you can mix and match in your robot code and in your tests. Use what you want, and nothing more. Set up all of them with just a few lines of code.
- Uses WPILib - Uses the WPILib classes underneath for safety and consistency.
Check out our new Using Strongback online book. It's chocked full of descriptions, details, and example code.
Strongback provides abstract interfaces for common actuators, sensors, user controls, and other devices. This makes your subsystems simpler and more focused. The component interfaces also allow your robot to create hardware implementations on the real robot, and your tests to create mock implementations so you can test more without the robot hardware.
The following are the low-level abstractions of physical components:
- AngleSensor - A sensor that returns instantaneous angles measured in degrees. The sensor can return absolute angles (including those beyond positive or negative 360 degrees), or it can also be zeroed so that all subsequent values are relative to the angle measured when the sensor is zeroed. An AngleSensor can represent potentiometers, encoders, and other similar devices.
- CurrentSensor - A sensor that returns the instantaneous and absolute current measured in Amps.
- VoltageSensor - A sensor that returns the instantaneous and absolute voltage measured in Volts.
- TemperatureSensor - A sensor that returns the instantaneous and absolute temperature measured in degrees Celcius.
- DistanceSensor - A sensor that returns the instantaneous distance measured in inches or feet from a nearby object. It can represent ultrasonic sensors, infrared proximity sensors, or even a vision system that estimates distance. For simplicity, it can be zeroed to return relative positions.
- Switch - A switch represents a device that has an active state when it is triggered and an inactive state when it isn't. It can represent buttons, limit switches, Reed switches, Hall effect sensors, etc.
- Fuse - A device that acts like a Switch but that can be explicitly triggered and optionally reset.
- SpeedSensor - A sensor that returns the instantaneous speed. SpeedSensor may be useful on its own, but it is intended primarily as a base interface for Motor.
- SpeedController - A device whose speed is able to be controlled. SpeedController may be useful on its own, but it is intended primarily as a base interface for Motor.
- Accelerometer - A sensor that provides the acceleration along a single axis.
- Relay - A device that can be turned on and off.
- Solenoid - A device that can be is a device that can be extended and retracted. Although similar to a Relay, pneumatic solenoids are common enough in FRC to distinguish as a separate low-level component.
The following are the higher-level abstractions that represent slightly more complex physical components, and are usually composed of one or more lower-level components:
- Motor - A device that is both a SpeedSensor and SpeedController. Quite obviously, it can represent a combination of an electric motor (e.g., CIM) and electronic speed controller (e.g., Talon).
- LimitedMotor - A Motor that is constrained to move between a maximum position and minimum position.
- TalonSRX - A motor controlled by a Talon SRX with a current sensor and position (angle) sensor, and that is optionally constrained to move between a maximum position and minimum position.
- Compass - An angle sensor that provides heading information in addition to angle (compass extends AngleSensor).
- Gyroscope - A gyroscope is a device that measures angular velocity (in degrees per second) about a single axis. A gyroscope can indirectly determine angular displacement by integrating velocity with respect to time, so it also extends Compass (which extends AngleSensor).
- TwoAxisAccelerometer - A combination of two single-axis Accelerometers. It can be used to represent a physical 2- or 3-axis accelerometer, such as the ADXL193 (which may no longer be supported by WPILib).
- ThreeAxisAccelerometer - A combination of three single-axis Accelerometers. It can be used to represent a physical 3-axis accelerometer, such as the ADXL345 or built-in accelerometer on the RoboRIO.
- PowerPanel - An abstraction of the sensors on the Power Distribution Panel.
- SolenoidWithPosition - A Solenoid that can determine its position. Typically this would be used to represent a pneumatic solenoid with one or two magnetic reed switches.
Strongback also provides several abstractions for human interface components connected to the Driver Station:
- Gamepad - Represents an Xbox-like controller, such as the Logitech DualAction or F310 gamepads.
- InputDevice - A simple collection of axes and buttons, such as a generic input device or joystick.
- FlightStick - A type of input device consisting of a joystick with twist and throttle, such as the Logitech Attack 3D or Microsoft SideWinder flight sticks.
Strongback provides a general-purpose execution framework so you can run multiple custom functions on a fixed schedule using a single thread. The framework can use a variety of clocks, and its precise and accurate timing is suitable for control systems.
Most robot programs that use WPILib have one thread that runs the main logic, and other threads for asynchronously processing commands, handling button presses, computing control system loops, etc. Using more threads than available cores means that the JVM has time-share each core to simultaneously run each thread. It is far better to use no more than one thread per available core.
Strongback's execution framework can be used for all of the asynchronous logic, and it efficiently runs all of this code using a single thread. Because control systems require execution of loops on very precise intervals, Strongback uses the best approaches to execute these loops on a very consistent, accurate, and precise schedule that can be as fast as 1 millisecond on the RoborRIO and most desktop/laptop hardware.
By default, Strongback will use this execution framework for all command processing, data and event recording, and switch detection and processing. You can also register your own functions.
Data and event recorders
Although unit testing code off robot is important, it is just as important to be able to test your robot as an integrated system. Running the real robot is great, but it's even better when you can capture and record real data about what the robot is actually doing.
Strongback's data recorder and event recorder systems act as a data acquisition system that can record in real-time the input and output signals from the RoboRIO, button presses, changes in command state, and other robot-specific events. The data recorder captures data on a repeating schedule (via the executor framework) and is suitable for recording continuous data channels such as voltages, currents, speeds, temperatures, distances, etc. The event recorder is for spurious data, such as command states, switches, button presses, etc.
These recorders are fast, very efficient, and lightweight so that they don't slow down the robot. The resulting data files can be downloaded from the robot, post-processed, and visualized with 3rd party tools (such as Excel or Tableau) to better understand exactly what the robot was doing and when. In the future we hope to provide ways of sending the data off-robot in realtime so that the information can be processed and visualized in realtime.
The data recorder and event recorder can be turned off when not used.
Strongback provides an improved, simplified, and testable command framework that reliably executes commands on a very consistent schedule. Conceptually it is very similar to the WPILib command framework, but there are several important differences:
- The abstract Command and CommandGroup classes are similar in concept to the WPILib commands and command groups, but Strongback's classes are simpler, have fewer dependencies, and don't know how to run themselves. Instead, you instantiate your commands and groups and then submit them to Strongback, which takes care of executing them. This design makes it much easier to test off-robot your commands and subsystems together, yet is just as easy to use.
- The WPILib command framework requires that subsystems actually extend the
Subsystemabstract class, which is fairly complex and actually uses static references between
Subsysteminstances that can wreak havoc in unit tests by consuming memory and leaking state between tests. Strongback's command framework defines a simple
Requirablemarker interface (with no methods), and these are used to determine the requirements for each command. Like the WPILib framework, submitting a command that requires objects currently in use by other running commands may result in the interruption of the currently-running commands.
- Strongback's fluent API for composing commands into groups is simpler and easier to understand and test.
- Strongback can automatically record all of the commands' state transitions with its event recorder framework so that you can more easily visualize and understand what your robot does at any given point in time.
- A simple but lightweight command test harness that makes it easy to test commands by stepping through the various states.
Strongback has a very simple and easy to use logging framework, and it uses it to record messages at various levels of interest (e.g., error, warning, informational, debug, and trace). Configure Strongback to use a specific level, and only those messages at that level and above are output; any messages at more detailed levels are dropped. Your robot code can also use the logging system.
By default it will write to
System.err, but you can configure writing to the JDK log system. You can even implement your own logger mechanism and have Strongback use it.
We are always looking for FRC students and mentors to use and help out the Strongback community. See our Community wiki page for details.