View Single Post
  #1   Spotlight this post!  
Unread 18-02-2010, 22:16
Lord_Jeremy's Avatar
Lord_Jeremy Lord_Jeremy is offline
Lord_Jeremy the Procrastinator
AKA: Jeremy Agostino
FRC #1546 (Chaos Inc.)
Team Role: Electrical
 
Join Date: Jan 2007
Rookie Year: 2007
Location: Baldwin, New York
Posts: 45
Lord_Jeremy is an unknown quantity at this point
Send a message via ICQ to Lord_Jeremy Send a message via AIM to Lord_Jeremy Send a message via MSN to Lord_Jeremy Send a message via Yahoo to Lord_Jeremy
How complex is your code?

I'm working on some stuff now and I'm just curious, how complex is everyone's robot code? I ask because I decided it would be a decent idea to write our own functional classes for just about everything and only use WPILibJ for the really low-level stuff. So far I've written just over 5000 lines of code. I've created separate classes for just about every functional component of the robot. In some cases, I just extended a WPILibJ class, such as with the compressor. In other cases, I've written fully-fledged control classes.

This year, I jumped at the chance to write our robot's code in Java. Aside from my being the senior programmer, it's given me a chance to really do what I've always wanted in regard to controlling the robot. I love Java's inheritance capabilities and approach to object oriented programming. I was determined to use both to their fullest extent.

I started by flushing out a number of classes for all the basic components of the robot. I put these in a "devices" packaged and named them all something like GenericJaguar or GenericJoystick. I also created a couple of interfaces. For example, GenericJaguar and GenericVictor both implement GenericSpeedController.

The next thing I worked on was something I call the orders system. Pretty much an order is a small class that gets instantiated and passed as a parameter to an "intelligent component". An intelligent component is just a class that extends IntelligentComponent, which contains a bunch of methods to accept, process, and retrieve orders from a queue. Orders can be either one-shot or timed interval. They process in the order they are received and orders will be moved from the waiting queue into the active queue until a WaitUntilCompletion order is reached. That way you can send all the orders to make the robot dance across the field in one go, with the proper wait orders spaced throughout, and it will handle it as it goes.

Then I worked on driving. I have TankDriveSystem class, which implements SmartDriveSystem, which extends DriveSystem. The DriveSystem interface contains just the bare minimum functions for driving. The SmartDriveSystem incorporates a procedure for recording sensor data (gyro, accelerometer, encoders) and using it to determine where on the field the robot is. This is of course most useful in autonomous and it depends on the robot being at a known starting position. With the order system, the autonomous routine can tell the robot to go to an X/Y position and the robot will (theoretically) turn towards the target and move forward until it records going the linear distance to the target. The drive package also contains stuff like DriveMotor and DriveJoystick, which are extensions of the generic versions with a side variable (0/1 for left/right) added.

Then came pneumatics. Initially I wasn't sure if we would be controlling our solenoids with spike relays or the solenoid module so I wrote both classes implementing PneumaticsOutput, with methods like Set, Toggle, and GetLastState. While the generic devices were relatively simple, for the pneumatics extensions I wrote full toggling functionality for ease of use. Then I wrote a SolenoidSystem interface, implemented by GenericSolenoidSystem. That class would just use orders to be triggered, as I had already decided that's how my kicker class would trigger it. In the future, I could write a SolenoidSystem that was controlled by buttons fairly easily.

Next was the kicker. In package manaipulators I wrote the class that represents our soccer ball kicker. Our kicker is essentially a foot on a pivot with bungie cords. It gets pulled cocked by a cylinder and latched by another cylinder. Then the loading cylinder retracts and we open the latch to fire. During construction I demanded that limit switches be placed on the bot so we could tell when the loading and latching was complete. This proved to be a good idea as it can take several seconds to load when we're low on air pressure. Anyway, I just set up a multi-step procedure that checks what step we're at and increments it when conditions are met. I passed two SolenoidSystems (one for the loader, one for the latch) as parameters to the kicker and I send orders to each system to tell it to extend or retract. Everyone on the team was wowed the first time the kicker went through it's cycle.

Autonomous was an interesting challenge. I wanted to write a system that allowed for easy creation of new routines. Therefore I wrote a Controller class that reads switches on the robot to determine what routine to select, then uses a switch case to instantiate the chosen routine into a generic AutonomousRoutine instance variable. Since all the possible routines (each is a separate class) implement AutonomousRoutine I can call them to execute with the same methods. The Controller also passes to the AutonomousRoutine (regardless of its type) all of the IntelligentComponents it is aware of. Since all the IntelligentComponent extensions can accept orders, the routine controls each component with orders. The routine just loads all the orders all in one go. In the future, I may write a SmartAutonomousRoutine that reacts to sensor data, but that's a ways off. I have yet to test the autonomous system, but it's really not that complicated, with probably the most complex thing being the bitfield shifting used to turn a bunch of binary switches into an integer value.

So yeah, that's my code. It's highly adaptable and easy to use. Even some of the densest builders on the team could understand how to use my library, as long as they don't actually look inside the classes . My goal was create a codebase where as little code as possible is actually put in the main class. I think I did a pretty smashing job, but we'll see on the game field.
__________________
Compiling...
Compiling...
Reply With Quote