|
|
|
![]() |
|
|||||||
|
||||||||
![]() |
|
|
Thread Tools | Rate Thread | Display Modes |
|
|
|
#1
|
|||
|
|||
|
Re: writing reusable code / preparing for the future
eh I really don't care anymore, I am going to publish it, I never really comment my code and its going to take people quite a while to even understand what something does
|
|
#2
|
|||||
|
|||||
|
Re: writing reusable code / preparing for the future
Quote:
2. If they cant understand what it does, then it is either too complex or not implemented "well". Example: If I have a VI that processes the lookup of kicker pullback for kick distance, I name it "kicker_lookup_distance.vi" (similar to how you would name a function "lookup_distance" and put it in namespace "kicker".) Within the VI, it is written in two portions: lookup range (0-1) and scale that to the correct voltage. I have a comment describing what each does, the variables defining vMax and vMin are global constants, and comments describing the process for determining the pullback, etc. If someone were to look at this VI, knowing that it's name was "kicker_lookup_distance", they would be able to tell what it does and what its purpose is. All of my code is written in this way, with things like state machines in seperate VI's from PID processing, gain scheduling, etc. and seperate VI's for more complex states (e.g. those that don't feed a position directly to the PID control). Each is well commented and a decent programmer should be able to figure out what it does between the comments, VI connector names, and VI (function) names. |
|
#3
|
||||
|
||||
|
Re: writing reusable code / preparing for the future
Yes, it's always a good idea to write reusable code. It may be annoying now, but it'll save you time in the future.
|
|
#4
|
||||
|
||||
|
Re: writing reusable code / preparing for the future
This is what an API is for. If you design an API before hand and code to that API, then when the new libraries roll around, you can have a single person modify the code that run underneath the API to use the new library, and all the other programmers can continue writing code for the robot since they know what the API looks like.
You could take the time in the off season to write the API, then when the season rolls around. The programmers can write and test code based on previous library releases knowing that it will work when they change to the new library. On the topic of reusable code. I always make my code as generic as possible. As example, I recently wrote a quick hearts game, and instead of writing a Deal() function that returned a bunch of hands I wrote a Deck class that would allow me to write a game like go fish if I chose to. Generic and reusable code is one of the hallmarks a good software design. |
|
#5
|
|||
|
|||
|
Re: writing reusable code / preparing for the future
Writing re-usable code for something like a drive train should be pretty easy if you just pay attention to how you build up the code base
1. Separate your constants from your code. Make a constants.h. Avoid magic numbers, "const RIGHT_DRIVE_SPEED_BIAS = .97" instead of throwing .97 into your function that calculates the drive train speed. Do this with speed controller ports, sensor ports, sensor center voltages (i.e. some potentiometer is at 3.423 volts when this arm is at rest), etc etc etc. Almost anything that is physically constant on the robot should be here. Why is this useful? You moved a motor? One side is a bit too fast? Replaced a pot? You change the code on 1 line and 1 line only, everything else still works perfectly. 2. Abstraction, use it. For our drive train code, the only public functions are accessible through a DriveTrainManager object. The manager has 2 DriveSide objects, each of which has a SteeringMotor, and each steering motor has its own PID class. DriveTrainManager has NO idea that SteeringMotors even exist, it only knows about the functions in DriveSide. Why? Theoretically (if we didn't do swerve drive again) the DriveTrainManager and DriveSide objects should be completely reusable, except for the functions that rotate the wheel modules obviously, if we decided to do tank drive. 3. Avoid coupled code (spaghetti code or the infamous spaghetti and meatballs code ). Your drive train should not be using code in your arm class, and visa versa, try to encapsulate each physical aspect of your robot into its own completely modular class. Then make 1 class that deals with all the interactions. Why? Say next year you don't have an arm, so you delete the arm class. Compile the code, and now you have 5 functions in your drive train that are referencing code that no longer exists, so now you have to restructure your drive train code. This can be a complete nightmare once your code base is large enough.4. Always make a plan, but never follow it. Planning is going to make you understand the code before you even write it, but as you begin to program you're going to realize that its all wrong and restructure the code over and over. You should know each object and module in your code before you start writing anything, or else you're going to end up writing coupled code in a struggle to get thing to work. |
![]() |
| Thread Tools | |
| Display Modes | Rate This Thread |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Team 3132 - Sample code for writing to a file on the cRIO | SteveGarward | C/C++ | 0 | 05-02-2010 07:26 |
| Preparing for Regionals!!! | tribotec_ca88 | General Forum | 3 | 26-02-2004 20:16 |
| How formal are your writing styles for the Chairman's award? | Katy | Chairman's Award | 16 | 16-04-2003 20:07 |
| Preparing for the invasion!!! | dlavery | Championship Event | 4 | 01-04-2002 19:44 |