Vehicle Configuration Directory Selection Sub-Application Architecture
Overview
The Vehicle Configuration Directory Selection sub-application allows users to either create a new vehicle
configuration project or open an existing one. It manages the selection and creation of vehicle directories,
handles template selection, and downloads parameter documentation metadata corresponding to the flight
controller firmware version to the project directory.
The architecture follows a clean layered design with dependency injection, where the frontend components
depend on the VehicleProjectManager factory/container class, which provides a unified interface to all
backend services. This ensures loose coupling and better testability.
Requirements
Functional Requirements
- Directory Management
- Must allow creation of new vehicle configuration directories
- Must allow opening of existing vehicle configuration directories
- Must provide re-open functionality for recently used directories
- Must validate directory structure and required files
- Must handle directory permissions and access rights
- Template System
- Must provide a comprehensive template overview interface
- Must support multiple vehicle types (ArduCopter, ArduPlane, Rover, Heli, etc.)
- Must allow template selection based on vehicle characteristics
- Must copy template files to new vehicle directories
- Must preserve template structure and file organization
- Vehicle Template Selection
- Must display available templates with descriptions
- Must show template compatibility information
- Must provide visual representation of template contents
- Must allow filtering and searching of templates
- Must support template comparison features
- Parameter Documentation Management
- Must download parameter documentation metadata for FC firmware version
- Must store documentation files in the appropriate project directory
- Must handle offline operation when documentation is already available
- Must validate documentation file integrity
- Must support multiple documentation formats
- Project Configuration
- Must initialize project configuration files
- Must set up directory structure for parameter files
- Must create necessary subdirectories and organize files
- Must handle configuration file validation
- Must support project metadata management
- Recent Vehicle Directories History
- Must maintain a list of the 5 most recently opened vehicle directories
- Must display recent directories in reverse chronological order (most recent first)
- Must persist the history list across application sessions in settings.json
- Must update history when a vehicle directory is successfully opened
- Must preserve history entries for directories that become temporarily unavailable
- Must be permissive when storing paths (directories may become valid later)
- Must validate paths strictly when opening/using them (show error if invalid or missing)
- Must display history in a read-only combobox widget with full absolute paths
- Must allow selection from history via dropdown selection only (no text editing)
- Must show error message if selected directory no longer exists
- Must maintain history order when the same directory is opened again (promote to top)
- Must limit history to maximum of 5 entries (oldest removed when limit exceeded)
- Must normalize path separators according to the operating system (backslashes on Windows, forward slashes on Unix)
- Must provide graceful fallback if history is empty or corrupted
Non-Functional Requirements
- Usability
- Directory selection should be intuitive and user-friendly
- Template overview should provide clear visual guidance
- File operations should provide clear progress feedback
- Error messages should be actionable and informative
- Performance
- Directory operations should complete quickly
- Template copying should handle large file sets efficiently
- Documentation download should not block the user interface
- Memory usage should be optimized for large template collections
- Reliability
- Must handle incomplete or corrupted templates gracefully
- Must verify successful completion of all file operations
- Must provide rollback capability for failed operations
- Must maintain project integrity during all operations
- Compatibility
- Must support different operating system path conventions
- Must handle various file system limitations
- Must work with different permission systems
- Must support unicode file names and paths
Architecture
Architectural Pattern
The directory selection sub-application follows a Factory/Container Pattern with Dependency Injection:
- Frontend Layer: GUI components (
VehicleProjectOpenerWindow, VehicleProjectCreatorWindow, DirectorySelectionWidgets)
- Facade Layer:
VehicleProjectManager - provides unified interface to all backend services
- Backend Layer: Specialized services (
LocalFilesystem, project creators, openers, etc.)
This architecture ensures:
- Separation of Concerns: Each layer has distinct responsibilities
- Dependency Inversion: Frontend depends on abstractions, not concrete implementations
- Testability: Easy to mock dependencies for unit testing
- Maintainability: Changes to backend services don’t affect frontend code
GUI Frontend Components
Project Opener Window

