initial structure implemented

docs -> _docs
This commit is contained in:
Oleksandr Bezdieniezhnykh
2025-12-01 14:20:56 +02:00
parent 9134c5db06
commit abc26d5c20
360 changed files with 3881 additions and 101 deletions
@@ -0,0 +1,61 @@
# Feature: System Configuration
## Description
Handles loading, validation, and runtime management of system-wide configuration including camera parameters, operational area bounds, model paths, database connections, and API endpoints.
## Component APIs Implemented
- `load_config(config_path: str) -> SystemConfig`
- `validate_config(config: SystemConfig) -> ValidationResult`
- `get_camera_params(camera_id: Optional[str] = None) -> CameraParameters`
- `update_config(section: str, key: str, value: Any) -> bool`
## External Tools and Services
- **PyYAML**: Configuration file parsing (YAML format)
- **pydantic**: Data model validation and serialization
- **os/pathlib**: File system operations for config file access
## Internal Methods
| Method | Purpose |
|--------|---------|
| `_parse_yaml_file` | Reads and parses YAML configuration file |
| `_apply_defaults` | Applies default values for missing configuration keys |
| `_validate_camera_params` | Validates camera parameters are within sensible bounds |
| `_validate_paths` | Checks that configured paths exist |
| `_validate_operational_area` | Validates operational area bounds are valid coordinates |
| `_build_camera_matrix` | Constructs camera intrinsic matrix from parameters |
| `_get_cached_config` | Returns cached configuration to avoid repeated file reads |
## Unit Tests
| Test Case | Description |
|-----------|-------------|
| `test_load_config_valid_yaml` | Load valid YAML config file, verify SystemConfig returned |
| `test_load_config_missing_file_uses_defaults` | Missing config file returns default configuration |
| `test_load_config_invalid_yaml_raises_error` | Malformed YAML raises appropriate error |
| `test_load_config_partial_uses_defaults` | Partial config merges with defaults |
| `test_validate_config_valid` | Valid configuration passes validation |
| `test_validate_config_invalid_focal_length` | Focal length <= 0 fails validation |
| `test_validate_config_invalid_sensor_size` | Sensor dimensions <= 0 fails validation |
| `test_validate_config_invalid_resolution` | Resolution <= 0 fails validation |
| `test_validate_config_invalid_operational_area` | Invalid lat/lon bounds fail validation |
| `test_validate_config_missing_paths` | Non-existent paths fail validation |
| `test_get_camera_params_default` | Get default camera returns valid parameters |
| `test_get_camera_params_specific_camera` | Get specific camera ID returns correct parameters |
| `test_get_camera_params_unknown_camera` | Unknown camera ID raises error |
| `test_update_config_valid_key` | Update existing key succeeds |
| `test_update_config_invalid_section` | Update non-existent section fails |
| `test_update_config_invalid_key` | Update non-existent key fails |
| `test_update_config_type_mismatch` | Update with wrong value type fails |
## Integration Tests
| Test Case | Description |
|-----------|-------------|
| `test_load_and_validate_full_config` | Load config file, validate, verify all sections accessible |
| `test_config_persistence_after_update` | Update config at runtime, verify changes persist in memory |
| `test_camera_params_consistency` | Camera params from get_camera_params match loaded config |
@@ -0,0 +1,50 @@
# Feature: Flight Configuration
## Description
Manages flight-specific configuration including operational altitude, frame spacing, and camera parameters per flight. Provides persistence and retrieval of flight configurations created during flight initialization.
## Component APIs Implemented
- `get_flight_config(flight_id: str) -> FlightConfig`
- `save_flight_config(flight_id: str, config: FlightConfig) -> bool`
- `get_operational_altitude(flight_id: str) -> float`
- `get_frame_spacing(flight_id: str) -> float`
## External Tools and Services
- **F03 Flight Database**: Persistence layer for flight-specific configuration storage
## Internal Methods
| Method | Purpose |
|--------|---------|
| `_build_flight_config` | Constructs FlightConfig from stored data |
| `_validate_flight_config` | Validates FlightConfig before persistence |
| `_cache_flight_config` | Caches flight config in memory for fast retrieval |
| `_invalidate_cache` | Clears cached flight config when updated |
## Unit Tests
| Test Case | Description |
|-----------|-------------|
| `test_get_flight_config_existing` | Get config for existing flight returns FlightConfig |
| `test_get_flight_config_nonexistent` | Get config for non-existent flight raises error |
| `test_save_flight_config_valid` | Save valid FlightConfig returns True |
| `test_save_flight_config_invalid_flight_id` | Save with empty flight_id fails |
| `test_save_flight_config_invalid_config` | Save with invalid config data fails |
| `test_get_operational_altitude_existing` | Get altitude for existing flight returns value |
| `test_get_operational_altitude_nonexistent` | Get altitude for non-existent flight raises error |
| `test_get_operational_altitude_range` | Verify altitude within expected range (100-500m) |
| `test_get_frame_spacing_existing` | Get frame spacing returns expected distance |
| `test_get_frame_spacing_default` | Frame spacing returns reasonable default (~100m) |
## Integration Tests
| Test Case | Description |
|-----------|-------------|
| `test_save_and_retrieve_flight_config` | Save flight config via save_flight_config, retrieve via get_flight_config, verify data matches |
| `test_flight_config_persists_to_database` | Save flight config, verify stored in F03 Flight Database |
| `test_altitude_and_spacing_consistency` | Flight config altitude matches get_operational_altitude result |
| `test_multiple_flights_isolation` | Multiple flights have independent configurations |
@@ -0,0 +1,283 @@
# Configuration Manager
## Interface Definition
**Interface Name**: `IConfigurationManager`
### Interface Methods
```python
class IConfigurationManager(ABC):
@abstractmethod
def load_config(self, config_path: str) -> SystemConfig:
pass
@abstractmethod
def get_camera_params(self, camera_id: Optional[str] = None) -> CameraParameters:
pass
@abstractmethod
def validate_config(self, config: SystemConfig) -> ValidationResult:
pass
@abstractmethod
def get_flight_config(self, flight_id: str) -> FlightConfig:
pass
@abstractmethod
def update_config(self, section: str, key: str, value: Any) -> bool:
pass
@abstractmethod
def get_operational_altitude(self, flight_id: str) -> float:
"""Returns predefined operational altitude for the flight (NOT from EXIF)."""
pass
@abstractmethod
def get_frame_spacing(self, flight_id: str) -> float:
"""Returns expected distance between consecutive frames in meters."""
pass
@abstractmethod
def save_flight_config(self, flight_id: str, config: FlightConfig) -> bool:
"""Persists flight-specific configuration."""
pass
```
## Component Description
### Responsibilities
- Load system configuration from files/environment
- Provide camera parameters (focal length, sensor size, resolution)
- Manage flight-specific configurations
- Validate configuration integrity
- Support configuration updates at runtime
### Scope
- System-wide configuration
- Camera parameter management
- Operational area bounds
- Model paths and settings
- Database connections
- API endpoints
## API Methods
### `load_config(config_path: str) -> SystemConfig`
**Description**: Loads system configuration.
**Called By**: System startup
**Input**: `config_path: str` - Path to config file (YAML/JSON)
**Output**: `SystemConfig` - Complete configuration
**Test Cases**:
1. Load valid config → succeeds
2. Missing file → uses defaults
3. Invalid config → raises error
---
### `get_camera_params(camera_id: Optional[str] = None) -> CameraParameters`
**Description**: Gets camera parameters.
**Called By**: All processing components
**Output**:
```python
CameraParameters:
focal_length: float
sensor_width: float
sensor_height: float
resolution_width: int
resolution_height: int
principal_point: Tuple[float, float]
distortion_coefficients: List[float]
```
**Test Cases**:
1. Get default camera → returns params
2. Get specific camera → returns params
---
### `validate_config(config: SystemConfig) -> ValidationResult`
**Description**: Validates configuration.
**Called By**: After load_config
**Validation Rules**:
- Camera parameters sensible
- Paths exist
- Operational area valid
- Database connection string valid
**Test Cases**:
1. Valid config → passes
2. Invalid focal length → fails
---
### `get_flight_config(flight_id: str) -> FlightConfig`
**Description**: Gets flight-specific configuration.
**Called By**: F02.1 Flight Lifecycle Manager
**Output**:
```python
FlightConfig:
camera_params: CameraParameters
altitude: float
operational_area: OperationalArea
```
**Test Cases**:
1. Get flight config → returns params
---
### `update_config(section: str, key: str, value: Any) -> bool`
**Description**: Updates config at runtime.
**Called By**: Admin tools
**Test Cases**:
1. Update value → succeeds
2. Invalid key → fails
---
### `get_operational_altitude(flight_id: str) -> float`
**Description**: Returns predefined operational altitude for the flight in meters. This is the altitude provided during flight creation, NOT extracted from EXIF metadata (images don't have GPS/altitude metadata per problem constraints).
**Called By**:
- F10 Factor Graph Optimizer (for scale resolution)
- H02 GSD Calculator (for GSD computation)
- F09 Metric Refinement (for alignment)
**Input**: `flight_id: str`
**Output**: `float` - Altitude in meters (typically 100-500m)
**Test Cases**:
1. Get existing flight altitude → returns value
2. Non-existent flight → raises error
---
### `get_frame_spacing(flight_id: str) -> float`
**Description**: Returns expected distance between consecutive frames in meters. Used for scale estimation in visual odometry.
**Called By**:
- F10 Factor Graph Optimizer (for expected displacement calculation)
**Input**: `flight_id: str`
**Output**: `float` - Expected frame spacing in meters (typically ~100m)
**Test Cases**:
1. Get frame spacing → returns expected distance
---
### `save_flight_config(flight_id: str, config: FlightConfig) -> bool`
**Description**: Persists flight-specific configuration when a flight is created.
**Called By**:
- F02.1 Flight Lifecycle Manager (during flight creation)
**Input**:
```python
flight_id: str
config: FlightConfig
```
**Output**: `bool` - True if saved successfully
**Test Cases**:
1. Save valid config → succeeds
2. Invalid flight_id → fails
## Data Models
### SystemConfig
```python
class SystemConfig(BaseModel):
camera: CameraParameters
operational_area: OperationalArea
models: ModelPaths
database: DatabaseConfig
api: APIConfig
```
### CameraParameters
```python
class CameraParameters(BaseModel):
focal_length: float # mm
sensor_width: float # mm
sensor_height: float # mm
resolution_width: int
resolution_height: int
principal_point: Tuple[float, float]
distortion_coefficients: List[float]
```
### OperationalArea
```python
class OperationalArea(BaseModel):
name: str = "Eastern Ukraine"
min_lat: float = 45.0
max_lat: float = 52.0
min_lon: float = 22.0
max_lon: float = 40.0
```
### RecoveryConfig
```python
class RecoveryConfig(BaseModel):
"""Configuration for failure recovery and progressive search."""
search_grid_sizes: List[int] = [1, 4, 9, 16, 25] # Progressive tile search grid
min_chunk_frames_for_matching: int = 5 # Minimum frames before chunk matching
max_chunk_frames_for_matching: int = 20 # Maximum frames per chunk
user_input_threshold_tiles: int = 25 # Request user input after this many tiles
chunk_matching_interval_seconds: float = 5.0 # Background matching interval
confidence_threshold_good: float = 0.7 # Confidence for good tracking
confidence_threshold_degraded: float = 0.5 # Confidence for degraded tracking
min_inlier_count_good: int = 50 # Inliers for good tracking
min_inlier_count_tracking: int = 20 # Minimum inliers before tracking loss
```
### RotationConfig
```python
class RotationConfig(BaseModel):
"""Configuration for image rotation and heading tracking."""
rotation_step_degrees: float = 30.0 # Degrees per rotation step
litesam_max_rotation_tolerance: float = 45.0 # Max rotation LiteSAM handles
sharp_turn_threshold_degrees: float = 45.0 # Threshold for sharp turn detection
heading_history_size: int = 10 # Number of headings to track
confidence_threshold: float = 0.7 # For accepting rotation match
@property
def rotation_iterations(self) -> int:
"""Number of rotation steps (360 / step_degrees)."""
return int(360 / self.rotation_step_degrees)
```
## Dependencies
### Internal Components
- **F03 Flight Database**: For flight-specific configuration persistence (save_flight_config stores to F03)
### External Dependencies
- **pydantic**: Data model validation
- **PyYAML**: Configuration file parsing