Skip to content

Architecture Modules

David Chan edited this page Oct 12, 2016 · 2 revisions

Modules

Modules make up the base of the entire system, with each module responsible for performing operations on the robot. Each module should be designed to perform a specific task, whether it is updating a key-value pair in the system memory, or computing motion parameters for execution. When designing modules, one should always keep in mind the flexibility of the system - that is, modules should be designed to be swappable, and modules should never have dependencies that are not compiled into each module. In our build system, modules are compiled independently from the main library and only include headers from the main library, which means that they can be dynamically loaded at runtime from .so files. This allows a large amount of extensibility to the code. If you would like to change any module, it is possible to do so without re-compiling the entire code base, which means that modules can easily be swapped and tested on the robot (even during runtime using our debugging tools), which makes for simple, quick and painless debugging.

Understanding the module structure

Modules provide an interface that can be dynamically linked to. There are a few different methods:

Install():The install method is called once when the module is installed to the system. When using multiple contexts, Install() is called only once for the first context.

Uninstall(): The Uninstall method is the same as the install method, only called when the module is unloaded. If the module is not unloaded, Uninstall is called when the program terminates by the watchdog process.

RunFrame(): The main meat of the module structure. Every time that a module is scheduled, the RunFrame() method is called.

ProcessIntent(Intent i): Intents are the only way that modules can communicate with each other, and with the system in general. Because of the dynamic structure of the module, it is impossible to set up inter-module calls without introducing unwanted dependencies. Intents are string based requests that each module is responsible for parsing - they have the option to ignore any intent, or to store it for processing later in a RunFrame() call. NO MODULE SHOULD EVER COMPUTE AN INTENT IN THIS FUNCTION That is, this method should be used only for deciding whether or not to store an intent, and to parse it into a module readable format. ALL COMPUTATION SHOULD BE DONE IN THE RUNFRAME() CALL.