Skip to content
margrevem edited this page May 13, 2021 · 4 revisions

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.

Basic utilities

Events & Logging

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.

Events & Logging class diagram

Log

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");

ErrorManager

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).

RobotLogger

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.

DisplayLogger

This class extends the the third-party LoggerBase class. It implements the functionality to send a show a log message on the display.

HeartbeatLed

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.

On-board elapsed time (OBET)

OBET class

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.

Display

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.

Display class diagram

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

DisplayManager

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.

Sensors

TODO

Sensor class diagram

Motor driver

TODO

GNC (Guidance, Navigation & Control)

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.

GNC (Guidance, Navigation & Control) class diagram

Links