mirror of
https://github.com/azaion/gps-denied-desktop.git
synced 2026-04-23 02:36:36 +00:00
initial structure implemented
docs -> _docs
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user