- File:
frontend_tkinter_project_opener.py
- Purpose: Main interface for opening existing vehicle projects and launching new project creation
- Responsibilities:
- Present three main options: Create New, Open Existing, Re-open Last Used
- Handle user interactions and directory selection through callback patterns
- Launch VehicleProjectCreatorWindow for new project creation
- Delegate business logic to VehicleProjectManager
- Manage UI state and user feedback for project opening operations
- Dependencies: Depends only on VehicleProjectManager interface
Project Creator Window

- File:
frontend_tkinter_project_creator.py
- Purpose: Dedicated interface for creating new vehicle projects from templates
- Responsibilities:
- Present template selection and project configuration options
- Handle new project settings and customization dynamically based on flight controller connection state
- Coordinate template selection through TemplateOverviewWindow
- Delegate project creation to VehicleProjectManager
- Provide feedback on creation progress and results
- Dependencies: Depends only on VehicleProjectManager interface
Template Overview Window
- File:
frontend_tkinter_template_overview.py
- Purpose: Visual interface for template browsing and selection
- Responsibilities:
- Display available vehicle templates
- Show template details and compatibility information
- Handle template selection and preview
- Provide template comparison features
- Dependencies: Accesses templates through VehicleProjectManager interface
- File:
frontend_tkinter_directory_selection.py
- Purpose: Reusable directory and path selection widgets
- Responsibilities:
- Provide common directory selection functionality through DirectorySelectionWidgets
- Handle path entry and validation through PathEntryWidget
- Support callback-based directory selection for flexible integration
- Manage widget state and user interactions
- Dependencies: No direct VehicleProjectManager dependency; uses callback patterns
Business logic components
VehicleProjectManager (Facade/Factory)
- File:
data_model_vehicle_project.py
- Purpose: Unified interface and factory for all vehicle project operations
- Responsibilities:
- Coordinate between frontend and backend services
- Provide high-level operations for project creation and opening
- Manage project lifecycle and state transitions
- Abstract backend complexity from frontend components
- Implement factory pattern for creating project-related objects
Backend Components (accessed via VehicleProjectManager)
Project Creation Services
- File:
data_model_vehicle_project_creator.py
- Purpose: Handle creation of new vehicle projects from templates
- Responsibilities:
- Template copying and customization (with optional transformations in a single pass)
- Project directory initialization
- Optional one-time import of FC parameter values when
use_fc_params=True
- Configuration file setup
- Project metadata creation
- Access: Through VehicleProjectManager factory methods
When use_fc_params=True and FC parameters are available, LocalFilesystem.copy_template_files_to_new_vehicle_dir()
applies both blank_change_reason and FC value substitution in a single ParDict-based parse-modify-write
pass per .param file, before re_init loads the directory.
Project Opening Services
- File:
data_model_vehicle_project_opener.py
- Purpose: Handle opening and validation of existing vehicle projects
- Responsibilities:
- Project directory validation
- Configuration file loading
- Project state reconstruction
- Error handling for corrupted projects
- Access: Through VehicleProjectManager factory methods
Configuration Steps Backend
- File:
backend_filesystem_configuration_steps.py
- Purpose: Manage configuration step definitions and documentation
- Responsibilities:
- Load configuration step metadata
- Validate configuration file structure
- Handle configuration step documentation
- Manage step sequencing and dependencies
Vehicle Components Backend
- File:
backend_filesystem_vehicle_components.py
- Purpose: Handle vehicle component definitions and templates
- Responsibilities:
- Load and validate vehicle component schemas
- Manage component template libraries
- Handle component compatibility checking
- Support component customization
Data Flow
The data flow follows the layered architecture pattern with clear separation of concerns:
- Application Initialization
- Legacy settings migration:
ProgramSettings.migrate_settings_to_latest_version() runs once on startup
- VehicleProjectManager is instantiated with required backend services
- VehicleProjectOpenerWindow receives VehicleProjectManager instance via dependency injection
- Recent directories history loaded via
ProgramSettings.get_recent_vehicle_dirs()
- Templates are loaded through VehicleProjectManager
- UI components are initialized with project manager reference
- Project Selection Flow
- User interacts with VehicleProjectOpenerWindow main interface
- Three options presented: Create New, Open Existing, Re-open Last Used
- For new projects: VehicleProjectOpenerWindow launches VehicleProjectCreatorWindow
- For existing projects: callback functions handle directory selection through VehicleDirectorySelectionWidgets
- New Project Creation Flow
- VehicleProjectCreatorWindow instantiated with project_manager reference
- User optionally enables
use_fc_params
- VehicleProjectCreator creates the directory from template
- During the copy step, FC source values and/or blank-change-reason are applied in a single
ParDict-based pass so that re_init reads fully-initialized files with no further writes
- Frontend presents template selection and project configuration options
- User selects template through TemplateOverviewWindow integration
- Frontend delegates to
project_manager.create_new_vehicle_from_template()
- VehicleProjectManager coordinates with project creator services
- Project creation delegated to specialized creator services
- Success/failure feedback provided through manager interface
- Existing Project Opening Flow
- User interacts with VehicleProjectOpenerWindow
- Frontend presents project opening and re-opening options
- User selects existing directory through DirectorySelectionWidgets with callbacks
- Callback functions call
project_manager.open_vehicle_directory() or project_manager.open_last_vehicle_directory()
- VehicleProjectManager validates directory through opener services
- Project state is reconstructed and validated
- Error handling managed through consistent interface
- Architecture Benefits
- Frontend never directly accesses backend services
- All business logic centralized in VehicleProjectManager
- Easy to test with mock VehicleProjectManager
- Changes to backend services don’t affect frontend code
- Clean separation between project opening and project creation concerns
- Recent Directories History Flow
- On application startup,
ProgramSettings.get_recent_vehicle_dirs() loads history from settings.json; the history is passed through the manager
- History is passed to VehicleProjectOpenerWindow to populate the combobox widget
- User selects a directory from the combobox dropdown
- Frontend calls
project_manager.open_vehicle_directory(selected_dir)
- The
VehicleProjectManager (business logic) stores the path in the recent‑vehicle history
using LocalFilesystem/ProgramSettings abstractions; the frontend never touches
the persistence layer directly
- History is updated: selected directory moved/added to position [0], oldest removed if > 5 entries
- Updated history is persisted to settings.json
- History order maintained: most recent [0] to oldest [4]
Data Models and Storage
Recent Vehicle Directories History Storage
The recent vehicle directories are stored in the settings.json file in the user configuration directory:
Settings File Location:
- Windows:
%APPDATA%\.ardupilot_methodic_configurator\settings.json
- Linux/macOS:
~/.config/.ardupilot_methodic_configurator/settings.json
Data Structure in settings.json:
{
"Format version": 2,
"recent_vehicle_history": [
"C:\\Users\\username\\vehicles\\Quadcopter_Project_2026",
"C:\\Users\\username\\vehicles\\Hexacopter_Project",
"/mnt/projects/ArduPlane_Project",
"C:\\Users\\username\\Documents\\Old_Copter",
"/home/user/ardupilot/Test_Vehicle"
],
"directory_selection": {
"template_dir": "...",
"new_base_dir": "..."
},
"display_usage_popup": { ... },
"connection_history": [ ... ]
}
Data Schema:
- Field Name:
recent_vehicle_history
- Type: Array of strings
- Maximum Length: 5 entries
- Entry Format: Full absolute path with OS-appropriate separators
- Ordering: Index [0] = most recent, Index [4] = oldest
- Path Normalization: Backslashes on Windows, forward slashes on Unix-like systems
- Persistence: Updated on every successful directory open operation
- Migration Strategy:
- Legacy
vehicle_dir from directory_selection is migrated on first startup
- Permissive validation: paths failing strict validation are still migrated with warnings
- Template directories are excluded (detected via
_is_template_directory() check)
- Legacy setting is removed after migration to prevent repeated migration attempts
- Migration occurs once and only once per installation
- Migration: If key doesn’t exist, it’s initialized as empty array
[]
Backward Compatibility:
- On first use after upgrade, legacy
vehicle_dir in directory_selection is migrated to recent_vehicle_history
- Migration is permissive: invalid paths are migrated with warnings (may become valid later)
- Template directory paths are excluded from migration (not user selections)
- Legacy
vehicle_dir setting is always removed after migration attempt (prevents repeated migrations)
- Once migrated,
vehicle_dir is no longer used or written
- The
get_recently_used_dirs() method (invoked via the manager) returns recent_vehicle_history[0] as the last opened directory, or defaults if empty
Integration Points
The directory selection sub-application integrates with other components through the VehicleProjectManager interface:
- Main Application (
__main__.py): Creates VehicleProjectManager and launches VehicleProjectOpenerWindow
- Flight Controller Communication: VehicleProjectManager receives firmware information
- Component Editor: Receives project instance from VehicleProjectManager
- Parameter Editor: Gets configuration and documentation through VehicleProjectManager
- Template System: Accessed through VehicleProjectManager template methods
- File Operations: All file system access goes through VehicleProjectManager facade
Dependency Management
The architecture implements Dependency Inversion Principle:
Frontend (GUI) → VehicleProjectManager (Interface) → Backend Services
Dependencies Flow:
- Frontend depends on VehicleProjectManager interface (abstraction)
- VehicleProjectManager depends on backend service interfaces
- Backend services implement concrete functionality
- No direct dependencies between frontend and backend services
Benefits:
- Easy unit testing with mock VehicleProjectManager
- Backend services can be replaced without frontend changes
- Clear separation of concerns across layers
- Reduced coupling between components
Template Management
Template Structure
Templates are organized hierarchically by vehicle type:
vehicle_templates/
├── ArduCopter/
│ ├── X-Quadcopter/
│ ├── Y6-Hexacopter/
│ └── Traditional-Helicopter/
├── ArduPlane/
│ ├── Fixed-Wing/
│ └── VTOL/
└── Rover/
├── 4WD/
└── Boat/
Template Content
Each template contains:
- Parameter files (*.param) for configuration steps
- Vehicle component configuration (vehicle_components.json)
- Configuration step definitions
- Documentation and readme files
- Default parameter values
Error Handling Strategy
- Directory Access Errors: Provide clear guidance for permission issues
- Template Corruption: Validate templates and provide recovery options
- Network Errors: Handle documentation download failures gracefully
- File System Errors: Provide detailed error information and recovery steps
Testing Strategy
The layered architecture enables comprehensive testing at each level:
Unit Testing
- VehicleProjectManager: Test facade methods with mocked backend services
- Frontend Components: Test with mocked VehicleProjectManager interface
- Backend Services: Test in isolation with mocked dependencies
- Integration Points: Test VehicleProjectManager coordination logic
Test Fixtures and Mocking
mock_project_manager: Mock VehicleProjectManager for frontend tests
mock_local_filesystem: Mock backend services for manager tests
- Dependency injection enables easy test isolation
- Clear interfaces make mocking straightforward
Test Coverage Areas
- Directory validation through VehicleProjectManager interface
- Template operations via manager facade methods
- Error handling across architecture layers
- UI interactions with mocked manager dependencies
- File system operations through abstracted interfaces
Architecture Testing Benefits
- Isolation: Each layer tested independently
- Maintainability: Tests don’t break when backend implementation changes
- Clarity: Test focus matches architectural responsibilities
- Reliability: Mock interfaces provide consistent test behavior
Note: Acceptance tests for the Recent Vehicle Directories History feature are implemented in tests/acceptance_recent_vehicle_directories_history.py.
File Structure
# Frontend Layer (GUI)
frontend_tkinter_project_opener.py # Main vehicle project selection interface
frontend_tkinter_project_creator.py # Dedicated new project creation interface
frontend_tkinter_directory_selection.py # Reusable directory selection widgets with callback support
frontend_tkinter_template_overview.py # Template browsing and selection interface
# Facade/Factory Layer (Business Logic Coordination)
data_model_vehicle_project.py # VehicleProjectManager facade/factory
# Backend Services Layer (Specialized Operations)
data_model_vehicle_project_creator.py # New project creation services
data_model_vehicle_project_opener.py # Existing project opening services
backend_filesystem.py # File system operations
backend_filesystem_configuration_steps.py # Configuration step management
backend_filesystem_vehicle_components.py # Vehicle component handling
# Test Layer
tests/test_frontend_tkinter_project_opener.py # Project opener tests with mocked dependencies
tests/test_frontend_tkinter_project_creator.py # Project creator tests with mocked dependencies
tests/test_frontend_tkinter_directory_selection.py # Directory widgets tests
tests/test_frontend_tkinter_template_overview.py # Template overview tests
tests/acceptance_recent_vehicle_directories_history.py # Acceptance tests for recent directories history feature
Dependencies
External Dependencies
- Python Standard Library:
os and pathlib for path operations
shutil for directory copying
json for configuration file handling
tkinter for GUI components
- Third-party Libraries:
jsonschema for configuration validation
PIL (Pillow) for image handling in templates
Internal Architecture Dependencies
- Frontend Layer Dependencies:
data_model_vehicle_project.VehicleProjectManager (facade interface)
frontend_tkinter_base_window for GUI base classes
frontend_tkinter_directory_selection for reusable widgets
frontend_tkinter_template_overview for template selection
frontend_tkinter_scroll_frame for scrollable interfaces
- VehicleProjectManager Dependencies:
backend_filesystem.LocalFilesystem for file operations
data_model_vehicle_project_creator for project creation
data_model_vehicle_project_opener for project opening
- Data model classes for configuration management
- Backend Services Dependencies:
- Standard library modules for specific operations
- Configuration and schema validation libraries
- File system and network access modules
Dependency Injection Pattern
The architecture implements dependency injection where:
- Frontend receives VehicleProjectManager instance via constructor
- VehicleProjectManager receives backend services via constructor
- No direct frontend-to-backend dependencies
- Easy to substitute mock objects for testing
- Clear separation of concerns across layers
Architectural Benefits
Design Patterns Implemented
- Facade Pattern: VehicleProjectManager provides simplified interface to complex backend subsystems
- Factory Pattern: VehicleProjectManager creates and manages project-related objects
- Dependency Injection: Components receive dependencies via constructor parameters
- Layer Architecture: Clear separation between frontend, facade, and backend layers
Code Quality Improvements
- Loose Coupling: Frontend components don’t depend on specific backend implementations
- High Cohesion: Each component has a single, well-defined responsibility
- Testability: Easy to unit test with mocked dependencies
- Maintainability: Changes to one layer don’t cascade to other layers
- Extensibility: New backend services can be added without frontend changes
Development Benefits
- Parallel Development: Frontend and backend teams can work independently
- Easier Debugging: Clear component boundaries make issue isolation simpler
- Better Testing: Each layer can be tested in isolation with appropriate mocks
- Code Reuse: VehicleProjectManager can be used by multiple frontend components
- Consistent Interface: All vehicle project operations go through unified interface
Template System Features
Template Categories
- Vehicle Type Based: Organized by ArduPilot vehicle type
- Size Categories: Small, medium, large vehicle templates
- Application Specific: Racing, photography, mapping, etc.
- Hardware Specific: Specific flight controller or component combinations
Template Validation
- Schema validation for all template configuration files
- Parameter file syntax checking
- Dependency verification between configuration steps
- Compatibility checking with different firmware versions
Template Customization
- User can modify templates after copying
- Support for local template libraries
- Template versioning and update mechanisms
- Template sharing and import/export functionality
- Lazy loading of template metadata
- Efficient directory scanning algorithms
- Parallel file operations where safe
- Caching of frequently accessed templates
- Progress reporting for long operations