Robot Control Library
Project Template

We highly suggest using or at least studying the rc_project_template available at https://github.com/StrawsonDesign/librobotcontrol/tree/master/rc_project_template.

Copying the Template

The project template source is also included as part of the librobotcontrol package and in installed to /usr/share/robotcontrol/rc_project_template so it can be easily copied and modified. We suggest copying the project and modifying as follows.

Make a Copy

Make a copy of the project template, rename the folder to your desired project name, and cd to your new directory.

cp -r /usr/share/robotcontrol/rc_project_template ~/new_project_name
cd new_project_name

Modify the Project Name

Change the name of the C source code file to match your project name. Now edit the makefile so it knows to compile the new C file. It will also produce a compiled executable with this new name.

mv rc_project_template.c new_project_name.c
nano Makefile

For now, you should only need to change the TARGET variable of the Makefile to match your project. As your project grows you may need to edit this Makefile further as required for your needs.

# This is a general use makefile for librobotcontrol projects written in C.
# Just change the target name to match your main source code filename.
TARGET = new_project_name
# compiler and linker binaries
CC := gcc
LINKER := gcc
.
.
.

Using the Makefile

For those unfamiliar with 'make' and Makefiles, 'make' is a mature and well-documented build tool for compiling source code. If you are interested, lots of good information about the make tool can be found at https://www.gnu.org/software/make/manual/html_node/Introduction.html.

To save the user the time and effort of learning how to create Makefiles, this template contains a simple and generic Makefile which links to the librobotcontrol library and provides the following common make commands:

make
make clean
make install
make uninstall
make runonboot

make (to compile)

This will use gcc to compile the C file you renamed in section 1 and will produce an executable with the same name, but without the '.c' extention. Part of the process is linking this executable to the librobotcontrol shared object. For convenience it also links to the 'math' and 'pthread' libraries as these are most common. It can be easily modified to link to other libraries by adding to the 'LDFLAGS' list in the Makefile.

make clean

As part of compiling and building process, a '.o' object file was also created along with the final executable. If you are making a backup of your project source files, or are pushing your progress up to a git repository (as you should!!) then it's helpful to clean up these compiled binary files. Executing 'make clean' in your project source directory will clean up these binary files leaving only the source code.

make install

Normally you would execute your newly-compiled executable from within the same directory that it exists. For example, compiling and executing the project template would look like this:

debian@beaglebone:~$ cd ../rc_project_template/
debian@beaglebone:~/rc_project_template$ make
Made: rc_project_template
debian@beaglebone:~/rc_project_template$ ./rc_project_template
running...

Once you are satisfied with the functionality of your new program, you will want to install the executable in a place where it can be run from anywhere for easy access in the future. This location is typically '/usr/local/bin/' for executables made locally by users. Instead of making a copy there manually, the 'make install' command will do this for you. You will have to use 'sudo' as the '/usr/' directory has restricted privileges.

debian@beaglebone:~/rc_project_template$ sudo make install
debian@beaglebone:~/rc_project_template$ cd ../
debian@beaglebone:~$ rc_project_template
running...

make uninstall

'make uninstall' simply deletes the copy of your current project executable from '/usr/local/bin/'. It will not delete your source files.

make runonboot

This 'runonboot' command is unique to the Makefile provided in the project template, whereas 'clean' 'install' and 'uninstall' are pretty much universal amongst other Makefiles. This command sets the program to run automatically on boot if the robotcontrol systemd service is enabled, see the Run on Boot section for more details.

Structure of the Project Template

Instead of try to explain how the template works line-by-line, we've tried to comment the code as informatively as possible. The complete C file is included here for easy access. We encourage the user to read it carefully to understand the structure.

/**
* @file rc_project_template.c
*
* This is meant to be a skeleton program for Robot Control projects. Change
* this description and file name before modifying for your own purpose.
*/
#include <stdio.h>
#include <robotcontrol.h> // includes ALL Robot Control subsystems
// function declarations
void on_pause_press();
void on_pause_release();
/**
* This template contains these critical components
* - ensure no existing instances are running and make new PID file
* - start the signal handler
* - initialize subsystems you wish to use
* - while loop that checks for EXITING condition
* - cleanup subsystems at the end
*
* @return 0 during normal operation, -1 on error
*/
int main()
{
// make sure another instance isn't running
// if return value is -3 then a background process is running with
// higher privaledges and we couldn't kill it, in which case we should
// not continue or there may be hardware conflicts. If it returned -4
// then there was an invalid argument that needs to be fixed.
if(rc_kill_existing_process(2.0)<-2) return -1;
// start signal handler so we can exit cleanly
fprintf(stderr,"ERROR: failed to start signal handler\n");
return -1;
}
// initialize pause button
fprintf(stderr,"ERROR: failed to initialize pause button\n");
return -1;
}
// Assign functions to be called when button events occur
rc_button_set_callbacks(RC_BTN_PIN_PAUSE,on_pause_press,on_pause_release);
// make PID file to indicate your project is running
// due to the check made on the call to rc_kill_existing_process() above
// we can be fairly confident there is no PID file already and we can
// make our own safely.
printf("\nPress and release pause button to turn green LED on and off\n");
printf("hold pause button down for 2 seconds to exit\n");
// Keep looping until state changes to EXITING
while(rc_get_state()!=EXITING){
// do things based on the state
}
else{
}
// always sleep at some point
rc_usleep(100000);
}
// turn off LEDs and close file descriptors
rc_button_cleanup(); // stop button handlers
rc_remove_pid_file(); // remove pid file LAST
return 0;
}
/**
* Make the Pause button toggle between paused and running states.
*/
void on_pause_release()
{
return;
}
/**
* If the user holds the pause button for 2 seconds, set state to EXITING which
* triggers the rest of the program to exit cleanly.
**/
void on_pause_press()
{
int i;
const int samples = 100; // check for release 100 times in this period
const int us_wait = 2000000; // 2 seconds
// now keep checking to see if the button is still held down
for(i=0;i<samples;i++){
rc_usleep(us_wait/samples);
}
printf("long press detected, shutting down\n");
return;
}