Skip to content

Instantly share code, notes, and snippets.

@pietroglyph
Last active December 19, 2017 22:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pietroglyph/9625b008083ef91c5d53df9c12d4e7a6 to your computer and use it in GitHub Desktop.
Save pietroglyph/9625b008083ef91c5d53df9c12d4e7a6 to your computer and use it in GitHub Desktop.
254 Evaulation Answers

Team 254 Codebase Evaluation Answers

  • OI
    • Dashboard UI events trigger robot behavior using NetworkTables. As far as I can tell, this really only happens in AutoModeSelector, which gets the selected auto option.
    • If a subsystem wishes to access any joystick data, it must be passed through a method on the subsystem. The aforementioned method should be called in teleopPeriodic (in Robot).
    • This is the only question I'm unsure about... It seems like starting position is baked into paths and the like, so there isn't really any system for detecting starting positions and applying them to Actions.
    • There is an interface called ControlBoardInterface that allows for easy switching between different control schemes (as long as they satisfy the interface), but remapping is done (if I understand the question, which is a little ambigious) with CheesyDriveHelper which accepts some joystick information from a ControlBoardInterface and does a lot of math I don't entirely understand. The curve seems pretty nice though, and it has an interesting control method (which I like quite a bit).
    • In the unmodified code a class called ControlBoard that implements ControlBoardInterface is used. I made a new method that also satisfies the interface to get the right mappings for the Xbox controller that I borrowed.
    • Satisfiers of ControlBoardInterface seem to be the ones fiddling with joystick directions (although this kind of modification can happen anywhere in between the joystick and the motors if you're not careful).
    • The most significant SmartDashboard updates happen when Robot.allPeriodic is called, because that calls SubsystemManager.outputToSmartDashboard(), which in turn calls that same method on every class that extends SubsystemManager.
    • If I understand the question then yes, ControlBoardInterface defines all the different names of values you should be able to get from a control board. This makes them identifiable.
  • Threads
    • Runnable is very simmilar to a first class function, and CrashTrackingRunnable just implements Runnable, providing a run method that catches exceptions and logs them with CrashTracker.
    • synchronized implies that a method is intended to be called by multiple threads.
    • Thread.sleep gurantees that it will return and throw an InterruptedException. This means that there is no gurantee that it runs for the time you specify. Additionally, even if it isn't interrupted, it is still subject to system specific behavior which will change exactly how long it sleeps for. This method is invoked a total of a total of four times in the codebase.
  • Subsystem
    • There are 10 subsystems in the original 2017 code. com.team254.frc2017.Subsystem is an abstract definition of the required behavior and methods of a subsystem.
    • See Constants.
    • Subsystems do not directly modify the state of other subsystems, instead they interact with Superstructure. Superstructure coordinates the state of all the subsystems (except drive, which has its own state). As a result, Robot doesn't directly interact with the subsystems, instead it interacts with Superstructure.
    • registerEnabledLoops a method in subsystem manager called in robotInit. This method calls the registerEnabledLoop method on each subsystem. This method gives subsystem a chance to register their loops (most only have one) with the Looper singleton.
    • LED is given a wanted state when setWantedState is invoked, and the next time it loops it tries to synchronize the wanted state with the current state. It blinks and does things based on the state and the time spend in that state. To get blinking behavior it performs integer division with timeInState as the divisor and mBlinkDuration / 2 as the dividend (I don't know why they divide by two, they could just put it in the constant). If the quotient of the aforementioned operation is even then the light should be on, otherwise, it should be off. TL;DR it stores a time value and sees if it's evenish or oddish.
    • This subsystem is the only one that Robot really interacts with in its periodic loops. It's also the one that coordinates the state of the other subsystems. You could say subsystem has the parent state.
    • Drivetrain
      • The subsystem has 7 internal states.
      • There are 5 actuators and 3 sensors.
      • Subsystem's abstract stop method ensures that all subsystems stop their actuators when appropriate. This makes it easy to ensure motor safety, as long as you know when to stop and actually stop when you implement the method.
      • RobotStateEstimator gets a bunch of info from Drive and feeds it into Kinematics, whose output it finally feeds into RobotState to be stored as a transform.
      • The only difficult part was filling in for functionality that the BNO didn't have. The NavX was well encapsulated, so there were only a few things to replace.
      • It runs in open loop.
      • AIM_TO_GOAL, DRIVE_TOWARDS_GOAL, and TURN_TO_HEADING (in the last case to make sure that the encoders are really where they say they are, I think. They do this with they gyro in other cases too, and I'm not completely sure I understand the rationale... TODO?).
      • There are two follower motors.
      • They use inches per second.
      • Yes, it does allow them to enter autonomous like modes (see Drive.setWantAimToGoal and the like).
      • aimToGoal just turns the robot and goes into driveTowardsGoal if it's too far away. driveTowardsGoal actually just drives forwards until it gets within kShooterOptimalRange*.
    • Vision
      • ...
  • Commands, scheduler
    • AutoModeSelector gets puts possible autonomous modes on network tables, and reads network tables to getSelectedAutoMode. This returns a child of AutoModeBase, which is then executed in a new thread with a CrashTrackingRunnable.
    • Autonomous modes don't directly control subsystems, instead they schedule actions which interact directly with subsystems. Actions are like commands, and modes are like command groups in traditional WPILib.
    • See above.
    • Autonomous modes can runActions, which calls the action's update method until isFinished returns true or the action isn't active any longer. This is the main scheduler loop for actions, it tries to update 50 times a second.
    • There are two threads running in autonomous, and there is only one thread running in teleop. However, there are also two threads running all the time once VisionServer is constructed.
    • Looper is a class runs an arbitrary number of loops in the same thread. Users of Looper can register new loops and stop and start the loops whenever they would like. There is only one Looper object present at runtime, mEnabledLooper in robot. The subsystem manager registers the enabled loops of all subsystems with this object, which then starts all the loops in teleop and autonomous init, and stops the loops in disabledInit.
    • A wanted state is an event sent to one of the state machines controlling subsystem behavior (in Superstructure, Drive, etc.) that specifies the state that should be transitioned to. It is not guranteed that the machine actually transitions into this state, but it does make it easy to see what state it will transition into. This is in contrast to classic WPILib, where the it is exteremely difficult to determine the robot's state at any given time. Multiple states are coordinted by Superstructure, and most of the code here sets the wanted state of superstructure, or somtimes the wanted state of a subsystem directly. systemState is the actual state of superstructure, wantedState is the wanted state, so it drives transitions of the actual system state. The state machine tries to match them up.
  • Paths
    • The cheesypath webapp outputs a class that implements PathContainer, and has an ArrayList of waypoints which it builds a bath from.
    • The adb installer script (FRC-2017-Public/installation/RIOdroid.roborio.sh) extracts RIOdroid.tar.gz to /, which puts a number of binary dependencies (of the script, and of RIOdroid itself, including adb) in the right places. It uses opkg to install more dependencies (also included in installation). Then it makes a symbolic link to install another dependency, then it puts a script to start adb in /etc/init.d and runs update-rc.d to put symlinks to the script in appropriate runlevs so that it starts when the rio starts. Finally, in makes everything executable and and sets rw permissions for everyone on /usr/bin/adb. This script doesn't do anything that really looks too bad, except maybe setting very loose permissions on a binary that gets started all the time (but people probably aren't going to be trying to hack our RoboRio). I know you mentioned see rm -rf *, but I didn't see that in this script... Are we looking at different scripts?
    • Crashes (and other logs) are written to /home/lvuser/crash_tracking.txt by CrashTracker.
@binnur
Copy link

binnur commented Dec 19, 2017

Nice summary!

starting position is baked into paths and the like
W/o looking at the code, I'd think the starting position derived/assumed based on the autonomous positions.

ControlBoardInterface and does a lot of math I don't entirely understand.
Interesting... It'd be good for us to get a handle on the math.

Robot.allPeriodic
This is automatically scheduled by the scheduler, no?

catches exceptions and logs them with CrashTracker
that is cool -- we haven't really done anything w/ exceptions to date. this would be a good design exercise for sure.

synchronized implies that a method is intended to be called by multiple threads
is there really multiple threads running? Later on you state '2 threads in auto and 1 in teleop'. What is the rationale for auto?

They use inches per second.
I like the standardization of units!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment