Go to Post The Scouting Award exists. It's called "Championship Winner". - Chris is me [more]
Home
Go Back   Chief Delphi > Technical > Programming > Java
CD-Media   CD-Spy  
portal register members calendar search Today's Posts Mark Forums Read FAQ rules

 
Reply
Thread Tools Rate Thread Display Modes
  #1   Spotlight this post!  
Unread 02-18-2010, 10:16 PM
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
  #2   Spotlight this post!  
Unread 02-19-2010, 11:08 AM
spartango spartango is offline
Registered User
FRC #0192 (GRT)
Team Role: Alumni
 
Join Date: Nov 2009
Rookie Year: 2008
Location: Palo Alto, CA
Posts: 43
spartango is an unknown quantity at this point
Re: How complex is your code?

Its interesting that you bring this up, because we have a similar degree of complexity, both in terms of code structure, features as well as physical lines of code. The abstraction building you describe is something we also did up front, building a neat little framework that supports and organizes the abstractions(with similar queueing systems etc). We also modularized the logic-level control over entire mechanisms, and have all these moving pieces setup in a threaded environment.
Something interesting we did was to implement an event-driven system that allows for asynchronous control, akin to AWT Events(MouseListener, KeyListener, ActionListener). This makes it so that many things that happen in teleoperated and autonomous modes arent run continuously, instead triggered by a button event or a sensor event or something.

If you are curious, we've published the event model and the entire framework code at http://code.google.com/p/grtframework for teams to peruse and use.
Reply With Quote
  #3   Spotlight this post!  
Unread 02-20-2010, 02:08 PM
ShotgunNinja's Avatar
ShotgunNinja ShotgunNinja is offline
Programming Mentor, FRC 4247
AKA: Nicholas Iannone
FRC #4247 (CougarBOTS)
Team Role: Mentor
 
Join Date: Jan 2008
Rookie Year: 2006
Location: Kenosha, WI
Posts: 158
ShotgunNinja is a jewel in the roughShotgunNinja is a jewel in the roughShotgunNinja is a jewel in the roughShotgunNinja is a jewel in the rough
Re: How complex is your code?

Wow, spartango, that's impressive that you have not only set up a Google Code for your program, but you've also added some decent Wiki documentation, complete with code examples and command explanations. It's not much in the way of professional documentation, but since the code's meant for less experienced programmers, the way that you've written it is perfect, telling the reader just what they need to know while not launching into any long explanations. Very nicely done.
__________________
Team #2970 Alum
Team #1652 Alum
2006: School Mascot for Team 1652
2007-2008: Programmer for Team 1652 (Robot Mafia)
2009: Programmer on Team 1652 (Robot Mafia), Programmer on Team 2970 (eSchool eBots)
2010-2016: Volunteer, Wisconsin Regional
2017: Programming Mentor, FRC 4247 (CougarBOTS, Obama SCTE, Milwaukee, WI)
Reply With Quote
  #4   Spotlight this post!  
Unread 02-21-2010, 03:00 AM
spartango spartango is offline
Registered User
FRC #0192 (GRT)
Team Role: Alumni
 
Join Date: Nov 2009
Rookie Year: 2008
Location: Palo Alto, CA
Posts: 43
spartango is an unknown quantity at this point
Re: How complex is your code?

Thank you. I'd appreciate any feedback you've got about the framework, and would love to implement any of the features you have, Lord_Jeremy, into it.
I apologize about the poor docs, hopefully the javadoc makes up for that somewhat
Reply With Quote
  #5   Spotlight this post!  
Unread 02-21-2010, 06:51 PM
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
Re: How complex is your code?

I've got my code set up on an ssh-enabled SVN, but I'm afraid I can't give login details because I didn't have time to set up access controls. I started out with insane documentation but as time became more precious I had to forego that in favor of actual functionality. When I have more time to correct some stupid hacks and finish the documentation I'll release my libraries.

One thing I did in my system that may or may not be a good idea is component registration. The way it works is that say you construct a TankDriveSystem. The only parameter it takes is an instance ID, which is an int you set so you can tell that TankDriveSystem apart from other TankDriveSystems, for example in autonomous handling. Anyway, after you construct a TankDriveSystem, you have to call RegisterMotor with a DriveMotor parameter. In this way, you give the TankDriveSystem instances of four (or two, or six, or seventeen) motors that are stored in a vector. The DriveMotor class contains an instance variable for the "control index," pretty much whether it's left or right. In something like holonomic drive systems, you might have four or even eight control indexes, while there are just two for tank drive. Next, in your teleopInit, you need to call RegisterJoystick with a DriveJoystick parameter. Since a DriveJoystick is just a GenericJoystick with the addition of a control index parameter, you can still use DriveJoystick members in your main class in other classes that just take a GenericJoystick. Then you have to ensure all settings are in place, by calling SetDriveMode (Linear or LowParabolic), SetMaxSpeed, and SetDeadzones. When I release my main class, you'll see what I mean.

