Programming: How do you go about it?

Do you just sit down and start writing code, or do you make a flowchart or some other type of diagram beforehand? Do you write a lot of code and then test, or test more often?

I’m curious about the programming process of other teams.

I tend to start with a good idea mentally of what I want to accomplish, then lay out all the steps in the program before testing it. That way I have all the code put together and can ignore the actual code writing part of it while testing.

First of all, thank you for asking this question. I wish more people asked this before programming.

For very simple pieces of code, I confess to just sitting there and writing it all out, and coming up with the logic on the spot. This isn’t good programming practice though, and for more advanced pieces of code, you should definitely “make a flowchart or some other type of diagram beforehand”. You might want to research “Finite State Machines” if you want to look into some types of diagrams that you can make.

As to whether you write a lot of code and test it all, or write small pieces and test them more often, I will tell you (and so will most people) that you should absolutely write small pieces and test them more often. Doing this will make finding errors in your code exponentially easier. This will also make programming much faster. This might be counter intuitive, but the amount of time that you will save on finding errors this way will most likely outweigh the amount of time you might save by not testing frequently. If getting your hands on the robot to test is a problem (I know that we all love to program on the day of the competition because the builders thought that programming meant smashing your hands on the keyboard a couple of times), if you program in ROBOTC, there is a great tool available for free, called ROBOTC Virtual World. It allows you to run your code on a robot right inside your computer. And while it may not be as good as the real thing, it’s a great way to get rid of a lot of bugs before you ever touch the real robot.

Of course these are just my opinions, and you are free to disregard them if you wish.

I know that I should be using diagrams, but I rarely bother. It’s pretty bad practice, but sometimes you just don’t have time. Make sure you reason your way through each step though, and a good question to be asking is “What effect will this line of code have on the robot in real life?”

Test early and test often definitely. Learn to use the debugger to get all of the relevant values up on your screen, and watch how the robot is responding to your code. Correct your code, and then move onto the next step. It is much easier to correct a problem if you are only checking one line of code at a time.

If you’re sitting around doing nothing because you’re waiting for the builders to finish the robot first, it can be a good idea to use that time to write out the steps of your proposed program - even if you’re not doing a proper flowchart with the symbols and stuff, it’s still helpful to just write what is effectively pseudocode that you can turn into code much faster later.

Just a note on ROBOTC Virtual World, I tried it last night and I found it rather annoying - a rather large amount of randomness has been added in (which kind of makes sense, since running the same program twice rarely produces an identical response), but I feel that it’s a bit too much.

How much preparation I use depends on the task at hand.
If I’m doing something easy (i.e. move forward, mapping buttons, etc.), I tend to just “write off the top of my head.”
If I’m writing auton, I like to draw my path on a map of the field, and then create the program from that.
If I’m doing something pretty difficult (i.e. multiple PID loops, creating some massive subroutine, or sensor sequence), I will write out a flowchart, pseudocode, or a graph/chart of sensor values to serve as a guide.

//Andrew

It’s interesting that you post this today as I was about to post a rant in the RobotC forum about the inadequacies of RobotC and the subsequent bad practices it forces onto the programmer. I’m fairly new to RobotC but decided to play with it a little over the summer to better support the student programmers on our team. Although a novice with RobotC, I’m not new to programming having spent the better part of the last 30 years programming everything from simple embedded systems to expensive super computers in a variety of languages including C.

I always knew RobotC did not support pointers and understand the underlying reasons for this, however, over the last hour I also find out that there is no initialization of static structures, no ability to pass an array of structures, no ability to pass a structure to a subroutine and then pass that on to another subroutine. It appears that all variables are globals ! so there is no stack. Now I may be wrong and out of line here but that what’s the debugger seems to indicate.

Rant over, now to your question and a few guidelines,

Break the problem down into small chunks, when I first started writing embedded code we had a rule that no subroutine should be more than 50 lines. Now it’s not always practical to do that but code or conditional statements that go on for pages and pages are difficult to read and should be avoided.

Try and keep the low level details away from the higher level concepts so that if the hardware changes the software can quickly be updated. For example, if you have a two motors driving the same wheel, have a subroutine that assigns a value to the two motors kept away from the code that determines the required speed. If you decide to add a third motor then only one line of code needs to be added, you don’t have to find every place that you were controlling them.

Use finite state machines. This works well with breaking the problem down into small chunks. Events are used to change from one state to another; for example, code to detect button presses may start in a state with no buttons pressed. What happens next? A button will be pressed so have some condition statements looking for buttons to go down, when this is detected then change to a state looking for that button to be released etc.

Use Pseudo code rather than flowcharts. Pseudo code is shorthand for the real code that conveys its intentions without having to follow any syntax. It can be in whatever style you want as long as it describes what the C code will do. Put the Pseudo code into the header above the subroutine that implements it, its hard to do that with flow charts.

Don’t use “magic numbers”. By this I mean don’t bury special numbers in the body of your code, for example, lets say you are comparing the value coming from a potentiometer to a fixed value of 1792 because you have determined that this is when something is at its limit. Do not bury 1792 into the code but instead make it a definition or constant near the start of the file.

Keep the code clean, use headers, and add the author of the code and the date created. Add a revision history once the code is stable and starts being used in competition so that others can see what changes are being made.

Test in small pieces before putting the whole application together.

Enough for now.

This is a really important and handy tip. If you don’t know how, at the top of your file (usually after the motors and sensors declaration), you can put


#define VARIABLE_NAME value

for example:


#define ARM_MAX 3500

which allows you to refer to it multiple times later in your code, and if you need to change the value (for example if the potentiometer has been moved), then you only need to change it once.

Another thing I would say is to COMMENT - I know a lot of programmers find it annoying to comment and can’t be bothered, but one day your programmer will be sick or can’t make it to the competition and someone else will have to try and figure out what your code is doing. Commenting goes a LONG way in helping other people understand what you’ve written and why. This is especially important for larger teams, which might have multiple programmers.

Another helpful thing is that if you’ve written your code into functions nicely and cleanly, and follow a consistent naming convention, you can save time by stealing bits of code from your old code - for example if you have a DriveTo function that uses shaft encoders to make your robot move a certain distance in a certain direction, you can pretty much copy paste that function and just make a few small changes to make it work again. Saves a lot of time!

Thank you all for your insightful replies. I will be sure to implement the ideas you present when I am programming this season. :smiley: