Programming#
Main Programming Tools#
- YARP: See Programming with YARP.
- C/C++: Low-level (control) programming. See below.
- CMake: See below.
- Python: High-level (algorithm) programming.
- Doxygen: Document code, within the code.
- Related issue: "Program documentation: md vs dox" (qa#29)
- You can find more general recommendations for programming at: ProgramaciĆ³n (Spanish)
General Programming#
- In case of trouble during installation of dependencies or additional software, take a look first at our dedicated repository: installation-guides (hosted site).
- If incorporating a new dependency or additional software, first take a look at our dedicated repository: installation-guides (hosted site). If it's not there, consider if it's a good option using the following recommended (but not mandatory) criteria: lightweight, flexible, multiplatform. If so, add it there, then link it to your project.
- Indent your code as if everything were Python. astyle can handle this quite automatically for you (use with caution).
- Any
toDo
,fixMe
, etc. inlined in code must be associated to an open issue (with bidirectional reference). - Headers, config files and CLI parameters.
- Read about Clean code.
- We use Test Driven Development and Continuous Integration.
- Let's repeat:
- DON'T ADD DIGITS to filenames as a hint of a specific version, iteration step, etc. - version control is for this.
- AVOID DUPLICATES of existing files and programs: don't repeat yourself (DRY). Prior to creating a new program, thoroughly analyze whether you can enhance an existing one through adjustment or implementation of new parameters. Once you are sure that the functionality of a program could be extended, proceed with the usual steps (open an issue or fork & create a pull request).
Programming in CMake#
- Tutorial (Spanish)
- Naming conventions:
- SCREAMING_SNAKE_CASE for the project name, files and configuration variables:
TEO_MAIN
,TEO_MAINConfig.cmake.in
,TEO_MAIN_INCLUDE_DIRS
. - kebab-case for installed YARP context directories as set by
yarp_configure_external_installation()
:teo-main
,asibot-openrave-models
. - Use the
ROBOTICSLAB_
(orroboticslab-
) prefix whenever the uniqueness of the chosen name for the project could be easily compromised (keep in mind you'll want to invokefind_package()
):ROBOTICSLAB_YARP_DEVICES
,ROBOTICSLAB_KINEMATICS_DYNAMICS_INCLUDE_DIRS
,roboticslab-vision
.
- SCREAMING_SNAKE_CASE for the project name, files and configuration variables:
Programming in C/C++#
- Some good slides on C are "Thinking in C" by Bruce Eckel, and some good books on C++ are "Thinking in C++" by Bruce Eckel.
- A nice IDE is Visual Studio Code, but you can also customize QtCreator, Eclipse, Atom or even Vim.
- Use project-generator for creation of new C/C++ projects.
- Report any problems with project-generator in its corresponding issues section. If you find that this solution doesn't suit you, at least stick to [CMake]((#programming-in-cmake) for any C/C++ project.
- Use UpperCamelCase for library and class names.
- Use lowerCamelCase for executable names.
- Avoid global variables.
- We prefer modern
std::string
class to alternatives likechar*
oryarp::os::ConstString
. - Store your classes inside a namespace block. Our current trend is
roboticslab::
(see https://github.com/roboticslab-uc3m/QA/issues/15). - Keep a minimalistic
main()
by implementing your program as an OOP class, see comments onRFModule
in best practices in Programming with YARP. - Create and maintain unit tests for each class. We are currently using gtest, see kinematics-dynamics/tests/testKdlSolver, which is then integrated with Travis CI.
- It is recommended to mark a function as DEPRECATED for a month before eliminating it from an API. DEPRECATED macros can be generated via CMake as done here, then used within code as here. The full procedure, as described at QA #21, should be:
- Open a GitHub Issue wherever the offending function is located.
- Label it as
announcement
. - Use the search bar to localize any call to said function across roboticslab-uc3m and list all affected repos.
- If necessary, elaborate a removal plan and detail any steps that need to be taken to perform a seamless migration to the new API.
- Ping the corresponding team or whoever could need more action on their end.
- Proceed gradually and, finally, kill the function.
- Always initialize class members, either in the class constructor or in any initialization method (e.g. your implementation of
DeviceDriver::open
when creating custom YARP devices) before doing the actual work. - More links to best practices:
If you have any doubts or comments#
Please read the Asking Questions section, and once you've succeded with its self-evaluation follow the recommendations by commenting publicly HERE if required.