
13-07-2015, 19:33
|
 |
Registered User
no team
Team Role: Programmer
|
|
Join Date: Aug 2013
Rookie Year: 2012
Location: Connecticut
Posts: 602
|
|
|
Team 236 2015 Code Release
After finally getting around the cleaning up our code, team 236 is releasing their 2015 robot code.
You can view it on GitHub here: https://github.com/dicarlo236/2015-R.../team236/robot
Here's a short list of all the interesting or unique features of our code - Autonomous Motion Profiling (see our autonomous mode video here)
(Code is Here, here, and here)
Our "train wreck" autonomous mode required very repeatable robot motion in order to get the "slapper" to hit all the recycling containers the same way each time, so we needed something better than PID or "drive until you go too far" control, so we used motion profiling to control our robot. I originally learned about this technique from Team 254 in St. Louis two years ago, and was inspired to try my own version after reading Jared Russell's posts on Chief Delphi and writing my own spline editor tool.
When the robot powers on, it generates a few motion profiles. These profiles describe the motion of each side of the robot's drive for each of our autonomous modes. The profiles are defined by setting a desired distance to travel, a maximum velocity, acceleration, and jerk. The result is a smooth s-curve velocity profile (trapezoidal acceleration profile).
To simplify this process from some of my other code to do this, we assume that the motion path will be symmetric, the maximum velocity will be a constant function, the maximum acceleration will be a constant function and that the robot can accelerate as fast as it can decelerate. This lets us generate a simple portion of the profile, then mirror it in many different ways to get the full profile. In reality, the robot cannot have as large of a velocity as it is turning, the robot can accelerate considerably faster at slower speeds than greater speeds, and the robot can decelerate significantly faster than it can accelerate, but we can ignore all these things if we are conservative with our maximum acceleration and velocity limits.
Later this summer, I'll be posting an updated version of my path planner software that doesn't make these assumptions, uses an acceleration profile of an electric motor, and has a nicer UI that zooms and pans.
Each profile contains a list of Elements, each spaced .02 seconds apart. Each Element contains the robot's position, velocity, acceleration, and jerk.
When we go to run autonomous mode, we follow this profile using both feedback and feedforward. We can very closely approximate the required motor power to achieve a given acceleration and velocity, and we can use this approximation to get within about half a foot of our target over 10 or 15 feet. To increase accuracy, we first tried using a PID loop that would constantly looking at where the robot was vs. where it should be at that point in time. The PID controller was difficult to tune, and positional accuracy wasn't super critical, so I switched to a simple proportional feedback controller that was tuned to give a very aggressive response (full speed when the robot is 1" or more off target).
- The updater
The updater will automatically call the update method of any object that implements updatable and has been added to the updater. Updatables can either be updated each time the robot receives a packet from the DS (through the teleopPeriodic() method) or at a constant 20 ms period. This is really useful for running checks to see if limits are being hit or running control loops. It's used to zero the elevator encoder when the bottom limit is hit and to run all elevator and drive control loops.
- The elevator control
The elevator height setpoint is determined by two factors, the height of the stack and the offset location. The d-pad buttons are used to set a constant offset for placing totes on the ground, the scoring platform, or the step, and the trigger buttons are used to increment or decrement the height by one tote. There's also a manual jog mode for when things go wrong. As the operator, I thought this layout was intuitive to use.
- The PID controller:
I wrote PID controller because I didn't really like how the WPI PID controller was set up. Instead of having each PID controller in a separate 20 ms period thread, we put all the PID and feedback controllers in one thread. It's easier to log data this way. The only feature that I think is unique is our at target detection. Instead of just checking if the error is zero, we check to see that the rate of change of the error is zero. This makes sure that you have actually settled at your target, rather than just blowing past it at full speed.
|