-
Notifications
You must be signed in to change notification settings - Fork 0
Software design
This page describes the software architecture of the robot's sub-modules.
Some basic principles :
- No dynamic allocation of memory
- No delay calls inside the main loop. Every call that takes some time should be handled as a state machine.
Some key aspects:
- Log messages can be 'consumed' by multiple providers (LCD screen, serial line, SD card, ..);
- All regular log messages are declared in a global configuration table and have a unique identifier.
- Debug log messages can be formatted with the well-known 'printf-like' wildcards (%d, %f, ..);
- Multiple log levels are available (debug, error, info, ...).
- All log messages are have an identifier. A static table contains the message in long format (max 80 characters) and in short format (max 20 characters). The long format is used for serial output and the short format for display output.
This class defines a log message (loglevel, long message and short message). A static array in logConfig.h contains a list with every possible log message except debug logs. The position in the array is also its ID.
Example of a Log instances in logConfig.h:
Log logs[NB_LOG_IDS];
logs[ERROR_1] = Log(ERROR, "Error 1", "More detailed description of error and where it occurs");
logs[INFO_5] = Log(INFO, "Boot complete", "The boot sequence is complete");
This class handles errors on the robot. There are two types of errors that can be thrown:
- Minor errors: In this case the robot continues to function normally but a log message is generated. Example: a sensor couldn't be read.
- Critical errors: In this case the robot can not continue to function and the function does not give the control back to the main loop. Generally this corresponds to a programming error that can only be detected at runtime. An event is generated, the heartbeat LED blinks rapidly and after a configurable delay the Arduino is reset. For example an array is accessed out of its boundaries (remember that all arrays are declared static).
This class handles all logs that are generated on-board. This class relies on a third-party library (arduino-logger). Logs are either printed on the serial line or/and on the display. Different types of logs can be emitted:
- Debug: Debugging messages only. Those kind of messages can be enabled/disabled by passing a compilation argument (-DDEBUG). They are not listed in the Log configuration and can be formatted.
- Info: Regular message. Example: The GNC mode changed.
- Warning: The aim of such a message is to alert the operator. Example: the robot detects an obstacle.
- Error: An error occurred but the robot continues to function. Those messages should be investigated.
- Critical: Those errors are indicating a system failure and are only generated by the ErrorManager. The Arduino will be reset.
The class contains a configuration table that specifies which log type has to be sent to what logger (display and/or serial). By default only errors and critical errors are shown on the display.
The flush() function is called in the main loop and flushes logs towards the display and the serial line at a configurable frequency. Critical errors are immediately flushed and the display is forced to refresh.
Example code snippet:
RobotLogger.debug("Print some variables: %d and %f", 16, 3.14);
RobotLogger.log(ERROR_1);
RobotLogger.log(INFO_5);
Corresponding output on the terminal:
[DEBUG] Print some variables: 16 and 3.14
[ERROR|137.65s|000] More detailed description of error and where it occurs
[INFO |138.23s|005] The boot sequence is complete
Corresponding output on the LCD:
E:000:Error 1
Only the error is shown with its id and the short message.
This class extends the the third-party LoggerBase class. It implements the functionality to send a show a log message on the display.
This class controls the on-board LED. In case of a critical error the LED blinks rapidly. In case of nominal execution it blinks at a configurable rate.
OBET is a relative time measurement starting at boot. The Obet class has two static member functions to get the current OBET in seconds or milliseconds. It can be used for logging.
Key aspects:
- The display shows the distance from obstacles (3 infra-red sensors), the current 'Drive'-mode and log messages.
- During boot (init), a splash screen with the 'Turbot' logo is shown.
Example output in 'line-following' mode:
TURBOT
L[56] M[80] R[!!]
GNC: Line following
[ ] [X] [ ] [ ] [ ]
Example output when a error is trown
TURBOT
L[56] M[80] R[!!]
GNC: Lawnmower
C:14:Critic error
This class contains an instance of the actual LCD third-party library LiquidCrystal_I2C. The refresh() function is called in the main loop and refreshes the display at a configurable frequency. The flush() function of the DisplayLogger class shall write only errors (by default) towards the LCD buffer.
TODO
TODO
To implement numerous GNC modes we use the State pattern. This enables us to easily add another mode to the architecture without interfering with existing ones.