When I began using the registration concept, my idea was that I wouldn't have to write half a million constructors to handle cases of two motors, four motors, or whatever. It also saves memory because when you hit autonomousInit, the DriveJoystick vector is cleared. I figured that the overhead this system created wouldn't be too much of a problem, considering how powerful the cRIO is. So far the only issue I had with the system was when I forgot to call the constructor on the Kicker, it kept throwing NullPointerException whenever I registered anything (I'm ashamed to say that it took me a half-hour to realize my mistake). In the drive class, conditionals testing the control index of a DriveMotor and DriveJoystick when they're pulled out of the vector are used to determine whether they're left or right. I think the biggest advantage of the registration is that the functions RegisterJoystick, ClearJoysticks, RegisterMotor, and ClearMotors are all implemented from the interface DriveSystem, so the drive system can be set up without really knowing exactly what kind of drive system it is. If I created two or three different tank drive systems that each used a different algorithm for controlling speed I would only have to change the member variable type and the constructor in the main class.

EDIT:
By the way, I'm extremely interested in your even-driven implementation. I don't really have time or the wherewithal to incorporate that into my libraries but post-season I may definitely look into that. Also, I just had a pretty cool idea. Currently the only really specific classes in my system are the autonomous routines and the kicker class. In that vein I named the kicker class Kicker2010. It pretty much just uses a stepping system, with limit switch tests, to execute a series of steps to load and fire the kicker. My idea is to create an interface SteppingSystem and class GenericSteppingSystem that you could register steps with. Heh, I'd probably create classes Step, TimedStep, ConditionalStep, and TimedConditionalStep. That way you could "build" your array of components into a functional system that acts at the touch of a button. Heh, I doubt I'll implement that for our Regional (again, I would need much testing before declaring such a system fit for the competition) but it's another post-season project.

2ND EDIT:
I just took a brief glance at your GRT framework and you did something I said I was going to do but completely forgot about! I need to implement a Disable and Enable order so that specific components are loaded and unloaded on demand...
__________________
Compiling...
Compiling...

Last edited by Lord_Jeremy : 02-21-2010 at 07:02 PM.
Reply With Quote
  #6   Spotlight this post!  
Unread 03-01-2010, 02:26 PM
FRC4ME FRC4ME is offline
Registered User
FRC #0339
 
Join Date: Feb 2008
Rookie Year: 2007
Location: Fredericksburg, VA
Posts: 324
FRC4ME has a brilliant futureFRC4ME has a brilliant futureFRC4ME has a brilliant futureFRC4ME has a brilliant futureFRC4ME has a brilliant futureFRC4ME has a brilliant futureFRC4ME has a brilliant futureFRC4ME has a brilliant futureFRC4ME has a brilliant futureFRC4ME has a brilliant futureFRC4ME has a brilliant future
Re: How complex is your code?

Heh, it's funny you should mention this because I did the exact same thing last year, my senior year on my high school team. Except I was using C++. After reading an awesome C++ book and having an "aha!" moment about polymorphism and object-oriented design, I was disappointed with WPI's failure to fully utilize these features and determined to basically rewrite the library, completely ignoring high-level WPI classes such as Gyro and PID and writing wrappers around the low-level hardware classes. Unfortunately, I never got my library working due to memory management bugs, but it was quite an experience! In one build season I went from a very limited knowledge of embedded C to an expert in object-oriented program design and implementation. In fact, I think C++ gave me a little too much to chew: I stumbled upon the template system and was no later trying to utilize template meta-programming in the robot code. For example, if you tried to instantiate an analog input on a channel that did not exist, you would get an error - at compile time.

This year, I'm a mentor for 619, we've got Java (which is awesome btw; it is so nice not having to worry about memory management!), and I'm teaching object-oriented programming to my team by having us finish the project that I started last year. It's actually working this time and is really awesome. Oddly enough, it's almost done now and has around 5,000 lines; I guess that's the number of lines necessary to make an FRC robot work.

We have three basic packages: input, controller, and output. Inputs implement one of two interfaces - AnalogIn, which has a get() method returning a double, and DigitalIn, which has an isOn() method returning a boolean. Outputs implement the similar AnalogOut and DigitalOut interfaces with set() methods. We make extensive use of Java's inner classes to break everything down into chunks of this simplicity. My rule is that if your sensor is too complex for these interfaces, you haven't sub-classed it enough.

The controller package contains controllers, which control outputs with inputs using some algorithm in a periodic thread. We also have an asynchronous package for the handling of asynchronous events.

The code isn't quite finished yet, but we plan to release it later this year.

Lord_Jeremy: be sure to keep working on your project to completion. What you're doing is probably the fastest way to develop object-oriented programming skills I can think of. An FRC robot provides a great sandbox where you can experiment with design patterns, make mistakes, and refactor the code every week if it isn't working out. You can't do that in an industrial setting. Take advantage of the opportunity you have now to learn and explore freely. Even if your code never works well enough to be used on the field, you'll gain more from the experience of writing it than you will in any classroom. I speak from experience here. It sounds like your code does work well enough to be used on the field, so that's even more awesome!
__________________
Go directly to queue. Do not pass pit.
Reply With Quote
  #7   Spotlight this post!  
Unread 03-03-2010, 11:27 PM
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
Re: How complex is your code?

I actually recently started work on a Java project of my own. I'm attempting to write an RTS game engine from the ground up. Although it's primarily a learning experience, I do intend to bring it to completion. Naturally, I'm fleshing out a beautifully complex inheritance tree, the majority of which is centered around objects.

It all starts with class Dependent, which is the base of all the objects in the game. In the objects package, there are a bunch of interfaces and an abstract class. The interfaces each represent a different functional element. For instance there is an EquipableObject and a MoveableObject and a DamageableObject and etc. They all extend GameObject, which contains some methods common to all objects. There is also the BaseObject abstract class, which extends Dependent and implements a few of the interfaces, containing method implementations generally common to all the types of objects in the game world. At the next level, there is the Unit abstract class, which implements just about all the interfaces and extends BaseObject. This is where most of the actual functionality specific to units gets flushed out. There's also Equipment, Prop, Projectile, and possibly more. They each implement different sets of interfaces. The other half of my tree is the default stats system. It starts with interface Info, which is empty. Then, for each object type interface, there's an object info interface. There's MoveableObjectInfo for MoveableObject and so on. they all extend Info. In each functionality interface (MoveableObject, etc), there's a method GetInfo which returns the Info subtype specific to that interface. Of course, there is the UnitInfo interface, which extends the info interfaces for all the interfaces Unit implements. Then in the Unit class, there is method GetInfo which returns a UnitInfo. Because of the way Java's typing works, that returned UnitInfo can be automatically casted to whatever it needs to be. So if DamageableObjectInfo contains a static float flStartingHP I can do unitInstance.GetInfo().flStartingHP.
__________________
Compiling...
Compiling...
Reply With Quote
  #8   Spotlight this post!  
Unread 03-07-2010, 10:41 PM
ideasrule's Avatar
ideasrule ideasrule is offline
Registered User
FRC #0610 (Coyotes)
Team Role: Programmer
 
Join Date: Jan 2010
Rookie Year: 2009
Location: Toronto
Posts: 108
ideasrule is a jewel in the roughideasrule is a jewel in the roughideasrule is a jewel in the roughideasrule is a jewel in the rough
Re: How complex is your code?

You guys are all very impressive. We basically rewrote the few vision classes in the WPILibj and ported a lot of functions from nivision.h. We used the default gyro class, but wrote a custom PID controller to turn. The other classes--Joystick, Jaguar, AxisCamera, Encoder, etc--worked very well for us and didn't require any changes.
Reply With Quote
  #9   Spotlight this post!  
Unread 03-08-2010, 10:24 PM
Robototes2412's Avatar
Robototes2412 Robototes2412 is offline
1 * 4 != 14
FRC #2412 (Robototes)
Team Role: Programmer
 
Join Date: Jan 2010
Rookie Year: 2007
Location: Bellevue
Posts: 312
Robototes2412 is on a distinguished road
Re: How complex is your code?

I had to rewrite the holonomic drive function (it failed miserably), it took me a loooong time. I named it com.shadowh511.mayor.WesleyCrusher.impulse (yes, i named my classes after TNG-2nd season bridge crew). It was about 14 lines of code rewritten 100 times. I have over 50 MB in backups from that function alone
Reply With Quote
  #10   Spotlight this post!  
Unread 03-09-2010, 08:56 AM
ideasrule's Avatar
ideasrule ideasrule is offline
Registered User
FRC #0610 (Coyotes)
Team Role: Programmer
 
Join Date: Jan 2010
Rookie Year: 2009
Location: Toronto
Posts: 108
ideasrule is a jewel in the roughideasrule is a jewel in the roughideasrule is a jewel in the roughideasrule is a jewel in the rough
Re: How complex is your code?

Quote:
Originally Posted by Robototes2412 View Post
I had to rewrite the holonomic drive function (it failed miserably), it took me a loooong time. I named it com.shadowh511.mayor.WesleyCrusher.impulse (yes, i named my classes after TNG-2nd season bridge crew). It was about 14 lines of code rewritten 100 times. I have over 50 MB in backups from that function alone
I don't know much about holonomic drive, but why couldn't you put the 14 lines in a function and call it 100 times?
Reply With Quote
  #11   Spotlight this post!  
Unread 03-11-2010, 09:40 PM
Kingofl337's Avatar
Kingofl337 Kingofl337 is offline
You didn't see anything....
AKA: Adam
FRC #0501 (Power Knights)
Team Role: Mentor
 
Join Date: Feb 2005
Rookie Year: 1998
Location: Manchester, NH
Posts: 861
Kingofl337 has a reputation beyond reputeKingofl337 has a reputation beyond reputeKingofl337 has a reputation beyond reputeKingofl337 has a reputation beyond reputeKingofl337 has a reputation beyond reputeKingofl337 has a reputation beyond reputeKingofl337 has a reputation beyond reputeKingofl337 has a reputation beyond reputeKingofl337 has a reputation beyond reputeKingofl337 has a reputation beyond reputeKingofl337 has a reputation beyond repute
Send a message via Yahoo to Kingofl337
Re: How complex is your code?

Quote:
Originally Posted by Robototes2412 View Post
I had to rewrite the holonomic drive function (it failed miserably), it took me a loooong time. I named it com.shadowh511.mayor.WesleyCrusher.impulse (yes, i named my classes after TNG-2nd season bridge crew). It was about 14 lines of code rewritten 100 times. I have over 50 MB in backups from that function alone


Did you destruct Lieutenant Yar?
__________________
FIRST Team 501 PowerKnights - Mentor
FIRST Team 40 Checkmate - Mentor Alum
FIRST Team 146 Blue Lightning - Alumni
Reply With Quote
  #12   Spotlight this post!  
Unread 03-11-2010, 11:23 PM
Robototes2412's Avatar
Robototes2412 Robototes2412 is offline
1 * 4 != 14
FRC #2412 (Robototes)
Team Role: Programmer
 
Join Date: Jan 2010
Rookie Year: 2007
Location: Bellevue
Posts: 312
Robototes2412 is on a distinguished road
Re: How complex is your code?

@kingof1337: no, she was already dead to me

@ideasrule: We had no mentors and we needed to get mecanum strafing and rotating done. I brute-forced it.
Reply With Quote
  #13   Spotlight this post!  
Unread 03-11-2010, 11:52 PM
synth3tk's Avatar
synth3tk synth3tk is offline
Volunteer / The Blue Alliance
AKA: David Thomas
no team
Team Role: Alumni
 
Join Date: Jan 2007
Rookie Year: 2007
Location: Ohio
Posts: 2,005
synth3tk has a reputation beyond reputesynth3tk has a reputation beyond reputesynth3tk has a reputation beyond reputesynth3tk has a reputation beyond reputesynth3tk has a reputation beyond reputesynth3tk has a reputation beyond reputesynth3tk has a reputation beyond reputesynth3tk has a reputation beyond reputesynth3tk has a reputation beyond reputesynth3tk has a reputation beyond reputesynth3tk has a reputation beyond repute
Re: How complex is your code?

With no students interested in programming, and my being the closest to learning Java, I just took the default code for the camera, the default code for the tankdrive, and added in simple stuff to use the joystick to control the kicker.

So, not really complex at all.

But it's intriguing to know that it can get as complex as we need it in the future.
Reply With Quote
Reply


Thread Tools
Display Modes Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
How Well Does YOUR Vision Code Perform? manderson5192 Programming 1 02-05-2010 07:53 AM
CNN Complex Ryan Albright General Forum 4 04-04-2007 02:52 PM
how to convert Easy C code into real code? TheHolyLancer Programming 1 01-29-2006 09:09 AM
Complex Equation Solver Dejhan_Tulip Math and Science 8 04-18-2004 09:13 PM
Kamen: Napolean Complex or Salesmanship Jordan A. Rumor Mill 27 07-26-2002 09:23 PM


All times are GMT -5. The time now is 07:31 AM.

The Chief Delphi Forums are sponsored by Innovation First International, Inc.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright © Chief Delphi