FIRST Robot Simulator - Robot C Code To Work With The Simulator
Click on a thumbnail sketch to see the full size picture.
Intro
This page will provide an introduction to the process of writing/compiling the C code of the Robot so that it will work with the Tcl Robot System Simulator.
Modifications to the C Code
Some of the code that Innovation First provides for the FRC is poorly designed. I am trying to pick a middle ground between completely rewriting their code and having a system that doesn't really work. To that end, I will have you make some changes to files that Innovation First has marked "do not modify". But don't worry. We won't break the system. We will just rewrite the code the way they should have. The most significant restructuring will happen in main.c and user_routines_fast.c. More on that later.
Breaking this down further, the customized C files used by the simulator consist of the files at right. The changes are explained below.
- user_routines.c
- user_routines.h
- user_routines_fast.c
- user_routines.c
- The "rom" keyword is not portable. Turn it into a macro that is removed when using this simulation package.
- Prototype some functions to reduce the number of warnings from the compiler.
- Fix some comments that caused warnings.
- Add an exmaple of using the report functions that I provide in supportfuncs.
- user_routines.h
- Prototype InterruptVectorLow() to reduce warnings.
- user_routines_fast.c
- We need two versions of InterruptVectorLow(). One for the FRC (in assembly language), and one for simulation (in C).
- Remove the while loop in autonomous mode. The right place for this loop is in main().
The standardized C files in the simulator are mostly slightly customized versions of the .h files that Innovation First provides. But in addition we also have the files at right.
- main.c -- derived from IFI code
- ifi_picdefs.h -- modified from IFI code
- printf_lib.h -- modified from IFI code
- simfuncs.c -- New
- simfuncs.h -- New
- supportfuncs.c -- New
- supportfuncs.h -- New
- main.c
- I don't have IFI's code to compare at this time. But the most significant difference is that the autonomous loop that was in user_routines_fast.c has been moved to this file where it belongs.
- Message interpretation and passing is implemented. This is the protocol used to communicate with the tcl GUI code.
- More #include files.
- ifi_picdefs.h
- This file was riddled with non-portable code. I have made edits that will allow it to be used in either the IFI compile environment, or a generic PC compiler for C.
- I also made a tweak that allows this file to declare some of its storage when included from main.c in the simulator environment. Again, this change is backward compatible.
- printf_lib.h
- When in the simulation environment this simply becomes "#include
". - simfuncs.c and simfuncs.h
- Defines some functions to implement the communication that we need with the TCL GUI code. Note that this is message based.
- supportfuncs.c and supportfuncs.c
- Define the report family of functions. These are designed to work either in the FRC environment or in the simulator. When used with the simulator they are parsed and highlighted by the TCL GUI in the log window.
- Makefile
- "make" compile manager configuration file. This file determines the minimum number of files that need to be recompiled based on the date codes of the files.
The files at right are supplied by Innovation First, but are not modified, either because they are not used or because they are OK as is.
- ifi_aliases.h -- OK as is.
- ifi_default.h -- OK as is.
- ifi_utilities.h -- OK as is.
- delays.h -- Not used.
- ifi_startup.c -- Not used.
- ifi_utilities.c -- Not used.
- printf_lib.c -- Not used.
- README.txt -- Not used.
Compiling Under Linux
Compling and maintaining the program under Linux is quick and easy. Simply run "make". If there are no compile errors, you will get a binary called "main". You can run it simply with "./main". (Exit by using Control-D.) But most people will find it more convenient to use the Tcl GUI. More on that later.
If you want to create additional source files that will be compiled and linked into the robot and simulator, there is a structure for that. The template files are designed to show the way.
- template.c -- function source
- template.h -- function prototype
- template_t.c -- test program source
- template_t.in -- test input
- template_t.ref -- test output reference
- template.README -- explain what this is about
You should copy each of those files. If you are creating a function called myfunc(), you would copy template.c to myfunc.c, etc. You then need to edit each of those files, customizing them for your purpose.
Before you link your function into user_routines or user_routines_fast there are some things to do. In order:
- Edit Makefile to add myfunc_t to FUNCTESTS. That is just a blank separated list.
- Create a test for your function in myfunc_t.c. Your test will read input lines from myfunc_t.in. myfunc_t.c is already set up to do that. All you need to do is pass what it reads to myfunc() and print out what it sees. It is best to show both input and output in the test program's printfs.
- Run "make". This will fail at the test. But it will first create the binary test program myfunc_t. You can run it interactively simply by typing
./myfunc_t(Exit by using Control-D.)- To try your prepared input lines, run
./myfunc_t < myfunc_t.inOf course you must have created myfunc_t.in first.- Study the output. Does the test do what you expected? If not, you may have a bug in myfunc(). It is generally a good idea to try some inputs into myfunc_t that are known to be invalid. It is best if myfunc() detects them and either uses a report function to complain or simply works around the bad input.
- Once you believe that myfunc and its test are running correctly you can run
./myfunc_t < myfunc_t.in > myfunc_t.refThis will create the myfunc_t.ref file.- Run
makeIt should run to completion without errors.- You can now start calling your new function myfunc() in user_routines and user_routines_fast. But be sure to add to those files the following line:
#include "myfunc.h"- Run
makeagain. It should run to completion. The new copy of "main" should now be using your new function.
Next Running It