Log in

View Full Version : Team 254 Presents: 2015 FRC Code


Ryan Johnson
27-07-2015, 12:04
Hi everyone,

Team 254 is happy to share the code base for our 2015 robot, Deadlift.

This year’s software includes new features such as a test harness and simulator code to run the program on a computer, web-based graphing tools, constants editor, and autonomous selection, blocking autonomous routines, and a controller that calculates and follows a trapezoidal motion profile, on the fly. Please take a look at the following repositories:

Robot Code: https://github.com/Team254/FRC-2015
Simulated Robot Hardware: https://github.com/Team254/Sim-FRC-2015
Simulator: https://github.com/tombot/FakeWPILib

orangemoore
27-07-2015, 12:07
I am really excited to look through this! Thanks for posting this.

AdamHeard
27-07-2015, 12:34
That doesn't mean anything. All of the commits on our team are tagged with the same name because they are done on the same computer.

You know what also doesn't mean anything?

Implied slander from an anonymous account.

notmattlythgoe
27-07-2015, 12:35
You know what also doesn't mean anything?

Implied slander from an anonymous account.

Truth.

Anupam Goli
27-07-2015, 13:04
So would it be possible to use the simulator and run our own code on it at any point, or are there any steps to make it work?

AlexanderTheOK
27-07-2015, 13:11
You know what also doesn't mean anything?

Implied slander from an anonymous account.

While it does look rather accusatory (the comment by Treefaceman that is) I still find the observation interesting. I've always found one of the nicest things about any revision control (svn or github) was that it sped up our understanding of the stranger bugs:
#define true ((rand()&15)!=15)
by letting us know who wrote the code in which it was introduced.

If a team of 254s caliber is seemingly forgoing this utility I would personally like to know why. (Different internal system for tracking bugs? Mentors reviewing code before it goes on github? All just speculation of course.)

JamesTerm
27-07-2015, 13:43
While it does look rather accusatory (the comment by Treefaceman that is) I still find the observation interesting. I've always found one of the nicest things about any revision control (svn or github) was that it sped up our understanding of the stranger bugs:
#define true ((rand()&15)!=15)
by letting us know who wrote the code in which it was introduced.

If a team of 254s caliber is seemingly forgoing this utility I would personally like to know why. (Different internal system for tracking bugs? Mentors reviewing code before it goes on github? All just speculation of course.)

I like using the "blame" utility in SVN where beside every line of code adds a column of who wrote it and which revision of when it was added/edited. Actually though what really happens (from our workplace) is that each engineer is responsible for their own "module ", This seems to work best for us... there by... reducing the need for "blame".

On a side note... what does that #define line of code do? Is that some fuzzy logic?

AlexanderTheOK
27-07-2015, 13:51
It was a prank a friend of mine played on me a few years ago (not while programming robots). Basically, true is true... Most of the time... It's not as easy to detect as #define true false. We had a whole slew of these we did back and forth.

artK
27-07-2015, 14:16
Couldn't help but notice that nearly all the commits were from Jared and Tom....

Nonetheless, excellent work!

I was a programmer with 254 from 2011-2014. As others mentioned, a lot of the commits are done from Tom or Jared's computer, but students and mentors write the code. 254 programmers usually followed pair/group programming practices, forcing students (and mentors who might be there) to check our work with each other, and a lot of work ends up getting done on a couple of computers. Additionally, when testing the code on the robot, you can only deploy code from one computer at a time, so writing on multiple machines is an unnecessary hassle most of the time.


If a team of 254s caliber is seemingly forgoing this utility I would personally like to know why. (Different internal system for tracking bugs? Mentors reviewing code before it goes on github? All just speculation of course.)

Github isn't designed for our practices of code writing. (Though a version control system that works for arbitrary groups of people committing as one would be cool). And for bugs, we usually just chased them down when we found them, getting help for them as needed.

Joey1939
27-07-2015, 15:36
I followed the directions here (https://github.com/Team254/FRC-2015/blob/master/README.md) to run the robot code in the simulator. I got the following error.


run_sim.rb:6:in `exists?': no implicit conversion of nil into String (TypeError)
from run_sim.rb:6:in `<main>'

thatprogrammer
27-07-2015, 18:01
Some questions (not a very advanced programmer, yet)
1. How do you run autonomous mode despite the looper? If you tried your approach on a normal iterative robot template, the loop would run on the wait commands, preventing it from advancing.
2. You need to generate splines to create paths for motion profiling, right?
3. What is the peacock motor?
Some more questions, but I'll wait for answers to to these first.

Jared
27-07-2015, 18:05
I followed the directions here (https://github.com/Team254/FRC-2015/blob/master/README.md) to run the robot code in the simulator. I got the following error.


run_sim.rb:6:in `exists?': no implicit conversion of nil into String (TypeError)
from run_sim.rb:6:in `<main>'


run_sim.rb takes two arguments, the robot code directory FRC-2015 and the sim directory, Sim-FRC-2015. It sounds like you're giving it only one argument.

Demian Martinez
27-07-2015, 23:40
Will we be seeing a build blog anytime soon? Thanks!

thatprogrammer
27-07-2015, 23:43
Will we be seeing a build blog anytime soon? Thanks!

They said it's unlikely in the post of their technical binder.

Demian Martinez
27-07-2015, 23:50
They said it's unlikely in the post of their technical binder.

That sucks :(. Was looking forward to it.

Thad House
28-07-2015, 19:20
Whats the license like for the code, specifically the stuff in the Simulated Robot Hardware repository. I would like to put some of that in the simulator side of the C# project if possible.

Tom Bottiglieri
28-07-2015, 20:52
Whats the license like for the code, specifically the stuff in the Simulated Robot Hardware repository. I would like to put some of that in the simulator side of the C# project if possible.

I added some license files to all the repos (MIT for all our stuff, BSD as some of the FakeWPILib is derivative of WPILib). Feel free to add whatever you see fit to your projects!

Tom Bottiglieri
28-07-2015, 21:04
Some questions (not a very advanced programmer, yet)
1. How do you run autonomous mode despite the looper? If you tried your approach on a normal iterative robot template, the loop would run on the wait commands, preventing it from advancing.
2. You need to generate splines to create paths for motion profiling, right?
3. What is the peacock motor?
Some more questions, but I'll wait for answers to to these first.
1. We run the auto in a separate thread (https://github.com/Team254/FRC-2015/blob/master/src/com/team254/frc2015/auto/AutoModeExecuter.java#L11-24). The main thread of the robot which handles iterative updates does nothing in auto mode (https://github.com/Team254/FRC-2015/blob/master/src/com/team254/frc2015/Robot.java#L96-97) because all of the marshaling done by the auto modes is done in another thread, and all of the control loops run in a different thread.

2. We didn't use any spline paths this year. All of the control loops were 1d (elevator carriages, drive forward, turn in place). All of the moving subsystems shared a generic base controller which could be tuned for the properties of that system. The motion profiling was done on the fly (this is a much easier calc than generating spline-y paths).

3. The original concept for our can grabber was a system that had 4 individual telescoping arms (feathers) that would go out and grab each can in auto, all starting from the robot centered on the field. This made the robot look like a peacock, and the name for that subsystem stuck through iterations. A motor peacock is just the motorized can grabber assembly.

thatprogrammer
28-07-2015, 21:32
Thanks for the replies.
Few more questions.
1. How much smaller/larger than your shafts/stock is the tubing you get from mcmaster to ensure a super snug fit? (NOT a code question, I know :p)
2. Any reason you chose not to use CAN control for your motors?
3. Did you ever figure out the timing issues java had?

Jared Russell
28-07-2015, 21:49
Thanks for the replies.
Few more questions.
1. How much smaller/larger than your shafts/stock is the tubing you get from mcmaster to ensure a super snug fit? (NOT a code question, I know :p)
2. Any reason you chose not to use CAN control for your motors?
3. Did you ever figure out the timing issues java had?

#1 I can't help with...

#2, the CAN-enabled Talon SRX was new to FRC this season, so we decided to stick with tried-and-true PWM in case there were teething problems. As it turned out, the CAN Talon works great, and I'd say there's a good chance we use them next year.

#3, yeah. The WPIlib JAR we used was tweaked to enable interrupts and the hardware timer to work correctly in Java (basically we just finished some incomplete JNI work). The source of the modified JAR is in the lib directory. Garbage collection and the JVM still mean that we aren't quite as reliable as a RT C++ thread would be, but it is pretty stable with our changes.

Abhishek R
28-07-2015, 22:50
3. The original concept for our can grabber was a system that had 4 individual telescoping arms (feathers) that would go out and grab each can in auto, all starting from the robot centered on the field. This made the robot look like a peacock, and the name for that subsystem stuck through iterations. A motor peacock is just the motorized can grabber assembly.

How early in the season did that idea come to inception?

Tom Bottiglieri
28-07-2015, 23:32
How early in the season did that idea come to inception?
We had some sketches of this day 1 of build.

M3rcuriel
29-07-2015, 00:31
Last year, you guys squared turn inputs when you were quickturning (in teleopPeriodic). I don't see it this year - what happened to that?

Tom Bottiglieri
29-07-2015, 10:18
Last year, you guys squared turn inputs when you were quickturning (in teleopPeriodic). I don't see it this year - what happened to that?
This robot drove very differently than past robots. It was quite tall and had omni wheels on the corners. We had to mess with the drive code a bit to get it back to a place where the driver felt comfortable. I think his complaint was quick turn was a bit hard to control and would go from zero to full spin too fast.

Jared
30-07-2015, 18:52
I'm a little confused with the simulator. FakeWPILib replaces classes that won't run on a computer, but it doesn't have a replacement class for NotifierJNI, which won't run on a computer. NotifierLooper uses NotifierJNI, which creates an unsatisfiedlinkerror exception.

M3rcuriel
30-07-2015, 19:24
Another question: what, conceptually, is a Tappable?

Jared
30-07-2015, 19:37
I think there's a bug in the solenoid.java file of FakeWPILib

public Solenoid(final int moduleNumber, final int channel) {
m_channel = channel;
initSolenoid((moduleNumber * 7) + channel);
}

Module 0, channel 7 will have an index of 7 as expected, but module 1, channel 0 will also have an index of 7. It should be moduleNumber*8 + channel, not 7.

Something is a little weird - the robot code can't work in the simulator with this version of FakeWPILib, which is also missing a NotifierJNI class. Perhaps there was another revision of FakeWPILib?

DampRobot
30-07-2015, 20:32
1. How much smaller/larger than your shafts/stock is the tubing you get from mcmaster to ensure a super snug fit? (NOT a code question, I know :p)


Not on 254, and it's been a few years, but when we build in intake with BBD in the 2013 offseason, we bought 1/2" ID tubing to go over 1/2" VP hex. There was plenty of interference, and it wasn't impossible to get on (although it was definitely hard). I've heard 254 transitioned from BBD to surgical recently though, so take my experience with a grain of salt.

Travis Covington
30-07-2015, 20:59
Not on 254, and it's been a few years, but when we build in intake with BBD in the 2013 offseason, we bought 1/2" ID tubing to go over 1/2" VP hex. There was plenty of interference, and it wasn't impossible to get on (although it was definitely hard). I've heard 254 transitioned from BBD to surgical recently though, so take my experience with a grain of salt.

We only used surgical tubing in 2014, as it gripped the ball better than the urethane and was way cheaper and came in thinner wall thicknesses. There is no rule for how much larger we go on tubing vs the shaft/driven tube size. We have not used the urethane directly on a non-hollow shaft since 2013. In 2014 we used thin wall aluminum tube with the surgical tubing over it. This year we made some custom wheels with large OD aluminum hubs and huge urethane tubing parted to the widths we wanted. Worked well.

Tom Bottiglieri
31-07-2015, 11:19
I'm a little confused with the simulator. FakeWPILib replaces classes that won't run on a computer, but it doesn't have a replacement class for NotifierJNI, which won't run on a computer. NotifierLooper uses NotifierJNI, which creates an unsatisfiedlinkerror exception.

We implemented the Notifier after we were done with the sim. We'll get a patch out or if someone wants to patch it, feel free to send a PR.

The fake wpi lib is by no means complete. We just implemented hardware abstractions as we went along and needed them.

feverittm
31-07-2015, 14:58
It appears that this build was done on a linux box (the ruby script is VERY linux specific). I have been trying to build the files (following the build method in the buy script) on my Windows machine using Java 8 JDK and ant loaded from the apache site. I have issues when I launch the sim with incompatibilities between 64 and 32 bit images and then with incompatible libraries in the wpilibj. I am doing this outside of eclipse to make sure I can control the build environment.

Has anyone been successful in compiling this under a windows box? If so could you provide any hints on how you did it?


Edit - Here is the transcript to the failure


Exception in thread "main" java.lang.UnsatisfiedLinkError: C:\Users\me\AppData\Local\Temp\libwpilibJavaJNI419 0642768369947334.so: Can't load this .dll (machine code=0xb0b0) on a AMD 64-bit platform
at java.lang.ClassLoader$NativeLibrary.load(Native Method)
at java.lang.ClassLoader.loadLibrary0(ClassLoader.jav a:1937)
at java.lang.ClassLoader.loadLibrary(ClassLoader.java :1822)
at java.lang.Runtime.load0(Runtime.java:809)
at java.lang.System.load(System.java:1086)
at edu.wpi.first.wpilibj.hal.JNIWrapper.<clinit>(JNIWrapper.java:53)
at edu.wpi.first.wpilibj.RobotBase.initializeHardware Configuration(RobotBase.java:167)
at edu.wpi.first.wpilibj.RobotBase.main(RobotBase.jav a:179)


Thanks

Jared Russell
31-07-2015, 15:27
I think there's a bug in the solenoid.java file of FakeWPILib

public Solenoid(final int moduleNumber, final int channel) {
m_channel = channel;
initSolenoid((moduleNumber * 7) + channel);
}

Module 0, channel 7 will have an index of 7 as expected, but module 1, channel 0 will also have an index of 7. It should be moduleNumber*8 + channel, not 7.

Yeah, this is a bug that didn't happen to affect our particular port layout. Good catch.

Jared
31-07-2015, 19:39
It appears that this build was done on a linux box (the ruby script is VERY linux specific). I have been trying to build the files (following the build method in the buy script) on my Windows machine using Java 8 JDK and ant loaded from the apache site. I have issues when I launch the sim with incompatibilities between 64 and 32 bit images and then with incompatible libraries in the wpilibj. I am doing this outside of eclipse to make sure I can control the build environment.

Has anyone been successful in compiling this under a windows box? If so could you provide any hints on how you did it?

Thanks

I ran it under windows doing the steps manually. Here's how:

Make sure you have the 32 bit jvm and jdk on your machine. Also, make sure your PATH variable points to the a 32 bit java 8 jdk/jre. To check run "java -d64 -version" and you should see an error that 64 bit is unsupported. Also run "javac -d64 -version" and you should get the same error message.

Download the three repositories (FakeWPILib, FRC-2015, Sim-FRC-2015) using the download zip option from the github page. Unzip them all to the same folder.

In FakeWPILib/src/edu/..../Solenoid.java, edit the constructor so it looks like the code below
public Solenoid(final int moduleNumber, final int channel) {
m_channel = channel;
initSolenoid((moduleNumber * 7) + channel);
}

In FRC-2015/src/com/team254/util/lib/MultiLooper.java, edit the constructor so it looks like the code below

public MultiLooper(String name, double period, boolean use_notifier) {
if (use_notifier) {
looper = new Looper(name, this, period);
} else {
looper = new Looper(name, this, period);
}
}

Open a command prompt window, and go to the FRC-2015 directory.
Run 'ant jar'
Make sure you see BUILD SUCCEEDED

Go to the FakeWPILib directory, and run ant jar
Make sure you see BUILD SUCCEEDED

Copy FakeWPILib/dist/FakeWPILib.jar to Sim-FRC-2015/lib/
Copy FRC-2015/dist/FRCUserProgram.jar to Sim-FRC-2015/lib/

Go to the Sim-FRC-2015
run ant compile

Delete Sim-FRC-2015/tmp if it exists
Copy FRC-2015/dist/FRCUserProgram.jar to Sim-FRC-2015/tmp (create tmp folder)

Create folder classes in tmp
Open command prompt window in classes, run 'jar -xf ../FRCUserProgram.jar

copy contents of FakeWPILib/bin/ to Sim-FRC-2015/tmp/classes, don't use command prompt for this, and be sure to merge folders and overwrite without rename when there are conflicts

copy contents of Sim-FRC-2015/bin/ to Sim-FRC-2015/tmp/classes, same way as before

open a command prompt window in Sim-FRC-2015/tmp
run 'jar -cmvf classes/META-INF/MANIFEST.MF to_sim.jar -C classes .'

to run simulation, run 'java -jar to_sim.jar'

To see the robot graphs, go to localhost:5800 in your browser.

If you get an error, post it here, and I can probably help.

Thad House
01-08-2015, 02:06
In DCMotor, is getPosition() in radians and getVelocity() in radians/second?

Jared Russell
01-08-2015, 10:53
In DCMotor, is getPosition() in radians and getVelocity() in radians/second?

Yes.

The sim is super rudimentary, incomplete, and there are some bugs - but we found it enormously useful for designing the controllers for our elevator and motorized can grabber.

The first time we ran our elevator trajectory controller on the actual robot, it just worked. For the can grabber, we used our model to choose an appropriate gear reduction for the gearbox and evaluate different types of stored energy assist.

No promises, but we will probably continue to work on refining the sim interface and the underlying physics models for next year (for example, in all of our experiments we observe a delay in motor movement that we cannot model, even if we consider inductance). Maybe we'll do a Championship Conference presentation on simulation...?

AustinSchuh
03-08-2015, 02:10
... (for example, in all of our experiments we observe a delay in motor movement that we cannot model, even if we consider inductance)...

I keep wondering if it is a combination of inductance, PWM output delay, and talon delay. It would be fun to track that down with an oscilloscope some time.

JamesTerm
03-08-2015, 11:26
No promises, but we will probably continue to work on refining the sim interface and the underlying physics models for next year (for example, in all of our experiments we observe a delay in motor movement that we cannot model, even if we consider inductance). Maybe we'll do a Championship Conference presentation on simulation...?

I'm curious...
The delay... is it around 100-400ms... and is there a load applied to the motor?

Jared Russell
03-08-2015, 11:34
I'm curious...
The delay... is it around 100-400ms... and is there a load applied to the motor?

I don't recall the measurement, but it was definitely less than 100ms. We had an LED hooked up to the speed controller output and used 240 fps video and frame counting for speed measurements between the LED going on and the beginning of visible motion (so delay in switching of the speed controller is not the culprit). We've seen this phenomenon occur with both loaded and unloaded motors (I mean, there's always a load, but you know what I mean). For most FRC applications, this is not a big deal, but when trying to shave milliseconds off a can grabber, it was a huge factor.

We tried modeling things like motor inductance, gear train/motor drag, multiple sources of inertial load, and battery/wire voltage drop, but haven't been able to isolate the culprit. Like Austin said, it is probably worth running some experiments.

AdamHeard
03-08-2015, 12:18
I don't recall the measurement, but it was definitely less than 100ms. We had an LED hooked up to the speed controller output and used 240 fps video and frame counting for speed measurements between the LED going on and the beginning of visible motion (so delay in switching of the speed controller is not the culprit). We've seen this phenomenon occur with both loaded and unloaded motors (I mean, there's always a load, but you know what I mean). For most FRC applications, this is not a big deal, but when trying to shave milliseconds off a can grabber, it was a huge factor.

We tried modeling things like motor inductance, gear train/motor drag, multiple sources of inertial load, and battery/wire voltage drop, but haven't been able to isolate the culprit. Like Austin said, it is probably worth running some experiments.

We observed the same delays during our testing.

Our model matched the shape and time of the response very well, but was time shifted over.

An interesting test would be wiring a motor + LED to run directly off a main breaker, and see how much the delay is reduced there.

Jared Russell
03-08-2015, 12:33
We observed the same delays during our testing.

Our model matched the shape and time of the response very well, but was time shifted over.

An interesting test would be wiring a motor + LED to run directly off a main breaker, and see how much the delay is reduced there.

Yeah. One possibility is an inductance/current ramping in the speed controller. This would cause the LED to light almost immediately, but the motor would be slow to generate torque.

DampRobot
03-08-2015, 13:04
Yeah. One possibility is an inductance/current ramping in the speed controller. This would cause the LED to light almost immediately, but the motor would be slow to generate torque.

Any chance this is due to backlash in the geartrain?

Jared Russell
03-08-2015, 13:19
Any chance this is due to backlash in the geartrain?

It's not - there is no visible motion in the geartrain or rotors, and happens even if you preload the transmission so the backlash is on the right side at start.

hf3132
08-08-2015, 01:06
On a slightly different note, I found this (https://github.com/Team254/FRC-2015/blob/master/src/com/team254/lib/util/LidarLiteSensor.java) LIDAR class in your code, but it doesn't appear that you use it anywhere else.

What did you plan on using the LIDAR for and why did you end up not using it (or am I just too blind to find it :))? Or was this just something you looked into during build season?

Jared Russell
08-08-2015, 01:30
On a slightly different note, I found this (https://github.com/Team254/FRC-2015/blob/master/src/com/team254/lib/util/LidarLiteSensor.java) LIDAR class in your code, but it doesn't appear that you use it anywhere else.

What did you plan on using the LIDAR for and why did you end up not using it (or am I just too blind to find it :))? Or was this just something you looked into during build season?

We played around a bit with using the LIDAR-Lite for helping with automating tote loading - knowing when to run the intake, when to raise the elevator to lift a tote, etc. Ultimately, we ended up using a bunch of Sharp IR sensors instead. Way cheaper, easier to interface with, much quicker to respond, and very robust as long as you use them in a "breakbeam"-like application (where you get a sudden large change in input signal rather than trying to estimate range precisely).

x86_4819
09-08-2015, 16:17
In FRC-2015/src/com/team254/frc2015/CheesyDriveHelper.java
if (isHighGear) {
wheelNonLinearity = 0.6;
// Apply a sin function that's scaled to make it feel better.
wheel = Math.sin(Math.PI / 2.0 * wheelNonLinearity * wheel)
/ Math.sin(Math.PI / 2.0 * wheelNonLinearity);
wheel = Math.sin(Math.PI / 2.0 * wheelNonLinearity * wheel)
/ Math.sin(Math.PI / 2.0 * wheelNonLinearity);
} else {
wheelNonLinearity = 0.5;
// Apply a sin function that's scaled to make it feel better.
wheel = Math.sin(Math.PI / 2.0 * wheelNonLinearity * wheel)
/ Math.sin(Math.PI / 2.0 * wheelNonLinearity);
wheel = Math.sin(Math.PI / 2.0 * wheelNonLinearity * wheel)
/ Math.sin(Math.PI / 2.0 * wheelNonLinearity);
wheel = Math.sin(Math.PI / 2.0 * wheelNonLinearity * wheel)
/ Math.sin(Math.PI / 2.0 * wheelNonLinearity);
}

What led you to use sin functions like this to scale your steering? Was it just trial-and-error, or was there some method to it?

Also, in the same code file, could you explain what you do with "negative inertia" better?

AustinSchuh
15-08-2015, 10:35
What led you to use sin functions like this to scale your steering? Was it just trial-and-error, or was there some method to it?

Also, in the same code file, could you explain what you do with "negative inertia" better?

The goal of the sin functions is to make the turning input less sensitive in the middle and more sensitive at the edges. I'm sure you could do it other ways, but that was the first one which popped into my head in 2011 when that code was written. When you are barreling down the field at full speed, you want to be able to make fine corrections, and also be able to throw it into a pretty hard spin.

Negative inertia is an idea which I stole from the Thinkpad trackpoint. https://en.wikipedia.org/wiki/Pointing_stick It adds extra turn power in to compensate for the inertia of the robot. The end result is that the robot feels more responsive.

x86_4819
23-08-2015, 22:39
Just out of curiosity, how much of this code do you guys re-use each year?

Jared Russell
24-08-2015, 10:49
Just out of curiosity, how much of this code do you guys re-use each year?

The drive code and a lot of the utility code (e.g. math functions, PID controllers, drivers, etc.) get re-used, but the majority of the automation, autonomous mode, user interface, etc., is game specific and written from scratch.

JamesTerm
24-08-2015, 12:05
Just out of curiosity, how much of this code do you guys re-use each year?

They release code each year... so you should be able to determine a detailed answer... if there is still access to previous year's code. I have kept some old code probably 3 or 4 years ago if you can't find it.

That state machine code is something really amazing... I haven't looked at it lately to see if it is still there, but perhaps someday I may have another look at how it has evolved.

thatprogrammer
24-08-2015, 17:05
Just out of curiosity, how much of this code do you guys re-use each year?
You can view their GitHub at: https://github.com/Team254
Examine the code and you should be able to tell what gets carried over and what doesn't.