fix(launch): Added parameter

This commit is contained in:
2025-10-08 18:40:05 +02:00
parent 161b5084fc
commit 6ccbc95b15
8 changed files with 3 additions and 149 deletions

View File

@@ -0,0 +1,133 @@
# ConfigManager (`assignments::one::ConfigManager`)
## Overview
The `ConfigManager` class is used to be able to store configuration values in a `TOML` file making it
possible to change project settings without the need of recompiling the codebase.
The [`toml++`](https://marzer.github.io/tomlplusplus/) library is used to parse TOML configuration
files and provides type-safe access to configuration parameters. It is automatically installed
using the `FetchContent_Declare` macro inside of the `CMakeLists.txt`.
## Implementation Details
### Dependencies
- **toml++**: Modern header-only C++17 TOML parser and serializer
- **rclcpp**: ROS2 C++ client library for logging
- **filesystem**: C++17 filesystem library for file operations
- **DatabaseConfig**: Custom data structure for database configuration
### Key Components
#### Constructor
```cpp
ConfigManager(rclcpp::Logger logger)
```
- Initializes the configuration manager making use of a ROS2 logger
- Calls `find_config_file()` and `load_config()` for automatic setup
- Automatically attempts to locate and load configuration from a list of pre-defined paths.
#### Configuration Loading
**`bool load_config(const std::string& config_file_path)`**
> Returns `true` on successful load, `false` on failure
- Uses `toml::parse_file()`
- Loads TOML configuration from specified file path
- Validates file existence before attempting to parse
- Error handling for:
- File not found errors
- TOML parsing errors
- General I/O exceptions
- Updates internal `loaded_` state flag
**`std::string find_config_file() const`**
> Returns first found configuration file path
> Returns empty string if no configuration file is found
- Automatically searches for configuration files in predefined locations
- Search paths (in order):
```cpp
std::vector<std::string> default_config_paths_ = {
"config.toml",
"./src/config.toml",
"../config.toml",
"../../config.toml",
"../../../config.toml",
"../../../../config.toml",
"/etc/ros2_grade_calculator/config.toml"
};
```
#### Configuration Access
**`std::optional<DatabaseConfig> get_database_config() const`**
> Returns `std::optional<DatabaseConfig>` for safe null handling
> Returns `std::nullopt` if:
> - Configuration is not loaded
> - Database section is missing
> - Parsing fails due to invalid format
- Calls `parse_database_config()` for actual parsing
**`bool is_loaded() const`**
> Returns `true` if configuration has been successfully loaded and parsed
- Getter for configuration load status
- Used by other components to verify configuration availability
### Configuration Parsing
**`DatabaseConfig parse_database_config(const toml::table& config) const`**
- parser for database configuration section
- Extracts all database-related parameters with defaults
#### Default Values and Fallbacks
- **host**: `"localhost"` - Local database server
- **port**: `5432` - Standard PostgreSQL port
- **dbname**: `"grades"` - Application-specific database
- **user**: `"postgres"` - Default PostgreSQL user
- **password**: `"postgres"` - Default PostgreSQL password
- **timeout**: `30` seconds - connection timeout
- **ssl**: `false` - Disabled by default for development
- **min_connections**: `1` - Minimal connection pool
- **max_connections**: `10` - connection pool limit
### Logging
- Uses ROS2 logger with `[CFG]` prefix for configuration operations
- Includes file paths in log messages
### Usage Examples
#### Automatic Configuration Loading
```cpp
// ConfigManager automatically finds and loads configuration
ConfigManager config_manager(node->get_logger());
if (config_manager.is_loaded()) {
auto db_config = config_manager.get_database_config();
if (db_config.has_value()) {
// Use database configuration
DatabaseManager db_manager(db_config.value());
}
}
```
### Configuration File Format
Example complete TOML configuration:
```toml
# Database connection settings
[database]
host = "localhost"
port = 5432
dbname = "grades"
user = "postgres"
password = "postgres"
timeout = 30
ssl = false
[database.pool]
min_connections = 1
max_connections = 10
```

View File

@@ -0,0 +1,125 @@
# DatabaseManager (`assignments::one::DatabaseManager`)
## Overview
The `DatabaseManager` class is a PostgreSQL database interface for the ROS2 grade calculator.
It handles all database operations including connection management, table creation and data insertion.
## Implementation Details
### Dependencies
- **pqxx**: Modern C++ PostgreSQL library for database connectivity
- **rclcpp**: ROS2 C++ client library for logging
- **ConfigManager**: Configuration manager for database settings
### Key Components
#### Constructor
```cpp
DatabaseManager(rclcpp::Logger logger)
```
- Initializes the database manager with ROS2 logging
- Creates a ConfigManager instance for configuration handling
- Automatically calls `init_database()` to establish connection and setup
#### Connection Management
**`bool connect(const std::string& connection_string)`**
> Returns `true` on successful connection, `false` on failure
- Establishes connection to PostgreSQL database using connection information from the config TOML
- Connection string format: `"host=localhost port=5432 dbname=grades user=postgres password=postgres"`
**`bool is_connected() const`**
> Returns `true` if connection exists and is open
- Check for active database connection status
#### Database Initialization
**`void init_database()`**
- Database setup process
- Loads configuration from ConfigManager
- Establishes connection using configuration settings
- Creates necessary tables and inserts sample data
- Error handling for configuration and connection failures
**`void create_tables()`**
- Creates all required database tables using SQL queries from `SQLQueries.hpp`
- Tables created:
- `enrollments`: Student course enrollments
- `exam_results`: Individual exam scores
- `course_results`: Final course grades and statistics
- Uses transactions for atomic table creation
**`void insert_sample_data()`**
- Inserts predefined sample student data
### Data Operations
#### Student Course Management
**`std::vector<StudentCourse> queue_pending_combinations()`**
> Returns vector of StudentCourse objects for processing queue
- Gets all student-course combinations that need exam results generated
- Executes complex SQL query to find missing exam results
**`bool enroll_student_into_course(const StudentCourse& sc)`**
> Returns `true` on successful enrollment, `false` on failure
- Enrolls a student into a specific course
#### Exam Result Processing
**`bool store_exam_result(const std::string& student_name, const std::string& course_name, int grade)`**
- Stores individual exam results in the database
- Parameters:
- `student_name`: Name of the student
- `course_name`: Name of the course
- `grade`: Exam score (10-100)
**`bool store_final_course_result(const StudentCourse& sc, int exam_count, int final_grade)`**
- Stores calculated final course results
- Parameters:
- `sc`: StudentCourse object containing student and course names
- `exam_count`: Number of exams taken
- `final_grade`: Calculated final grade
- Used by grade calculation nodes for final result storage
#### Grade Retrieval
**`int get_final_course_grade(const StudentCourse& sc)`**
> Returns:
> - `> 0`: Valid final grade (rounded average)
> - `-1`: No exams taken or no results found
- Gets final calculated grade for a student-course combination
- Performs average calculation with proper rounding
- Used by nodes to check if final grading is complete
### Logging
- Uses ROS2 logger with `[DBS]` prefix for database operations
- Different log levels:
- `INFO`: Successful operations, connection status
- `ERROR`: SQL errors, connection failures, configuration issues
- `WARN`: Non-critical issues, missing configurations
### Usage Examples
#### Basic Database Setup
```cpp
// Create DatabaseManager with ROS2 logger
DatabaseManager db_manager(node->get_logger());
// Check connection status
if (db_manager.is_connected()) {
// Database ready for operations
bool success = db_manager.store_exam_result("Wessel", "ROS2", 85);
if (success) {
RCLCPP_INFO(logger, "Exam result stored successfully");
}
}
```