Major feat(Documentation): Complete documentation rework

Split documentation into three folders: Architecture, Testing and
Installation.

Rework and expand architecture.md alongside interfaces.md

Split all parts to do with testing from Architecture md's into Test md's

Add parameter to ExamResultGenerator node documentation
This commit is contained in:
2025-10-08 16:30:05 +02:00
parent 130b495030
commit 5e1df5367c
15 changed files with 609 additions and 131 deletions

View File

@@ -34,7 +34,6 @@ The system consists of multiple ROS2 nodes that communicate through topics and s
- Simulates exam result generation for testing and demonstration
- ([Full documentation](doc/nodes/ExamResultGenerator.md))
2. **FinalGradeDeterminator** (`assignments::one::final_grade_determinator`)
- Collect grades from ExamResultGenerator
- Send results to the GradeCalculator
@@ -46,7 +45,6 @@ The system consists of multiple ROS2 nodes that communicate through topics and s
- Ensures grade results are within valid bounds (10-100)
- ([Full documentation](doc/nodes/GradeCalculator.md))
#### Database Management
- **DatabaseManager**: Handles all database operations including storing final course results
@@ -127,4 +125,3 @@ source install/setup.bash
sudo docker-compose up
ros2 launch g2_2025_grade_calculator_pkg grade_calculator.launch.xml
```

View File

@@ -0,0 +1,79 @@
## Unit Tests
Unit tests for `ConfigManager` are implemented in `src/g2_2025_grade_calculator_pkg/test/ConfigManager.test.cpp` using Google Test and ROS2 test utilities. The tests use temporary TOML files to validate configuration loading and parsing functionality.
### Test Cases
#### 1. ConstructorTest
**Description:** Verifies that ConfigManager can be created with a ROS2 logger without crashing.
- **Test Action:** Create ConfigManager instance with ROS2 logger
- **Expected Result:** Instance created successfully without exceptions
#### 2. LoadValidConfigTest
**Description:** Tests loading of valid TOML configuration files with proper parsing.
- **Test Action:**
- Create temporary TOML file with valid configuration
- Call `load_config()` with file path
- **Expected Result:**
- Returns `true`
- `is_loaded()` returns `true`
#### 3. LoadInvalidFileTest
**Description:** Tests error handling when attempting to load non-existent configuration files.
- **Test Action:** Call `load_config()` with non-existent file path
- **Expected Result:**
- Returns `false`
- `is_loaded()` returns `false`
#### 4. DatabaseConfigParsingTest
**Description:** Tests complete database configuration parsing with all parameters.
- **Test Configuration:**
```toml
[database]
host = "test_host"
port = 1234
dbname = "test_db"
user = "test_user"
password = "test_password"
timeout = 60
ssl = true
[database.pool]
min_connections = 2
max_connections = 20
```
- **Expected Result:** All configuration values parsed correctly with proper types
#### 5. DatabaseConfigWithoutPoolTest
**Description:** Tests default values when optional pool section is missing from configuration.
- **Test Configuration:**
```toml
[database]
host = "localhost"
port = 5432
dbname = "grades"
user = "postgres"
password = "postgres"
```
- **Expected Result:**
- Main database config parsed correctly
- Default pool values: `min_connections = 1`, `max_connections = 10`
#### 6. GetConfigWithoutLoadingTest
**Description:** Tests behavior when attempting to access configuration before loading any file.
- **Test Action:** Call `get_database_config()` without loading configuration
- **Expected Result:**
- Returns `std::nullopt`
- `is_loaded()` returns `false`

View File

@@ -0,0 +1,65 @@
## Unit Tests
Unit tests for `DatabaseManager` are implemented in `src/g2_2025_grade_calculator_pkg/test/DatabaseManager.test.cpp` using Google Test and ROS2 test utilities. The tests are designed to work reliably whether a database connection is available or not, focusing on error handling and method behavior validation.
### Test Cases
#### 1. ConstructorTest
**Description:** Verifies that DatabaseManager can be created without crashing and proper initialization occurs.
- **Test Action:** Create DatabaseManager instance with ROS2 logger
- **Expected Result:** Instance created successfully without exceptions
#### 2. ConnectionStatusTest
**Description:** Tests that the `is_connected()` method returns a valid boolean value.
- **Test Action:** Call `is_connected()` method
- **Expected Result:** Returns either `true` or `false` (no crashes or invalid states)
#### 3. QueuePendingCombinationsTest
**Description:** Verifies retrieval of pending student-course combinations that need exam results.
- **Test Action:** Call `queue_pending_combinations()`
- **Expected Result:** Returns valid vector (empty if no database connection, populated if connected)
#### 4. StoreExamResultTest
**Description:** Tests exam result storage with graceful handling of connection states.
- **Test Action:**
- Student: `"TestStudent"`
- Course: `"TestCourse"`
- Grade: `85`
- **Expected Result:** Returns `false` if no connection, `true` if connected and successful
#### 5. EnrollStudentTest
**Description:** Tests student enrollment into courses.
- **Test Action:**
- StudentCourse object with test data
- **Expected Result:** Returns `false` if no connection, `true` if connected and successful
#### 6. GetFinalGradeTest
**Description:** Tests final grade retrieval for non-existent student-course combinations.
- **Test Action:**
- Student: `"NonExistentStudent"`
- Course: `"NonExistentCourse"`
- **Expected Result:** Returns `-1` (no results found or no connection)
#### 7. StoreFinalResultTest
**Description:** Tests storing calculated final course results.
- **Test Action:**
- StudentCourse object
- Exam count: `3`
- Final grade: `75`
- **Expected Result:** Returns `false` if no connection, `true` if connected and successful

View File

@@ -1,43 +1,3 @@
# ExamResultGenerator (`assignments::one::exam_result_generator`)
## Overview
The `ExamResultGenerator` is the core node responsible for simulating exam result generation.
It maintains a queue of student-course combinations that need exam results, generates random
grades, and publishes them to the system.
#### Implementation Details
**Constructor**
```cpp
ExamResultGenerator()
```
- Initializes ROS2 node with name `exam_result_generator`
- Sets up random number generation infrastructure
- Creates DatabaseManager instance with node logger
- Establishes ROS2 publishers, subscribers, and timers
- Loads initial pending combinations from database
**Core Functions**
**`void queue_pending_combinations()`**
- Gets all student-course combinations needing exam results
- Populates operations queue from database
- Called at initialization and when database state changes
**`void generate_random_result()`**
- Main exam result generation executed by timer
- Selects random student-course combination from queue
- Stores result in database and publishes to ROS2 topic
**`void student_management_callback(const g2_2025_interfaces::msg::Student::SharedPtr msg)`**
- Toggles combinations in/out of processing queue
- Updates database with new enrollments
**`void add_student_course_combination(const StudentCourse& sc)`**
- Enrolls student into course via database
- Adds combination to processing queue
---
## Unit Tests

View File

@@ -1,47 +1,3 @@
# FinalGradeDeterminator (`assignments::one::final_grade_determinator`)
## Overview
The `FinalGradeDeterminator` node collects exam results for student-course combinations, triggers grade calculation when enough results are gathered, and stores final grades in the database. It interacts with ROS2 publishers, subscribers, and service clients to manage the grading workflow.
#### Implementation Details
**Parameters**
- **`grade_collection_amount`** (int, default: 5): Number of exam results required before triggering grade calculation for a student-course combination.
**Constructor**
```cpp
FinalGradeDeterminator()
```
- Initializes ROS2 node with name `final_grade_determinator`
- Declares and retrieves `grade_collection_amount` parameter
- Sets up `DatabaseManager`
- Creates publisher for student course management
- Subscribes to exam results topic
- Initializes service client for grade calculation
**Core Functions**
**`void exam_results_callback(const g2_2025_interfaces::msg::Exam::SharedPtr msg)`**
- Updates internal map with received exam result for student-course combo
- Checks if enough results have been collected
- Triggers grade calculation request when threshold is met
**`void grade_calculator_request(StudentCourse combo)`**
- Waits for grade calculator service to be available
- Sends async request with collected exam grades for the student-course combination
- Uses callback to handle service response
**`void grade_calculator_response(rclcpp::Client<g2_2025_interfaces::srv::Exams>::SharedFuture future, StudentCourse studentCourseCombo)`**
- Verifies database connection
- Publishes final student message to ROS2 topic
- Logs final grade information
- Stores final course result in database
---
## Unit Tests
Unit tests for `FinalGradeDeterminator` are implemented in `src/g2_2025_grade_calculator_pkg/test/FinalGradeDeterminator.test.cpp` using Google Test and ROS2 test utilities. The tests use a mock database manager and a mock grade calculator service to simulate the node's interactions.

View File

@@ -1,31 +1,3 @@
# GradeCalculator (`assignments::one::grade_calculator::GradeCalculator`)
## Overview
The `GradeCalculator` node provides a ROS2 service for calculating student exam grades. It processes exam scores, applies custom logic for specific student names, and ensures grade results are within valid bounds.
#### Implementation Details
**Constructor**
```cpp
GradeCalculator()
```
- Initializes ROS2 node with name `grade_calculator`
- Creates a ROS2 service server for `grade_calculator_service`
- Binds the service callback to handle grade calculation requests
- Logs service startup
**Core Functions**
**`void grade_calculator_callback(const Exams::Request::SharedPtr request, const Exams::Response::SharedPtr response)`**
- Checks if exam grades are provided
- Calculates the total and average of exam grades
- Converts student name to lowercase for comparison
- Adds a bonus of 10 points if the student name is "wessel"
- Ensures the final grade is clamped between 10 and 100
- Sends the calculated grade back through the service response
---
## Unit Tests
Unit tests for `GradeCalculator` are implemented in `src/g2_2025_grade_calculator_pkg/test/GradeCalculator.test.cpp` using Google Test and ROS2 test utilities. The tests use a client to call the grade calculation service and verify the results.

View File

@@ -0,0 +1,147 @@
# TI Minor Grade Generator Design Document
## Project Overview
The TI Minor Grade Generator is a distributed ROS2-based system designed to manage student exam results and calculate final course grades. The system follows microservices architecture principles with clear separation of concerns and robust data management.
## System Architecture
### High-Level Architecture
The system consists of multiple ROS2 nodes that communicate through standardized topics and services to process exam data, calculate grades, and persist results. The architecture ensures scalability, maintainability, and fault tolerance.
### Key Design Principles
- **Microservices Architecture**: Each component has a single responsibility
- **Asynchronous Communication**: Uses ROS2 topics and services for loose coupling
- **Data Persistence**: Centralized database management for reliable storage
- **Configurable Parameters**: TOML-based configuration for environment flexibility
- **Comprehensive Testing**: Unit and integration tests ensure reliability
## System Components
### Core Nodes
#### 1. FinalGradeDeterminator Node
**Namespace**: `assignments::one::final_grade_determinator`
**Brief Description**: Collects exam results, triggers grade calculation when thresholds are met, and stores final grades.
**Key Features**: Configurable collection thresholds, automatic grade calculation triggering, database persistence
*For detailed documentation, see: [FinalGradeDeterminator.md](nodes/FinalGradeDeterminator.md)*
#### 2. GradeCalculator Node
**Namespace**: `assignments::one::grade_calculator`
**Brief Description**: Provides grade calculation service with business logic including bonus points and grade validation.
**Key Features**: Average calculation, special student rules, grade bounds validation (10-100)
*For detailed documentation, see: [GradeCalculator.md](nodes/GradeCalculator.md)*
#### 3. ExamResultGenerator Node
**Namespace**: `assignments::one::exam_result_generator`
**Brief Description**: Simulates exam result generation by maintaining a queue of student-course combinations and publishing random grades.
**Key Features**: Database-driven queue management, random grade generation, student enrollment handling
*For detailed documentation, see: [ExamResultGenerator.md](nodes/ExamResultGenerator.md)*
#### 4. RetakeScheduler Node
**Namespace**: `assignments::one::retake_scheduler`
**Brief Description**: Manages retake exam scheduling and coordination for students who need to retake exams.
**Key Features**: Retake request processing, schedule management, action server implementation for retake workflows
*For detailed documentation, see: [RetakeScheduler.md](nodes/RetakeScheduler.md)*
#### 5. RetakeGradeDeterminator Node
**Namespace**: `assignments::one::retake_grade_determinator`
**Brief Description**: Handles grade calculation and processing specifically for retake exams.
**Key Features**: Retake-specific grade processing, integration with main grade system, retake result validation
*For detailed documentation, see: [RetakeGradeDeterminator.md](nodes/RetakeGradeDeterminator.md)*
### Data Management
#### DatabaseManager
**Brief Description**: PostgreSQL database interface handling connections, table management, and data persistence.
**Key Features**: Connection management, automatic table creation, student enrollment tracking, exam result storage
*For detailed documentation, see: [DatabaseManager.md](../DatabaseManager.md)*
#### ConfigManager
**Brief Description**: TOML-based configuration management system allowing runtime configuration without recompilation.
**Key Features**: Automatic config file discovery, type-safe TOML parsing, database connection configuration
*For detailed documentation, see: [ConfigManager.md](../ConfigManager.md)*
### Communication Interfaces
#### ROS2 Message and Service Interfaces
**Brief Description**: Custom message types and service definitions for inter-node communication.
**Key Components**: Exam and Student message types, Grade calculation service, Retake action interface, standardized timestamps
*For detailed documentation, see: [interfaces.md](interfaces/interfaces.md)*
## System Workflow
### 1. Exam Result Processing
1. **Input**: Exam results are published to the `exam_results` topic
2. **Collection**: FinalGradeDeterminator receives and stores exam results by student-course combination
3. **Monitoring**: System tracks the number of results per student-course pair
4. **Threshold Check**: When `grade_collection_amount` results are collected, proceed to calculation
### 2. Grade Calculation Process
1. **Service Request**: FinalGradeDeterminator calls GradeCalculator service
2. **Calculation**: GradeCalculator computes final grade using business logic
3. **Validation**: Result is validated and clamped to acceptable range
4. **Response**: Calculated grade is returned to FinalGradeDeterminator
### 3. Result Management
1. **Database Storage**: Final grade is persisted in the database
2. **Publication**: Student information is published to management topic
3. **Logging**: Process completion is logged for audit purposes
### 4. Retake Processing Workflow
1. **Retake Request**: RetakeScheduler receives retake requests via action interface
2. **Schedule Management**: System schedules retake exams and manages timelines
3. **Retake Execution**: Student completes retake exam, results are processed
4. **Grade Processing**: RetakeGradeDeterminator calculates retake grades with specialized logic
5. **Integration**: Retake results are integrated with main grade system and database
## Configuration Management
### TOML Configuration Structure
The system uses TOML files for environment-specific configuration:
```toml
[database]
host = "localhost"
port = 5432
name = "grade_db"
user = "grade_user"
password = "secure_password"
[grade_calculation]
collection_amount = 5
min_grade = 10
max_grade = 100
[logging]
level = "INFO"
output_file = "grade_system.log"
```

View File

@@ -0,0 +1,170 @@
# ROS2 Interface Definitions - g2_2025_interfaces
## Package Overview
This document describes the custom ROS2 interface definitions in the `g2_2025_interfaces` package. These interfaces provide standardized communication protocols for the TI Minor Grade Generator system.
**Package Name**: `g2_2025_interfaces`
**Interface Types**: Messages, Services, Actions
**Location**: `src/g2_2025_interfaces/`
## Message Types (.msg)
### Exam.msg
Represents examination result data exchanged between system components.
```
string student_name
string course_name
int32 result
builtin_interfaces/Time timestamp
```
**Field Descriptions**:
- `student_name`: Name identifier for the student
- `course_name`: Course identifier for the examination
- `result`: Numerical exam result/grade (integer value)
- `timestamp`: Timestamp of the message
**Usage**: Primary message type for exam result communication between ExamResultGenerator and grade processing nodes.
### Student.msg
Represents student information and course enrollment data.
```
string student_name
string course_name
builtin_interfaces/Time timestamp
```
**Field Descriptions**:
- `student_name`: Name identifier for the student
- `course_name`: Course identifier for enrollment/management
- `timestamp`: Timestamp of the message
**Usage**: Used for student-course management operations and enrollment tracking.
## Service Definitions (.srv)
### Exams.srv
Service interface for grade calculation operations using multiple exam results.
#### Request
```
string student_name
string course_name
int32[] exam_grades
```
#### Response
```
int32 result # Final calculated result
```
**Request Fields**:
- `student_name`: Student identifier for grade calculation
- `course_name`: Course identifier for context
- `exam_grades`: Array of exam grades to be processed
**Response Fields**:
- `result`: Final calculated grade result (integer value)
**Usage**: Main service interface used by GradeCalculator node for processing multiple exam grades into final results.
## Action Definitions (.action)
### Retake.action
Action interface for managing retake exam scheduling and processing workflows.
#### Goal
```
string student_name
string course_name
```
#### Result
```
# Empty result section - completion indicates success
```
#### Feedback
```
float32 result
```
**Goal Fields**:
- `student_name`: Student for which a retake is requested
- `course_name`: Course for which a retake is requested
**Feedback Fields**:
- `result`: Progress indicator or intermediate result (float value)
**Usage**: Used by RetakeScheduler node to handle long-running retake management operations with progress feedback.
## Node Interface Usage
### ExamResultGenerator Node
**Publishers**:
- **Topic**: `exam_results`
- **Message Type**: `g2_2025_interfaces::msg::Exam`
- **Purpose**: Publishes generated exam results to downstream processing nodes
- **Rate**: Configurable interval (default: 2 seconds)
**Subscribers**:
- **Topic**: `student_course_management`
- **Message Type**: `g2_2025_interfaces::msg::Student`
- **Purpose**: Receives student-course enrollment updates for exam generation queue
### FinalGradeDeterminator Node
**Subscribers**:
- **Topic**: `exam_results`
- **Message Type**: `g2_2025_interfaces::msg::Exam`
- **Purpose**: Collects exam results for grade calculation processing
**Service Clients**:
- **Service**: `calculate_grade`
- **Service Type**: `g2_2025_interfaces::srv::Exams`
- **Purpose**: Requests grade calculation from GradeCalculator when threshold is met
**Publishers**:
- **Topic**: `student_course_management`
- **Message Type**: `g2_2025_interfaces::msg::Student`
- **Purpose**: Communicate end of enrollment or re-enrolment
### GradeCalculator Node
**Service Servers**:
- **Service**: `calculate_grade`
- **Service Type**: `g2_2025_interfaces::srv::Exams`
- **Purpose**: Provides grade calculation services for multiple exam grades
- **Processing**: Applies business logic (averaging, bonus points, validation)
### RetakeScheduler Node
**Action Servers**:
- **Action**: `retake_request`
- **Action Type**: `g2_2025_interfaces::action::Retake`
- **Purpose**: Handles long-running retake scheduling operations
- **Feedback**: Provides progress updates during scheduling process
### RetakeGradeDeterminator Node
**Service Clients**:
- **Service**: `calculate_grade`
- **Service Type**: `g2_2025_interfaces::srv::Exams`
- **Purpose**: Requests specialized retake grade calculations
**Subscribers**:
- **Topic**: `retake_results`
- **Message Type**: `g2_2025_interfaces::msg::Exam`
- **Purpose**: Processes completed retake exam results
## Related Documentation
- [System Architecture](../Orig.md): Overall system design and communication patterns

View File

@@ -0,0 +1,43 @@
# ExamResultGenerator (`assignments::one::exam_result_generator`)
## Overview
The `ExamResultGenerator` is the core node responsible for simulating exam result generation.
It maintains a queue of student-course combinations that need exam results, generates random
grades, and publishes them to the system.
#### Implementation Details
**Parameters**
- **`delay_between_grades_ms`** (int, default: 2000): Delay (in milliseconds) between generated grades.
**Constructor**
```cpp
ExamResultGenerator()
```
- Initializes ROS2 node with name `exam_result_generator`
- Sets up random number generation infrastructure
- Creates DatabaseManager instance with node logger
- Establishes ROS2 publishers, subscribers, and timers
- Loads initial pending combinations from database
**Core Functions**
**`void queue_pending_combinations()`**
- Gets all student-course combinations needing exam results
- Populates operations queue from database
- Called at initialization and when database state changes
**`void generate_random_result()`**
- Main exam result generation executed by timer
- Selects random student-course combination from queue
- Stores result in database and publishes to ROS2 topic
**`void student_management_callback(const g2_2025_interfaces::msg::Student::SharedPtr msg)`**
- Toggles combinations in/out of processing queue
- Updates database with new enrollments
**`void add_student_course_combination(const StudentCourse& sc)`**
- Enrolls student into course via database
- Adds combination to processing queue

View File

@@ -0,0 +1,42 @@
# FinalGradeDeterminator (`assignments::one::final_grade_determinator`)
## Overview
The `FinalGradeDeterminator` node collects exam results for student-course combinations, triggers grade calculation when enough results are gathered, and stores final grades in the database. It interacts with ROS2 publishers, subscribers, and service clients to manage the grading workflow.
#### Implementation Details
**Parameters**
- **`grade_collection_amount`** (int, default: 5): Number of exam results required before triggering grade calculation for a student-course combination.
**Constructor**
```cpp
FinalGradeDeterminator()
```
- Initializes ROS2 node with name `final_grade_determinator`
- Declares and retrieves `grade_collection_amount` parameter
- Sets up `DatabaseManager`
- Creates publisher for student course management
- Subscribes to exam results topic
- Initializes service client for grade calculation
**Core Functions**
**`void exam_results_callback(const g2_2025_interfaces::msg::Exam::SharedPtr msg)`**
- Updates internal map with received exam result for student-course combo
- Checks if enough results have been collected
- Triggers grade calculation request when threshold is met
**`void grade_calculator_request(StudentCourse combo)`**
- Waits for grade calculator service to be available
- Sends async request with collected exam grades for the student-course combination
- Uses callback to handle service response
**`void grade_calculator_response(rclcpp::Client<g2_2025_interfaces::srv::Exams>::SharedFuture future, StudentCourse studentCourseCombo)`**
- Verifies database connection
- Publishes final student message to ROS2 topic
- Logs final grade information
- Stores final course result in database

View File

@@ -0,0 +1,25 @@
# GradeCalculator (`assignments::one::grade_calculator::GradeCalculator`)
## Overview
The `GradeCalculator` node provides a ROS2 service for calculating student exam grades. It processes exam scores, applies custom logic for specific student names, and ensures grade results are within valid bounds.
#### Implementation Details
**Constructor**
```cpp
GradeCalculator()
```
- Initializes ROS2 node with name `grade_calculator`
- Creates a ROS2 service server for `grade_calculator_service`
- Binds the service callback to handle grade calculation requests
- Logs service startup
**Core Functions**
**`void grade_calculator_callback(const Exams::Request::SharedPtr request, const Exams::Response::SharedPtr response)`**
- Checks if exam grades are provided
- Calculates the total and average of exam grades
- Converts student name to lowercase for comparison
- Adds a bonus of 10 points if the student name is "wessel"
- Ensures the final grade is clamped between 10 and 100
- Sends the calculated grade back through the service response

View File

@@ -0,0 +1,38 @@
## Installation
### Prerequisites
- ROS2 Jazzy or newer installed ([ROS2 Installation Guide](https://docs.ros.org/en/jazzy/Installation.html))
- CMake (version 3.8+)
- Python 3.8+
- libtomlplusplus-dev
- libpqxx-dev
- Colcon build tool
- Docker compose
### Clone the Repository
```bash
git clone https://git.wessel.gg/inholland/ros2-assignments.git
cd ros2-assignments
```
### Build the Workspace
```bash
colcon build
```
Any parameters can be changed before building by editing the `grade_calculator.launch.xml` in the launch folder
### Source the Workspace
```bash
source install/setup.bash
```
### Run the System
```bash
sudo docker-compose up
ros2 launch g2_2025_grade_calculator_pkg grade_calculator.launch.xml
```

View File

@@ -1,16 +0,0 @@
# Interface Overview
**Publishers**
- Topic: `exam_results`
- Message Type: `g2_2025_interfaces::msg::Exam`
- Publishes generated exam results to downstream nodes
**Subscribers**
- Topic: `student_course_management`
- Message Type: `g2_2025_interfaces::msg::Student`
- Handles requests to add/remove student-course combinations
**Timers**
- Interval: 2 seconds
- Function: `generate_random_result()`
- Generates and publishes exam results at regular intervals