mirror of
https://github.com/azaion/gps-denied-onboard.git
synced 2026-04-22 07:16:38 +00:00
Remove UAV frame material documentation and update README with detailed project requirements. Refactor skills documentation to clarify modes of operation and enhance input specifications. Delete unused E2E test infrastructure template.
This commit is contained in:
+2
-1
@@ -3,10 +3,11 @@
|
|||||||
### BUILD (green-field or new features)
|
### BUILD (green-field or new features)
|
||||||
|
|
||||||
```
|
```
|
||||||
1. Create _docs/00_problem/ — describe what you're building
|
1. Create _docs/00_problem/ — describe what you're building, restrictions, acceptance criteria and samples of data system works with
|
||||||
- problem.md (required)
|
- problem.md (required)
|
||||||
- restrictions.md (required)
|
- restrictions.md (required)
|
||||||
- acceptance_criteria.md (required)
|
- acceptance_criteria.md (required)
|
||||||
|
- input_data (required)
|
||||||
- security_approach.md (optional)
|
- security_approach.md (optional)
|
||||||
|
|
||||||
2. /research — produces solution drafts in _docs/01_solution/
|
2. /research — produces solution drafts in _docs/01_solution/
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ name: decompose
|
|||||||
description: |
|
description: |
|
||||||
Decompose planned components into atomic implementable features with bootstrap structure plan.
|
Decompose planned components into atomic implementable features with bootstrap structure plan.
|
||||||
4-step workflow: bootstrap structure plan, feature decomposition, cross-component verification, and Jira task creation.
|
4-step workflow: bootstrap structure plan, feature decomposition, cross-component verification, and Jira task creation.
|
||||||
Supports project mode (_docs/ structure), single component mode, and standalone mode (@file.md).
|
Supports full decomposition (_docs/ structure) and single component mode.
|
||||||
Trigger phrases:
|
Trigger phrases:
|
||||||
- "decompose", "decompose features", "feature decomposition"
|
- "decompose", "decompose features", "feature decomposition"
|
||||||
- "task decomposition", "break down components"
|
- "task decomposition", "break down components"
|
||||||
@@ -27,7 +27,7 @@ Decompose planned components into atomic, implementable feature specs with a boo
|
|||||||
|
|
||||||
Determine the operating mode based on invocation before any other logic runs.
|
Determine the operating mode based on invocation before any other logic runs.
|
||||||
|
|
||||||
**Full project mode** (no explicit input file provided):
|
**Default** (no explicit input file provided):
|
||||||
- PLANS_DIR: `_docs/02_plans/`
|
- PLANS_DIR: `_docs/02_plans/`
|
||||||
- TASKS_DIR: `_docs/02_tasks/`
|
- TASKS_DIR: `_docs/02_tasks/`
|
||||||
- Reads from: `_docs/00_problem/`, `_docs/01_solution/`, PLANS_DIR
|
- Reads from: `_docs/00_problem/`, `_docs/01_solution/`, PLANS_DIR
|
||||||
@@ -36,36 +36,28 @@ Determine the operating mode based on invocation before any other logic runs.
|
|||||||
**Single component mode** (provided file is within `_docs/02_plans/` and inside a `components/` subdirectory):
|
**Single component mode** (provided file is within `_docs/02_plans/` and inside a `components/` subdirectory):
|
||||||
- PLANS_DIR: `_docs/02_plans/`
|
- PLANS_DIR: `_docs/02_plans/`
|
||||||
- TASKS_DIR: `_docs/02_tasks/`
|
- TASKS_DIR: `_docs/02_tasks/`
|
||||||
- Derive `<topic>`, component number, and component name from the file path
|
- Derive component number and component name from the file path
|
||||||
- Ask user for the parent Epic ID
|
- Ask user for the parent Epic ID
|
||||||
- Runs Step 2 (that component only) + Step 4 (Jira)
|
- Runs Step 2 (that component only) + Step 4 (Jira)
|
||||||
- Overwrites existing feature files in that component's TASKS_DIR subdirectory
|
- Overwrites existing feature files in that component's TASKS_DIR subdirectory
|
||||||
|
|
||||||
**Standalone mode** (explicit input file provided, not within `_docs/02_plans/`):
|
|
||||||
- INPUT_FILE: the provided file (treated as a component spec)
|
|
||||||
- Derive `<topic>` from the input filename (without extension)
|
|
||||||
- TASKS_DIR: `_standalone/<topic>/tasks/`
|
|
||||||
- Guardrails relaxed: only INPUT_FILE must exist and be non-empty
|
|
||||||
- Ask user for the parent Epic ID
|
|
||||||
- Runs Step 2 (that component only) + Step 4 (Jira)
|
|
||||||
|
|
||||||
Announce the detected mode and resolved paths to the user before proceeding.
|
Announce the detected mode and resolved paths to the user before proceeding.
|
||||||
|
|
||||||
## Input Specification
|
## Input Specification
|
||||||
|
|
||||||
### Required Files
|
### Required Files
|
||||||
|
|
||||||
**Full project mode:**
|
**Default:**
|
||||||
|
|
||||||
| File | Purpose |
|
| File | Purpose |
|
||||||
|------|---------|
|
|------|---------|
|
||||||
| `_docs/00_problem/problem.md` | Problem description and context |
|
| `_docs/00_problem/problem.md` | Problem description and context |
|
||||||
| `_docs/00_problem/restrictions.md` | Constraints and limitations (if available) |
|
| `_docs/00_problem/restrictions.md` | Constraints and limitations |
|
||||||
| `_docs/00_problem/acceptance_criteria.md` | Measurable acceptance criteria (if available) |
|
| `_docs/00_problem/acceptance_criteria.md` | Measurable acceptance criteria |
|
||||||
| `_docs/01_solution/solution.md` | Finalized solution |
|
| `_docs/01_solution/solution.md` | Finalized solution |
|
||||||
| `PLANS_DIR/<topic>/architecture.md` | Architecture from plan skill |
|
| `PLANS_DIR/architecture.md` | Architecture from plan skill |
|
||||||
| `PLANS_DIR/<topic>/system-flows.md` | System flows from plan skill |
|
| `PLANS_DIR/system-flows.md` | System flows from plan skill |
|
||||||
| `PLANS_DIR/<topic>/components/[##]_[name]/description.md` | Component specs from plan skill |
|
| `PLANS_DIR/components/[##]_[name]/description.md` | Component specs from plan skill |
|
||||||
|
|
||||||
**Single component mode:**
|
**Single component mode:**
|
||||||
|
|
||||||
@@ -74,34 +66,23 @@ Announce the detected mode and resolved paths to the user before proceeding.
|
|||||||
| The provided component `description.md` | Component spec to decompose |
|
| The provided component `description.md` | Component spec to decompose |
|
||||||
| Corresponding `tests.md` in the same directory (if available) | Test specs for context |
|
| Corresponding `tests.md` in the same directory (if available) | Test specs for context |
|
||||||
|
|
||||||
**Standalone mode:**
|
|
||||||
|
|
||||||
| File | Purpose |
|
|
||||||
|------|---------|
|
|
||||||
| INPUT_FILE (the provided file) | Component spec to decompose |
|
|
||||||
|
|
||||||
### Prerequisite Checks (BLOCKING)
|
### Prerequisite Checks (BLOCKING)
|
||||||
|
|
||||||
**Full project mode:**
|
**Default:**
|
||||||
1. At least one `<topic>/` directory exists under PLANS_DIR with `architecture.md` and `components/` — **STOP if missing**
|
1. PLANS_DIR contains `architecture.md` and `components/` — **STOP if missing**
|
||||||
2. If multiple topics exist, ask user which one to decompose
|
2. Create TASKS_DIR if it does not exist
|
||||||
3. Create TASKS_DIR if it does not exist
|
3. If TASKS_DIR already contains artifacts, ask user: **resume from last checkpoint or start fresh?**
|
||||||
4. If `TASKS_DIR/<topic>/` already exists, ask user: **resume from last checkpoint or start fresh?**
|
|
||||||
|
|
||||||
**Single component mode:**
|
**Single component mode:**
|
||||||
1. The provided component file exists and is non-empty — **STOP if missing**
|
1. The provided component file exists and is non-empty — **STOP if missing**
|
||||||
2. Create the component's subdirectory under TASKS_DIR if it does not exist
|
2. Create the component's subdirectory under TASKS_DIR if it does not exist
|
||||||
|
|
||||||
**Standalone mode:**
|
|
||||||
1. INPUT_FILE exists and is non-empty — **STOP if missing**
|
|
||||||
2. Create TASKS_DIR if it does not exist
|
|
||||||
|
|
||||||
## Artifact Management
|
## Artifact Management
|
||||||
|
|
||||||
### Directory Structure
|
### Directory Structure
|
||||||
|
|
||||||
```
|
```
|
||||||
TASKS_DIR/<topic>/
|
TASKS_DIR/
|
||||||
├── initial_structure.md (Step 1, full mode only)
|
├── initial_structure.md (Step 1, full mode only)
|
||||||
├── cross_dependencies.md (Step 3, full mode only)
|
├── cross_dependencies.md (Step 3, full mode only)
|
||||||
├── SUMMARY.md (final)
|
├── SUMMARY.md (final)
|
||||||
@@ -126,7 +107,7 @@ TASKS_DIR/<topic>/
|
|||||||
|
|
||||||
### Resumability
|
### Resumability
|
||||||
|
|
||||||
If `TASKS_DIR/<topic>/` already contains artifacts:
|
If TASKS_DIR already contains artifacts:
|
||||||
|
|
||||||
1. List existing files and match them to the save timing table
|
1. List existing files and match them to the save timing table
|
||||||
2. Identify the last completed component based on which feature files exist
|
2. Identify the last completed component based on which feature files exist
|
||||||
@@ -139,7 +120,7 @@ At the start of execution, create a TodoWrite with all applicable steps. Update
|
|||||||
|
|
||||||
## Workflow
|
## Workflow
|
||||||
|
|
||||||
### Step 1: Bootstrap Structure Plan (full project mode only)
|
### Step 1: Bootstrap Structure Plan (default mode only)
|
||||||
|
|
||||||
**Role**: Professional software architect
|
**Role**: Professional software architect
|
||||||
**Goal**: Produce `initial_structure.md` describing the project skeleton for implementation
|
**Goal**: Produce `initial_structure.md` describing the project skeleton for implementation
|
||||||
@@ -191,7 +172,7 @@ For each component (or the single provided component):
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Step 3: Cross-Component Verification (full project mode only)
|
### Step 3: Cross-Component Verification (default mode only)
|
||||||
|
|
||||||
**Role**: Professional software architect and analyst
|
**Role**: Professional software architect and analyst
|
||||||
**Goal**: Verify feature consistency across all components
|
**Goal**: Verify feature consistency across all components
|
||||||
@@ -223,8 +204,7 @@ For each component (or the single provided component):
|
|||||||
1. For each feature spec, create a Jira task following the parsing rules and field mapping from `gen_jira_task_and_branch.md` (skip branch creation and file renaming — those happen during implementation)
|
1. For each feature spec, create a Jira task following the parsing rules and field mapping from `gen_jira_task_and_branch.md` (skip branch creation and file renaming — those happen during implementation)
|
||||||
2. In full mode: search Jira for epics matching component names/labels to find parent epic IDs
|
2. In full mode: search Jira for epics matching component names/labels to find parent epic IDs
|
||||||
3. In single component mode: use the Epic ID obtained during context resolution
|
3. In single component mode: use the Epic ID obtained during context resolution
|
||||||
4. In standalone mode: use the Epic ID obtained during context resolution
|
4. Do NOT create git branches or rename files — that happens during implementation
|
||||||
5. Do NOT create git branches or rename files — that happens during implementation
|
|
||||||
|
|
||||||
**Self-verification**:
|
**Self-verification**:
|
||||||
- [ ] Every feature has a corresponding Jira task
|
- [ ] Every feature has a corresponding Jira task
|
||||||
@@ -265,7 +245,7 @@ After all steps complete, write `SUMMARY.md` using `templates/summary.md` as str
|
|||||||
┌────────────────────────────────────────────────────────────────┐
|
┌────────────────────────────────────────────────────────────────┐
|
||||||
│ Feature Decomposition (4-Step Method) │
|
│ Feature Decomposition (4-Step Method) │
|
||||||
├────────────────────────────────────────────────────────────────┤
|
├────────────────────────────────────────────────────────────────┤
|
||||||
│ CONTEXT: Resolve mode (full / single component / standalone) │
|
│ CONTEXT: Resolve mode (default / single component) │
|
||||||
│ 1. Bootstrap Structure → initial_structure.md (full only) │
|
│ 1. Bootstrap Structure → initial_structure.md (full only) │
|
||||||
│ [BLOCKING: user confirms structure] │
|
│ [BLOCKING: user confirms structure] │
|
||||||
│ 2. Feature Decompose → [##]_[name]/[##].[##]_feature_* │
|
│ 2. Feature Decompose → [##]_[name]/[##].[##]_feature_* │
|
||||||
|
|||||||
+161
-107
@@ -2,8 +2,8 @@
|
|||||||
name: plan
|
name: plan
|
||||||
description: |
|
description: |
|
||||||
Decompose a solution into architecture, system flows, components, tests, and Jira epics.
|
Decompose a solution into architecture, system flows, components, tests, and Jira epics.
|
||||||
Systematic 5-step planning workflow with BLOCKING gates, self-verification, and structured artifact management.
|
Systematic 6-step planning workflow with BLOCKING gates, self-verification, and structured artifact management.
|
||||||
Supports project mode (_docs/ + _docs/02_plans/ structure) and standalone mode (@file.md).
|
Uses _docs/ + _docs/02_plans/ structure.
|
||||||
Trigger phrases:
|
Trigger phrases:
|
||||||
- "plan", "decompose solution", "architecture planning"
|
- "plan", "decompose solution", "architecture planning"
|
||||||
- "break down the solution", "create planning documents"
|
- "break down the solution", "create planning documents"
|
||||||
@@ -13,7 +13,7 @@ disable-model-invocation: true
|
|||||||
|
|
||||||
# Solution Planning
|
# Solution Planning
|
||||||
|
|
||||||
Decompose a problem and solution into architecture, system flows, components, tests, and Jira epics through a systematic 5-step workflow.
|
Decompose a problem and solution into architecture, system flows, components, tests, and Jira epics through a systematic 6-step workflow.
|
||||||
|
|
||||||
## Core Principles
|
## Core Principles
|
||||||
|
|
||||||
@@ -25,65 +25,68 @@ Decompose a problem and solution into architecture, system flows, components, te
|
|||||||
|
|
||||||
## Context Resolution
|
## Context Resolution
|
||||||
|
|
||||||
Determine the operating mode based on invocation before any other logic runs.
|
Fixed paths — no mode detection needed:
|
||||||
|
|
||||||
**Project mode** (no explicit input file provided):
|
|
||||||
- PROBLEM_FILE: `_docs/00_problem/problem.md`
|
- PROBLEM_FILE: `_docs/00_problem/problem.md`
|
||||||
- SOLUTION_FILE: `_docs/01_solution/solution.md`
|
- SOLUTION_FILE: `_docs/01_solution/solution.md`
|
||||||
- PLANS_DIR: `_docs/02_plans/`
|
- PLANS_DIR: `_docs/02_plans/`
|
||||||
- All existing guardrails apply as-is.
|
|
||||||
|
|
||||||
**Standalone mode** (explicit input file provided, e.g. `/plan @some_doc.md`):
|
Announce the resolved paths to the user before proceeding.
|
||||||
- INPUT_FILE: the provided file (treated as combined problem + solution context)
|
|
||||||
- Derive `<topic>` from the input filename (without extension)
|
|
||||||
- PLANS_DIR: `_standalone/<topic>/plans/`
|
|
||||||
- Guardrails relaxed: only INPUT_FILE must exist and be non-empty
|
|
||||||
- `acceptance_criteria.md` and `restrictions.md` are optional — warn if absent
|
|
||||||
|
|
||||||
Announce the detected mode and resolved paths to the user before proceeding.
|
|
||||||
|
|
||||||
## Input Specification
|
## Input Specification
|
||||||
|
|
||||||
### Required Files
|
### Required Files
|
||||||
|
|
||||||
**Project mode:**
|
|
||||||
|
|
||||||
| File | Purpose |
|
| File | Purpose |
|
||||||
|------|---------|
|
|------|---------|
|
||||||
| PROBLEM_FILE (`_docs/00_problem/problem.md`) | Problem description and context |
|
| `_docs/00_problem/problem.md` | Problem description and context |
|
||||||
| `_docs/00_problem/input_data/` | Reference data examples (if available) |
|
| `_docs/00_problem/acceptance_criteria.md` | Measurable acceptance criteria |
|
||||||
| `_docs/00_problem/restrictions.md` | Constraints and limitations (if available) |
|
| `_docs/00_problem/restrictions.md` | Constraints and limitations |
|
||||||
| `_docs/00_problem/acceptance_criteria.md` | Measurable acceptance criteria (if available) |
|
| `_docs/00_problem/input_data/` | Reference data examples |
|
||||||
| SOLUTION_FILE (`_docs/01_solution/solution.md`) | Solution draft to decompose |
|
| `_docs/01_solution/solution.md` | Finalized solution to decompose |
|
||||||
|
|
||||||
**Standalone mode:**
|
|
||||||
|
|
||||||
| File | Purpose |
|
|
||||||
|------|---------|
|
|
||||||
| INPUT_FILE (the provided file) | Combined problem + solution context |
|
|
||||||
|
|
||||||
### Prerequisite Checks (BLOCKING)
|
### Prerequisite Checks (BLOCKING)
|
||||||
|
|
||||||
**Project mode:**
|
Run sequentially before any planning step:
|
||||||
1. PROBLEM_FILE exists and is non-empty — **STOP if missing**
|
|
||||||
2. SOLUTION_FILE exists and is non-empty — **STOP if missing**
|
|
||||||
3. Create PLANS_DIR if it does not exist
|
|
||||||
4. If `PLANS_DIR/<topic>/` already exists, ask user: **resume from last checkpoint or start fresh?**
|
|
||||||
|
|
||||||
**Standalone mode:**
|
**Prereq 1: Data Gate**
|
||||||
1. INPUT_FILE exists and is non-empty — **STOP if missing**
|
|
||||||
2. Warn if no `restrictions.md` or `acceptance_criteria.md` provided alongside INPUT_FILE
|
1. `_docs/00_problem/acceptance_criteria.md` exists and is non-empty — **STOP if missing**
|
||||||
3. Create PLANS_DIR if it does not exist
|
2. `_docs/00_problem/restrictions.md` exists and is non-empty — **STOP if missing**
|
||||||
4. If `PLANS_DIR/<topic>/` already exists, ask user: **resume from last checkpoint or start fresh?**
|
3. `_docs/00_problem/input_data/` exists and contains at least one data file — **STOP if missing**
|
||||||
|
4. `_docs/00_problem/problem.md` exists and is non-empty — **STOP if missing**
|
||||||
|
|
||||||
|
All four are mandatory. If any is missing or empty, STOP and ask the user to provide them. If the user cannot provide the required data, planning cannot proceed — just stop.
|
||||||
|
|
||||||
|
**Prereq 2: Finalize Solution Draft**
|
||||||
|
|
||||||
|
Only runs after the Data Gate passes:
|
||||||
|
|
||||||
|
1. Scan `_docs/01_solution/` for files matching `solution_draft*.md`
|
||||||
|
2. Identify the highest-numbered draft (e.g. `solution_draft06.md`)
|
||||||
|
3. **Rename** it to `_docs/01_solution/solution.md`
|
||||||
|
4. If `solution.md` already exists, ask the user whether to overwrite or keep existing
|
||||||
|
5. Verify `solution.md` is non-empty — **STOP if missing or empty**
|
||||||
|
|
||||||
|
**Prereq 3: Workspace Setup**
|
||||||
|
|
||||||
|
1. Create PLANS_DIR if it does not exist
|
||||||
|
2. If PLANS_DIR already contains artifacts, ask user: **resume from last checkpoint or start fresh?**
|
||||||
|
|
||||||
## Artifact Management
|
## Artifact Management
|
||||||
|
|
||||||
### Directory Structure
|
### Directory Structure
|
||||||
|
|
||||||
At the start of planning, create a topic-named working directory under PLANS_DIR:
|
All artifacts are written directly under PLANS_DIR:
|
||||||
|
|
||||||
```
|
```
|
||||||
PLANS_DIR/<topic>/
|
PLANS_DIR/
|
||||||
|
├── e2e_test_infrastructure/
|
||||||
|
│ ├── environment.md
|
||||||
|
│ ├── test_data.md
|
||||||
|
│ ├── functional_tests.md
|
||||||
|
│ ├── non_functional_tests.md
|
||||||
|
│ └── traceability_matrix.md
|
||||||
├── architecture.md
|
├── architecture.md
|
||||||
├── system-flows.md
|
├── system-flows.md
|
||||||
├── risk_mitigations.md
|
├── risk_mitigations.md
|
||||||
@@ -100,7 +103,6 @@ PLANS_DIR/<topic>/
|
|||||||
│ ├── 01_helper_[name]/
|
│ ├── 01_helper_[name]/
|
||||||
│ ├── 02_helper_[name]/
|
│ ├── 02_helper_[name]/
|
||||||
│ └── ...
|
│ └── ...
|
||||||
├── e2e_test_infrastructure.md
|
|
||||||
├── diagrams/
|
├── diagrams/
|
||||||
│ ├── components.drawio
|
│ ├── components.drawio
|
||||||
│ └── flows/
|
│ └── flows/
|
||||||
@@ -113,15 +115,19 @@ PLANS_DIR/<topic>/
|
|||||||
|
|
||||||
| Step | Save immediately after | Filename |
|
| Step | Save immediately after | Filename |
|
||||||
|------|------------------------|----------|
|
|------|------------------------|----------|
|
||||||
| Step 1 | Architecture analysis complete | `architecture.md` |
|
| Step 1 | E2E environment spec | `e2e_test_infrastructure/environment.md` |
|
||||||
| Step 1 | System flows documented | `system-flows.md` |
|
| Step 1 | E2E test data spec | `e2e_test_infrastructure/test_data.md` |
|
||||||
| Step 2 | Each component analyzed | `components/[##]_[name]/description.md` |
|
| Step 1 | E2E functional tests | `e2e_test_infrastructure/functional_tests.md` |
|
||||||
| Step 2 | Common helpers generated | `common-helpers/[##]_helper_[name].md` |
|
| Step 1 | E2E non-functional tests | `e2e_test_infrastructure/non_functional_tests.md` |
|
||||||
| Step 2 | Diagrams generated | `diagrams/` |
|
| Step 1 | E2E traceability matrix | `e2e_test_infrastructure/traceability_matrix.md` |
|
||||||
| Step 3 | Risk assessment complete | `risk_mitigations.md` |
|
| Step 2 | Architecture analysis complete | `architecture.md` |
|
||||||
| Step 4 | Tests written per component | `components/[##]_[name]/tests.md` |
|
| Step 2 | System flows documented | `system-flows.md` |
|
||||||
| Step 4b | E2E test infrastructure spec | `e2e_test_infrastructure.md` |
|
| Step 3 | Each component analyzed | `components/[##]_[name]/description.md` |
|
||||||
| Step 5 | Epics created in Jira | Jira via MCP |
|
| Step 3 | Common helpers generated | `common-helpers/[##]_helper_[name].md` |
|
||||||
|
| Step 3 | Diagrams generated | `diagrams/` |
|
||||||
|
| Step 4 | Risk assessment complete | `risk_mitigations.md` |
|
||||||
|
| Step 5 | Tests written per component | `components/[##]_[name]/tests.md` |
|
||||||
|
| Step 6 | Epics created in Jira | Jira via MCP |
|
||||||
| Final | All steps complete | `FINAL_report.md` |
|
| Final | All steps complete | `FINAL_report.md` |
|
||||||
|
|
||||||
### Save Principles
|
### Save Principles
|
||||||
@@ -133,7 +139,7 @@ PLANS_DIR/<topic>/
|
|||||||
|
|
||||||
### Resumability
|
### Resumability
|
||||||
|
|
||||||
If `PLANS_DIR/<topic>/` already contains artifacts:
|
If PLANS_DIR already contains artifacts:
|
||||||
|
|
||||||
1. List existing files and match them to the save timing table above
|
1. List existing files and match them to the save timing table above
|
||||||
2. Identify the last completed step based on which artifacts exist
|
2. Identify the last completed step based on which artifacts exist
|
||||||
@@ -142,26 +148,81 @@ If `PLANS_DIR/<topic>/` already contains artifacts:
|
|||||||
|
|
||||||
## Progress Tracking
|
## Progress Tracking
|
||||||
|
|
||||||
At the start of execution, create a TodoWrite with all steps (1 through 5, including 4b). Update status as each step completes.
|
At the start of execution, create a TodoWrite with all steps (1 through 6). Update status as each step completes.
|
||||||
|
|
||||||
## Workflow
|
## Workflow
|
||||||
|
|
||||||
### Step 1: Solution Analysis
|
### Step 1: E2E Test Infrastructure
|
||||||
|
|
||||||
|
**Role**: Professional Quality Assurance Engineer
|
||||||
|
**Goal**: Analyze input data completeness and produce detailed black-box E2E test specifications
|
||||||
|
**Constraints**: Spec only — no test code. Tests describe what the system should do given specific inputs, not how the system is built.
|
||||||
|
|
||||||
|
#### Phase 1a: Input Data Completeness Analysis
|
||||||
|
|
||||||
|
1. Read `_docs/01_solution/solution.md` (finalized in Prereq 2)
|
||||||
|
2. Read `acceptance_criteria.md`, `restrictions.md`
|
||||||
|
3. Read testing strategy from solution.md
|
||||||
|
4. Analyze `input_data/` contents against:
|
||||||
|
- Coverage of acceptance criteria scenarios
|
||||||
|
- Coverage of restriction edge cases
|
||||||
|
- Coverage of testing strategy requirements
|
||||||
|
5. Threshold: at least 70% coverage of the scenarios
|
||||||
|
6. If coverage is low, search the internet for supplementary data, assess quality with user, and if user agrees, add to `input_data/`
|
||||||
|
7. Present coverage assessment to user
|
||||||
|
|
||||||
|
**BLOCKING**: Do NOT proceed until user confirms the input data coverage is sufficient.
|
||||||
|
|
||||||
|
#### Phase 1b: Black-Box Test Scenario Specification
|
||||||
|
|
||||||
|
Based on all acquired data, acceptance_criteria, and restrictions, form detailed test scenarios:
|
||||||
|
|
||||||
|
1. Define test environment using `templates/e2e-environment.md` as structure
|
||||||
|
2. Define test data management using `templates/e2e-test-data.md` as structure
|
||||||
|
3. Write functional test scenarios (positive + negative) using `templates/e2e-functional-tests.md` as structure
|
||||||
|
4. Write non-functional test scenarios (performance, resilience, security, edge cases) using `templates/e2e-non-functional-tests.md` as structure
|
||||||
|
5. Build traceability matrix using `templates/e2e-traceability-matrix.md` as structure
|
||||||
|
|
||||||
|
**Self-verification**:
|
||||||
|
- [ ] Every acceptance criterion is covered by at least one test scenario
|
||||||
|
- [ ] Every restriction is verified by at least one test scenario
|
||||||
|
- [ ] Positive and negative scenarios are balanced
|
||||||
|
- [ ] Consumer app has no direct access to system internals
|
||||||
|
- [ ] Docker environment is self-contained (`docker compose up` sufficient)
|
||||||
|
- [ ] External dependencies have mock/stub services defined
|
||||||
|
- [ ] Traceability matrix has no uncovered AC or restrictions
|
||||||
|
|
||||||
|
**Save action**: Write all files under `e2e_test_infrastructure/`:
|
||||||
|
- `environment.md`
|
||||||
|
- `test_data.md`
|
||||||
|
- `functional_tests.md`
|
||||||
|
- `non_functional_tests.md`
|
||||||
|
- `traceability_matrix.md`
|
||||||
|
|
||||||
|
**BLOCKING**: Present test coverage summary (from traceability_matrix.md) to user. Do NOT proceed until confirmed.
|
||||||
|
|
||||||
|
Capture any new questions, findings, or insights that arise during test specification — these feed forward into Steps 2 and 3.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Step 2: Solution Analysis
|
||||||
|
|
||||||
**Role**: Professional software architect
|
**Role**: Professional software architect
|
||||||
**Goal**: Produce `architecture.md` and `system-flows.md` from the solution draft
|
**Goal**: Produce `architecture.md` and `system-flows.md` from the solution draft
|
||||||
**Constraints**: No code, no component-level detail yet; focus on system-level view
|
**Constraints**: No code, no component-level detail yet; focus on system-level view
|
||||||
|
|
||||||
1. Read all input files thoroughly
|
1. Read all input files thoroughly
|
||||||
2. Research unknown or questionable topics via internet; ask user about ambiguities
|
2. Incorporate findings, questions, and insights discovered during Step 1 (E2E test infrastructure)
|
||||||
3. Document architecture using `templates/architecture.md` as structure
|
3. Research unknown or questionable topics via internet; ask user about ambiguities
|
||||||
4. Document system flows using `templates/system-flows.md` as structure
|
4. Document architecture using `templates/architecture.md` as structure
|
||||||
|
5. Document system flows using `templates/system-flows.md` as structure
|
||||||
|
|
||||||
**Self-verification**:
|
**Self-verification**:
|
||||||
- [ ] Architecture covers all capabilities mentioned in solution.md
|
- [ ] Architecture covers all capabilities mentioned in solution.md
|
||||||
- [ ] System flows cover all main user/system interactions
|
- [ ] System flows cover all main user/system interactions
|
||||||
- [ ] No contradictions with problem.md or restrictions.md
|
- [ ] No contradictions with problem.md or restrictions.md
|
||||||
- [ ] Technology choices are justified
|
- [ ] Technology choices are justified
|
||||||
|
- [ ] E2E test findings are reflected in architecture decisions
|
||||||
|
|
||||||
**Save action**: Write `architecture.md` and `system-flows.md`
|
**Save action**: Write `architecture.md` and `system-flows.md`
|
||||||
|
|
||||||
@@ -169,19 +230,20 @@ At the start of execution, create a TodoWrite with all steps (1 through 5, inclu
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Step 2: Component Decomposition
|
### Step 3: Component Decomposition
|
||||||
|
|
||||||
**Role**: Professional software architect
|
**Role**: Professional software architect
|
||||||
**Goal**: Decompose the architecture into components with detailed specs
|
**Goal**: Decompose the architecture into components with detailed specs
|
||||||
**Constraints**: No code; only names, interfaces, inputs/outputs. Follow SRP strictly.
|
**Constraints**: No code; only names, interfaces, inputs/outputs. Follow SRP strictly.
|
||||||
|
|
||||||
1. Identify components from the architecture; think about separation, reusability, and communication patterns
|
1. Identify components from the architecture; think about separation, reusability, and communication patterns
|
||||||
2. If additional components are needed (data preparation, shared helpers), create them
|
2. Use E2E test scenarios from Step 1 to validate component boundaries
|
||||||
3. For each component, write a spec using `templates/component-spec.md` as structure
|
3. If additional components are needed (data preparation, shared helpers), create them
|
||||||
4. Generate diagrams:
|
4. For each component, write a spec using `templates/component-spec.md` as structure
|
||||||
|
5. Generate diagrams:
|
||||||
- draw.io component diagram showing relations (minimize line intersections, group semantically coherent components, place external users near their components)
|
- draw.io component diagram showing relations (minimize line intersections, group semantically coherent components, place external users near their components)
|
||||||
- Mermaid flowchart per main control flow
|
- Mermaid flowchart per main control flow
|
||||||
5. Components can share and reuse common logic, same for multiple components. Hence for such occurences common-helpers folder is specified.
|
6. Components can share and reuse common logic, same for multiple components. Hence for such occurences common-helpers folder is specified.
|
||||||
|
|
||||||
**Self-verification**:
|
**Self-verification**:
|
||||||
- [ ] Each component has a single, clear responsibility
|
- [ ] Each component has a single, clear responsibility
|
||||||
@@ -189,23 +251,24 @@ At the start of execution, create a TodoWrite with all steps (1 through 5, inclu
|
|||||||
- [ ] All inter-component interfaces are defined (who calls whom, with what)
|
- [ ] All inter-component interfaces are defined (who calls whom, with what)
|
||||||
- [ ] Component dependency graph has no circular dependencies
|
- [ ] Component dependency graph has no circular dependencies
|
||||||
- [ ] All components from architecture.md are accounted for
|
- [ ] All components from architecture.md are accounted for
|
||||||
|
- [ ] Every E2E test scenario can be traced through component interactions
|
||||||
|
|
||||||
**Save action**: Write:
|
**Save action**: Write:
|
||||||
- each component `components/[##]_[name]/description.md`
|
- each component `components/[##]_[name]/description.md`
|
||||||
- comomon helper `common-helpers/[##]_helper_[name].md`
|
- common helper `common-helpers/[##]_helper_[name].md`
|
||||||
- diagrams `diagrams/`
|
- diagrams `diagrams/`
|
||||||
|
|
||||||
**BLOCKING**: Present component list with one-line summaries to user. Do NOT proceed until user confirms.
|
**BLOCKING**: Present component list with one-line summaries to user. Do NOT proceed until user confirms.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Step 3: Architecture Review & Risk Assessment
|
### Step 4: Architecture Review & Risk Assessment
|
||||||
|
|
||||||
**Role**: Professional software architect and analyst
|
**Role**: Professional software architect and analyst
|
||||||
**Goal**: Validate all artifacts for consistency, then identify and mitigate risks
|
**Goal**: Validate all artifacts for consistency, then identify and mitigate risks
|
||||||
**Constraints**: This is a review step — fix problems found, do not add new features
|
**Constraints**: This is a review step — fix problems found, do not add new features
|
||||||
|
|
||||||
#### 3a. Evaluator Pass (re-read ALL artifacts)
|
#### 4a. Evaluator Pass (re-read ALL artifacts)
|
||||||
|
|
||||||
Review checklist:
|
Review checklist:
|
||||||
- [ ] All components follow Single Responsibility Principle
|
- [ ] All components follow Single Responsibility Principle
|
||||||
@@ -220,7 +283,7 @@ Review checklist:
|
|||||||
|
|
||||||
Fix any issues found before proceeding to risk identification.
|
Fix any issues found before proceeding to risk identification.
|
||||||
|
|
||||||
#### 3b. Risk Identification
|
#### 4b. Risk Identification
|
||||||
|
|
||||||
1. Identify technical and project risks
|
1. Identify technical and project risks
|
||||||
2. Assess probability and impact using `templates/risk-register.md`
|
2. Assess probability and impact using `templates/risk-register.md`
|
||||||
@@ -236,11 +299,11 @@ Fix any issues found before proceeding to risk identification.
|
|||||||
|
|
||||||
**BLOCKING**: Present risk summary to user. Ask whether assessment is sufficient.
|
**BLOCKING**: Present risk summary to user. Ask whether assessment is sufficient.
|
||||||
|
|
||||||
**Iterative**: If user requests another round, repeat Step 3 and write `risk_mitigations_##.md` (## as sequence number). Continue until user confirms.
|
**Iterative**: If user requests another round, repeat Step 4 and write `risk_mitigations_##.md` (## as sequence number). Continue until user confirms.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Step 4: Test Specifications
|
### Step 5: Test Specifications
|
||||||
|
|
||||||
**Role**: Professional Quality Assurance Engineer
|
**Role**: Professional Quality Assurance Engineer
|
||||||
**Goal**: Write test specs for each component achieving minimum 75% acceptance criteria coverage
|
**Goal**: Write test specs for each component achieving minimum 75% acceptance criteria coverage
|
||||||
@@ -261,35 +324,12 @@ Fix any issues found before proceeding to risk identification.
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Step 4b: E2E Black-Box Test Infrastructure
|
### Step 6: Jira Epics
|
||||||
|
|
||||||
**Role**: Professional Quality Assurance Engineer
|
|
||||||
**Goal**: Specify a separate consumer application and Docker environment for black-box end-to-end testing of the main system
|
|
||||||
**Constraints**: Spec only — no test code. Consumer must treat the main system as a black box (no internal imports, no direct DB access).
|
|
||||||
|
|
||||||
1. Define Docker environment: services (system under test, test DB, consumer app, dependencies), networks, volumes
|
|
||||||
2. Specify consumer application: tech stack, entry point, communication interfaces with the main system
|
|
||||||
3. Define E2E test scenarios from acceptance criteria — focus on critical end-to-end use cases that cross component boundaries
|
|
||||||
4. Specify test data management: seed data, isolation strategy, external dependency mocks
|
|
||||||
5. Define CI/CD integration: when to run, gate behavior, timeout
|
|
||||||
6. Define reporting format (CSV: test ID, name, execution time, result, error message)
|
|
||||||
|
|
||||||
Use `templates/e2e-test-infrastructure.md` as structure.
|
|
||||||
|
|
||||||
**Self-verification**:
|
|
||||||
- [ ] Critical acceptance criteria are covered by at least one E2E scenario
|
|
||||||
- [ ] Consumer app has no direct access to system internals
|
|
||||||
- [ ] Docker environment is self-contained (`docker compose up` sufficient)
|
|
||||||
- [ ] External dependencies have mock/stub services defined
|
|
||||||
|
|
||||||
**Save action**: Write `e2e_test_infrastructure.md`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Step 5: Jira Epics
|
|
||||||
|
|
||||||
**Role**: Professional product manager
|
**Role**: Professional product manager
|
||||||
|
|
||||||
**Goal**: Create Jira epics from components, ordered by dependency
|
**Goal**: Create Jira epics from components, ordered by dependency
|
||||||
|
|
||||||
**Constraints**: Be concise — fewer words with the same meaning is better
|
**Constraints**: Be concise — fewer words with the same meaning is better
|
||||||
|
|
||||||
1. Generate Jira Epics from components using Jira MCP, structured per `templates/epic-spec.md`
|
1. Generate Jira Epics from components using Jira MCP, structured per `templates/epic-spec.md`
|
||||||
@@ -312,16 +352,26 @@ Use `templates/e2e-test-infrastructure.md` as structure.
|
|||||||
|
|
||||||
Before writing the final report, verify ALL of the following:
|
Before writing the final report, verify ALL of the following:
|
||||||
|
|
||||||
|
### E2E Test Infrastructure
|
||||||
|
- [ ] Every acceptance criterion is covered in traceability_matrix.md
|
||||||
|
- [ ] Every restriction is verified by at least one test
|
||||||
|
- [ ] Positive and negative scenarios are balanced
|
||||||
|
- [ ] Docker environment is self-contained
|
||||||
|
- [ ] Consumer app treats main system as black box
|
||||||
|
- [ ] CI/CD integration and reporting defined
|
||||||
|
|
||||||
### Architecture
|
### Architecture
|
||||||
- [ ] Covers all capabilities from solution.md
|
- [ ] Covers all capabilities from solution.md
|
||||||
- [ ] Technology choices are justified
|
- [ ] Technology choices are justified
|
||||||
- [ ] Deployment model is defined
|
- [ ] Deployment model is defined
|
||||||
|
- [ ] E2E test findings are reflected in architecture decisions
|
||||||
|
|
||||||
### Components
|
### Components
|
||||||
- [ ] Every component follows SRP
|
- [ ] Every component follows SRP
|
||||||
- [ ] No circular dependencies
|
- [ ] No circular dependencies
|
||||||
- [ ] All inter-component interfaces are defined and consistent
|
- [ ] All inter-component interfaces are defined and consistent
|
||||||
- [ ] No orphan components (unused by any flow)
|
- [ ] No orphan components (unused by any flow)
|
||||||
|
- [ ] Every E2E test scenario can be traced through component interactions
|
||||||
|
|
||||||
### Risks
|
### Risks
|
||||||
- [ ] All High/Critical risks have mitigations
|
- [ ] All High/Critical risks have mitigations
|
||||||
@@ -333,12 +383,6 @@ Before writing the final report, verify ALL of the following:
|
|||||||
- [ ] All 4 test types are represented per component (where applicable)
|
- [ ] All 4 test types are represented per component (where applicable)
|
||||||
- [ ] Test data management is defined
|
- [ ] Test data management is defined
|
||||||
|
|
||||||
### E2E Test Infrastructure
|
|
||||||
- [ ] Critical use cases covered by E2E scenarios
|
|
||||||
- [ ] Docker environment is self-contained
|
|
||||||
- [ ] Consumer app treats main system as black box
|
|
||||||
- [ ] CI/CD integration and reporting defined
|
|
||||||
|
|
||||||
### Epics
|
### Epics
|
||||||
- [ ] Every component maps to an epic
|
- [ ] Every component maps to an epic
|
||||||
- [ ] Dependency order is correct
|
- [ ] Dependency order is correct
|
||||||
@@ -348,6 +392,7 @@ Before writing the final report, verify ALL of the following:
|
|||||||
|
|
||||||
## Common Mistakes
|
## Common Mistakes
|
||||||
|
|
||||||
|
- **Proceeding without input data**: all three data gate items (acceptance_criteria, restrictions, input_data) must be present before any planning begins
|
||||||
- **Coding during planning**: this workflow produces documents, never code
|
- **Coding during planning**: this workflow produces documents, never code
|
||||||
- **Multi-responsibility components**: if a component does two things, split it
|
- **Multi-responsibility components**: if a component does two things, split it
|
||||||
- **Skipping BLOCKING gates**: never proceed past a BLOCKING marker without user confirmation
|
- **Skipping BLOCKING gates**: never proceed past a BLOCKING marker without user confirmation
|
||||||
@@ -355,13 +400,15 @@ Before writing the final report, verify ALL of the following:
|
|||||||
- **Copy-pasting problem.md**: the architecture doc should analyze and transform, not repeat the input
|
- **Copy-pasting problem.md**: the architecture doc should analyze and transform, not repeat the input
|
||||||
- **Vague interfaces**: "component A talks to component B" is not enough; define the method, input, output
|
- **Vague interfaces**: "component A talks to component B" is not enough; define the method, input, output
|
||||||
- **Ignoring restrictions.md**: every constraint must be traceable in the architecture or risk register
|
- **Ignoring restrictions.md**: every constraint must be traceable in the architecture or risk register
|
||||||
|
- **Ignoring E2E findings**: insights from Step 1 must feed into architecture (Step 2) and component decomposition (Step 3)
|
||||||
|
|
||||||
## Escalation Rules
|
## Escalation Rules
|
||||||
|
|
||||||
| Situation | Action |
|
| Situation | Action |
|
||||||
|-----------|--------|
|
|-----------|--------|
|
||||||
|
| Missing acceptance_criteria.md, restrictions.md, or input_data/ | **STOP** — planning cannot proceed |
|
||||||
| Ambiguous requirements | ASK user |
|
| Ambiguous requirements | ASK user |
|
||||||
| Missing acceptance criteria | ASK user |
|
| Input data coverage below 70% | Search internet for supplementary data, ASK user to validate |
|
||||||
| Technology choice with multiple valid options | ASK user |
|
| Technology choice with multiple valid options | ASK user |
|
||||||
| Component naming | PROCEED, confirm at next BLOCKING gate |
|
| Component naming | PROCEED, confirm at next BLOCKING gate |
|
||||||
| File structure within templates | PROCEED |
|
| File structure within templates | PROCEED |
|
||||||
@@ -372,18 +419,25 @@ Before writing the final report, verify ALL of the following:
|
|||||||
|
|
||||||
```
|
```
|
||||||
┌────────────────────────────────────────────────────────────────┐
|
┌────────────────────────────────────────────────────────────────┐
|
||||||
│ Solution Planning (5-Step Method) │
|
│ Solution Planning (6-Step Method) │
|
||||||
├────────────────────────────────────────────────────────────────┤
|
├────────────────────────────────────────────────────────────────┤
|
||||||
│ CONTEXT: Resolve mode (project vs standalone) + set paths │
|
│ PREREQ 1: Data Gate (BLOCKING) │
|
||||||
│ 1. Solution Analysis → architecture.md, system-flows.md │
|
│ → verify AC, restrictions, input_data exist — STOP if not │
|
||||||
|
│ PREREQ 2: Finalize solution draft │
|
||||||
|
│ → rename highest solution_draft##.md to solution.md │
|
||||||
|
│ PREREQ 3: Workspace setup │
|
||||||
|
│ → create PLANS_DIR/ if needed │
|
||||||
|
│ │
|
||||||
|
│ 1. E2E Test Infra → e2e_test_infrastructure/ (5 files) │
|
||||||
|
│ [BLOCKING: user confirms test coverage] │
|
||||||
|
│ 2. Solution Analysis → architecture.md, system-flows.md │
|
||||||
│ [BLOCKING: user confirms architecture] │
|
│ [BLOCKING: user confirms architecture] │
|
||||||
│ 2. Component Decompose → components/[##]_[name]/description │
|
│ 3. Component Decompose → components/[##]_[name]/description │
|
||||||
│ [BLOCKING: user confirms decomposition] │
|
│ [BLOCKING: user confirms decomposition] │
|
||||||
│ 3. Review & Risk Assess → risk_mitigations.md │
|
│ 4. Review & Risk → risk_mitigations.md │
|
||||||
│ [BLOCKING: user confirms risks, iterative] │
|
│ [BLOCKING: user confirms risks, iterative] │
|
||||||
│ 4. Test Specifications → components/[##]_[name]/tests.md │
|
│ 5. Test Specifications → components/[##]_[name]/tests.md │
|
||||||
│ 4b.E2E Test Infra → e2e_test_infrastructure.md │
|
│ 6. Jira Epics → Jira via MCP │
|
||||||
│ 5. Jira Epics → Jira via MCP │
|
|
||||||
│ ───────────────────────────────────────────────── │
|
│ ───────────────────────────────────────────────── │
|
||||||
│ Quality Checklist → FINAL_report.md │
|
│ Quality Checklist → FINAL_report.md │
|
||||||
├────────────────────────────────────────────────────────────────┤
|
├────────────────────────────────────────────────────────────────┤
|
||||||
|
|||||||
+5
-56
@@ -1,16 +1,15 @@
|
|||||||
# E2E Black-Box Test Infrastructure Template
|
# E2E Test Environment Template
|
||||||
|
|
||||||
Describes a separate consumer application that tests the main system as a black box.
|
Save as `PLANS_DIR/<topic>/e2e_test_infrastructure/environment.md`.
|
||||||
Save as `PLANS_DIR/<topic>/e2e_test_infrastructure.md`.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
```markdown
|
```markdown
|
||||||
# E2E Test Infrastructure
|
# E2E Test Environment
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
**System under test**: [main system name and entry points — API URLs, message queues, etc.]
|
**System under test**: [main system name and entry points — API URLs, message queues, serial ports, etc.]
|
||||||
**Consumer app purpose**: Standalone application that exercises the main system through its public interfaces, validating end-to-end use cases without access to internals.
|
**Consumer app purpose**: Standalone application that exercises the main system through its public interfaces, validating end-to-end use cases without access to internals.
|
||||||
|
|
||||||
## Docker Environment
|
## Docker Environment
|
||||||
@@ -22,7 +21,7 @@ Save as `PLANS_DIR/<topic>/e2e_test_infrastructure.md`.
|
|||||||
| system-under-test | [main app image or build context] | The main system being tested | [ports] |
|
| system-under-test | [main app image or build context] | The main system being tested | [ports] |
|
||||||
| test-db | [postgres/mysql/etc.] | Database for the main system | [ports] |
|
| test-db | [postgres/mysql/etc.] | Database for the main system | [ports] |
|
||||||
| e2e-consumer | [build context for consumer app] | Black-box test runner | — |
|
| e2e-consumer | [build context for consumer app] | Black-box test runner | — |
|
||||||
| [dependency] | [image] | [purpose — cache, queue, etc.] | [ports] |
|
| [dependency] | [image] | [purpose — cache, queue, mock, etc.] | [ports] |
|
||||||
|
|
||||||
### Networks
|
### Networks
|
||||||
|
|
||||||
@@ -68,54 +67,6 @@ services:
|
|||||||
- No internal module imports
|
- No internal module imports
|
||||||
- No shared memory or file system with the main system
|
- No shared memory or file system with the main system
|
||||||
|
|
||||||
## E2E Test Scenarios
|
|
||||||
|
|
||||||
### Acceptance Criteria Traceability
|
|
||||||
|
|
||||||
| AC ID | Acceptance Criterion | E2E Test IDs | Coverage |
|
|
||||||
|-------|---------------------|-------------|----------|
|
|
||||||
| AC-01 | [criterion] | E2E-01 | Covered |
|
|
||||||
| AC-02 | [criterion] | E2E-02, E2E-03 | Covered |
|
|
||||||
| AC-03 | [criterion] | — | NOT COVERED — [reason] |
|
|
||||||
|
|
||||||
### E2E-01: [Scenario Name]
|
|
||||||
|
|
||||||
**Summary**: [One sentence: what end-to-end use case this validates]
|
|
||||||
|
|
||||||
**Traces to**: AC-01
|
|
||||||
|
|
||||||
**Preconditions**:
|
|
||||||
- [System state required before test]
|
|
||||||
|
|
||||||
**Steps**:
|
|
||||||
|
|
||||||
| Step | Consumer Action | Expected System Response |
|
|
||||||
|------|----------------|------------------------|
|
|
||||||
| 1 | [call / send] | [response / event] |
|
|
||||||
| 2 | [call / send] | [response / event] |
|
|
||||||
|
|
||||||
**Max execution time**: [e.g., 10s]
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### E2E-02: [Scenario Name]
|
|
||||||
|
|
||||||
(repeat structure)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Test Data Management
|
|
||||||
|
|
||||||
**Seed data**:
|
|
||||||
|
|
||||||
| Data Set | Description | How Loaded | Cleanup |
|
|
||||||
|----------|-------------|-----------|---------|
|
|
||||||
| [name] | [what it contains] | [SQL script / API call / fixture file] | [how removed after test] |
|
|
||||||
|
|
||||||
**Isolation strategy**: [e.g., each test run gets a fresh DB via container restart, or transactions are rolled back, or namespaced data]
|
|
||||||
|
|
||||||
**External dependencies**: [any external APIs that need mocking or sandbox environments]
|
|
||||||
|
|
||||||
## CI/CD Integration
|
## CI/CD Integration
|
||||||
|
|
||||||
**When to run**: [e.g., on PR merge to dev, nightly, before production deploy]
|
**When to run**: [e.g., on PR merge to dev, nightly, before production deploy]
|
||||||
@@ -134,8 +85,6 @@ services:
|
|||||||
|
|
||||||
## Guidance Notes
|
## Guidance Notes
|
||||||
|
|
||||||
- Every E2E test MUST trace to at least one acceptance criterion. If it doesn't, question whether it's needed.
|
|
||||||
- The consumer app must treat the main system as a true black box — no internal imports, no direct DB queries against the main system's database.
|
- The consumer app must treat the main system as a true black box — no internal imports, no direct DB queries against the main system's database.
|
||||||
- Keep the number of E2E tests focused on critical use cases. Exhaustive testing belongs in per-component tests (Step 4).
|
|
||||||
- Docker environment should be self-contained — `docker compose up` must be sufficient to run the full suite.
|
- Docker environment should be self-contained — `docker compose up` must be sufficient to run the full suite.
|
||||||
- If the main system requires external services (payment gateways, third-party APIs), define mock/stub services in the Docker environment.
|
- If the main system requires external services (payment gateways, third-party APIs), define mock/stub services in the Docker environment.
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
# E2E Functional Tests Template
|
||||||
|
|
||||||
|
Save as `PLANS_DIR/<topic>/e2e_test_infrastructure/functional_tests.md`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
# E2E Functional Tests
|
||||||
|
|
||||||
|
## Positive Scenarios
|
||||||
|
|
||||||
|
### FT-P-01: [Scenario Name]
|
||||||
|
|
||||||
|
**Summary**: [One sentence: what end-to-end use case this validates]
|
||||||
|
**Traces to**: AC-[ID], AC-[ID]
|
||||||
|
**Category**: [which AC category — e.g., Position Accuracy, Image Processing, etc.]
|
||||||
|
|
||||||
|
**Preconditions**:
|
||||||
|
- [System state required before test]
|
||||||
|
|
||||||
|
**Input data**: [reference to specific data set or file from test_data.md]
|
||||||
|
|
||||||
|
**Steps**:
|
||||||
|
|
||||||
|
| Step | Consumer Action | Expected System Response |
|
||||||
|
|------|----------------|------------------------|
|
||||||
|
| 1 | [call / send / provide input] | [response / event / output] |
|
||||||
|
| 2 | [call / send / provide input] | [response / event / output] |
|
||||||
|
|
||||||
|
**Expected outcome**: [specific, measurable result]
|
||||||
|
**Max execution time**: [e.g., 10s]
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### FT-P-02: [Scenario Name]
|
||||||
|
|
||||||
|
(repeat structure)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Negative Scenarios
|
||||||
|
|
||||||
|
### FT-N-01: [Scenario Name]
|
||||||
|
|
||||||
|
**Summary**: [One sentence: what invalid/edge input this tests]
|
||||||
|
**Traces to**: AC-[ID] (negative case), RESTRICT-[ID]
|
||||||
|
**Category**: [which AC/restriction category]
|
||||||
|
|
||||||
|
**Preconditions**:
|
||||||
|
- [System state required before test]
|
||||||
|
|
||||||
|
**Input data**: [reference to specific invalid data or edge case]
|
||||||
|
|
||||||
|
**Steps**:
|
||||||
|
|
||||||
|
| Step | Consumer Action | Expected System Response |
|
||||||
|
|------|----------------|------------------------|
|
||||||
|
| 1 | [provide invalid input / trigger edge case] | [error response / graceful degradation / fallback behavior] |
|
||||||
|
|
||||||
|
**Expected outcome**: [system rejects gracefully / falls back to X / returns error Y]
|
||||||
|
**Max execution time**: [e.g., 5s]
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### FT-N-02: [Scenario Name]
|
||||||
|
|
||||||
|
(repeat structure)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Guidance Notes
|
||||||
|
|
||||||
|
- Functional tests should typically trace to at least one acceptance criterion or restriction. Tests without a trace are allowed but should have a clear justification.
|
||||||
|
- Positive scenarios validate the system does what it should.
|
||||||
|
- Negative scenarios validate the system rejects or handles gracefully what it shouldn't accept.
|
||||||
|
- Expected outcomes must be specific and measurable — not "works correctly" but "returns position within 50m of ground truth."
|
||||||
|
- Input data references should point to specific entries in test_data.md.
|
||||||
@@ -0,0 +1,97 @@
|
|||||||
|
# E2E Non-Functional Tests Template
|
||||||
|
|
||||||
|
Save as `PLANS_DIR/<topic>/e2e_test_infrastructure/non_functional_tests.md`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
# E2E Non-Functional Tests
|
||||||
|
|
||||||
|
## Performance Tests
|
||||||
|
|
||||||
|
### NFT-PERF-01: [Test Name]
|
||||||
|
|
||||||
|
**Summary**: [What performance characteristic this validates]
|
||||||
|
**Traces to**: AC-[ID]
|
||||||
|
**Metric**: [what is measured — latency, throughput, frame rate, etc.]
|
||||||
|
|
||||||
|
**Preconditions**:
|
||||||
|
- [System state, load profile, data volume]
|
||||||
|
|
||||||
|
**Steps**:
|
||||||
|
|
||||||
|
| Step | Consumer Action | Measurement |
|
||||||
|
|------|----------------|-------------|
|
||||||
|
| 1 | [action] | [what to measure and how] |
|
||||||
|
|
||||||
|
**Pass criteria**: [specific threshold — e.g., p95 latency < 400ms]
|
||||||
|
**Duration**: [how long the test runs]
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Resilience Tests
|
||||||
|
|
||||||
|
### NFT-RES-01: [Test Name]
|
||||||
|
|
||||||
|
**Summary**: [What failure/recovery scenario this validates]
|
||||||
|
**Traces to**: AC-[ID]
|
||||||
|
|
||||||
|
**Preconditions**:
|
||||||
|
- [System state before fault injection]
|
||||||
|
|
||||||
|
**Fault injection**:
|
||||||
|
- [What fault is introduced — process kill, network partition, invalid input sequence, etc.]
|
||||||
|
|
||||||
|
**Steps**:
|
||||||
|
|
||||||
|
| Step | Action | Expected Behavior |
|
||||||
|
|------|--------|------------------|
|
||||||
|
| 1 | [inject fault] | [system behavior during fault] |
|
||||||
|
| 2 | [observe recovery] | [system behavior after recovery] |
|
||||||
|
|
||||||
|
**Pass criteria**: [recovery time, data integrity, continued operation]
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Security Tests
|
||||||
|
|
||||||
|
### NFT-SEC-01: [Test Name]
|
||||||
|
|
||||||
|
**Summary**: [What security property this validates]
|
||||||
|
**Traces to**: AC-[ID], RESTRICT-[ID]
|
||||||
|
|
||||||
|
**Steps**:
|
||||||
|
|
||||||
|
| Step | Consumer Action | Expected Response |
|
||||||
|
|------|----------------|------------------|
|
||||||
|
| 1 | [attempt unauthorized access / injection / etc.] | [rejection / no data leak / etc.] |
|
||||||
|
|
||||||
|
**Pass criteria**: [specific security outcome]
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Resource Limit Tests
|
||||||
|
|
||||||
|
### NFT-RES-LIM-01: [Test Name]
|
||||||
|
|
||||||
|
**Summary**: [What resource constraint this validates]
|
||||||
|
**Traces to**: AC-[ID], RESTRICT-[ID]
|
||||||
|
|
||||||
|
**Preconditions**:
|
||||||
|
- [System running under specified constraints]
|
||||||
|
|
||||||
|
**Monitoring**:
|
||||||
|
- [What resources to monitor — memory, CPU, GPU, disk, temperature]
|
||||||
|
|
||||||
|
**Duration**: [how long to run]
|
||||||
|
**Pass criteria**: [resource stays within limit — e.g., memory < 8GB throughout]
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Guidance Notes
|
||||||
|
|
||||||
|
- Performance tests should run long enough to capture steady-state behavior, not just cold-start.
|
||||||
|
- Resilience tests must define both the fault and the expected recovery — not just "system should recover."
|
||||||
|
- Security tests at E2E level focus on black-box attacks (unauthorized API calls, malformed input), not code-level vulnerabilities.
|
||||||
|
- Resource limit tests must specify monitoring duration — short bursts don't prove sustained compliance.
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
# E2E Test Data Template
|
||||||
|
|
||||||
|
Save as `PLANS_DIR/<topic>/e2e_test_infrastructure/test_data.md`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
# E2E Test Data Management
|
||||||
|
|
||||||
|
## Seed Data Sets
|
||||||
|
|
||||||
|
| Data Set | Description | Used by Tests | How Loaded | Cleanup |
|
||||||
|
|----------|-------------|---------------|-----------|---------|
|
||||||
|
| [name] | [what it contains] | [test IDs] | [SQL script / API call / fixture file / volume mount] | [how removed after test] |
|
||||||
|
|
||||||
|
## Data Isolation Strategy
|
||||||
|
|
||||||
|
[e.g., each test run gets a fresh container restart, or transactions are rolled back, or namespaced data, or separate DB per test group]
|
||||||
|
|
||||||
|
## Input Data Mapping
|
||||||
|
|
||||||
|
| Input Data File | Source Location | Description | Covers Scenarios |
|
||||||
|
|-----------------|----------------|-------------|-----------------|
|
||||||
|
| [filename] | `_docs/00_problem/input_data/[filename]` | [what it contains] | [test IDs that use this data] |
|
||||||
|
|
||||||
|
## External Dependency Mocks
|
||||||
|
|
||||||
|
| External Service | Mock/Stub | How Provided | Behavior |
|
||||||
|
|-----------------|-----------|-------------|----------|
|
||||||
|
| [service name] | [mock type] | [Docker service / in-process stub / recorded responses] | [what it returns / simulates] |
|
||||||
|
|
||||||
|
## Data Validation Rules
|
||||||
|
|
||||||
|
| Data Type | Validation | Invalid Examples | Expected System Behavior |
|
||||||
|
|-----------|-----------|-----------------|------------------------|
|
||||||
|
| [type] | [rules] | [invalid input examples] | [how system should respond] |
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Guidance Notes
|
||||||
|
|
||||||
|
- Every seed data set should be traceable to specific test scenarios.
|
||||||
|
- Input data from `_docs/00_problem/input_data/` should be mapped to test scenarios that use it.
|
||||||
|
- External mocks must be deterministic — same input always produces same output.
|
||||||
|
- Data isolation must guarantee no test can affect another test's outcome.
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
# E2E Traceability Matrix Template
|
||||||
|
|
||||||
|
Save as `PLANS_DIR/<topic>/e2e_test_infrastructure/traceability_matrix.md`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
# E2E Traceability Matrix
|
||||||
|
|
||||||
|
## Acceptance Criteria Coverage
|
||||||
|
|
||||||
|
| AC ID | Acceptance Criterion | Test IDs | Coverage |
|
||||||
|
|-------|---------------------|----------|----------|
|
||||||
|
| AC-01 | [criterion text] | FT-P-01, NFT-PERF-01 | Covered |
|
||||||
|
| AC-02 | [criterion text] | FT-P-02, FT-N-01 | Covered |
|
||||||
|
| AC-03 | [criterion text] | — | NOT COVERED — [reason and mitigation] |
|
||||||
|
|
||||||
|
## Restrictions Coverage
|
||||||
|
|
||||||
|
| Restriction ID | Restriction | Test IDs | Coverage |
|
||||||
|
|---------------|-------------|----------|----------|
|
||||||
|
| RESTRICT-01 | [restriction text] | FT-N-02, NFT-RES-LIM-01 | Covered |
|
||||||
|
| RESTRICT-02 | [restriction text] | — | NOT COVERED — [reason and mitigation] |
|
||||||
|
|
||||||
|
## Coverage Summary
|
||||||
|
|
||||||
|
| Category | Total Items | Covered | Not Covered | Coverage % |
|
||||||
|
|----------|-----------|---------|-------------|-----------|
|
||||||
|
| Acceptance Criteria | [N] | [N] | [N] | [%] |
|
||||||
|
| Restrictions | [N] | [N] | [N] | [%] |
|
||||||
|
| **Total** | [N] | [N] | [N] | [%] |
|
||||||
|
|
||||||
|
## Uncovered Items Analysis
|
||||||
|
|
||||||
|
| Item | Reason Not Covered | Risk | Mitigation |
|
||||||
|
|------|-------------------|------|-----------|
|
||||||
|
| [AC/Restriction ID] | [why it cannot be tested at E2E level] | [what could go wrong] | [how risk is addressed — e.g., covered by component tests in Step 5] |
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Guidance Notes
|
||||||
|
|
||||||
|
- Every acceptance criterion must appear in the matrix — either covered or explicitly marked as not covered with a reason.
|
||||||
|
- Every restriction must appear in the matrix.
|
||||||
|
- NOT COVERED items must have a reason and a mitigation strategy (e.g., "covered at component test level" or "requires real hardware").
|
||||||
|
- Coverage percentage should be at least 75% for acceptance criteria at the E2E level.
|
||||||
@@ -44,6 +44,7 @@ Determine the operating mode based on invocation before any other logic runs.
|
|||||||
- `restrictions.md` and `acceptance_criteria.md` are optional — warn if absent, proceed if user confirms
|
- `restrictions.md` and `acceptance_criteria.md` are optional — warn if absent, proceed if user confirms
|
||||||
- Mode detection uses OUTPUT_DIR for `solution_draft*.md` scanning
|
- Mode detection uses OUTPUT_DIR for `solution_draft*.md` scanning
|
||||||
- Draft numbering works the same, scoped to OUTPUT_DIR
|
- Draft numbering works the same, scoped to OUTPUT_DIR
|
||||||
|
- **Final step**: after all research is complete, move INPUT_FILE into `_standalone/<topic>/`
|
||||||
|
|
||||||
Announce the detected mode and resolved paths to the user before proceeding.
|
Announce the detected mode and resolved paths to the user before proceeding.
|
||||||
|
|
||||||
@@ -932,6 +933,7 @@ Execution flow:
|
|||||||
2. Guardrails: verify INPUT_FILE exists and is non-empty, warn about missing restrictions/AC
|
2. Guardrails: verify INPUT_FILE exists and is non-empty, warn about missing restrictions/AC
|
||||||
3. Mode detection + full research flow as in Example 1, scoped to standalone paths
|
3. Mode detection + full research flow as in Example 1, scoped to standalone paths
|
||||||
4. Output: `_standalone/my_problem/01_solution/solution_draft01.md`
|
4. Output: `_standalone/my_problem/01_solution/solution_draft01.md`
|
||||||
|
5. Move `my_problem.md` into `_standalone/my_problem/`
|
||||||
|
|
||||||
### Example 4: Force Initial Research (Override)
|
### Example 4: Force Initial Research (Override)
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,73 @@
|
|||||||
|
# Question Decomposition
|
||||||
|
|
||||||
|
## Original Question
|
||||||
|
"Analyze completeness of the current solution. How mature is it?"
|
||||||
|
|
||||||
|
## Active Mode
|
||||||
|
**Mode B: Solution Assessment** — 5 solution drafts exist (`solution_draft01.md` through `solution_draft05.md`). Assessing the latest draft (05) for completeness and maturity.
|
||||||
|
|
||||||
|
## Question Type Classification
|
||||||
|
**Knowledge Organization + Problem Diagnosis**
|
||||||
|
- Knowledge Organization: systematically map what a complete GPS-denied nav system requires vs what is present
|
||||||
|
- Problem Diagnosis: identify gaps, weak points, and missing elements that reduce maturity
|
||||||
|
|
||||||
|
## Research Subject Boundary Definition
|
||||||
|
|
||||||
|
| Dimension | Boundary |
|
||||||
|
|-----------|----------|
|
||||||
|
| **Population** | Fixed-wing UAV GPS-denied visual navigation systems using visual odometry + satellite matching + IMU fusion |
|
||||||
|
| **Geography** | Eastern/southern Ukraine conflict zone operations |
|
||||||
|
| **Timeframe** | Current state of art (2024-2026), focusing on Jetson-class embedded deployment |
|
||||||
|
| **Level** | System-level architecture completeness — from sensor input to flight controller output |
|
||||||
|
|
||||||
|
## Problem Context Summary
|
||||||
|
|
||||||
|
The solution is a real-time GPS-denied visual navigation system for a custom 3.5m fixed-wing UAV:
|
||||||
|
- **Hardware**: Jetson Orin Nano Super (8GB), ADTI 20L V1 camera (0.7fps), Viewpro A40 Pro gimbal, Pixhawk 6x
|
||||||
|
- **Core pipeline**: cuVSLAM VO (0.7fps) → ESKF fusion → GPS_INPUT via pymavlink at 5-10Hz
|
||||||
|
- **Satellite correction**: LiteSAM/EfficientLoFTR/XFeat TRT FP16 on keyframes, async Stream B
|
||||||
|
- **5 draft iterations**: progressed from initial architecture → TRT migration → camera rate correction + UAV platform specs
|
||||||
|
- **Supporting docs**: tech_stack.md, security_analysis.md
|
||||||
|
|
||||||
|
## Decomposed Sub-Questions (Mode B)
|
||||||
|
|
||||||
|
### Functional Completeness
|
||||||
|
- **SQ-1**: What components does a mature GPS-denied visual navigation system require that are missing or under-specified in the current draft?
|
||||||
|
- **SQ-2**: How complete is the ESKF sensor fusion specification? (state vector, process model, measurement models, Q/R tuning, observability analysis)
|
||||||
|
- **SQ-3**: How does the system handle disconnected route segments (sharp turns with no overlap)? Is this adequately specified?
|
||||||
|
- **SQ-4**: What coordinate system transformations are needed (camera → body → NED → WGS84) and are they specified?
|
||||||
|
- **SQ-5**: How does the system handle initial localization (first frame + satellite matching bootstrap)?
|
||||||
|
- **SQ-6**: Is the re-localization request workflow (to ground station) sufficiently defined?
|
||||||
|
- **SQ-7**: How complete is the offline tile preparation pipeline (zoom levels, storage requirements, coverage calculation)?
|
||||||
|
- **SQ-8**: Is the object localization component sufficiently specified for operational use?
|
||||||
|
|
||||||
|
### Performance & Robustness
|
||||||
|
- **SQ-9**: What are the realistic drift characteristics of cuVSLAM at 0.7fps over long straight segments?
|
||||||
|
- **SQ-10**: How robust is satellite matching with Google Maps imagery in the operational area?
|
||||||
|
- **SQ-11**: What happens during extended periods with no satellite match (cloud cover on tiles, homogeneous terrain)?
|
||||||
|
- **SQ-12**: Is the 5-10Hz GPS_INPUT rate adequate for the flight controller's EKF?
|
||||||
|
|
||||||
|
### Maturity Assessment
|
||||||
|
- **SQ-13**: What is the Technology Readiness Level (TRL) of each component?
|
||||||
|
- **SQ-14**: What validation/testing has been done vs what is only planned?
|
||||||
|
- **SQ-15**: What operational procedures are missing (pre-flight checklist, in-flight monitoring, post-flight analysis)?
|
||||||
|
- **SQ-16**: Are there any inconsistencies between documents (tech_stack.md, security_analysis.md, solution_draft05.md)?
|
||||||
|
|
||||||
|
### Security
|
||||||
|
- **SQ-17**: Are there security gaps not covered by the existing security_analysis.md?
|
||||||
|
- **SQ-18**: How does the MAVLink GPS_INPUT message security work (spoofing of the GPS replacement itself)?
|
||||||
|
|
||||||
|
## Timeliness Sensitivity Assessment
|
||||||
|
|
||||||
|
- **Research Topic**: GPS-denied visual navigation system completeness and maturity
|
||||||
|
- **Sensitivity Level**: 🟡 Medium
|
||||||
|
- **Rationale**: Core algorithms (VO, ESKF, feature matching) are well-established. Hardware (Jetson Orin Nano Super) is relatively new but stable. cuVSLAM library updates are moderate pace. No rapidly-changing AI/LLM dependencies.
|
||||||
|
- **Source Time Window**: 1-2 years
|
||||||
|
- **Priority official sources to consult**:
|
||||||
|
1. NVIDIA cuVSLAM / Isaac ROS documentation
|
||||||
|
2. PX4/ArduPilot MAVLink GPS_INPUT documentation
|
||||||
|
3. LiteSAM / EfficientLoFTR papers and repos
|
||||||
|
- **Key version information to verify**:
|
||||||
|
- cuVSLAM: PyCuVSLAM v15.0.0
|
||||||
|
- TensorRT: 10.3.0
|
||||||
|
- JetPack: 6.2.2
|
||||||
@@ -0,0 +1,166 @@
|
|||||||
|
# Source Registry
|
||||||
|
|
||||||
|
## Source #1
|
||||||
|
- **Title**: ArduPilot AP_GPS_Params — GPS_RATE minimum 5Hz
|
||||||
|
- **Link**: https://github.com/ArduPilot/ardupilot/pull/15980
|
||||||
|
- **Tier**: L1
|
||||||
|
- **Publication Date**: 2024
|
||||||
|
- **Timeliness Status**: ✅ Currently valid
|
||||||
|
- **Target Audience**: ArduPilot flight controller users
|
||||||
|
- **Research Boundary Match**: ✅ Full match
|
||||||
|
- **Summary**: ArduPilot enforces minimum 5Hz GPS update rate. GPS_RATE parameter description: "Lowering below 5Hz(default) is not allowed."
|
||||||
|
- **Related Sub-question**: SQ-12
|
||||||
|
|
||||||
|
## Source #2
|
||||||
|
- **Title**: MAVLink GPS_INPUT Message Definition
|
||||||
|
- **Link**: https://ardupilot.org/mavproxy/docs/modules/GPSInput.html
|
||||||
|
- **Tier**: L1
|
||||||
|
- **Publication Date**: 2024
|
||||||
|
- **Timeliness Status**: ✅ Currently valid
|
||||||
|
- **Target Audience**: MAVLink developers
|
||||||
|
- **Research Boundary Match**: ✅ Full match
|
||||||
|
- **Summary**: GPS_INPUT requires: lat, lon, alt, fix_type, hdop, vdop, horiz_accuracy, vert_accuracy, speed_accuracy, vn, ve, vd, time_usec, time_week, time_week_ms, satellites_visible, gps_id, ignore_flags. GPS_TYPE=14 for MAVLink GPS.
|
||||||
|
- **Related Sub-question**: SQ-6, SQ-12
|
||||||
|
|
||||||
|
## Source #3
|
||||||
|
- **Title**: pymavlink GPS_INPUT example (GPS_INPUT_pymavlink.py)
|
||||||
|
- **Link**: https://webperso.ensta.fr/lebars/Share/GPS_INPUT_pymavlink.py
|
||||||
|
- **Tier**: L3
|
||||||
|
- **Publication Date**: 2024
|
||||||
|
- **Timeliness Status**: ✅ Currently valid
|
||||||
|
- **Target Audience**: pymavlink developers
|
||||||
|
- **Research Boundary Match**: ✅ Full match
|
||||||
|
- **Summary**: Working pymavlink example sending GPS_INPUT over serial at 10Hz with GPS time calculation from system time.
|
||||||
|
- **Related Sub-question**: SQ-6
|
||||||
|
|
||||||
|
## Source #4
|
||||||
|
- **Title**: PyCuVSLAM API Reference (v15.0.0)
|
||||||
|
- **Link**: https://wiki.seeedstudio.com/pycuvslam_recomputer_robotics/
|
||||||
|
- **Tier**: L2
|
||||||
|
- **Publication Date**: 2026-03
|
||||||
|
- **Timeliness Status**: ✅ Currently valid
|
||||||
|
- **Target Audience**: cuVSLAM developers on Jetson
|
||||||
|
- **Research Boundary Match**: ✅ Full match
|
||||||
|
- **Summary**: cuVSLAM supports mono/stereo/inertial modes. Requires Camera model (fx,fy,cx,cy,distortion), ImuCalibration (noise density, random walk, frequency, T_imu_rig). Modes: Performance/Precision/Moderate. IMU fallback ~1s acceptable quality.
|
||||||
|
- **Related Sub-question**: SQ-1, SQ-5, SQ-9
|
||||||
|
|
||||||
|
## Source #5
|
||||||
|
- **Title**: ESKF Python implementation for fixed-wing UAV
|
||||||
|
- **Link**: https://github.com/ludvigls/ESKF
|
||||||
|
- **Tier**: L4
|
||||||
|
- **Publication Date**: 2023
|
||||||
|
- **Timeliness Status**: ✅ Currently valid
|
||||||
|
- **Target Audience**: ESKF implementers
|
||||||
|
- **Research Boundary Match**: ✅ Full match
|
||||||
|
- **Summary**: Reference ESKF: 16-state vector (pos[3], vel[3], quat[4], acc_bias[3], gyro_bias[3]). Prediction with IMU at high rate. Update with GPS position/velocity. Tuning parameters: Q (process noise), R (measurement noise).
|
||||||
|
- **Related Sub-question**: SQ-2
|
||||||
|
|
||||||
|
## Source #6
|
||||||
|
- **Title**: ROS ESKF based on PX4/ecl — multi-sensor fusion
|
||||||
|
- **Link**: https://github.com/EliaTarasov/ESKF
|
||||||
|
- **Tier**: L4
|
||||||
|
- **Publication Date**: 2022
|
||||||
|
- **Timeliness Status**: ✅ Currently valid
|
||||||
|
- **Target Audience**: UAV ESKF implementers
|
||||||
|
- **Research Boundary Match**: ✅ Full match
|
||||||
|
- **Summary**: ESKF fusing GPS, Magnetometer, Vision Pose, Optical Flow, RangeFinder with IMU. Shows that vision pose and optical flow are separate measurement models, each with its own observation matrix and noise parameters.
|
||||||
|
- **Related Sub-question**: SQ-2
|
||||||
|
|
||||||
|
## Source #7
|
||||||
|
- **Title**: Visual-Inertial Odometry Scale Observability (Range-VIO)
|
||||||
|
- **Link**: https://arxiv.org/abs/2103.15215
|
||||||
|
- **Tier**: L1
|
||||||
|
- **Publication Date**: 2021
|
||||||
|
- **Timeliness Status**: ✅ Currently valid (fundamental research)
|
||||||
|
- **Target Audience**: VIO researchers
|
||||||
|
- **Research Boundary Match**: ✅ Full match
|
||||||
|
- **Summary**: Monocular VIO cannot observe metric scale without accelerometer excitation (not constant velocity). A 1D range sensor makes scale observable. For our case, barometric altitude + known flight altitude provides this constraint.
|
||||||
|
- **Related Sub-question**: SQ-2, SQ-4
|
||||||
|
|
||||||
|
## Source #8
|
||||||
|
- **Title**: NaviLoc: Trajectory-Level Visual Localization for GNSS-Denied UAVs
|
||||||
|
- **Link**: https://www.mdpi.com/2504-446X/10/2/97
|
||||||
|
- **Tier**: L1
|
||||||
|
- **Publication Date**: 2025
|
||||||
|
- **Timeliness Status**: ✅ Currently valid
|
||||||
|
- **Target Audience**: GPS-denied UAV navigation researchers
|
||||||
|
- **Research Boundary Match**: ✅ Full match
|
||||||
|
- **Summary**: Trajectory-level optimization fusing VPR with VIO achieves 19.5m mean error at 50-150m altitude. Key insight: treating satellite matching as noisy measurement rather than ground truth, with trajectory-level optimization. Runs at 9 FPS on RPi 5.
|
||||||
|
- **Related Sub-question**: SQ-3, SQ-13
|
||||||
|
|
||||||
|
## Source #9
|
||||||
|
- **Title**: SatLoc-Fusion: Hierarchical Adaptive Fusion Framework
|
||||||
|
- **Link**: https://www.scilit.com/publications/e5cafaf875a49297a62b298a89d5572f
|
||||||
|
- **Tier**: L1
|
||||||
|
- **Publication Date**: 2025
|
||||||
|
- **Timeliness Status**: ✅ Currently valid
|
||||||
|
- **Target Audience**: GPS-denied UAV researchers
|
||||||
|
- **Research Boundary Match**: ✅ Full match
|
||||||
|
- **Summary**: Three-layer fusion: absolute geo-localization (DinoV2), relative VO (XFeat), optical flow velocity. Adaptive weighting based on confidence. Achieves <15m error, >90% trajectory coverage. 2Hz on 6 TFLOPS edge.
|
||||||
|
- **Related Sub-question**: SQ-3, SQ-10, SQ-13
|
||||||
|
|
||||||
|
## Source #10
|
||||||
|
- **Title**: Auterion GPS-Denied Workflow
|
||||||
|
- **Link**: https://docs.auterion.com/vehicle-operation/auterion-mission-control/useful-resources/operations/gps-denied-workflow
|
||||||
|
- **Tier**: L2
|
||||||
|
- **Publication Date**: 2025
|
||||||
|
- **Timeliness Status**: ✅ Currently valid
|
||||||
|
- **Target Audience**: UAV operators
|
||||||
|
- **Research Boundary Match**: ⚠️ Partial overlap (multirotor focus, but procedures applicable)
|
||||||
|
- **Summary**: Pre-flight: manually set home position, reset heading/position, configure wind. In-flight: enable INS mode. Defines operational procedures for GPS-denied missions.
|
||||||
|
- **Related Sub-question**: SQ-15
|
||||||
|
|
||||||
|
## Source #11
|
||||||
|
- **Title**: PX4 GNSS-Degraded & Denied Flight (Dead-Reckoning)
|
||||||
|
- **Link**: https://docs.px4.io/main/en/advanced_config/gnss_degraded_or_denied_flight.html
|
||||||
|
- **Tier**: L1
|
||||||
|
- **Publication Date**: 2025
|
||||||
|
- **Timeliness Status**: ✅ Currently valid
|
||||||
|
- **Target Audience**: PX4 users
|
||||||
|
- **Research Boundary Match**: ⚠️ Partial overlap (PX4-specific, but concepts apply to ArduPilot)
|
||||||
|
- **Summary**: GPS-denied requires redundant position/velocity sensors. Dead-reckoning mode for intermittent GNSS loss. Defines failsafe behaviors when GPS is lost.
|
||||||
|
- **Related Sub-question**: SQ-15
|
||||||
|
|
||||||
|
## Source #12
|
||||||
|
- **Title**: Google Maps Ukraine satellite imagery coverage
|
||||||
|
- **Link**: https://newsukraine.rbc.ua/news/google-maps-has-surprise-for-satellite-imagery-1727182380.html
|
||||||
|
- **Tier**: L3
|
||||||
|
- **Publication Date**: 2024-09
|
||||||
|
- **Timeliness Status**: ✅ Currently valid
|
||||||
|
- **Target Audience**: General public
|
||||||
|
- **Research Boundary Match**: ✅ Full match
|
||||||
|
- **Summary**: Google Maps improved imagery quality with Cloud Score+ AI. However, conflict zone imagery is intentionally older (>1 year). Ukrainian officials flagged security concerns about imagery revealing military positions.
|
||||||
|
- **Related Sub-question**: SQ-10
|
||||||
|
|
||||||
|
## Source #13
|
||||||
|
- **Title**: Jetson Orin Nano Super thermal behavior at 25W
|
||||||
|
- **Link**: https://edgeaistack.app/blog/jetson-orin-nano-power-consumption/
|
||||||
|
- **Tier**: L3
|
||||||
|
- **Publication Date**: 2025
|
||||||
|
- **Timeliness Status**: ✅ Currently valid
|
||||||
|
- **Target Audience**: Jetson developers
|
||||||
|
- **Research Boundary Match**: ✅ Full match
|
||||||
|
- **Summary**: Thermal throttling at SoC junction >80°C. Sustained GPU at 25W: ~50-51°C reported. Active cooling required for >15W. Most production workloads 8-15W.
|
||||||
|
- **Related Sub-question**: SQ-11
|
||||||
|
|
||||||
|
## Source #14
|
||||||
|
- **Title**: Automated Image Matching for Satellite Images with Different GSDs
|
||||||
|
- **Link**: https://www.kjrs.org/journal/view.html?pn=related&uid=756&vmd=Full
|
||||||
|
- **Tier**: L1
|
||||||
|
- **Publication Date**: 2024
|
||||||
|
- **Timeliness Status**: ✅ Currently valid
|
||||||
|
- **Target Audience**: Remote sensing researchers
|
||||||
|
- **Research Boundary Match**: ✅ Full match
|
||||||
|
- **Summary**: GSD mismatch between satellite and aerial images requires scale normalization via subsampling/super-resolution. Coarse-to-fine matching strategy effective. Scale-invariant features (SIFT, deep features) partially handle scale differences.
|
||||||
|
- **Related Sub-question**: SQ-7
|
||||||
|
|
||||||
|
## Source #15
|
||||||
|
- **Title**: Optimized VO and satellite image matching for UAVs (Istanbul Tech thesis)
|
||||||
|
- **Link**: https://polen.itu.edu.tr/items/1fe1e872-7cea-44d8-a8de-339e4587bee6
|
||||||
|
- **Tier**: L1
|
||||||
|
- **Publication Date**: 2025
|
||||||
|
- **Timeliness Status**: ✅ Currently valid
|
||||||
|
- **Target Audience**: GPS-denied UAV researchers
|
||||||
|
- **Research Boundary Match**: ✅ Full match
|
||||||
|
- **Summary**: Complete VO+satellite matching pipeline. Coordinate transforms: GPS → local NED for trajectory comparison. PnP solver for UAV pose from correspondences. Map retrieval using VO-estimated position to crop satellite tiles.
|
||||||
|
- **Related Sub-question**: SQ-4, SQ-5
|
||||||
@@ -0,0 +1,169 @@
|
|||||||
|
# Fact Cards
|
||||||
|
|
||||||
|
## Fact #1 — ArduPilot minimum GPS rate is 5Hz
|
||||||
|
- **Statement**: ArduPilot enforces a hard minimum of 5Hz for GPS_INPUT updates. The GPS_RATE parameter description states: "Lowering below 5Hz(default) is not allowed." The EKF scales buffers based on this rate.
|
||||||
|
- **Source**: Source #1 (ArduPilot AP_GPS_Params)
|
||||||
|
- **Phase**: Assessment
|
||||||
|
- **Target Audience**: ArduPilot-based flight controllers
|
||||||
|
- **Confidence**: ✅ High
|
||||||
|
- **Related Dimension**: Flight controller integration completeness
|
||||||
|
|
||||||
|
## Fact #2 — GPS_INPUT requires velocity + accuracy + GPS time fields
|
||||||
|
- **Statement**: GPS_INPUT message requires not just lat/lon/alt, but also: vn/ve/vd velocity components, hdop/vdop, horiz_accuracy/vert_accuracy/speed_accuracy, fix_type, time_week/time_week_ms, satellites_visible, and ignore_flags bitmap. The solution draft05 mentions GPS_INPUT but does not specify how these fields are populated (especially velocity from ESKF, accuracy from covariance, GPS time conversion from system time).
|
||||||
|
- **Source**: Source #2 (MAVLink GPS_INPUT definition), Source #3 (pymavlink example)
|
||||||
|
- **Phase**: Assessment
|
||||||
|
- **Target Audience**: GPS-denied system
|
||||||
|
- **Confidence**: ✅ High
|
||||||
|
- **Related Dimension**: Flight controller integration completeness
|
||||||
|
|
||||||
|
## Fact #3 — ESKF state vector needs explicit definition
|
||||||
|
- **Statement**: Standard ESKF for UAV VIO fusion uses 15-16 state error vector: δp[3], δv[3], δθ[3] (attitude error in so(3)), δba[3] (accel bias), δbg[3] (gyro bias), optionally δg[3] (gravity). The solution draft05 says "16-state vector" and "ESKF + buffers ~10MB" but never defines the actual state vector, process model (F, Q matrices), measurement models (H matrices for VO and satellite), or noise parameters.
|
||||||
|
- **Source**: Source #5 (ludvigls/ESKF), Source #6 (EliaTarasov/ESKF)
|
||||||
|
- **Phase**: Assessment
|
||||||
|
- **Target Audience**: GPS-denied system
|
||||||
|
- **Confidence**: ✅ High
|
||||||
|
- **Related Dimension**: Sensor fusion completeness
|
||||||
|
|
||||||
|
## Fact #4 — Monocular VIO has scale ambiguity without excitation
|
||||||
|
- **Statement**: Monocular visual-inertial odometry cannot observe metric scale during constant-velocity flight (zero accelerometer excitation). This is a fundamental observability limitation. The solution uses monocular cuVSLAM + IMU, and fixed-wing UAVs fly mostly at constant velocity. Scale must be provided externally — via known altitude (barometric + predefined mission altitude) or satellite matching absolute position.
|
||||||
|
- **Source**: Source #7 (Range-VIO scale observability paper)
|
||||||
|
- **Phase**: Assessment
|
||||||
|
- **Target Audience**: GPS-denied system
|
||||||
|
- **Confidence**: ✅ High
|
||||||
|
- **Related Dimension**: Sensor fusion completeness, core algorithm correctness
|
||||||
|
|
||||||
|
## Fact #5 — cuVSLAM requires explicit camera calibration and IMU calibration
|
||||||
|
- **Statement**: PyCuVSLAM requires Camera(fx, fy, cx, cy, width, height) + Distortion model + ImuCalibration(gyroscope_noise_density, gyroscope_random_walk, accelerometer_noise_density, accelerometer_random_walk, frequency, T_imu_rig). The solution draft05 does not specify any camera calibration procedure, IMU noise parameters, or the T_imu_rig (IMU-to-camera) extrinsic transformation.
|
||||||
|
- **Source**: Source #4 (PyCuVSLAM docs)
|
||||||
|
- **Phase**: Assessment
|
||||||
|
- **Target Audience**: GPS-denied system
|
||||||
|
- **Confidence**: ✅ High
|
||||||
|
- **Related Dimension**: Visual odometry completeness
|
||||||
|
|
||||||
|
## Fact #6 — cuVSLAM IMU fallback provides ~1s acceptable tracking
|
||||||
|
- **Statement**: When visual tracking fails (featureless terrain, darkness), cuVSLAM falls back to IMU-only integration which provides "approximately 1 second" of acceptable tracking quality before drift becomes unacceptable. After that, tracking is lost.
|
||||||
|
- **Source**: Source #4 (PyCuVSLAM/Isaac ROS docs)
|
||||||
|
- **Phase**: Assessment
|
||||||
|
- **Target Audience**: GPS-denied system
|
||||||
|
- **Confidence**: ✅ High
|
||||||
|
- **Related Dimension**: Resilience, edge case handling
|
||||||
|
|
||||||
|
## Fact #7 — Disconnected route segments need satellite re-localization
|
||||||
|
- **Statement**: When a UAV makes a sharp turn and the next photos have no overlap with previous frames, cuVSLAM will lose tracking. The solution must re-localize using satellite imagery. The AC requires handling "more than 2 such disconnected segments" as a core strategy. Solution draft05 mentions this requirement but does not define the concrete re-localization algorithm (how satellite match triggers, how the new position is initialized in ESKF, how the map is connected to the previous segment).
|
||||||
|
- **Source**: Source #8 (NaviLoc), Source #9 (SatLoc-Fusion), AC requirements
|
||||||
|
- **Phase**: Assessment
|
||||||
|
- **Target Audience**: GPS-denied system
|
||||||
|
- **Confidence**: ✅ High
|
||||||
|
- **Related Dimension**: Functional completeness — disconnected segments
|
||||||
|
|
||||||
|
## Fact #8 — Coordinate transformation chain is undefined
|
||||||
|
- **Statement**: The system needs a well-defined coordinate transformation chain: (1) pixel coordinates → camera frame (using intrinsics), (2) camera frame → body frame (camera mount extrinsics), (3) body frame → NED frame (using attitude from ESKF), (4) NED → WGS84 (using reference point). For satellite matching: geo-referenced tile coordinates → WGS84. For object localization: pixel + camera angle + altitude → ground point → WGS84. None of these transformations are explicitly defined in draft05.
|
||||||
|
- **Source**: Source #15 (Istanbul Tech thesis), Source #7
|
||||||
|
- **Phase**: Assessment
|
||||||
|
- **Target Audience**: GPS-denied system
|
||||||
|
- **Confidence**: ✅ High
|
||||||
|
- **Related Dimension**: Coordinate system completeness
|
||||||
|
|
||||||
|
## Fact #9 — GSD normalization required for satellite-aerial matching
|
||||||
|
- **Statement**: Camera GSD at 600m altitude with ADTI 20L V1 (16mm, APS-C) is ~15.9 cm/pixel. Google Maps zoom 19 ≈ 0.3 m/pixel, zoom 18 ≈ 0.6 m/pixel. The GSD ratio is ~2:1 to ~4:1 depending on zoom level and altitude. Draft05's "pre-resize" step in the offline pipeline is mentioned but not specified: what resolution? what zoom level? The matching model (LiteSAM/XFeat) input size must match appropriately.
|
||||||
|
- **Source**: Source #14 (GSD matching paper), solution_draft05 calculations
|
||||||
|
- **Phase**: Assessment
|
||||||
|
- **Target Audience**: GPS-denied system
|
||||||
|
- **Confidence**: ✅ High
|
||||||
|
- **Related Dimension**: Satellite matching completeness
|
||||||
|
|
||||||
|
## Fact #10 — Google Maps imagery in conflict zones is intentionally outdated
|
||||||
|
- **Statement**: Google Maps deliberately serves older imagery (>1 year) for conflict zones in Ukraine. Ukrainian officials have flagged security concerns. The operational area (eastern/southern Ukraine) is directly in the conflict zone. Imagery may be 1-3+ years old, with seasonal differences (summer tiles vs winter flight, or vice versa). This is a HIGH-severity gap for satellite matching accuracy.
|
||||||
|
- **Source**: Source #12 (Google Maps Ukraine coverage)
|
||||||
|
- **Phase**: Assessment
|
||||||
|
- **Target Audience**: GPS-denied system
|
||||||
|
- **Confidence**: ✅ High
|
||||||
|
- **Related Dimension**: Satellite imagery quality risk
|
||||||
|
|
||||||
|
## Fact #11 — No operational procedures defined
|
||||||
|
- **Statement**: Mature GPS-denied systems (Auterion, PX4) define: pre-flight checklist (set home position, verify sensors, verify tile coverage), in-flight monitoring procedures (what to watch, when to intervene), and post-flight analysis (compare estimated vs actual GPS on return). Solution draft05 has no operational procedures section.
|
||||||
|
- **Source**: Source #10 (Auterion), Source #11 (PX4)
|
||||||
|
- **Phase**: Assessment
|
||||||
|
- **Target Audience**: GPS-denied system operators
|
||||||
|
- **Confidence**: ✅ High
|
||||||
|
- **Related Dimension**: Operational maturity
|
||||||
|
|
||||||
|
## Fact #12 — Object localization lacks implementation detail
|
||||||
|
- **Statement**: AC requires: "Other onboard AI systems can request GPS coordinates of objects detected by the AI camera." The solution says "trigonometric calculation using UAV GPS position, camera angle, zoom, altitude." But no API is defined, no coordinate math is shown, no handling of camera zoom/angle → ground projection is specified. The Viewpro A40 Pro gimbal angle and zoom parameters are not integrated.
|
||||||
|
- **Source**: Acceptance criteria, solution_draft05
|
||||||
|
- **Phase**: Assessment
|
||||||
|
- **Target Audience**: GPS-denied system
|
||||||
|
- **Confidence**: ✅ High
|
||||||
|
- **Related Dimension**: Object localization completeness
|
||||||
|
|
||||||
|
## Fact #13 — Tech stack document is inconsistent with draft05
|
||||||
|
- **Statement**: tech_stack.md says "camera @ ~3fps" in non-functional requirements. Draft05 corrected this to 0.7fps. tech_stack.md lists LiteSAM benchmark decision at 480px/640px/800px; draft05 uses 1280px. tech_stack.md doesn't mention EfficientLoFTR as fallback. These inconsistencies indicate the tech_stack.md was not updated after draft05 changes.
|
||||||
|
- **Source**: tech_stack.md, solution_draft05.md
|
||||||
|
- **Phase**: Assessment
|
||||||
|
- **Target Audience**: GPS-denied system
|
||||||
|
- **Confidence**: ✅ High
|
||||||
|
- **Related Dimension**: Document consistency, maturity
|
||||||
|
|
||||||
|
## Fact #14 — Confidence scoring is undefined in draft05
|
||||||
|
- **Statement**: Draft05 says "Confidence Scoring → GPS_INPUT Mapping — Unchanged from draft03" but draft05 is supposed to be self-contained. The actual confidence scoring logic (how VO confidence + satellite match confidence map to GPS_INPUT fix_type, hdop, horiz_accuracy) is never defined in the current draft. This is critical because ArduPilot's EKF uses these accuracy fields to weight the GPS data.
|
||||||
|
- **Source**: Source #2 (GPS_INPUT fields), solution_draft05
|
||||||
|
- **Phase**: Assessment
|
||||||
|
- **Target Audience**: GPS-denied system
|
||||||
|
- **Confidence**: ✅ High
|
||||||
|
- **Related Dimension**: Flight controller integration, confidence scoring
|
||||||
|
|
||||||
|
## Fact #15 — Initial bootstrap sequence is incomplete
|
||||||
|
- **Statement**: Draft05 startup reads GLOBAL_POSITION_INT to get initial GPS position. But: (1) cuVSLAM needs its first frame + features to initialize — how is the first satellite match triggered? (2) ESKF needs initial state — position from GPS, but velocity? attitude? (3) How does the system know GPS is denied and should start sending GPS_INPUT? (4) Is there a handoff protocol from real GPS to GPS-denied system?
|
||||||
|
- **Source**: solution_draft05, Source #10 (Auterion procedures)
|
||||||
|
- **Phase**: Assessment
|
||||||
|
- **Target Audience**: GPS-denied system
|
||||||
|
- **Confidence**: ✅ High
|
||||||
|
- **Related Dimension**: Startup and bootstrap completeness
|
||||||
|
|
||||||
|
## Fact #16 — No recovery from companion computer reboot
|
||||||
|
- **Statement**: AC requires: "On companion computer reboot mid-flight, the system should attempt to re-initialize from the flight controller's current IMU-extrapolated position." Draft05 does not address this scenario. The system needs: read current FC position estimate, re-initialize ESKF, reload TRT engines (~1-3s), start cuVSLAM with no prior map, trigger immediate satellite re-localization.
|
||||||
|
- **Source**: Acceptance criteria, solution_draft05
|
||||||
|
- **Phase**: Assessment
|
||||||
|
- **Target Audience**: GPS-denied system
|
||||||
|
- **Confidence**: ✅ High
|
||||||
|
- **Related Dimension**: Resilience, failsafe completeness
|
||||||
|
|
||||||
|
## Fact #17 — No position refinement mechanism
|
||||||
|
- **Statement**: AC states: "The system may refine previously calculated positions and send corrections to the flight controller as updated estimates." Draft05 does not define how this works. When a satellite match provides an absolute correction, do previously estimated positions get retroactively corrected? Is this communicated to the flight controller? How?
|
||||||
|
- **Source**: Acceptance criteria, solution_draft05
|
||||||
|
- **Phase**: Assessment
|
||||||
|
- **Target Audience**: GPS-denied system
|
||||||
|
- **Confidence**: ⚠️ Medium (AC is ambiguous about necessity)
|
||||||
|
- **Related Dimension**: Position refinement
|
||||||
|
|
||||||
|
## Fact #18 — Tile storage requirements not calculated
|
||||||
|
- **Statement**: The solution mentions "preload tiles ±2km" and "GeoHash-indexed directory" but never calculates: how many tiles are needed for a mission area, what storage space is required, what zoom levels to use, or how to handle the trade-off between tile coverage area and storage limit. At zoom 19 (~0.3m/pixel), each 256×256 tile covers ~77m × 77m. Covering a 200km flight path with ±2km buffer would require ~130,000 tiles (~2.5GB JPEG).
|
||||||
|
- **Source**: solution_draft05, tech_stack.md
|
||||||
|
- **Phase**: Assessment
|
||||||
|
- **Target Audience**: GPS-denied system
|
||||||
|
- **Confidence**: ⚠️ Medium (estimates based on standard tile sizes)
|
||||||
|
- **Related Dimension**: Offline preparation completeness
|
||||||
|
|
||||||
|
## Fact #19 — 3 consecutive failed frames → re-localization request undefined
|
||||||
|
- **Statement**: AC requires: "If system cannot determine position of 3 consecutive frames by any means, send re-localization request to ground station operator via telemetry link." Draft05 does not define: (1) the re-localization request message format, (2) what "any means" includes (VO failed + satellite match failed + IMU drift exceeded threshold?), (3) how the operator response is received and applied, (4) what the system does while waiting.
|
||||||
|
- **Source**: Acceptance criteria, solution_draft05
|
||||||
|
- **Phase**: Assessment
|
||||||
|
- **Target Audience**: GPS-denied system
|
||||||
|
- **Confidence**: ✅ High
|
||||||
|
- **Related Dimension**: Ground station integration, resilience
|
||||||
|
|
||||||
|
## Fact #20 — FastAPI endpoints mentioned but not defined
|
||||||
|
- **Statement**: Draft05 mentions FastAPI for "local IPC" but the REST API endpoints are only defined in security_analysis.md (POST /sessions, GET /sessions/{id}/stream, POST /sessions/{id}/anchor, DELETE /sessions/{id}). The solution draft itself doesn't specify the API contract, request/response schemas, or how other onboard systems interact.
|
||||||
|
- **Source**: solution_draft05, security_analysis.md
|
||||||
|
- **Phase**: Assessment
|
||||||
|
- **Target Audience**: GPS-denied system
|
||||||
|
- **Confidence**: ✅ High
|
||||||
|
- **Related Dimension**: API completeness
|
||||||
|
|
||||||
|
## Fact #21 — NaviLoc achieves 19.5m error with trajectory-level optimization
|
||||||
|
- **Statement**: Recent research (NaviLoc, 2025) shows that trajectory-level optimization treating satellite matching as noisy measurement achieves 19.5m mean error at 50-150m altitude, 16× better than per-frame matching. The solution's approach of per-keyframe satellite matching + ESKF correction is simpler but potentially less accurate than trajectory-level optimization.
|
||||||
|
- **Source**: Source #8 (NaviLoc)
|
||||||
|
- **Phase**: Assessment
|
||||||
|
- **Target Audience**: GPS-denied system
|
||||||
|
- **Confidence**: ⚠️ Medium (NaviLoc operates at lower altitude with higher overlap)
|
||||||
|
- **Related Dimension**: Algorithm maturity, accuracy potential
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
# Comparison Framework
|
||||||
|
|
||||||
|
## Selected Framework Type
|
||||||
|
Knowledge Organization + Problem Diagnosis — mapping completeness dimensions against solution state
|
||||||
|
|
||||||
|
## Completeness Dimensions
|
||||||
|
|
||||||
|
1. Core Pipeline Definition
|
||||||
|
2. Sensor Fusion (ESKF) Specification
|
||||||
|
3. Visual Odometry Configuration
|
||||||
|
4. Satellite Image Matching Pipeline
|
||||||
|
5. Coordinate System & Transformations
|
||||||
|
6. Flight Controller Integration (GPS_INPUT)
|
||||||
|
7. Disconnected Route Segment Handling
|
||||||
|
8. Startup, Bootstrap & Failsafe
|
||||||
|
9. Object Localization
|
||||||
|
10. Offline Preparation Pipeline
|
||||||
|
11. Ground Station Integration
|
||||||
|
12. Operational Procedures
|
||||||
|
13. API & Inter-system Communication
|
||||||
|
14. Document Consistency
|
||||||
|
15. Testing Coverage vs AC
|
||||||
|
|
||||||
|
## Maturity Scoring
|
||||||
|
|
||||||
|
| Score | Level | Description |
|
||||||
|
|-------|-------|-------------|
|
||||||
|
| 1 | Concept | Mentioned but not specified |
|
||||||
|
| 2 | Defined | Architecture-level description, component selected |
|
||||||
|
| 3 | Detailed | Implementation details, data flows, algorithms specified |
|
||||||
|
| 4 | Validated | Benchmarked, tested, edge cases handled |
|
||||||
|
| 5 | Production | Field-tested, operational procedures, monitoring |
|
||||||
|
|
||||||
|
## Completeness Assessment Matrix
|
||||||
|
|
||||||
|
| Dimension | Current State | Maturity | Key Gaps | Facts |
|
||||||
|
|-----------|--------------|----------|----------|-------|
|
||||||
|
| Core Pipeline | VO → ESKF → GPS_INPUT flow well-defined. Dual CUDA stream architecture. Camera rate corrected to 0.7fps. Time budgets calculated. | 3 | Self-contained — but references "unchanged from draft03" in several places instead of restating | — |
|
||||||
|
| ESKF Specification | "16-state vector", "ESKF + buffers ~10MB", "ESKF measurement update" | 1.5 | No state vector definition, no process model (F,Q), no measurement models (H for VO, H for satellite), no noise parameters, no scale observability analysis, no tuning strategy | #3, #4 |
|
||||||
|
| VO Configuration | cuVSLAM selected, 0.7fps feasibility analyzed, pyramid-LK range calculated, overlap >95% | 2.5 | No camera calibration procedure, no IMU calibration parameters (noise density, random walk), no T_imu_rig extrinsic, no cuVSLAM mode selection (Mono vs Inertial), no cuVSLAM initialization procedure | #5, #6 |
|
||||||
|
| Satellite Matching | LiteSAM/EfficientLoFTR/XFeat decision tree, TRT conversion workflow, async Stream B | 2.5 | No GSD normalization spec, no tile-to-camera scale matching, no matching confidence threshold, no geometric verification details beyond "RANSAC homography", no match-to-WGS84 conversion | #9, #14 |
|
||||||
|
| Coordinate System | WGS84 output mentioned. Camera footprint calculated. | 1 | No transformation chain defined (pixel→camera→body→NED→WGS84). No camera-to-body extrinsic. No reference point definition for NED. No handling of terrain elevation. | #8 |
|
||||||
|
| Flight Controller Integration | pymavlink, GPS_INPUT, 5-10Hz, UART | 2 | No GPS_INPUT field population spec (where do velocity, accuracy, hdop come from?). No fix_type mapping. No GPS time conversion. No ignore_flags. Confidence scoring undefined in current draft. | #1, #2, #14 |
|
||||||
|
| Disconnected Segments | Mentioned in AC, satellite matching acknowledged as solution | 1.5 | No algorithm for detecting tracking loss. No re-localization trigger. No position initialization after re-localization. No map discontinuity handling. | #7 |
|
||||||
|
| Startup & Failsafe | 12-step startup sequence. Engine load times. | 2 | No GPS-denied handoff protocol. No mid-flight reboot recovery. No "3 consecutive failed frames" handling. No operator re-localization workflow. | #15, #16, #19 |
|
||||||
|
| Object Localization | "Trigonometric calculation" mentioned | 1 | No math defined. No API endpoint. No Viewpro gimbal integration spec. No accuracy analysis. | #12 |
|
||||||
|
| Offline Preparation | Tile download → validate → pre-resize → store. TRT engine build. | 2 | No zoom level selection. No storage calculation. No coverage verification. No tile freshness check. No pre-flight validation tool. | #18 |
|
||||||
|
| Ground Station Integration | NAMED_VALUE_FLOAT at 1Hz for confidence/drift. Operator re-localization hint mentioned in AC. | 1.5 | Re-localization request/response undefined. Ground station display requirements undefined. Operator workflow undefined. | #19 |
|
||||||
|
| Operational Procedures | None defined | 0 | No pre-flight checklist. No in-flight monitoring guide. No post-flight analysis. No failure response procedures. | #11 |
|
||||||
|
| API & IPC | FastAPI mentioned for "local IPC" | 1.5 | Endpoints only in security_analysis.md, not in solution. No request/response schemas. No SSE event format. No object localization API. | #20 |
|
||||||
|
| Document Consistency | 3 documents (draft05, tech_stack, security) | — | tech_stack.md has 3fps (should be 0.7fps). LiteSAM resolution mismatch. EfficientLoFTR missing from tech_stack. | #13 |
|
||||||
|
| Testing vs AC | Tests cover TRT, cuVSLAM 0.7fps, shutter. | 2.5 | No explicit mapping of tests to AC items. Missing tests: disconnected segments, re-localization, 3-consecutive-failure, object localization, operator workflow, mid-flight reboot. | — |
|
||||||
|
|
||||||
|
## Overall Maturity Assessment
|
||||||
|
|
||||||
|
| Category | Avg Score | Assessment |
|
||||||
|
|----------|-----------|------------|
|
||||||
|
| Hardware/Platform | 3.5 | Well-researched: UAV specs, camera analysis, memory budget, thermal |
|
||||||
|
| Core Algorithms (VO, matching) | 2.5 | Component selection solid, but implementation specs missing |
|
||||||
|
| Sensor Fusion (ESKF) | 1.5 | Severely under-specified |
|
||||||
|
| System Integration | 1.5 | GPS_INPUT, coordinate transforms, API all incomplete |
|
||||||
|
| Operational Readiness | 0.5 | No operational procedures, no deployment pipeline |
|
||||||
|
| **Overall** | **~2.0** | **Architecture-level design, not implementation-ready** |
|
||||||
@@ -0,0 +1,166 @@
|
|||||||
|
# Reasoning Chain
|
||||||
|
|
||||||
|
## Dimension 1: ESKF Sensor Fusion Specification
|
||||||
|
|
||||||
|
### Fact Confirmation
|
||||||
|
Per Fact #3, standard ESKF for UAV VIO uses 15-16 state error vector: δp[3], δv[3], δθ[3], δba[3], δbg[3]. Per Fact #4, monocular VIO cannot observe metric scale during constant-velocity flight (fundamental observability limitation). Per Fact #7, scale requires external constraint (altitude or satellite absolute position).
|
||||||
|
|
||||||
|
### Current State
|
||||||
|
Draft05 says "Custom ESKF (NumPy/SciPy)", "16-state vector", "ESKF measurement update ~1ms", "ESKF IMU prediction at 5-10Hz". But provides zero mathematical detail.
|
||||||
|
|
||||||
|
### Conclusion
|
||||||
|
The ESKF is the **most under-specified critical component**. Without defining:
|
||||||
|
- State vector and error state vector explicitly
|
||||||
|
- Process model (how IMU data propagates the state)
|
||||||
|
- VO measurement model (how cuVSLAM relative pose updates the filter)
|
||||||
|
- Satellite measurement model (how absolute position corrections are applied)
|
||||||
|
- How scale is maintained (altitude constraint? satellite corrections only?)
|
||||||
|
- Q and R matrices (at least initial values and tuning approach)
|
||||||
|
|
||||||
|
...the system cannot be implemented. The ESKF is the central hub connecting all sensors — its specification drives the entire data flow.
|
||||||
|
|
||||||
|
### Confidence: ✅ High
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Dimension 2: Flight Controller Integration (GPS_INPUT)
|
||||||
|
|
||||||
|
### Fact Confirmation
|
||||||
|
Per Fact #1, ArduPilot requires minimum 5Hz GPS_INPUT rate. Per Fact #2, GPS_INPUT has 15+ mandatory fields including velocity, accuracy, fix_type, GPS time. Per Fact #14, confidence scoring that maps internal state to GPS_INPUT accuracy fields is undefined.
|
||||||
|
|
||||||
|
### Current State
|
||||||
|
Draft05 specifies: pymavlink, GPS_INPUT, 5-10Hz, UART. This satisfies the rate requirement. But the message population is unspecified.
|
||||||
|
|
||||||
|
### Conclusion
|
||||||
|
The GPS_INPUT integration has the right architecture (5-10Hz, pymavlink, UART) but is missing the **data mapping layer**:
|
||||||
|
- `vn, ve, vd` must come from ESKF velocity estimate — requires ESKF to output velocity
|
||||||
|
- `horiz_accuracy, vert_accuracy` must come from ESKF covariance matrix (sqrt of position covariance diagonal)
|
||||||
|
- `hdop, vdop` need to be synthesized from accuracy values (hdop ≈ horiz_accuracy / expected_CEP_factor)
|
||||||
|
- `fix_type` must map from internal confidence (3=3D fix when satellite-anchored, 2=2D when VO-only?)
|
||||||
|
- `speed_accuracy` from ESKF velocity covariance
|
||||||
|
- GPS time (time_week, time_week_ms) requires conversion from system time to GPS epoch
|
||||||
|
- `satellites_visible` should be set to a constant (e.g., 10) to avoid triggering satellite-count failsafes
|
||||||
|
|
||||||
|
This is a tractable implementation detail but must be specified before coding.
|
||||||
|
|
||||||
|
### Confidence: ✅ High
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Dimension 3: Coordinate System & Transformations
|
||||||
|
|
||||||
|
### Fact Confirmation
|
||||||
|
Per Fact #8, the system needs pixel → camera → body → NED → WGS84 chain. Per Fact #9, satellite tiles have different GSD than camera imagery. Per Source #15, similar systems define explicit coordinate transforms with PnP solvers.
|
||||||
|
|
||||||
|
### Current State
|
||||||
|
Draft05 calculates camera footprint and GSD but never defines the transformation chain. Object localization mentions "trigonometric calculation" without math.
|
||||||
|
|
||||||
|
### Conclusion
|
||||||
|
This is a **fundamental architectural gap**. Every position estimate flows through coordinate transforms. Without defining them:
|
||||||
|
- cuVSLAM outputs relative pose in camera frame — how is this converted to NED displacement?
|
||||||
|
- Satellite matching outputs pixel correspondences — how does homography → WGS84 position?
|
||||||
|
- Object localization needs camera ray → ground intersection — impossible without camera-to-body and body-to-NED transforms
|
||||||
|
- The camera is "not autostabilized" — so body frame attitude matters for ground projection
|
||||||
|
|
||||||
|
The fix requires defining: camera intrinsic matrix K, camera-to-body rotation T_cam_body, and the ESKF attitude estimate for body-to-NED.
|
||||||
|
|
||||||
|
### Confidence: ✅ High
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Dimension 4: Disconnected Route Segments
|
||||||
|
|
||||||
|
### Fact Confirmation
|
||||||
|
Per Fact #7, AC explicitly requires handling disconnected segments as "core to the system." Per Fact #6, cuVSLAM IMU fallback gives ~1s before tracking loss. Per Source #8, trajectory-level optimization can handle segment connections.
|
||||||
|
|
||||||
|
### Current State
|
||||||
|
Draft05 acknowledges this in AC but the solution section says "sharp-turn frames are expected to fail VO and should be handled by satellite-based re-localization." No algorithm is specified.
|
||||||
|
|
||||||
|
### Conclusion
|
||||||
|
The solution needs a concrete **re-localization pipeline**:
|
||||||
|
1. Detect tracking loss (cuVSLAM returns tracking_lost state)
|
||||||
|
2. Continue ESKF with IMU-only prediction (high uncertainty growth)
|
||||||
|
3. Immediately trigger satellite matching on next available frame
|
||||||
|
4. If satellite match succeeds: reset ESKF position to matched position, reset cuVSLAM (or start new track)
|
||||||
|
5. If satellite match fails: retry on next frame, increment failure counter
|
||||||
|
6. If 3 consecutive failures: send re-localization request to ground station
|
||||||
|
7. When new segment starts: mark as disconnected, continue building trajectory
|
||||||
|
8. Optionally: if a later satellite match connects two segments to the same reference, merge them
|
||||||
|
|
||||||
|
This is not trivial but follows directly from the existing architecture. It's a missing algorithm, not a missing component.
|
||||||
|
|
||||||
|
### Confidence: ✅ High
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Dimension 5: Startup Bootstrap & Failsafe
|
||||||
|
|
||||||
|
### Fact Confirmation
|
||||||
|
Per Fact #15, the bootstrap sequence has gaps (first satellite match, initial ESKF state, GPS-denied handoff). Per Fact #16, AC requires mid-flight reboot recovery. Per Fact #19, AC requires 3-consecutive-failure re-localization request.
|
||||||
|
|
||||||
|
### Current State
|
||||||
|
Draft05 has a 12-step startup sequence that covers the happy path. The failure paths and special cases are not addressed.
|
||||||
|
|
||||||
|
### Conclusion
|
||||||
|
Three failsafe scenarios need specification:
|
||||||
|
1. **GPS-denied handoff**: How does the system know to start? Options: (a) always running — takes over when GPS quality degrades, (b) operator command, (c) automatic GPS quality monitoring. The system should probably always be running in parallel and the FC uses the best available source.
|
||||||
|
2. **Mid-flight reboot**: Read FC position → init ESKF with high uncertainty → start cuVSLAM → immediate satellite match → within ~5s should have a position estimate. TRT engine load (1-3s) is the main startup cost.
|
||||||
|
3. **3 consecutive failures**: Define "failure" precisely (VO lost + satellite match failed + IMU-only drift > threshold). Send NAMED_VALUE_FLOAT or custom MAVLink message to ground station. Define operator response format.
|
||||||
|
|
||||||
|
### Confidence: ✅ High
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Dimension 6: Satellite Matching Pipeline Details
|
||||||
|
|
||||||
|
### Fact Confirmation
|
||||||
|
Per Fact #9, camera GSD is ~15.9 cm/pixel at 600m with ADTI+16mm lens. Satellite at zoom 19 is ~0.3 m/pixel. Per Fact #10, Google Maps imagery in Ukraine conflict zone is intentionally >1 year old. Per Fact #14, the solution says "pre-resize" but doesn't specify to what resolution.
|
||||||
|
|
||||||
|
### Current State
|
||||||
|
Draft05 has a solid model selection decision tree (LiteSAM → EfficientLoFTR → XFeat) and TRT conversion workflow. But the actual matching pipeline data flow is incomplete.
|
||||||
|
|
||||||
|
### Conclusion
|
||||||
|
The matching pipeline needs:
|
||||||
|
- **Input preparation**: Camera frame (5456×3632 at ~15.9 cm/pixel at 600m) → downsample to matcher input resolution (1280px for LiteSAM). Satellite tile at zoom 18 (~0.6 m/pixel) → no resize needed if using 256px tiles, or assemble 5×5 tile mosaic for coverage.
|
||||||
|
- **GSD matching**: Either downsample camera image to satellite GSD, or specify that the matcher handles multi-scale internally. LiteSAM was designed for satellite-aerial matching so it may handle this. XFeat is general-purpose and may need explicit scale normalization.
|
||||||
|
- **Tile selection**: Given ESKF position estimate + uncertainty, select the correct satellite tile(s). What if the position estimate has drifted and the wrong tile is selected? Need a search radius based on ESKF covariance.
|
||||||
|
- **Match → position**: Homography from RANSAC → decompose to get translation in satellite coordinate frame → convert to WGS84 using tile's geo-reference.
|
||||||
|
- **Seasonal/temporal mismatch**: Tiles could be from different seasons. Feature matching must be robust to appearance changes.
|
||||||
|
|
||||||
|
### Confidence: ✅ High
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Dimension 7: Operational Maturity
|
||||||
|
|
||||||
|
### Fact Confirmation
|
||||||
|
Per Fact #11, mature systems (Auterion, PX4) define pre-flight checklists, in-flight monitoring, failure response procedures. Per Fact #13, documents are inconsistent (tech_stack.md still says 3fps).
|
||||||
|
|
||||||
|
### Current State
|
||||||
|
Zero operational procedures defined. Documents are partially inconsistent.
|
||||||
|
|
||||||
|
### Conclusion
|
||||||
|
This is expected at this stage of development (architecture/design phase). Operational procedures should come after implementation and initial testing. However, the document inconsistencies should be fixed now to avoid confusion during implementation. The tech_stack.md and solution_draft should be aligned.
|
||||||
|
|
||||||
|
### Confidence: ✅ High
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Dimension 8: Object Localization
|
||||||
|
|
||||||
|
### Fact Confirmation
|
||||||
|
Per Fact #12, AC requires other AI systems to request GPS coordinates of detected objects. The Viewpro A40 Pro gimbal has configurable angle and zoom.
|
||||||
|
|
||||||
|
### Current State
|
||||||
|
Draft05 says "trigonometric calculation using UAV GPS position, camera angle, zoom, altitude. Flat terrain assumed."
|
||||||
|
|
||||||
|
### Conclusion
|
||||||
|
The math is straightforward but needs specification:
|
||||||
|
- Input: pixel coordinates (u,v) in Viewpro image, gimbal angles (pan, tilt), zoom level, UAV position (from GPS-denied system), UAV altitude
|
||||||
|
- Process: (1) pixel → ray in camera frame using intrinsics + zoom, (2) camera frame → body frame using gimbal angles, (3) body frame → NED using UAV attitude, (4) ray-ground intersection assuming flat terrain at known altitude, (5) NED offset → WGS84
|
||||||
|
- Output: lat, lon of object + accuracy estimate (propagated from UAV position accuracy + gimbal angle uncertainty)
|
||||||
|
- API: FastAPI endpoint for other onboard systems to call
|
||||||
|
|
||||||
|
This is a 2-point complexity task but should be specified in the solution.
|
||||||
|
|
||||||
|
### Confidence: ✅ High
|
||||||
@@ -0,0 +1,96 @@
|
|||||||
|
# Validation Log
|
||||||
|
|
||||||
|
## Validation Scenario 1: Normal Straight Flight (Happy Path)
|
||||||
|
|
||||||
|
### Expected Based on Conclusions
|
||||||
|
UAV flies straight at 70 km/h, 600m altitude. ADTI captures at 0.7fps. cuVSLAM processes each frame (~9ms), ESKF fuses VO + IMU. Every 5-10 frames, satellite matching provides absolute correction. GPS_INPUT sent at 5-10Hz.
|
||||||
|
|
||||||
|
### Actual Validation Results
|
||||||
|
The happy path is well-specified in draft05. Time budgets, memory budgets, overlap calculations all valid. The 5-10Hz ESKF IMU prediction fills gaps between 0.7fps camera frames. Satellite matching async on Stream B.
|
||||||
|
|
||||||
|
**GAP**: Even on straight flight, the GPS_INPUT message field population is undefined. Where does velocity come from? What fix_type is sent? What accuracy values?
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Validation Scenario 2: Sharp Turn with No Overlap
|
||||||
|
|
||||||
|
### Expected Based on Conclusions
|
||||||
|
UAV makes a 90° turn. Next frame has zero overlap with previous. cuVSLAM loses tracking. System falls back to IMU. ESKF uncertainty grows rapidly. Satellite matching on next frame provides re-localization.
|
||||||
|
|
||||||
|
### Actual Validation Results
|
||||||
|
**CRITICAL GAP**: No algorithm defined for this scenario. Questions:
|
||||||
|
1. How does the system detect cuVSLAM tracking loss? (cuVSLAM API presumably returns a tracking state)
|
||||||
|
2. During IMU-only phase, what is the ESKF prediction uncertainty growth rate? (~1-2m/s drift with consumer IMU)
|
||||||
|
3. When satellite match succeeds after the turn, how is ESKF re-initialized? (measurement update with very high innovation? or state reset?)
|
||||||
|
4. How is cuVSLAM re-initialized on the new heading? (new track from scratch? or cuVSLAM loop closure if it sees previous terrain?)
|
||||||
|
5. If the turn area is over featureless terrain (farmland), satellite matching may also fail — then what?
|
||||||
|
|
||||||
|
The AC says "sharp-turn frames should be within 200m drift and angle <70 degrees" — this bounds the problem but the solution doesn't address it algorithmically.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Validation Scenario 3: Long Flight Over Uniform Terrain
|
||||||
|
|
||||||
|
### Expected Based on Conclusions
|
||||||
|
UAV flies 50km straight over large agricultural fields. cuVSLAM may struggle with low-texture terrain. Satellite matching is the only absolute correction source.
|
||||||
|
|
||||||
|
### Actual Validation Results
|
||||||
|
This scenario tests the limits of the design:
|
||||||
|
- cuVSLAM at 600m altitude sees ~577m × 870m footprint. If it's a single wheat field, features may be sparse. cuVSLAM falls back to IMU (~1s acceptable, then tracking lost).
|
||||||
|
- Satellite matching must carry the entire position estimation burden.
|
||||||
|
- At 0.7fps with keyframe every 5-10 frames: satellite match every 7-14s.
|
||||||
|
- Between matches, IMU-only drift at 70 km/h: ~14m/s × time × drift_rate. With consumer IMU: ~1-5m drift per second.
|
||||||
|
- Over 14s between matches: ~14-70m potential drift. AC requires <100m between anchors.
|
||||||
|
|
||||||
|
**GAP**: The system's behavior in this degraded mode needs explicit specification. Is this VO-failed + satellite-only + IMU acceptable? What's the accuracy?
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Validation Scenario 4: First Frame After GPS Denial
|
||||||
|
|
||||||
|
### Expected Based on Conclusions
|
||||||
|
GPS was working. Now it's denied/spoofed. System takes over.
|
||||||
|
|
||||||
|
### Actual Validation Results
|
||||||
|
**GAP**: No handoff protocol defined. Questions:
|
||||||
|
1. How does the system detect GPS denial? (it doesn't — it's assumed the operator knows)
|
||||||
|
2. The initial ESKF state comes from GLOBAL_POSITION_INT — but this might be the spoofed GPS. How to validate?
|
||||||
|
3. If GPS is being spoofed rather than denied, the initial position could be wrong by kilometers.
|
||||||
|
4. Draft05 assumes clean initial GPS. This is reasonable for the first version but should be acknowledged as a limitation.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Validation Scenario 5: Mid-Flight Companion Computer Reboot
|
||||||
|
|
||||||
|
### Expected Based on Conclusions
|
||||||
|
Companion computer crashes and reboots. Flight controller continues flying on IMU dead reckoning.
|
||||||
|
|
||||||
|
### Actual Validation Results
|
||||||
|
**GAP**: AC requires recovery. Draft05 doesn't address it. Sequence should be:
|
||||||
|
1. Jetson boots (~30-60s depending on boot time)
|
||||||
|
2. GPS-Denied service starts (systemd)
|
||||||
|
3. Connect to FC, get current position (IMU-extrapolated, may have significant drift)
|
||||||
|
4. Load TRT engines (~1-3s each, total ~2-6s)
|
||||||
|
5. Start cuVSLAM (no prior map, fresh start)
|
||||||
|
6. Immediate satellite match to get absolute position
|
||||||
|
7. Total recovery time: ~35-70s. During this time, FC uses IMU-only. At 70 km/h: ~700-1400m of uncontrolled drift.
|
||||||
|
|
||||||
|
This is a real operational concern and should be documented even if the solution is "acknowledge the limitation."
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Counterexamples
|
||||||
|
- **NaviLoc achieves 19.5m at lower altitude**: Our system operates at 600-1000m with larger footprints and coarser GSD. The accuracy requirement (50m for 80%, 20m for 60%) is less demanding. The simpler ESKF approach may be adequate.
|
||||||
|
- **SatLoc-Fusion uses DinoV2 for place recognition**: Our system uses feature matching (LiteSAM/XFeat) which is more precise but less robust to appearance changes. DinoV2 is more robust to seasonal changes but gives coarser position.
|
||||||
|
|
||||||
|
## Review Checklist
|
||||||
|
- [x] Draft conclusions consistent with fact cards
|
||||||
|
- [x] No important dimensions missed
|
||||||
|
- [x] No over-extrapolation
|
||||||
|
- [ ] Issue: ESKF specification is too underspecified to validate accuracy claims
|
||||||
|
- [ ] Issue: Disconnected segment handling is critical AC and has no algorithm
|
||||||
|
- [ ] Issue: GPS_INPUT field mapping undocumented
|
||||||
|
- [ ] Issue: Object localization API undefined
|
||||||
|
|
||||||
|
## Conclusions Requiring Revision
|
||||||
|
None requiring reversal. All identified gaps are genuine and supported by facts.
|
||||||
@@ -0,0 +1,568 @@
|
|||||||
|
# Solution Draft
|
||||||
|
|
||||||
|
## Assessment Findings
|
||||||
|
|
||||||
|
| Old Component Solution | Weak Point (functional/security/performance) | New Solution |
|
||||||
|
|------------------------|----------------------------------------------|-------------|
|
||||||
|
| ESKF described as "16-state vector, ~10MB" with no mathematical specification | **Functional**: No state vector, no process model (F,Q), no measurement models (H for VO, H for satellite), no noise parameters, no scale observability analysis. Impossible to implement or validate accuracy claims. | **Define complete ESKF specification**: 15-state error vector, IMU-driven prediction, dual measurement models (VO relative pose, satellite absolute position), initial Q/R values, scale constraint via altitude + satellite corrections. |
|
||||||
|
| GPS_INPUT at 5-10Hz via pymavlink — no field mapping | **Functional**: GPS_INPUT requires 15+ fields (velocity, accuracy, hdop, fix_type, GPS time). No specification of how ESKF state maps to these fields. ArduPilot requires minimum 5Hz. | **Define GPS_INPUT population spec**: velocity from ESKF, accuracy from covariance, fix_type from confidence tier, GPS time from system clock conversion, synthesized hdop/vdop. |
|
||||||
|
| Confidence scoring "unchanged from draft03" — not in draft05 | **Functional**: Draft05 is supposed to be self-contained. Confidence scoring determines GPS_INPUT accuracy fields and fix_type — directly affects how ArduPilot EKF weights the position data. | **Define confidence scoring inline**: 3 tiers (satellite-anchored, VO-tracked, IMU-only) mapping to fix_type + accuracy values. |
|
||||||
|
| Coordinate transformations not defined | **Functional**: No pixel→camera→body→NED→WGS84 chain. Camera is not autostabilized, so body attitude matters. Satellite match → WGS84 conversion undefined. Object localization impossible without these transforms. | **Define coordinate transformation chain**: camera intrinsics K, camera-to-body extrinsic T_cam_body, body-to-NED from ESKF attitude, NED origin at mission start point. |
|
||||||
|
| Disconnected route segments — "satellite re-localization" mentioned but no algorithm | **Functional**: AC requires handling as "core to the system." Multiple disconnected segments expected. No tracking-loss detection, no re-localization trigger, no ESKF re-initialization, no cuVSLAM restart procedure. | **Define re-localization pipeline**: detect cuVSLAM tracking loss → IMU-only ESKF prediction → trigger satellite match on every frame → on match success: ESKF position reset + cuVSLAM restart → on 3 consecutive failures: operator re-localization request. |
|
||||||
|
| No startup handoff from GPS to GPS-denied | **Functional**: System reads GLOBAL_POSITION_INT at startup but no protocol for when GPS is lost/spoofed vs system start. No validation of initial position. | **Define handoff protocol**: system runs continuously, FC receives both real GPS and GPS_INPUT. GPS-denied system always provides its estimate; FC selects best source. Initial position validated against first satellite match. |
|
||||||
|
| No mid-flight reboot recovery | **Functional**: AC requires: "re-initialize from flight controller's current IMU-extrapolated position." No procedure defined. Recovery time estimation missing. | **Define reboot recovery sequence**: read FC position → init ESKF with high uncertainty → load TRT engines → start cuVSLAM → immediate satellite match. Estimated recovery: ~35-70s. Document as known limitation. |
|
||||||
|
| 3-consecutive-failure re-localization request undefined | **Functional**: AC requires ground station re-localization request. No message format, no operator workflow, no system behavior while waiting. | **Define re-localization protocol**: detect 3 failures → send custom MAVLink message with last known position + uncertainty → operator provides approximate coordinates → system uses as ESKF measurement with high covariance. |
|
||||||
|
| Object localization — "trigonometric calculation" with no details | **Functional**: No math, no API, no Viewpro gimbal integration, no accuracy propagation. Other onboard systems cannot use this component as specified. | **Define object localization**: pixel→ray using Viewpro intrinsics + gimbal angles → body frame → NED → ray-ground intersection → WGS84. FastAPI endpoint: POST /objects/locate. Accuracy propagated from UAV position + gimbal uncertainty. |
|
||||||
|
| Satellite matching — GSD normalization and tile selection unspecified | **Functional**: Camera GSD ~15.9 cm/px at 600m vs satellite ~0.3 m/px at zoom 19. The "pre-resize" step is mentioned but not specified. Tile selection radius based on ESKF uncertainty not defined. | **Define GSD handling**: downsample camera frame to match satellite GSD. Define tile selection: ESKF position ± 3σ_horizontal → select tiles covering that area. Assemble tile mosaic for matching. |
|
||||||
|
| Satellite tile storage requirements not calculated | **Functional**: "±2km" preload mentioned but no storage estimate. At zoom 19: a 200km path with ±2km buffer requires ~130K tiles (~2.5GB). | **Calculate tile storage**: specify zoom level (18 preferred — 0.6m/px, 4× fewer tiles), estimate storage per mission profile, define maximum mission area by storage limit. |
|
||||||
|
| FastAPI endpoints not in solution draft | **Functional**: Endpoints only in security_analysis.md. No request/response schemas. No SSE event format. No object localization endpoint. | **Consolidate API spec in solution**: define all endpoints, SSE event schema, object localization endpoint. Reference security_analysis.md for auth. |
|
||||||
|
| cuVSLAM configuration missing (calibration, IMU params, mode) | **Functional**: No camera calibration procedure, no IMU noise parameters, no T_imu_rig extrinsic, no mode selection (Mono vs Inertial). | **Define cuVSLAM configuration**: use Inertial mode, specify required calibration data (camera intrinsics, distortion, IMU noise params from datasheet, T_imu_rig from physical measurement), define calibration procedure. |
|
||||||
|
| tech_stack.md inconsistent with draft05 | **Functional**: tech_stack.md says 3fps (should be 0.7fps), LiteSAM at 480px (should be 1280px), missing EfficientLoFTR. | **Flag for update**: tech_stack.md must be synchronized with draft05 corrections. Not addressed in this draft — separate task. |
|
||||||
|
|
||||||
|
## Overall Maturity Assessment
|
||||||
|
|
||||||
|
| Category | Maturity (1-5) | Assessment |
|
||||||
|
|----------|---------------|------------|
|
||||||
|
| Hardware & Platform Selection | 3.5 | UAV airframe, cameras, Jetson, batteries — well-researched with specs, weight budget, endurance calculations. Ready for procurement. |
|
||||||
|
| Core Algorithm Selection | 3.0 | cuVSLAM, LiteSAM/XFeat, ESKF — components selected with comparison tables, fallback chains, decision trees. Day-one benchmarks defined. |
|
||||||
|
| AI Inference Runtime | 3.5 | TRT Engine migration thoroughly analyzed. Conversion workflows, memory savings, performance estimates. Code wrapper provided. |
|
||||||
|
| Sensor Fusion (ESKF) | 1.5 | Mentioned but not specified. No implementable detail. Blockerfor coding. |
|
||||||
|
| System Integration | 1.5 | GPS_INPUT, coordinate transforms, inter-component data flow — all under-specified. |
|
||||||
|
| Edge Cases & Resilience | 1.0 | Disconnected segments, reboot recovery, re-localization — acknowledged but no algorithms. |
|
||||||
|
| Operational Readiness | 0.5 | No pre-flight procedures, no in-flight monitoring, no failure response. |
|
||||||
|
| Security | 3.0 | Comprehensive threat model, OP-TEE analysis, LUKS, secure boot. Well-researched. |
|
||||||
|
| **Overall TRL** | **~2.5** | **Technology concept formulated + some component validation. Not implementation-ready.** |
|
||||||
|
|
||||||
|
The solution is at approximately **TRL 3** (proof of concept) for hardware/algorithm selection and **TRL 1-2** (basic concept) for system integration, ESKF, and operational procedures.
|
||||||
|
|
||||||
|
## Product Solution Description
|
||||||
|
|
||||||
|
A real-time GPS-denied visual navigation system for fixed-wing UAVs, running on a Jetson Orin Nano Super (8GB). All AI model inference uses native TensorRT Engine files. The system replaces the GPS module by sending MAVLink GPS_INPUT messages via pymavlink over UART at 5-10Hz.
|
||||||
|
|
||||||
|
Position is determined by fusing: (1) CUDA-accelerated visual odometry (cuVSLAM in Inertial mode) from ADTI 20L V1 at 0.7 fps sustained, (2) absolute position corrections from satellite image matching (LiteSAM or XFeat — TRT Engine FP16) using keyframes from the same ADTI image stream, and (3) IMU data from the flight controller via ESKF. Viewpro A40 Pro is reserved for AI object detection only.
|
||||||
|
|
||||||
|
The ESKF is the central state estimator with 15-state error vector. It fuses:
|
||||||
|
- **IMU prediction** at 5-10Hz (high-frequency pose propagation)
|
||||||
|
- **cuVSLAM VO measurement** at 0.7Hz (relative pose correction)
|
||||||
|
- **Satellite matching measurement** at ~0.07-0.14Hz (absolute position correction)
|
||||||
|
|
||||||
|
GPS_INPUT messages carry position, velocity, and accuracy derived from the ESKF state and covariance.
|
||||||
|
|
||||||
|
**Hard constraint**: ADTI 20L V1 shoots at 0.7 fps sustained (1430ms interval). Full VO+ESKF pipeline within 400ms per frame. Satellite matching async on keyframes (every 5-10 camera frames). GPS_INPUT at 5-10Hz (ESKF IMU prediction fills gaps between camera frames).
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────────────────────────────────────────┐
|
||||||
|
│ OFFLINE (Before Flight) │
|
||||||
|
│ 1. Satellite Tiles → Download & Validate → Pre-resize → Store │
|
||||||
|
│ (Google Maps) (≥0.5m/px, <2yr) (matcher res) (GeoHash)│
|
||||||
|
│ 2. TRT Engine Build (one-time per model version): │
|
||||||
|
│ PyTorch model → reparameterize → ONNX export → trtexec --fp16 │
|
||||||
|
│ Output: litesam.engine, xfeat.engine │
|
||||||
|
│ 3. Camera + IMU calibration (one-time per hardware unit) │
|
||||||
|
│ 4. Copy tiles + engines + calibration to Jetson storage │
|
||||||
|
└─────────────────────────────────────────────────────────────────────┘
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
┌─────────────────────────────────────────────────────────────────────┐
|
||||||
|
│ ONLINE (During Flight) │
|
||||||
|
│ │
|
||||||
|
│ STARTUP: │
|
||||||
|
│ 1. pymavlink → read GLOBAL_POSITION_INT → init ESKF state │
|
||||||
|
│ 2. Load TRT engines + allocate GPU buffers │
|
||||||
|
│ 3. Load camera calibration + IMU calibration │
|
||||||
|
│ 4. Start cuVSLAM (Inertial mode) with ADTI 20L V1 │
|
||||||
|
│ 5. Preload satellite tiles ±2km into RAM │
|
||||||
|
│ 6. First satellite match → validate initial position │
|
||||||
|
│ 7. Begin GPS_INPUT output loop at 5-10Hz │
|
||||||
|
│ │
|
||||||
|
│ EVERY CAMERA FRAME (0.7fps from ADTI 20L V1): │
|
||||||
|
│ ┌──────────────────────────────────────┐ │
|
||||||
|
│ │ ADTI 20L V1 → Downsample (CUDA) │ │
|
||||||
|
│ │ → cuVSLAM VO+IMU (~9ms) │ ← CUDA Stream A │
|
||||||
|
│ │ → ESKF VO measurement │ │
|
||||||
|
│ └──────────────────────────────────────┘ │
|
||||||
|
│ │
|
||||||
|
│ 5-10Hz CONTINUOUS (IMU-driven between camera frames): │
|
||||||
|
│ ┌──────────────────────────────────────┐ │
|
||||||
|
│ │ IMU data → ESKF prediction │ │
|
||||||
|
│ │ ESKF state → GPS_INPUT fields │ │
|
||||||
|
│ │ GPS_INPUT → Flight Controller (UART) │ │
|
||||||
|
│ └──────────────────────────────────────┘ │
|
||||||
|
│ │
|
||||||
|
│ KEYFRAMES (every 5-10 camera frames, async): │
|
||||||
|
│ ┌──────────────────────────────────────┐ │
|
||||||
|
│ │ Camera frame → GSD downsample │ │
|
||||||
|
│ │ Select satellite tile (ESKF pos±3σ) │ │
|
||||||
|
│ │ TRT inference (Stream B): LiteSAM/ │ │
|
||||||
|
│ │ XFeat → correspondences │ │
|
||||||
|
│ │ RANSAC → homography → WGS84 position │ │
|
||||||
|
│ │ ESKF satellite measurement update │──→ Position correction │
|
||||||
|
│ └──────────────────────────────────────┘ │
|
||||||
|
│ │
|
||||||
|
│ TRACKING LOSS (cuVSLAM fails — sharp turn / featureless): │
|
||||||
|
│ ┌──────────────────────────────────────┐ │
|
||||||
|
│ │ ESKF → IMU-only prediction (growing │ │
|
||||||
|
│ │ uncertainty) │ │
|
||||||
|
│ │ Satellite match on EVERY frame │ │
|
||||||
|
│ │ On match success → ESKF reset + │ │
|
||||||
|
│ │ cuVSLAM restart │ │
|
||||||
|
│ │ 3 consecutive failures → operator │ │
|
||||||
|
│ │ re-localization request │ │
|
||||||
|
│ └──────────────────────────────────────┘ │
|
||||||
|
│ │
|
||||||
|
│ TELEMETRY (1Hz): │
|
||||||
|
│ ┌──────────────────────────────────────┐ │
|
||||||
|
│ │ NAMED_VALUE_FLOAT: confidence, drift │──→ Ground Station │
|
||||||
|
│ └──────────────────────────────────────┘ │
|
||||||
|
└─────────────────────────────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
### Component: ESKF Sensor Fusion (NEW — previously unspecified)
|
||||||
|
|
||||||
|
**Error-State Kalman Filter** fusing IMU, visual odometry, and satellite matching.
|
||||||
|
|
||||||
|
**Nominal state vector** (propagated by IMU):
|
||||||
|
|
||||||
|
| State | Symbol | Size | Description |
|
||||||
|
|-------|--------|------|-------------|
|
||||||
|
| Position | p | 3 | NED position relative to mission origin (meters) |
|
||||||
|
| Velocity | v | 3 | NED velocity (m/s) |
|
||||||
|
| Attitude | q | 4 | Unit quaternion (body-to-NED rotation) |
|
||||||
|
| Accel bias | b_a | 3 | Accelerometer bias (m/s²) |
|
||||||
|
| Gyro bias | b_g | 3 | Gyroscope bias (rad/s) |
|
||||||
|
|
||||||
|
**Error-state vector** (estimated by ESKF): δx = [δp, δv, δθ, δb_a, δb_g]ᵀ ∈ ℝ¹⁵
|
||||||
|
where δθ ∈ so(3) is the 3D rotation error.
|
||||||
|
|
||||||
|
**Prediction step** (IMU at 5-10Hz from flight controller):
|
||||||
|
- Input: accelerometer a_m, gyroscope ω_m, dt
|
||||||
|
- Propagate nominal state: p += v·dt, v += (R(q)·(a_m - b_a) - g)·dt, q ⊗= Exp(ω_m - b_g)·dt
|
||||||
|
- Propagate error covariance: P = F·P·Fᵀ + Q
|
||||||
|
- F is the 15×15 error-state transition matrix (standard ESKF formulation)
|
||||||
|
- Q: process noise diagonal, initial values from IMU datasheet noise densities
|
||||||
|
|
||||||
|
**VO measurement update** (0.7Hz from cuVSLAM):
|
||||||
|
- cuVSLAM outputs relative pose: ΔR, Δt (camera frame)
|
||||||
|
- Transform to NED: Δp_ned = R_body_ned · T_cam_body · Δt
|
||||||
|
- Innovation: z = Δp_ned_measured - Δp_ned_predicted
|
||||||
|
- Observation matrix H_vo maps error state to relative position change
|
||||||
|
- R_vo: measurement noise, initial ~0.1-0.5m (from cuVSLAM precision at 600m+ altitude)
|
||||||
|
- Kalman update: K = P·Hᵀ·(H·P·Hᵀ + R)⁻¹, δx = K·z, P = (I - K·H)·P
|
||||||
|
|
||||||
|
**Satellite measurement update** (0.07-0.14Hz, async):
|
||||||
|
- Satellite matching outputs absolute position: lat_sat, lon_sat in WGS84
|
||||||
|
- Convert to NED relative to mission origin
|
||||||
|
- Innovation: z = p_satellite - p_predicted
|
||||||
|
- H_sat = [I₃, 0, 0, 0, 0] (directly observes position)
|
||||||
|
- R_sat: measurement noise, from matching confidence (~5-20m based on RANSAC inlier ratio)
|
||||||
|
- Provides absolute position correction — bounds drift accumulation
|
||||||
|
|
||||||
|
**Scale observability**:
|
||||||
|
- Monocular cuVSLAM has scale ambiguity during constant-velocity flight
|
||||||
|
- Scale is constrained by: (1) satellite matching absolute positions (primary), (2) known flight altitude from barometer + predefined mission altitude, (3) IMU accelerometer during maneuvers
|
||||||
|
- During long straight segments without satellite correction, scale drift is possible. Satellite corrections every ~7-14s re-anchor scale.
|
||||||
|
|
||||||
|
**Tuning approach**: Start with IMU datasheet noise values for Q. Start with conservative R values (high measurement noise). Tune on flight test data by comparing ESKF output to known GPS ground truth.
|
||||||
|
|
||||||
|
| Solution | Tools | Advantages | Limitations | Performance | Fit |
|
||||||
|
|----------|-------|-----------|-------------|------------|-----|
|
||||||
|
| Custom ESKF (Python/NumPy) | NumPy, SciPy | Full control, minimal dependencies, well-understood algorithm | Implementation effort, tuning required | <1ms per step | ✅ Selected |
|
||||||
|
| FilterPy ESKF | FilterPy v1.4.5 | Reference implementation, less code | Less flexible for multi-rate fusion | <1ms per step | ⚠️ Fallback |
|
||||||
|
|
||||||
|
### Component: Coordinate System & Transformations (NEW — previously undefined)
|
||||||
|
|
||||||
|
**Reference frames**:
|
||||||
|
- **Camera frame (C)**: origin at camera optical center, Z forward, X right, Y down (OpenCV convention)
|
||||||
|
- **Body frame (B)**: origin at UAV CG, X forward (nose), Y right (starboard), Z down
|
||||||
|
- **NED frame (N)**: North-East-Down, origin at mission start point
|
||||||
|
- **WGS84**: latitude, longitude, altitude (output format)
|
||||||
|
|
||||||
|
**Transformation chain**:
|
||||||
|
|
||||||
|
1. **Pixel → Camera ray**: p_cam = K⁻¹ · [u, v, 1]ᵀ where K = camera intrinsic matrix (ADTI 20L V1: fx, fy from 16mm lens + APS-C sensor)
|
||||||
|
2. **Camera → Body**: p_body = T_cam_body · p_cam where T_cam_body is the fixed mounting rotation (camera points nadir: 90° pitch rotation from body X-forward to camera Z-down)
|
||||||
|
3. **Body → NED**: p_ned = R_body_ned(q) · p_body where q is the ESKF quaternion attitude estimate
|
||||||
|
4. **NED → WGS84**: lat = lat_origin + p_north / R_earth, lon = lon_origin + p_east / (R_earth · cos(lat_origin)) where (lat_origin, lon_origin) is the mission start GPS position
|
||||||
|
|
||||||
|
**Camera intrinsic matrix K** (ADTI 20L V1 + 16mm lens):
|
||||||
|
- Sensor: 23.2 × 15.4 mm, Resolution: 5456 × 3632
|
||||||
|
- fx = fy = focal_mm × width_px / sensor_width_mm = 16 × 5456 / 23.2 = 3763 pixels
|
||||||
|
- cx = 2728, cy = 1816 (sensor center)
|
||||||
|
- Distortion: Brown model (k1, k2, p1, p2 from calibration)
|
||||||
|
|
||||||
|
**T_cam_body** (camera mount):
|
||||||
|
- Navigation camera is fixed, pointing nadir (downward), not autostabilized
|
||||||
|
- R_cam_body = R_x(180°) · R_z(0°) (camera Z-axis aligned with body -Z, camera X with body X)
|
||||||
|
- Translation: offset from CG to camera mount (measured during assembly, typically <0.3m)
|
||||||
|
|
||||||
|
**Satellite match → WGS84**:
|
||||||
|
- Feature correspondences between camera frame and geo-referenced satellite tile
|
||||||
|
- Homography H maps camera pixels to satellite tile pixels
|
||||||
|
- Satellite tile pixel → WGS84 via tile's known georeference (zoom level + tile x,y → lat,lon)
|
||||||
|
- Camera center projects to satellite pixel (cx_sat, cy_sat) via H
|
||||||
|
- Convert (cx_sat, cy_sat) to WGS84 using tile georeference
|
||||||
|
|
||||||
|
### Component: GPS_INPUT Message Population (NEW — previously undefined)
|
||||||
|
|
||||||
|
| GPS_INPUT Field | Source | Computation |
|
||||||
|
|-----------------|--------|-------------|
|
||||||
|
| lat, lon | ESKF position (NED) | NED → WGS84 conversion using mission origin |
|
||||||
|
| alt | ESKF position (Down) + mission origin altitude | alt = alt_origin - p_down |
|
||||||
|
| vn, ve, vd | ESKF velocity state | Direct from ESKF v[0], v[1], v[2] |
|
||||||
|
| fix_type | Confidence tier | 3 (3D fix) when satellite-anchored (last match <30s). 2 (2D) when VO-only. 0 (no fix) when IMU-only >5s |
|
||||||
|
| hdop | ESKF horizontal covariance | hdop = sqrt(P[0,0] + P[1,1]) / 5.0 (approximate CEP→HDOP mapping) |
|
||||||
|
| vdop | ESKF vertical covariance | vdop = sqrt(P[2,2]) / 5.0 |
|
||||||
|
| horiz_accuracy | ESKF horizontal covariance | horiz_accuracy = sqrt(P[0,0] + P[1,1]) meters |
|
||||||
|
| vert_accuracy | ESKF vertical covariance | vert_accuracy = sqrt(P[2,2]) meters |
|
||||||
|
| speed_accuracy | ESKF velocity covariance | speed_accuracy = sqrt(P[3,3] + P[4,4]) m/s |
|
||||||
|
| time_week, time_week_ms | System time | Convert Unix time to GPS epoch (GPS epoch = 1980-01-06, subtract leap seconds) |
|
||||||
|
| satellites_visible | Constant | 10 (synthetic — prevents satellite-count failsafes in ArduPilot) |
|
||||||
|
| gps_id | Constant | 0 |
|
||||||
|
| ignore_flags | Constant | 0 (provide all fields) |
|
||||||
|
|
||||||
|
**Confidence tiers** mapping to GPS_INPUT:
|
||||||
|
|
||||||
|
| Tier | Condition | fix_type | horiz_accuracy | Rationale |
|
||||||
|
|------|-----------|----------|----------------|-----------|
|
||||||
|
| HIGH | Satellite match <30s ago, ESKF covariance < 400m² | 3 (3D fix) | From ESKF P (typically 5-20m) | Absolute position anchor recent |
|
||||||
|
| MEDIUM | cuVSLAM tracking OK, no recent satellite match | 3 (3D fix) | From ESKF P (typically 20-50m) | Relative tracking valid, drift growing |
|
||||||
|
| LOW | cuVSLAM lost, IMU-only | 2 (2D fix) | From ESKF P (50-200m+, growing) | Only IMU dead reckoning, rapid drift |
|
||||||
|
| FAILED | 3+ consecutive total failures | 0 (no fix) | 999.0 | System cannot determine position |
|
||||||
|
|
||||||
|
### Component: Disconnected Route Segment Handling (NEW — previously undefined)
|
||||||
|
|
||||||
|
**Trigger**: cuVSLAM reports tracking_lost OR tracking confidence drops below threshold
|
||||||
|
|
||||||
|
**Algorithm**:
|
||||||
|
|
||||||
|
```
|
||||||
|
STATE: TRACKING_NORMAL
|
||||||
|
cuVSLAM provides relative pose
|
||||||
|
ESKF VO measurement updates at 0.7Hz
|
||||||
|
Satellite matching on keyframes (every 5-10 frames)
|
||||||
|
|
||||||
|
STATE: TRACKING_LOST (enter when cuVSLAM reports loss)
|
||||||
|
1. ESKF continues with IMU-only prediction (no VO updates)
|
||||||
|
→ uncertainty grows rapidly (~1-5 m/s drift with consumer IMU)
|
||||||
|
2. Switch satellite matching to EVERY frame (not just keyframes)
|
||||||
|
→ maximize chances of getting absolute correction
|
||||||
|
3. For each camera frame:
|
||||||
|
a. Attempt satellite match using ESKF predicted position ± 3σ for tile selection
|
||||||
|
b. If match succeeds (RANSAC inlier ratio > 30%):
|
||||||
|
→ ESKF measurement update with satellite position
|
||||||
|
→ Restart cuVSLAM with current frame as new origin
|
||||||
|
→ Transition to TRACKING_NORMAL
|
||||||
|
→ Reset failure counter
|
||||||
|
c. If match fails:
|
||||||
|
→ Increment failure_counter
|
||||||
|
→ Continue IMU-only ESKF prediction
|
||||||
|
4. If failure_counter >= 3:
|
||||||
|
→ Send re-localization request to ground station
|
||||||
|
→ GPS_INPUT fix_type = 0 (no fix), horiz_accuracy = 999.0
|
||||||
|
→ Continue attempting satellite matching on each frame
|
||||||
|
5. If operator sends re-localization hint (approximate lat,lon):
|
||||||
|
→ Use as ESKF measurement with high covariance (~500m)
|
||||||
|
→ Attempt satellite match in that area
|
||||||
|
→ On success: transition to TRACKING_NORMAL
|
||||||
|
|
||||||
|
STATE: SEGMENT_DISCONNECT
|
||||||
|
After re-localization following tracking loss:
|
||||||
|
→ New cuVSLAM track is independent of previous track
|
||||||
|
→ ESKF maintains global NED position continuity via satellite anchor
|
||||||
|
→ No need to "connect" segments at the cuVSLAM level
|
||||||
|
→ ESKF already handles this: satellite corrections keep global position consistent
|
||||||
|
```
|
||||||
|
|
||||||
|
### Component: Satellite Image Matching Pipeline (UPDATED — added GSD + tile selection details)
|
||||||
|
|
||||||
|
**GSD normalization**:
|
||||||
|
- Camera GSD at 600m: ~15.9 cm/pixel (ADTI 20L V1 + 16mm)
|
||||||
|
- Satellite tile GSD at zoom 18: ~0.6 m/pixel
|
||||||
|
- Scale ratio: ~3.8:1
|
||||||
|
- Downsample camera image to satellite GSD before matching: resize from 5456×3632 to ~1440×960 (matching zoom 18 GSD)
|
||||||
|
- This is close to LiteSAM's 1280px input — use 1280px with minor GSD mismatch acceptable for matching
|
||||||
|
|
||||||
|
**Tile selection**:
|
||||||
|
- Input: ESKF position estimate (lat, lon) + horizontal covariance σ_h
|
||||||
|
- Search radius: max(3·σ_h, 500m) — at least 500m to handle initial uncertainty
|
||||||
|
- Compute geohash for center position → load tiles covering the search area
|
||||||
|
- Assemble tile mosaic if needed (typically 2×2 to 4×4 tiles for adequate coverage)
|
||||||
|
- If ESKF uncertainty > 2km: tile selection unreliable, fall back to wider search or request operator input
|
||||||
|
|
||||||
|
**Tile storage calculation** (zoom 18 — 0.6 m/pixel):
|
||||||
|
- Each 256×256 tile covers ~153m × 153m
|
||||||
|
- Flight path 200km with ±2km buffer: area ≈ 200km × 4km = 800 km²
|
||||||
|
- Tiles needed: 800,000,000 / (153 × 153) ≈ 34,200 tiles
|
||||||
|
- Storage: ~10-15KB per JPEG tile → ~340-510 MB
|
||||||
|
- With zoom 19 overlap tiles for higher precision: ×4 = ~1.4-2.0 GB
|
||||||
|
- Recommended: zoom 18 primary + zoom 19 for ±500m along flight path → ~500-800 MB total
|
||||||
|
|
||||||
|
| Solution | Tools | Advantages | Limitations | Performance (est. Orin Nano Super TRT FP16) | Params | Fit |
|
||||||
|
|----------|-------|-----------|-------------|----------------------------------------------|--------|-----|
|
||||||
|
| LiteSAM (opt) TRT Engine FP16 @ 1280px | trtexec + tensorrt Python | Best satellite-aerial accuracy (RMSE@30=17.86m UAV-VisLoc), 6.31M params | MinGRU TRT export needs verification (LOW-MEDIUM risk) | Est. ~165-330ms | 6.31M | ✅ Primary |
|
||||||
|
| EfficientLoFTR TRT Engine FP16 | trtexec + tensorrt Python | Proven TRT path (Coarse_LoFTR_TRT). Semi-dense. CVPR 2024. | 2.4x more params than LiteSAM. | Est. ~200-400ms | 15.05M | ✅ Fallback if LiteSAM TRT fails |
|
||||||
|
| XFeat TRT Engine FP16 | trtexec + tensorrt Python | Fastest. Proven TRT implementation. | General-purpose, not designed for cross-view gap. | Est. ~50-100ms | <5M | ✅ Speed fallback |
|
||||||
|
|
||||||
|
### Component: cuVSLAM Configuration (NEW — previously undefined)
|
||||||
|
|
||||||
|
**Mode**: Inertial (mono camera + IMU)
|
||||||
|
|
||||||
|
**Camera configuration** (ADTI 20L V1 + 16mm lens):
|
||||||
|
- Model: Brown distortion
|
||||||
|
- fx = fy = 3763 px (16mm on 23.2mm sensor at 5456px width)
|
||||||
|
- cx = 2728 px, cy = 1816 px
|
||||||
|
- Distortion coefficients: from calibration (k1, k2, p1, p2)
|
||||||
|
- Border: 50px (ignore lens edge distortion)
|
||||||
|
|
||||||
|
**IMU configuration** (Pixhawk 6x IMU — ICM-42688-P):
|
||||||
|
- Gyroscope noise density: 3.0 × 10⁻³ °/s/√Hz
|
||||||
|
- Gyroscope random walk: 5.0 × 10⁻⁵ °/s²/√Hz
|
||||||
|
- Accelerometer noise density: 70 µg/√Hz
|
||||||
|
- Accelerometer random walk: ~2.0 × 10⁻³ m/s³/√Hz
|
||||||
|
- IMU frequency: 200 Hz (from flight controller via MAVLink)
|
||||||
|
- T_imu_rig: measured transformation from Pixhawk IMU to camera center (translation + rotation)
|
||||||
|
|
||||||
|
**cuVSLAM settings**:
|
||||||
|
- OdometryMode: INERTIAL
|
||||||
|
- MulticameraMode: PRECISION (favor accuracy over speed — we have 1430ms budget)
|
||||||
|
- Input resolution: downsample to 1280×852 (or 720p) for processing speed
|
||||||
|
- async_bundle_adjustment: True
|
||||||
|
|
||||||
|
**Initialization**:
|
||||||
|
- cuVSLAM initializes automatically when it receives the first camera frame + IMU data
|
||||||
|
- First few frames used for feature initialization and scale estimation
|
||||||
|
- First satellite match validates and corrects the initial position
|
||||||
|
|
||||||
|
**Calibration procedure** (one-time per hardware unit):
|
||||||
|
1. Camera intrinsics: checkerboard calibration with OpenCV (or use manufacturer data if available)
|
||||||
|
2. Camera-IMU extrinsic (T_imu_rig): Kalibr tool with checkerboard + IMU data
|
||||||
|
3. IMU noise parameters: Allan variance analysis or use datasheet values
|
||||||
|
4. Store calibration files on Jetson storage
|
||||||
|
|
||||||
|
### Component: AI Model Inference Runtime (UNCHANGED)
|
||||||
|
|
||||||
|
Native TRT Engine — optimal performance and memory on fixed NVIDIA hardware. See draft05 for full comparison table and conversion workflow.
|
||||||
|
|
||||||
|
### Component: Visual Odometry (UNCHANGED)
|
||||||
|
|
||||||
|
cuVSLAM in Inertial mode, fed by ADTI 20L V1 at 0.7 fps sustained. See draft05 for feasibility analysis at 0.7fps.
|
||||||
|
|
||||||
|
### Component: Flight Controller Integration (UPDATED — added GPS_INPUT field spec)
|
||||||
|
|
||||||
|
pymavlink over UART at 5-10Hz. GPS_INPUT field population defined above.
|
||||||
|
|
||||||
|
ArduPilot configuration:
|
||||||
|
- GPS1_TYPE = 14 (MAVLink)
|
||||||
|
- GPS_RATE = 5 (minimum, matching our 5-10Hz output)
|
||||||
|
- EK3_SRC1_POSXY = 1 (GPS), EK3_SRC1_VELXY = 1 (GPS) — EKF uses GPS_INPUT as position/velocity source
|
||||||
|
|
||||||
|
### Component: Object Localization (NEW — previously undefined)
|
||||||
|
|
||||||
|
**Input**: pixel coordinates (u, v) in Viewpro A40 Pro image, current gimbal angles (pan_deg, tilt_deg), zoom factor, UAV position from GPS-denied system, UAV altitude
|
||||||
|
|
||||||
|
**Process**:
|
||||||
|
1. Pixel → camera ray: ray_cam = K_viewpro⁻¹(zoom) · [u, v, 1]ᵀ
|
||||||
|
2. Camera → gimbal frame: ray_gimbal = R_gimbal(pan, tilt) · ray_cam
|
||||||
|
3. Gimbal → body: ray_body = T_gimbal_body · ray_gimbal
|
||||||
|
4. Body → NED: ray_ned = R_body_ned(q) · ray_body
|
||||||
|
5. Ray-ground intersection: assuming flat terrain at UAV altitude h: t = -h / ray_ned[2], p_ground_ned = p_uav_ned + t · ray_ned
|
||||||
|
6. NED → WGS84: convert to lat, lon
|
||||||
|
|
||||||
|
**Output**: { lat, lon, accuracy_m, confidence }
|
||||||
|
- accuracy_m propagated from: UAV position accuracy (from ESKF) + gimbal angle uncertainty + altitude uncertainty
|
||||||
|
|
||||||
|
**API endpoint**: POST /objects/locate
|
||||||
|
- Request: { pixel_x, pixel_y, gimbal_pan_deg, gimbal_tilt_deg, zoom_factor }
|
||||||
|
- Response: { lat, lon, alt, accuracy_m, confidence, uav_position: {lat, lon, alt}, timestamp }
|
||||||
|
|
||||||
|
### Component: Startup, Handoff & Failsafe (UPDATED — added handoff + reboot + re-localization)
|
||||||
|
|
||||||
|
**GPS-denied handoff protocol**:
|
||||||
|
- GPS-denied system runs continuously from companion computer boot
|
||||||
|
- Reads initial position from FC (GLOBAL_POSITION_INT) — this may be real GPS or last known
|
||||||
|
- First satellite match validates the initial position
|
||||||
|
- FC receives both real GPS (if available) and GPS_INPUT; FC EKF selects best source based on accuracy
|
||||||
|
- No explicit "switch" — the GPS-denied system is a secondary GPS source
|
||||||
|
|
||||||
|
**Startup sequence** (expanded from draft05):
|
||||||
|
1. Boot Jetson → start GPS-Denied service (systemd)
|
||||||
|
2. Connect to flight controller via pymavlink on UART
|
||||||
|
3. Wait for heartbeat
|
||||||
|
4. Initialize PyCUDA context
|
||||||
|
5. Load TRT engines: litesam.engine + xfeat.engine (~1-3s each)
|
||||||
|
6. Allocate GPU I/O buffers
|
||||||
|
7. Create CUDA streams: Stream A (cuVSLAM), Stream B (satellite matching)
|
||||||
|
8. Load camera calibration + IMU calibration files
|
||||||
|
9. Read GLOBAL_POSITION_INT → set mission origin (NED reference point) → init ESKF
|
||||||
|
10. Start cuVSLAM (Inertial mode) with ADTI 20L V1 camera stream
|
||||||
|
11. Preload satellite tiles within ±2km into RAM
|
||||||
|
12. Trigger first satellite match → validate initial position
|
||||||
|
13. Begin GPS_INPUT output loop at 5-10Hz
|
||||||
|
14. System ready
|
||||||
|
|
||||||
|
**Mid-flight reboot recovery**:
|
||||||
|
1. Jetson boots (~30-60s)
|
||||||
|
2. GPS-Denied service starts, connects to FC
|
||||||
|
3. Read GLOBAL_POSITION_INT (FC's current IMU-extrapolated position)
|
||||||
|
4. Init ESKF with this position + HIGH uncertainty covariance (σ = 200m)
|
||||||
|
5. Load TRT engines (~2-6s total)
|
||||||
|
6. Start cuVSLAM (fresh, no prior map)
|
||||||
|
7. Immediate satellite matching on first camera frame
|
||||||
|
8. On satellite match success: ESKF corrected, uncertainty drops
|
||||||
|
9. Estimated total recovery: ~35-70s
|
||||||
|
10. During recovery: FC uses IMU-only dead reckoning (at 70 km/h: ~700-1400m uncontrolled drift)
|
||||||
|
11. **Known limitation**: recovery time is dominated by Jetson boot time
|
||||||
|
|
||||||
|
**3-consecutive-failure re-localization**:
|
||||||
|
- Trigger: VO lost + satellite match failed × 3 consecutive camera frames
|
||||||
|
- Action: send re-localization request via MAVLink STATUSTEXT or custom message
|
||||||
|
- Message content: "RELOC_REQ: last_lat={lat} last_lon={lon} uncertainty={σ}m"
|
||||||
|
- Operator response: MAVLink COMMAND_LONG with approximate lat/lon
|
||||||
|
- System: use operator position as ESKF measurement with R = diag(500², 500², 100²) meters²
|
||||||
|
- System continues satellite matching with updated search area
|
||||||
|
- While waiting: GPS_INPUT fix_type=0, IMU-only ESKF prediction continues
|
||||||
|
|
||||||
|
### Component: Ground Station Telemetry (UPDATED — added re-localization)
|
||||||
|
|
||||||
|
MAVLink messages to ground station:
|
||||||
|
|
||||||
|
| Message | Rate | Content |
|
||||||
|
|---------|------|---------|
|
||||||
|
| NAMED_VALUE_FLOAT "gps_conf" | 1Hz | Confidence score (0.0-1.0) |
|
||||||
|
| NAMED_VALUE_FLOAT "gps_drift" | 1Hz | Estimated drift from last satellite anchor (meters) |
|
||||||
|
| NAMED_VALUE_FLOAT "gps_hacc" | 1Hz | Horizontal accuracy (meters, from ESKF) |
|
||||||
|
| STATUSTEXT | On event | "RELOC_REQ: ..." for re-localization request |
|
||||||
|
| STATUSTEXT | On event | Tracking loss / recovery notifications |
|
||||||
|
|
||||||
|
### Component: Thermal Management (UNCHANGED)
|
||||||
|
Same adaptive pipeline from draft05. Active cooling required at 25W. Throttling at 80°C SoC junction.
|
||||||
|
|
||||||
|
### Component: API & Inter-System Communication (NEW — consolidated)
|
||||||
|
|
||||||
|
FastAPI (Uvicorn) running locally on Jetson for inter-process communication with other onboard systems.
|
||||||
|
|
||||||
|
| Endpoint | Method | Purpose | Auth |
|
||||||
|
|----------|--------|---------|------|
|
||||||
|
| /sessions | POST | Start GPS-denied session | JWT |
|
||||||
|
| /sessions/{id}/stream | GET (SSE) | Real-time position + confidence stream | JWT |
|
||||||
|
| /sessions/{id}/anchor | POST | Operator re-localization hint | JWT |
|
||||||
|
| /sessions/{id} | DELETE | End session | JWT |
|
||||||
|
| /objects/locate | POST | Object GPS from pixel coordinates | JWT |
|
||||||
|
| /health | GET | System health + memory + thermal | None |
|
||||||
|
|
||||||
|
**SSE event schema** (1Hz):
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"type": "position",
|
||||||
|
"timestamp": "2026-03-17T12:00:00.000Z",
|
||||||
|
"lat": 48.123456,
|
||||||
|
"lon": 37.654321,
|
||||||
|
"alt": 600.0,
|
||||||
|
"accuracy_h": 15.2,
|
||||||
|
"accuracy_v": 8.1,
|
||||||
|
"confidence": "HIGH",
|
||||||
|
"drift_from_anchor": 12.5,
|
||||||
|
"vo_status": "tracking",
|
||||||
|
"last_satellite_match_age_s": 8.3
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## UAV Platform
|
||||||
|
|
||||||
|
Unchanged from draft05. See draft05 for: airframe configuration (3.5m S-2 composite, 12.5kg AUW), flight performance (3.4h endurance at 50 km/h), camera specifications (ADTI 20L V1 + 16mm, Viewpro A40 Pro), ground coverage calculations.
|
||||||
|
|
||||||
|
## Speed Optimization Techniques
|
||||||
|
|
||||||
|
Unchanged from draft05. Key points: cuVSLAM ~9ms/frame, native TRT Engine (no ONNX RT), dual CUDA streams, 5-10Hz GPS_INPUT from ESKF IMU prediction.
|
||||||
|
|
||||||
|
## Processing Time Budget
|
||||||
|
|
||||||
|
Unchanged from draft05. VO frame: ~17-22ms. Satellite matching: ≤210ms async. Well within 1430ms frame interval.
|
||||||
|
|
||||||
|
## Memory Budget (Jetson Orin Nano Super, 8GB shared)
|
||||||
|
|
||||||
|
| Component | Memory | Notes |
|
||||||
|
|-----------|--------|-------|
|
||||||
|
| OS + runtime | ~1.5GB | JetPack 6.2 + Python |
|
||||||
|
| cuVSLAM | ~200-500MB | CUDA library + map |
|
||||||
|
| LiteSAM TRT engine | ~50-80MB | If LiteSAM fails: EfficientLoFTR ~100-150MB |
|
||||||
|
| XFeat TRT engine | ~30-50MB | |
|
||||||
|
| Preloaded satellite tiles | ~200MB | ±2km of flight plan |
|
||||||
|
| pymavlink + MAVLink | ~20MB | |
|
||||||
|
| FastAPI (local IPC) | ~50MB | |
|
||||||
|
| ESKF + buffers | ~10MB | |
|
||||||
|
| **Total** | **~2.1-2.9GB** | **26-36% of 8GB** |
|
||||||
|
|
||||||
|
## Key Risks and Mitigations
|
||||||
|
|
||||||
|
| Risk | Likelihood | Impact | Mitigation |
|
||||||
|
|------|-----------|--------|------------|
|
||||||
|
| LiteSAM MinGRU ops unsupported in TRT 10.3 | LOW-MEDIUM | LiteSAM TRT export fails | Day-one verification. Fallback: EfficientLoFTR TRT → XFeat TRT. |
|
||||||
|
| cuVSLAM fails on low-texture terrain at 0.7fps | HIGH | Frequent tracking loss | Satellite matching corrections bound drift. Re-localization pipeline handles tracking loss. IMU bridges short gaps. |
|
||||||
|
| Google Maps satellite quality in conflict zone | HIGH | Satellite matching fails, outdated imagery | Pre-flight tile validation. Consider alternative providers (Bing, Mapbox). Robust to seasonal appearance changes via feature-based matching. |
|
||||||
|
| ESKF scale drift during long constant-velocity segments | MEDIUM | Position error exceeds 100m between satellite anchors | Satellite corrections every 7-14s re-anchor. Altitude constraint from barometer. Monitor drift rate — if >50m between corrections, increase satellite matching frequency. |
|
||||||
|
| Monocular scale ambiguity | MEDIUM | Metric scale lost during constant-velocity flight | Satellite absolute corrections provide scale. Known altitude constrains vertical scale. IMU acceleration during turns provides observability. |
|
||||||
|
| AUW exceeds AT4125 recommended range | MEDIUM | Reduced endurance, motor thermal stress | 12.5 kg vs 8-10 kg recommended. Monitor motor temps. Weight optimization. |
|
||||||
|
| ADTI mechanical shutter lifespan | MEDIUM | Replacement needed periodically | ~8,800 actuations/flight at 0.7fps. Estimated 11-57 flights before replacement. Budget as consumable. |
|
||||||
|
| Mid-flight companion computer failure | LOW | ~35-70s position gap | Reboot recovery procedure defined. FC uses IMU dead reckoning during gap. Known limitation. |
|
||||||
|
| Thermal throttling on Jetson | MEDIUM | Satellite matching latency increases | Active cooling required. Monitor SoC temp. Throttling at 80°C. Our workload ~8-15W typical — well under 25W TDP. |
|
||||||
|
| Engine incompatibility after JetPack update | MEDIUM | Must rebuild engines | Include engine rebuild in update procedure. |
|
||||||
|
| TRT engine build OOM on 8GB | LOW | Cannot build on target | Models small (6.31M, <5M). Reduce --memPoolSize if needed. |
|
||||||
|
|
||||||
|
## Testing Strategy
|
||||||
|
|
||||||
|
### Integration / Functional Tests
|
||||||
|
- **ESKF correctness**: Feed recorded IMU + synthetic VO/satellite data → verify output matches reference ESKF implementation
|
||||||
|
- **GPS_INPUT field validation**: Send GPS_INPUT to SITL ArduPilot → verify EKF accepts and uses the data correctly
|
||||||
|
- **Coordinate transform chain**: Known GPS → NED → pixel → back to GPS — verify round-trip error <0.1m
|
||||||
|
- **Disconnected segment handling**: Simulate tracking loss → verify satellite re-localization triggers → verify cuVSLAM restarts → verify ESKF position continuity
|
||||||
|
- **3-consecutive-failure**: Simulate VO + satellite failures → verify re-localization request sent → verify operator hint accepted
|
||||||
|
- **Object localization**: Known object at known GPS → verify computed GPS matches within camera accuracy
|
||||||
|
- **Mid-flight reboot**: Kill GPS-denied process → restart → verify recovery within expected time → verify position accuracy after recovery
|
||||||
|
- **TRT engine load test**: Verify engines load successfully on Jetson
|
||||||
|
- **TRT inference correctness**: Compare TRT output vs PyTorch reference (max L1 error < 0.01)
|
||||||
|
- **CUDA Stream pipelining**: Verify Stream B satellite matching does not block Stream A VO
|
||||||
|
- **ADTI sustained capture rate**: Verify 0.7fps sustained >30 min without buffer overflow
|
||||||
|
- **Confidence tier transitions**: Verify fix_type and accuracy change correctly across HIGH → MEDIUM → LOW → FAILED transitions
|
||||||
|
|
||||||
|
### Non-Functional Tests
|
||||||
|
- **End-to-end accuracy** (primary validation): Fly with real GPS recording → run GPS-denied system in parallel → compare estimated vs real positions → verify 80% within 50m, 60% within 20m
|
||||||
|
- **VO drift rate**: Measure cuVSLAM drift over 1km straight segment without satellite correction
|
||||||
|
- **Satellite matching accuracy**: Compare satellite-matched position vs real GPS at known locations
|
||||||
|
- **Processing time**: Verify end-to-end per-frame <400ms
|
||||||
|
- **Memory usage**: Monitor over 30-min session → verify <8GB, no leaks
|
||||||
|
- **Thermal**: Sustained 30-min run → verify no throttling
|
||||||
|
- **GPS_INPUT rate**: Verify consistent 5-10Hz delivery to FC
|
||||||
|
- **Tile storage**: Validate calculated storage matches actual for test mission area
|
||||||
|
- **MinGRU TRT compatibility** (day-one blocker): Clone LiteSAM → ONNX export → polygraphy → trtexec
|
||||||
|
- **Flight endurance**: Ground-test full system power draw against 267W estimate
|
||||||
|
|
||||||
|
## References
|
||||||
|
- ArduPilot GPS_RATE parameter: https://github.com/ArduPilot/ardupilot/pull/15980
|
||||||
|
- MAVLink GPS_INPUT message: https://ardupilot.org/mavproxy/docs/modules/GPSInput.html
|
||||||
|
- pymavlink GPS_INPUT example: https://webperso.ensta.fr/lebars/Share/GPS_INPUT_pymavlink.py
|
||||||
|
- ESKF reference (fixed-wing UAV): https://github.com/ludvigls/ESKF
|
||||||
|
- ROS ESKF multi-sensor: https://github.com/EliaTarasov/ESKF
|
||||||
|
- Range-VIO scale observability: https://arxiv.org/abs/2103.15215
|
||||||
|
- NaviLoc trajectory-level localization: https://www.mdpi.com/2504-446X/10/2/97
|
||||||
|
- SatLoc-Fusion hierarchical framework: https://www.scilit.com/publications/e5cafaf875a49297a62b298a89d5572f
|
||||||
|
- Auterion GPS-denied workflow: https://docs.auterion.com/vehicle-operation/auterion-mission-control/useful-resources/operations/gps-denied-workflow
|
||||||
|
- PX4 GNSS-denied flight: https://docs.px4.io/main/en/advanced_config/gnss_degraded_or_denied_flight.html
|
||||||
|
- ArduPilot GPS_INPUT advanced usage: https://discuss.ardupilot.org/t/advanced-usage-of-gps-type-mav-14/99406
|
||||||
|
- Google Maps Ukraine imagery: https://newsukraine.rbc.ua/news/google-maps-has-surprise-for-satellite-imagery-1727182380.html
|
||||||
|
- Jetson Orin Nano Super thermal: https://edgeaistack.app/blog/jetson-orin-nano-power-consumption/
|
||||||
|
- GSD matching research: https://www.kjrs.org/journal/view.html?pn=related&uid=756&vmd=Full
|
||||||
|
- VO+satellite matching pipeline: https://polen.itu.edu.tr/items/1fe1e872-7cea-44d8-a8de-339e4587bee6
|
||||||
|
- PyCuVSLAM docs: https://wiki.seeedstudio.com/pycuvslam_recomputer_robotics/
|
||||||
|
- Pixhawk 6x IMU (ICM-42688-P) datasheet: https://invensense.tdk.com/products/motion-tracking/6-axis/icm-42688-p/
|
||||||
|
- All references from solution_draft05.md
|
||||||
|
|
||||||
|
## Related Artifacts
|
||||||
|
- AC Assessment: `_docs/00_research/gps_denied_nav/00_ac_assessment.md`
|
||||||
|
- Completeness assessment research: `_docs/00_research/solution_completeness_assessment/`
|
||||||
|
- Previous research: `_docs/00_research/trt_engine_migration/`
|
||||||
|
- Tech stack evaluation: `_docs/01_solution/tech_stack.md` (needs sync with draft05 corrections)
|
||||||
|
- Security analysis: `_docs/01_solution/security_analysis.md`
|
||||||
|
- Previous draft: `_docs/01_solution/solution_draft05.md`
|
||||||
@@ -0,0 +1,98 @@
|
|||||||
|
# Acceptance Criteria Assessment
|
||||||
|
|
||||||
|
## Context
|
||||||
|
|
||||||
|
Balloon at 10km altitude. AI detection model trained on imagery from 600-1000m altitude (trucks, vehicles, tracked machinery). Goal: reuse model by using a zoom gimbal camera to achieve equivalent Ground Sample Distance (GSD) from 10km. Budget: under $30k.
|
||||||
|
|
||||||
|
## Key Technical Analysis
|
||||||
|
|
||||||
|
### GSD Requirements
|
||||||
|
|
||||||
|
The AI model was trained on 600-1000m imagery. Typical drone cameras at those altitudes produce:
|
||||||
|
|
||||||
|
- At 600m: GSD ~5-10 cm/pixel
|
||||||
|
- At 1000m: GSD ~10-15 cm/pixel
|
||||||
|
|
||||||
|
For vehicle detection per NIIRS scale:
|
||||||
|
|
||||||
|
- Vehicle detection: ~1m GSD
|
||||||
|
- Vehicle type identification: ~25-50 cm GSD
|
||||||
|
- Detailed vehicle description: ~10 cm GSD
|
||||||
|
|
||||||
|
Target GSD from 10km: **5-15 cm/pixel** to match training data.
|
||||||
|
|
||||||
|
### Required Focal Length from 10km
|
||||||
|
|
||||||
|
Formula: `focal_length = (pixel_pitch × altitude) / target_GSD`
|
||||||
|
|
||||||
|
|
||||||
|
| Sensor Type | Pixel Pitch | Target GSD 15cm | Target GSD 10cm | Target GSD 5cm |
|
||||||
|
| ----------------- | ----------- | --------------- | --------------- | -------------- |
|
||||||
|
| 1/2.8" (5MP) | ~2.0µm | 133mm | 200mm | 400mm |
|
||||||
|
| 1/2.3" (25MP) | ~1.05µm | 70mm | 105mm | 210mm |
|
||||||
|
| 1" (20MP) | ~2.4µm | 160mm | 240mm | 480mm |
|
||||||
|
| Full-frame (61MP) | 3.76µm | 251mm | 376mm | 752mm |
|
||||||
|
|
||||||
|
|
||||||
|
### Atmospheric Resolution Limit
|
||||||
|
|
||||||
|
From 10km looking down, atmospheric turbulence limits ground resolution to approximately **4.6 cm** (theoretical, under ideal conditions). Practical limit: **5-8 cm** depending on weather. This means:
|
||||||
|
|
||||||
|
- GSD finer than ~5 cm provides no benefit
|
||||||
|
- 10-15 cm GSD is safely achievable (optics-limited, not atmosphere-limited)
|
||||||
|
|
||||||
|
### Environmental Conditions at 10km Altitude
|
||||||
|
|
||||||
|
- Temperature: approximately **-50°C**
|
||||||
|
- Pressure: ~264 hPa (26% of sea level)
|
||||||
|
- Consumer cameras rated 0°C to 40°C — **will not function without heated enclosure**
|
||||||
|
- Drone gimbal cameras rated -20°C to +60°C — **still insufficient for -50°C**
|
||||||
|
- All solutions require thermal management (insulated/heated housing)
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
|
||||||
|
|
||||||
|
| Criterion | Derived Value | Researched Feasibility | Cost/Timeline Impact | Status |
|
||||||
|
| --------------------- | -------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------- | ---------------------------------------------- |
|
||||||
|
| Budget | <$30k | Realistic. Good systems $5k-15k, premium $15k-25k including enclosure | Achievable | Confirmed |
|
||||||
|
| GSD from 10km | 5-15 cm/pixel (match training data) | Achievable with 170-800mm FL depending on sensor. Atmospheric limit ~5cm | Core requirement, drives lens/sensor choice | Confirmed |
|
||||||
|
| FOV per frame | >200m ground width | At 10-15cm GSD with 2000-8000px: 200-1200m width. Acceptable | No issue with most cameras | Confirmed |
|
||||||
|
| Gimbal stabilization | 3-axis, ±0.02° or better | Standard in $2k-8k gimbal cameras. Balloon needs additional passive stabilization | Balloon motion is the challenge, not gimbal specs | Modified — need passive + active stabilization |
|
||||||
|
| Image quality for AI | Must be compatible with model trained at 600-1000m | Atmospheric haze at 10km WILL degrade contrast vs clean 600-1000m imagery. May need dehazing and/or model fine-tuning | Moderate risk — software mitigation possible | Added |
|
||||||
|
| Operating temperature | Balloon has thermal protection — not a concern | User confirmed thermal management is handled | No additional cost | Removed |
|
||||||
|
| Weight | Not critical | Most camera+gimbal systems 1-5kg. Enclosure adds 1-3kg. Total 3-8kg | Fine for balloon | Confirmed |
|
||||||
|
|
||||||
|
|
||||||
|
## Restrictions Assessment
|
||||||
|
|
||||||
|
|
||||||
|
| Restriction | Derived Value | Researched Feasibility | Cost/Timeline Impact | Status |
|
||||||
|
| --------------------------- | ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------- | --------- |
|
||||||
|
| Balloon platform at 10km | Fixed constraint | Unusual altitude — between aerostat (500-3500m) and HAPS (18-20km). Very few purpose-built systems. Must adapt drone/DSLR equipment | Custom integration required | Confirmed |
|
||||||
|
| AI model reuse (no retrain) | Must match training GSD | Feasible for GSD matching. Image quality differences (haze, contrast) may require model fine-tuning or preprocessing | Low-moderate risk | Confirmed |
|
||||||
|
| Temperature at 10km | -50°C ambient | Heated enclosure mandatory. All cameras, gimbals, and batteries need thermal protection. Power budget increases 20-50W for heating | $2k-5k added, +2-3kg weight | Added |
|
||||||
|
| Pressure at 10km | ~264 hPa | Some electronics may need conformal coating or pressurized housing. Lens fogging risk. Most industrial electronics tolerate low pressure | Minor added cost ($500-1k) | Added |
|
||||||
|
| Power at 10km | Balloon power source | Camera (10-20W) + gimbal (20-50W) + heating (20-50W) ≈ 50-120W total. Balloon must supply sufficient power | Must verify balloon power budget | Added |
|
||||||
|
| Atmospheric haze | 10km air column | Clear weather (user-specified) helps. Contrast reduction is inevitable. Computational dehazing recommended | Software mitigation, low cost | Added |
|
||||||
|
|
||||||
|
|
||||||
|
## Key Findings
|
||||||
|
|
||||||
|
1. **GSD matching is achievable** within budget. Multiple camera/lens combinations can deliver 5-15 cm/pixel GSD from 10km
|
||||||
|
2. **Thermal management is the hidden critical requirement**. No commercial camera or gimbal operates at -50°C without protection
|
||||||
|
3. **Atmospheric degradation is the biggest risk for AI model reuse**. Even with perfect GSD match, image contrast/sharpness will be lower than training data from 600-1000m. Recommend computational dehazing and potential model fine-tuning
|
||||||
|
4. **Balloon motion stabilization** requires both passive (pendulum damping, suspension design) and active (3-axis gimbal) approaches
|
||||||
|
5. **Budget is realistic** for mid-range solutions ($8k-20k for camera+gimbal+enclosure) with room for integration costs
|
||||||
|
|
||||||
|
## Sources
|
||||||
|
|
||||||
|
- NIIRS Civil Reference Guide (irp.fas.org) — GSD requirements for vehicle detection
|
||||||
|
- Pix4D — GSD calculation methodology
|
||||||
|
- "Limiting Resolution Looking Down Through the Atmosphere" (Optica) — atmospheric resolution limits
|
||||||
|
- UAVOS POD specifications — stratospheric camera benchmark (69cm GSD at 15km)
|
||||||
|
- Airmobi/Viewpro A40 Pro, Z40K — drone gimbal camera specs and pricing
|
||||||
|
- LoongUAV VT500Rs — high-res zoom gimbal specs
|
||||||
|
- Sony FE 400-800mm announcement — super telephoto lens specs/pricing
|
||||||
|
- Gremsy T7 specifications — gimbal payload capacity
|
||||||
|
- IAState Digital Press — high-altitude balloon payload stabilization research
|
||||||
|
|
||||||
+56
@@ -0,0 +1,56 @@
|
|||||||
|
# Question Decomposition
|
||||||
|
|
||||||
|
## Original Question
|
||||||
|
|
||||||
|
Research gimbal camera options under $30k for a balloon at 10km altitude to produce imagery compatible with an AI detection model trained on 600-1000m altitude data (10-20 cm/pixel GSD). Targets: trucks, vehicles, tracked machinery.
|
||||||
|
|
||||||
|
## Active Mode
|
||||||
|
|
||||||
|
Mode A Phase 2 — Initial Research (no existing solution draft)
|
||||||
|
|
||||||
|
## Question Type Classification
|
||||||
|
|
||||||
|
**Decision Support** — need to evaluate trade-offs between different gimbal camera systems for a specific use case.
|
||||||
|
|
||||||
|
## Research Subject Boundary Definition
|
||||||
|
|
||||||
|
- **Population**: Commercial and semi-professional gimbal camera systems suitable for balloon platforms
|
||||||
|
- **Geography**: Global market, available for purchase/export
|
||||||
|
- **Timeframe**: Currently available products (2024-2026)
|
||||||
|
- **Level**: Systems under $30k, excluding military-restricted/ITAR-controlled equipment
|
||||||
|
- **Platform**: High-altitude balloon at 10km with thermal protection
|
||||||
|
|
||||||
|
## Problem Context Summary
|
||||||
|
|
||||||
|
- Balloon at 10km altitude, thermally protected
|
||||||
|
- AI model trained on 600-1000m imagery, GSD ~10-20 cm/pixel
|
||||||
|
- Target objects: trucks, vehicles, tracked machinery
|
||||||
|
- Need zoom gimbal camera to achieve equivalent GSD from 10km
|
||||||
|
- Budget: under $30k
|
||||||
|
- Weight: not a major constraint
|
||||||
|
- Weather: mostly sunny conditions (eastern/southern Ukraine)
|
||||||
|
|
||||||
|
## Decomposed Sub-Questions
|
||||||
|
|
||||||
|
1. What are the available commercial gimbal camera categories suitable for this application?
|
||||||
|
2. For each category, what specific products can deliver 10-20 cm/pixel GSD from 10km?
|
||||||
|
3. What are the trade-offs between integrated zoom gimbals vs separate camera+lens+gimbal setups?
|
||||||
|
4. How does atmospheric haze affect AI model performance, and what mitigation exists?
|
||||||
|
5. What gimbal stabilization approach works best for balloon platforms?
|
||||||
|
6. What is the total system cost (camera + gimbal + integration) for each option?
|
||||||
|
7. What are the power requirements and interfaces for each option?
|
||||||
|
|
||||||
|
## Timeliness Sensitivity Assessment
|
||||||
|
|
||||||
|
- **Research Topic**: Gimbal cameras and aerial surveillance equipment
|
||||||
|
- **Sensitivity Level**: 🟡 Medium
|
||||||
|
- **Rationale**: Hardware products evolve on 1-2 year cycles. New products appear but existing ones remain available.
|
||||||
|
- **Source Time Window**: 2 years
|
||||||
|
- **Priority official sources**:
|
||||||
|
1. Manufacturer product pages (Viewpro, Airmobi, LoongUAV, Sony, Gremsy)
|
||||||
|
2. Distributor sites with pricing (druav.com, dronexpert.nl)
|
||||||
|
- **Key version information to verify**:
|
||||||
|
- ViewPro A40 Pro: current variant and pricing
|
||||||
|
- LOONG VT500Rs: availability and pricing
|
||||||
|
- Sony FE 400-800mm: shipping status and pricing
|
||||||
|
|
||||||
+146
@@ -0,0 +1,146 @@
|
|||||||
|
# Source Registry
|
||||||
|
|
||||||
|
## Source #1
|
||||||
|
- **Title**: Civil NIIRS Reference Guide
|
||||||
|
- **Link**: https://irp.fas.org/imint/niirs_c/guide.htm
|
||||||
|
- **Tier**: L1
|
||||||
|
- **Publication Date**: Established standard (ongoing)
|
||||||
|
- **Timeliness Status**: ✅ Currently valid
|
||||||
|
- **Target Audience**: Military/intelligence imagery analysts
|
||||||
|
- **Research Boundary Match**: ✅ Full match — GSD requirements for vehicle detection
|
||||||
|
- **Summary**: NIIRS 6 required for vehicle type identification (~25-50cm GSD). Detailed vehicle description at ~10cm GSD.
|
||||||
|
|
||||||
|
## Source #2
|
||||||
|
- **Title**: Limiting Resolution Looking Down Through the Atmosphere
|
||||||
|
- **Link**: https://opg.optica.org/josa/abstract.cfm?uri=josa-56-10-1380
|
||||||
|
- **Tier**: L1
|
||||||
|
- **Publication Date**: Academic publication
|
||||||
|
- **Timeliness Status**: ✅ Currently valid (fundamental physics)
|
||||||
|
- **Summary**: Atmospheric turbulence limits ground resolution from high altitude to ~4.6cm. Independent of optics quality.
|
||||||
|
|
||||||
|
## Source #3
|
||||||
|
- **Title**: Pix4D — How to select Camera Focal Length and Flight Altitude
|
||||||
|
- **Link**: https://support.pix4d.com/hc/en-us/articles/202558849
|
||||||
|
- **Tier**: L2
|
||||||
|
- **Publication Date**: Updated regularly
|
||||||
|
- **Timeliness Status**: ✅ Currently valid
|
||||||
|
- **Summary**: GSD = (pixel_pitch × altitude) / focal_length. Standard formula for aerial imaging.
|
||||||
|
|
||||||
|
## Source #4
|
||||||
|
- **Title**: Airmobi A40 Pro Product Page
|
||||||
|
- **Link**: https://www.airmobi.com/product/a40-pro-40x-optical-zoom-3-axis-ai-tracking-gimbal-camera/
|
||||||
|
- **Tier**: L1 (manufacturer)
|
||||||
|
- **Publication Date**: 2024-2025
|
||||||
|
- **Timeliness Status**: ✅ Currently valid
|
||||||
|
- **Summary**: $2,299. 40x optical zoom, 170mm max FL, 1/2.8" Sony CMOS, 5MP, 3-axis gimbal. AI tracking. Detects vehicles up to 16km.
|
||||||
|
|
||||||
|
## Source #5
|
||||||
|
- **Title**: ViewPro Z40K Product Page
|
||||||
|
- **Link**: https://www.viewprouav.com/product/z40k-single-4k-hd-25-times-zoom-gimbal-camera.html
|
||||||
|
- **Tier**: L1 (manufacturer)
|
||||||
|
- **Publication Date**: 2024-2025
|
||||||
|
- **Timeliness Status**: ✅ Currently valid
|
||||||
|
- **Summary**: $3,000-5,000. 20x optical (40x hybrid) zoom, 1/2.3" Panasonic 25.9MP, 4K video, 3-axis gimbal.
|
||||||
|
|
||||||
|
## Source #6
|
||||||
|
- **Title**: SIYI ZT30 Product Page
|
||||||
|
- **Link**: https://shop.siyi.biz/products/siyi-zt30
|
||||||
|
- **Tier**: L1 (manufacturer)
|
||||||
|
- **Publication Date**: 2024-2025
|
||||||
|
- **Timeliness Status**: ✅ Currently valid
|
||||||
|
- **Summary**: $6,099-7,309. 30x optical zoom, 1/2.7" 8MP, 4K, thermal+LRF, 4-sensor pod. 9W average power.
|
||||||
|
|
||||||
|
## Source #7
|
||||||
|
- **Title**: DJI Zenmuse H30T Specs
|
||||||
|
- **Link**: https://enterprise.dji.com/zenmuse-h30-series/specs
|
||||||
|
- **Tier**: L1 (manufacturer)
|
||||||
|
- **Publication Date**: 2024-2025
|
||||||
|
- **Timeliness Status**: ✅ Currently valid
|
||||||
|
- **Summary**: $10,240-11,610. 34x optical, 1/1.8" 40MP, 4K, thermal 1280×1024, LRF. LOCKED TO DJI MATRICE PLATFORM.
|
||||||
|
|
||||||
|
## Source #8
|
||||||
|
- **Title**: LOONG VT500Rs Product Page
|
||||||
|
- **Link**: https://www.loonguav.com/vt500rs
|
||||||
|
- **Tier**: L1 (manufacturer)
|
||||||
|
- **Publication Date**: 2024-2025
|
||||||
|
- **Timeliness Status**: ✅ Currently valid
|
||||||
|
- **Summary**: Price unknown. 42x optical, 48MP (8000×6000), dual visible cameras, thermal, LRF. 1.2kg. Military ISR focus.
|
||||||
|
|
||||||
|
## Source #9
|
||||||
|
- **Title**: Sony FE 400-800mm F6.3-8 G OSS Announcement
|
||||||
|
- **Link**: https://alphauniverse.com/stories/sony-unveils-specialty-400800mm-f6-38-g-oss-super-telephoto-zoom-g-lens/
|
||||||
|
- **Tier**: L1 (manufacturer)
|
||||||
|
- **Publication Date**: 2025-02-26
|
||||||
|
- **Timeliness Status**: ✅ Currently valid
|
||||||
|
- **Summary**: £2,399 (~$3,000). 400-800mm f/6.3-8, 2,475g. Supports 1.4x/2x TC for 1120/1600mm. Shipping March 2025.
|
||||||
|
|
||||||
|
## Source #10
|
||||||
|
- **Title**: Gremsy T7 Specifications
|
||||||
|
- **Link**: https://gremsy.com/gremsy-t7-spec
|
||||||
|
- **Tier**: L1 (manufacturer)
|
||||||
|
- **Publication Date**: 2024-2025
|
||||||
|
- **Timeliness Status**: ✅ Currently valid
|
||||||
|
- **Summary**: $2,349. 3.175kg max payload. 3-axis, ±0.02° vibration. USB/CAN/UART. Phase One compatible.
|
||||||
|
|
||||||
|
## Source #11
|
||||||
|
- **Title**: Viewpro Viewlink Serial Command Protocol V3.3.3
|
||||||
|
- **Link**: https://www.viewprotech.com/index.php?ac=article&at=read&did=510
|
||||||
|
- **Tier**: L2 (manufacturer documentation)
|
||||||
|
- **Publication Date**: 2024
|
||||||
|
- **Timeliness Status**: ✅ Currently valid
|
||||||
|
- **Summary**: Documented serial UART and TCP protocol for controlling Viewpro gimbals from custom platforms.
|
||||||
|
|
||||||
|
## Source #12
|
||||||
|
- **Title**: ArduPilot ViewPro Gimbal Driver (AP_Mount)
|
||||||
|
- **Link**: https://github.com/ArduPilot/ardupilot/pull/22568
|
||||||
|
- **Tier**: L2 (open source)
|
||||||
|
- **Publication Date**: 2023-2024
|
||||||
|
- **Timeliness Status**: ✅ Currently valid
|
||||||
|
- **Summary**: Lua-based gimbal driver for Viewpro cameras in ArduPilot. Demonstrates serial integration feasibility.
|
||||||
|
|
||||||
|
## Source #13
|
||||||
|
- **Title**: MAVLink Gimbal Protocol v2
|
||||||
|
- **Link**: https://mavlink.io/en/services/gimbal_v2.html
|
||||||
|
- **Tier**: L1 (protocol standard)
|
||||||
|
- **Publication Date**: Ongoing standard
|
||||||
|
- **Timeliness Status**: ✅ Currently valid
|
||||||
|
- **Summary**: Standard protocol for gimbal control via MAVLink. Supports companion computer as gimbal manager.
|
||||||
|
|
||||||
|
## Source #14
|
||||||
|
- **Title**: UAVOS POD Stratospheric Earth Observation Payload
|
||||||
|
- **Link**: https://uasweekly.com/2026/02/02/uavos-unveils-stratospheric-earth-observation-payload/
|
||||||
|
- **Tier**: L2 (press release)
|
||||||
|
- **Publication Date**: 2026-02-02
|
||||||
|
- **Timeliness Status**: ✅ Currently valid
|
||||||
|
- **Summary**: 3.6kg, 69cm GSD from 15km, gyro-stabilized. Benchmark for stratospheric imaging. Price unknown (likely >>$30k).
|
||||||
|
|
||||||
|
## Source #15
|
||||||
|
- **Title**: A40TR Pro Product Page (Airmobi)
|
||||||
|
- **Link**: https://www.airmobi.com/product/a40tr-pro-40x-eo-ir-lrf-ai-object-tracking-gimbal-camera/
|
||||||
|
- **Tier**: L1 (manufacturer)
|
||||||
|
- **Publication Date**: 2024-2025
|
||||||
|
- **Timeliness Status**: ✅ Currently valid
|
||||||
|
- **Summary**: $7,499-7,999. 40x zoom EO + thermal + LRF. 3-axis gimbal. ±0.005° pointing. MIL-STD-810H certified.
|
||||||
|
|
||||||
|
## Source #16
|
||||||
|
- **Title**: Foxtech Seeker-30 TR Product Page
|
||||||
|
- **Link**: https://store.foxtech.com/seeker-30-tr-30x-optical-zoom-camera-with-3-axis-gimbal/
|
||||||
|
- **Tier**: L1 (manufacturer)
|
||||||
|
- **Publication Date**: 2024-2025
|
||||||
|
- **Timeliness Status**: ✅ Currently valid
|
||||||
|
- **Summary**: $3,899-4,299. 30x optical zoom, 2.13MP 1080p. Auto tracking. 4.0kg. Serial/PWM control.
|
||||||
|
|
||||||
|
## Source #17
|
||||||
|
- **Title**: High-altitude balloon payload stabilization research
|
||||||
|
- **Link**: https://iastatedigitalpress.com/ahac/article/5570/galley/5436/view/
|
||||||
|
- **Tier**: L1 (academic)
|
||||||
|
- **Timeliness Status**: ✅ Currently valid
|
||||||
|
- **Summary**: Balloon payloads experience continuous rotation and pendulum swinging. Active gimbals may be insufficient alone. Passive stabilization through suspension design is critical.
|
||||||
|
|
||||||
|
## Source #18
|
||||||
|
- **Title**: Sony RX10 IV Specifications
|
||||||
|
- **Link**: https://www.bhphotovideo.com/c/product/1361560-REG/
|
||||||
|
- **Tier**: L1
|
||||||
|
- **Publication Date**: 2017 (product), specs current
|
||||||
|
- **Timeliness Status**: ✅ Currently valid (still in production)
|
||||||
|
- **Summary**: $1,700. 1" sensor 20MP, 24-600mm equiv (8.8-220mm actual), 2.41µm pixel pitch. 4K video.
|
||||||
@@ -0,0 +1,103 @@
|
|||||||
|
# Fact Cards
|
||||||
|
|
||||||
|
## Fact #1
|
||||||
|
- **Statement**: GSD formula: GSD = (pixel_pitch × altitude) / focal_length. This is the fundamental relationship between sensor, optics, altitude, and ground resolution.
|
||||||
|
- **Source**: Source #3 (Pix4d)
|
||||||
|
- **Phase**: Phase 2
|
||||||
|
- **Confidence**: ✅ High
|
||||||
|
|
||||||
|
## Fact #2
|
||||||
|
- **Statement**: Atmospheric turbulence limits ground resolution from 10km altitude to approximately 4.6 cm regardless of optical system quality. Practical achievable limit is 5-8 cm in good conditions.
|
||||||
|
- **Source**: Source #2 (Optica journal)
|
||||||
|
- **Phase**: Phase 1
|
||||||
|
- **Confidence**: ✅ High
|
||||||
|
|
||||||
|
## Fact #3
|
||||||
|
- **Statement**: Vehicle detection requires ~1m GSD. Vehicle type identification requires ~25-50 cm GSD. Detailed vehicle description requires ~10 cm GSD. Per NIIRS scale.
|
||||||
|
- **Source**: Source #1 (NIIRS Guide)
|
||||||
|
- **Phase**: Phase 1
|
||||||
|
- **Confidence**: ✅ High
|
||||||
|
|
||||||
|
## Fact #4
|
||||||
|
- **Statement**: Training data GSD is approximately 10-20 cm/pixel (user confirmed). Target GSD from 10km must match this range.
|
||||||
|
- **Source**: User confirmation
|
||||||
|
- **Phase**: Phase 1
|
||||||
|
- **Confidence**: ✅ High
|
||||||
|
|
||||||
|
## Fact #5
|
||||||
|
- **Statement**: ViewPro A40 Pro achieves GSD of 11.6 cm/pixel from 10km at maximum zoom (170mm FL, 5MP stills). Video (1080p) gives 15.6 cm/pixel. Both within target 10-20 cm range.
|
||||||
|
- **Source**: Source #4 (Airmobi), calculated
|
||||||
|
- **Phase**: Phase 2
|
||||||
|
- **Confidence**: ✅ High (calculation verified)
|
||||||
|
|
||||||
|
## Fact #6
|
||||||
|
- **Statement**: ViewPro Z40K achieves GSD of ~10.3 cm/pixel from 10km at maximum optical zoom (~102mm FL, 25.9MP). Significantly more pixels per frame than A40 Pro (5888 vs 2560).
|
||||||
|
- **Source**: Source #5 (Viewpro), calculated
|
||||||
|
- **Phase**: Phase 2
|
||||||
|
- **Confidence**: ⚠️ Medium (FL estimated from HFOV spec)
|
||||||
|
|
||||||
|
## Fact #7
|
||||||
|
- **Statement**: DJI Zenmuse H30T achieves GSD of ~5.7 cm/pixel from 10km (172mm FL, 40MP). Best integrated zoom camera GSD. But LOCKED to DJI Matrice platform — cannot be used on custom balloon platform without reverse engineering.
|
||||||
|
- **Source**: Source #7 (DJI)
|
||||||
|
- **Phase**: Phase 2
|
||||||
|
- **Confidence**: ✅ High
|
||||||
|
|
||||||
|
## Fact #8
|
||||||
|
- **Statement**: LOONG VT500Rs achieves GSD of ~4.8 cm/pixel from 10km (192mm FL, 48MP). Near atmospheric limit. Price unknown, estimated $10k-20k based on market positioning.
|
||||||
|
- **Source**: Source #8 (LoongUAV), calculated
|
||||||
|
- **Phase**: Phase 2
|
||||||
|
- **Confidence**: ⚠️ Medium (price estimated)
|
||||||
|
|
||||||
|
## Fact #9
|
||||||
|
- **Statement**: Sony α7RV + FE 400-800mm achieves 4.7-9.4 cm/pixel GSD from 10km (400-800mm FL, 61MP, 3.76µm pixel pitch). Best image quality due to full-frame sensor and large pixels. Total weight with lens: 3,140g.
|
||||||
|
- **Source**: Source #9, #10 (Sony, Gremsy), calculated
|
||||||
|
- **Phase**: Phase 2
|
||||||
|
- **Confidence**: ✅ High
|
||||||
|
|
||||||
|
## Fact #10
|
||||||
|
- **Statement**: Viewpro gimbal cameras have documented serial (UART) and TCP/IP control protocols (Viewlink V3.3.3). ArduPilot has native Lua driver for Viewpro gimbals. Suitable for custom platform integration.
|
||||||
|
- **Source**: Source #11, #12 (Viewpro, ArduPilot)
|
||||||
|
- **Phase**: Phase 2
|
||||||
|
- **Confidence**: ✅ High
|
||||||
|
|
||||||
|
## Fact #11
|
||||||
|
- **Statement**: Gremsy T7 gimbal has 3.175kg max payload. Sony α7RV (665g) + FE 400-800mm (2,475g) = 3,140g — at the payload limit with virtually no margin. Risk of unreliable operation.
|
||||||
|
- **Source**: Source #10 (Gremsy)
|
||||||
|
- **Phase**: Phase 2
|
||||||
|
- **Confidence**: ✅ High
|
||||||
|
|
||||||
|
## Fact #12
|
||||||
|
- **Statement**: Balloon payloads experience continuous rotation and pendulum swinging. Active gimbal alone may be insufficient. Passive stabilization through suspension design is critical for image quality.
|
||||||
|
- **Source**: Source #17 (Iowa State)
|
||||||
|
- **Phase**: Phase 2
|
||||||
|
- **Confidence**: ✅ High
|
||||||
|
|
||||||
|
## Fact #13
|
||||||
|
- **Statement**: SIYI ZT30 is a 4-sensor pod ($6,099-7,309) with 30x optical zoom, 8MP, 4K, thermal, and LRF. 9W average power. Achieves ~12 cm/pixel GSD from 10km.
|
||||||
|
- **Source**: Source #6 (SIYI)
|
||||||
|
- **Phase**: Phase 2
|
||||||
|
- **Confidence**: ✅ High
|
||||||
|
|
||||||
|
## Fact #14
|
||||||
|
- **Statement**: A40TR Pro ($7,499-7,999) adds thermal imaging and laser rangefinder to the 40x zoom capability. MIL-STD-810H certified for -40°C to +55°C — best temperature rating among all options.
|
||||||
|
- **Source**: Source #15 (Airmobi)
|
||||||
|
- **Phase**: Phase 2
|
||||||
|
- **Confidence**: ✅ High
|
||||||
|
|
||||||
|
## Fact #15
|
||||||
|
- **Statement**: Sony RX10 IV ($1,700) with 1" sensor and 220mm actual FL achieves ~11 cm/pixel GSD from 10km. Has 20MP resolution (5472×3648). Needs external gimbal for balloon mounting. No documented remote zoom control for UAV integration.
|
||||||
|
- **Source**: Source #18 (B&H)
|
||||||
|
- **Phase**: Phase 2
|
||||||
|
- **Confidence**: ⚠️ Medium (remote control integration unclear)
|
||||||
|
|
||||||
|
## Fact #16
|
||||||
|
- **Statement**: With zoom capability, cameras can be adjusted to match any target GSD within their zoom range. A camera capable of 5cm GSD at max zoom can be zoomed out to deliver 10-20cm GSD matching training data. This means over-capability in GSD is an advantage, not a problem.
|
||||||
|
- **Source**: Derived from GSD formula
|
||||||
|
- **Phase**: Phase 2
|
||||||
|
- **Confidence**: ✅ High
|
||||||
|
|
||||||
|
## Fact #17
|
||||||
|
- **Statement**: Atmospheric haze at 10km reduces image contrast compared to 600-1000m imagery. Even with matched GSD, the AI model may need image preprocessing (dehazing) or fine-tuning for degraded imagery.
|
||||||
|
- **Source**: Source #2 (atmospheric research)
|
||||||
|
- **Phase**: Phase 2
|
||||||
|
- **Confidence**: ⚠️ Medium (impact on specific AI model unknown)
|
||||||
+51
@@ -0,0 +1,51 @@
|
|||||||
|
# Comparison Framework
|
||||||
|
|
||||||
|
## Selected Framework Type
|
||||||
|
Decision Support — evaluating trade-offs between gimbal camera systems for a specific use case
|
||||||
|
|
||||||
|
## Selected Dimensions
|
||||||
|
1. GSD from 10km (achievable ground resolution)
|
||||||
|
2. Image resolution / FOV coverage
|
||||||
|
3. Sensor quality (size, SNR, dynamic range)
|
||||||
|
4. Integration feasibility (control protocol, balloon platform compatibility)
|
||||||
|
5. Stabilization quality (gimbal precision, balloon motion handling)
|
||||||
|
6. Additional sensors (thermal, LRF)
|
||||||
|
7. Power requirements
|
||||||
|
8. Weight
|
||||||
|
9. Price (total system cost)
|
||||||
|
10. Atmospheric haze resilience (sensor size impact on contrast)
|
||||||
|
|
||||||
|
## GSD Calculations Summary
|
||||||
|
|
||||||
|
All calculations assume:
|
||||||
|
- Altitude: 10,000m
|
||||||
|
- Target GSD: 10-20 cm/pixel (to match AI training data)
|
||||||
|
|
||||||
|
| System | Sensor | Pixel Pitch | Max FL | GSD@10km | Resolution | FOV@10km | In Target? |
|
||||||
|
|---|---|---|---|---|---|---|---|
|
||||||
|
| A40 Pro | 1/2.8" 5MP | 1.98µm | 170mm | 11.6 cm | 2560×1920 | 297×223m | ✅ Yes |
|
||||||
|
| Z40K | 1/2.3" 25.9MP | 1.05µm | ~102mm | 10.3 cm | 5888×4400 | 606×453m | ✅ Yes |
|
||||||
|
| SIYI ZT30 | 1/2.7" 8MP | ~1.65µm | ~138mm | 12.0 cm | 3264×2448 | 392×294m | ✅ Yes |
|
||||||
|
| A40TR Pro | 1/2.8" 5MP | 1.98µm | 170mm | 11.6 cm | 2560×1920 | 297×223m | ✅ Yes |
|
||||||
|
| DJI H30T | 1/1.8" 40MP | 0.99µm | 172mm | 5.7 cm | 7296×5472 | 416×312m | ✅ (adjustable) |
|
||||||
|
| VT500Rs | ~1/2" 48MP | 0.92µm | 192mm | 4.8 cm | 8000×6000 | 385×289m | ✅ (adjustable) |
|
||||||
|
| Sony α7RV+800mm | FF 61MP | 3.76µm | 800mm | 4.7 cm | 9504×6336 | 447×298m | ✅ (adjustable) |
|
||||||
|
| Sony RX10 IV | 1" 20MP | 2.41µm | 220mm | 11.0 cm | 5472×3648 | 602×401m | ✅ Yes |
|
||||||
|
|
||||||
|
## Initial Population
|
||||||
|
|
||||||
|
| Dimension | A40 Pro | Z40K | SIYI ZT30 | A40TR Pro | Sony α7RV+800mm | Sony RX10 IV |
|
||||||
|
|---|---|---|---|---|---|---|
|
||||||
|
| GSD@10km | 11.6 cm ✅ | 10.3 cm ✅ | 12.0 cm ✅ | 11.6 cm ✅ | 4.7-9.4 cm ✅ | 11.0 cm ✅ |
|
||||||
|
| Resolution | 5MP (low) | 25.9MP (good) | 8MP (adequate) | 5MP (low) | 61MP (excellent) | 20MP (good) |
|
||||||
|
| FOV@10km | 297×223m | 606×453m | 392×294m | 297×223m | 447×298m | 602×401m |
|
||||||
|
| Sensor quality | Small, low SNR | Small, decent | Small, adequate | Small, low SNR | Full-frame, excellent | 1", good |
|
||||||
|
| Integration | Serial/TCP ✅ | Serial/TCP ✅ | Serial ✅ | Serial/TCP ✅ | Custom ⚠️ | Custom ⚠️ |
|
||||||
|
| Gimbal quality | ±0.02° | ±0.02° | ±0.01° | ±0.005° | Gremsy T7 ±0.02° | Needs external |
|
||||||
|
| Additional sensors | AI tracking | AI tracking | Thermal+LRF | Thermal+LRF | None | None |
|
||||||
|
| Power | ~15-25W | ~15-25W | 9W avg | ~20-30W | ~40-60W | ~10-15W |
|
||||||
|
| Weight | ~1kg | ~1kg | ~1.2kg | ~1.5kg | ~5kg total | ~1.1kg+gimbal |
|
||||||
|
| Price | $2,299 | $3,000-5,000 | $6,099-7,309 | $7,499-7,999 | ~$10,850 | ~$4,200-5,200 |
|
||||||
|
| Haze resilience | Low | Low | Low | Low | High | Moderate |
|
||||||
|
|
||||||
|
Note: DJI H30T ($10,240-11,610) and LOONG VT500Rs (price unknown) excluded from primary comparison due to DJI platform lock and unknown pricing respectively.
|
||||||
+130
@@ -0,0 +1,130 @@
|
|||||||
|
# Reasoning Chain
|
||||||
|
|
||||||
|
## Dimension 1: GSD Achievability
|
||||||
|
|
||||||
|
### Fact Confirmation
|
||||||
|
All candidate systems achieve 10-20 cm/pixel GSD from 10km (Facts #5-#9, #15). The atmospheric limit is ~5cm (Fact #2), so all options are optics-limited (good — no wasted capability).
|
||||||
|
|
||||||
|
### Reference Comparison
|
||||||
|
Systems with higher zoom/longer FL can achieve finer GSD but can always zoom out to match training data (Fact #16). Higher-capability systems provide flexibility to zoom in for closer inspection of specific targets.
|
||||||
|
|
||||||
|
### Conclusion
|
||||||
|
All candidates pass the GSD requirement. Systems with higher resolution sensors (Z40K 25.9MP, Sony α7RV 61MP) provide significantly better spatial coverage per frame at the target GSD.
|
||||||
|
|
||||||
|
### Confidence
|
||||||
|
✅ High — based on verified calculations
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Dimension 2: Image Quality for AI Model Reuse
|
||||||
|
|
||||||
|
### Fact Confirmation
|
||||||
|
The AI model was trained on 10-20 cm/pixel imagery from 600-1000m altitude (Fact #4). At that altitude, atmospheric path is short — images are sharp with high contrast. At 10km, haze reduces contrast (Fact #17).
|
||||||
|
|
||||||
|
### Reference Comparison
|
||||||
|
Larger sensors have better SNR and dynamic range, which partially compensates for atmospheric degradation:
|
||||||
|
- Full-frame (Sony α7RV): 3.76µm pixels, excellent SNR
|
||||||
|
- 1" sensor (RX10 IV): 2.41µm pixels, good SNR
|
||||||
|
- 1/2.3" to 1/2.8" (drone gimbals): 1.0-2.0µm pixels, limited SNR
|
||||||
|
|
||||||
|
Smaller pixels on drone gimbals mean each pixel gathers less light, amplifying atmospheric haze impact.
|
||||||
|
|
||||||
|
### Conclusion
|
||||||
|
For AI model reuse from 10km, larger sensors provide measurably better imagery. However, the practical impact depends on atmospheric conditions. In mostly sunny weather (user constraint), even small-sensor cameras may produce adequate results. Computational dehazing can bridge the gap. The Sony full-frame option offers the best margin of safety for image quality.
|
||||||
|
|
||||||
|
### Confidence
|
||||||
|
⚠️ Medium — depends on specific atmospheric conditions and AI model sensitivity
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Dimension 3: Platform Integration
|
||||||
|
|
||||||
|
### Fact Confirmation
|
||||||
|
Viewpro cameras have documented serial (Viewlink) and TCP protocols (Fact #10). ArduPilot has native Lua driver. SIYI has serial protocol. DJI H30T is locked to DJI Matrice (Fact #7). Sony cameras have no native gimbal/serial integration.
|
||||||
|
|
||||||
|
### Reference Comparison
|
||||||
|
- Viewpro/Airmobi: Plug-and-play for custom platforms via UART/TCP. Best integration story.
|
||||||
|
- SIYI: Serial protocol available, community support in ArduPilot ecosystem.
|
||||||
|
- Sony + Gremsy: Gremsy T7 has MAVLink support, but camera zoom/photo control requires separate integration (USB/HDMI). More complex.
|
||||||
|
- DJI: Effectively impossible on non-DJI platforms.
|
||||||
|
|
||||||
|
### Conclusion
|
||||||
|
Chinese drone gimbal cameras (Viewpro, SIYI) offer the simplest path to balloon integration. Sony approach requires significantly more custom engineering. DJI is disqualified for this use case.
|
||||||
|
|
||||||
|
### Confidence
|
||||||
|
✅ High — based on manufacturer documentation and open-source drivers
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Dimension 4: Balloon-Specific Stabilization
|
||||||
|
|
||||||
|
### Fact Confirmation
|
||||||
|
Balloon payloads experience continuous rotation and pendulum swinging (Fact #12). Active gimbal alone may be insufficient. All candidate gimbals have ±0.01° to ±0.02° vibration accuracy.
|
||||||
|
|
||||||
|
### Comparison
|
||||||
|
All integrated drone gimbals are designed for UAV vibration (high frequency, small amplitude). Balloon motion is different (low frequency, large amplitude rotation/swinging). The A40TR Pro has the tightest pointing accuracy (±0.005°) and MIL-STD certification.
|
||||||
|
|
||||||
|
For the Sony approach, the Gremsy T7 is at payload limit (3,140g vs 3,175g max) — this leaves almost no margin and the gimbal motors may struggle with balloon-specific motion compensation.
|
||||||
|
|
||||||
|
### Conclusion
|
||||||
|
All candidates need passive stabilization via suspension design (anti-rotation mechanism, pendulum dampers). The gimbal handles residual motion. The A40TR Pro has the best specifications for pointing accuracy. The Sony approach has gimbal weight margin concerns.
|
||||||
|
|
||||||
|
### Confidence
|
||||||
|
⚠️ Medium — balloon-specific testing required to validate
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Dimension 5: Cost-Benefit Analysis
|
||||||
|
|
||||||
|
### Fact Confirmation
|
||||||
|
Budget: $30k. Options range from $2,299 to ~$10,850 for the camera system alone. Need to account for integration hardware, cables, power, and passive stabilization.
|
||||||
|
|
||||||
|
### Comparison
|
||||||
|
| Option | Camera System | Integration/Mounting | Passive Stabilization | Total Est. |
|
||||||
|
|---|---|---|---|---|
|
||||||
|
| A40 Pro | $2,299 | $500 | $1,000-2,000 | $3,800-4,800 |
|
||||||
|
| Z40K | $3,000-5,000 | $500 | $1,000-2,000 | $4,500-7,500 |
|
||||||
|
| SIYI ZT30 | $6,099-7,309 | $500 | $1,000-2,000 | $7,600-9,800 |
|
||||||
|
| A40TR Pro | $7,499-7,999 | $500 | $1,000-2,000 | $9,000-10,500 |
|
||||||
|
| Sony α7RV+800mm+T7 | $10,850 | $2,000-3,000 | $1,000-2,000 | $13,850-15,850 |
|
||||||
|
|
||||||
|
All options are well within $30k budget.
|
||||||
|
|
||||||
|
### Conclusion
|
||||||
|
There's significant budget headroom. The decision should be driven by image quality needs and integration simplicity rather than cost alone. Even the premium Sony option leaves >$14k for contingency and additional equipment.
|
||||||
|
|
||||||
|
### Confidence
|
||||||
|
✅ High — pricing from manufacturer sources
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Dimension 6: Recommendation Reasoning
|
||||||
|
|
||||||
|
### For maximum simplicity and value: ViewPro Z40K ($3,000-5,000)
|
||||||
|
- 25.9MP resolution gives excellent ground coverage (606×453m FOV)
|
||||||
|
- 10.3 cm GSD at max zoom matches training data
|
||||||
|
- 4K video for review
|
||||||
|
- Documented serial protocol for custom integration
|
||||||
|
- Lightweight (~1kg)
|
||||||
|
- Leaves >$25k budget for spare units, integration, and contingency
|
||||||
|
|
||||||
|
### For maximum image quality: Sony α7RV + FE 400-800mm + Gremsy T7 (~$10,850)
|
||||||
|
- Full-frame sensor provides best atmospheric haze resilience
|
||||||
|
- Adjustable zoom from 400-800mm (9.4-4.7 cm GSD)
|
||||||
|
- 61MP resolution for highest detail
|
||||||
|
- Risk: weight at gimbal limit, complex integration, no turnkey zoom control
|
||||||
|
|
||||||
|
### For best balance of quality, features, and integration: A40TR Pro ($7,499-7,999)
|
||||||
|
- 40x zoom (170mm max) gives 11.6 cm GSD — within target
|
||||||
|
- MIL-STD-810H certification (-40°C to +55°C) — best environmental rating
|
||||||
|
- Thermal camera for night/low-visibility operation
|
||||||
|
- Laser rangefinder for target distance measurement
|
||||||
|
- ±0.005° pointing accuracy — tightest of all options
|
||||||
|
- Documented serial protocol
|
||||||
|
- Only 1.5kg
|
||||||
|
|
||||||
|
### For maximum versatility with multi-sensor: SIYI ZT30 ($6,099-7,309)
|
||||||
|
- 4 sensors (zoom, thermal, wide-angle, LRF)
|
||||||
|
- 12 cm GSD at max zoom — within target
|
||||||
|
- Lowest power consumption (9W average)
|
||||||
|
- Wide ArduPilot/PX4 community support
|
||||||
+51
@@ -0,0 +1,51 @@
|
|||||||
|
# Validation Log
|
||||||
|
|
||||||
|
## Validation Scenario
|
||||||
|
A balloon at 10km altitude in eastern Ukraine on a sunny day needs to photograph a convoy of military trucks on a road. The AI model (trained on 600-1000m imagery at 10-20 cm/pixel) must detect and classify the vehicles.
|
||||||
|
|
||||||
|
## Expected Based on Conclusions
|
||||||
|
|
||||||
|
### Using ViewPro Z40K:
|
||||||
|
- GSD at max zoom: 10.3 cm/pixel. Each truck (~8m long) ≈ 78 pixels long in the image.
|
||||||
|
- FOV: 606×453m — covers a road segment of ~600m. Can see multiple vehicles.
|
||||||
|
- Image quality: 25.9MP provides good detail. Small sensor (1/2.3") may show some contrast loss from haze in sunny conditions.
|
||||||
|
- Integration: Serial control from companion computer. Can trigger photos and adjust zoom remotely.
|
||||||
|
- Expected: Model should detect trucks with reasonable confidence. May need dehazing in hazy conditions.
|
||||||
|
|
||||||
|
### Using A40TR Pro:
|
||||||
|
- GSD at max zoom: 11.6 cm/pixel. Each truck ≈ 69 pixels long.
|
||||||
|
- FOV: 297×223m — narrower coverage, fewer vehicles per frame.
|
||||||
|
- Thermal camera adds night capability and can detect engine heat signatures.
|
||||||
|
- MIL-STD certified, most robust for field conditions.
|
||||||
|
- Expected: Model should detect trucks. Thermal overlay provides backup detection.
|
||||||
|
|
||||||
|
### Using Sony α7RV + 400-800mm:
|
||||||
|
- At 600mm (15.8 cm GSD target): GSD = 6.3 cm/pixel. Each truck ≈ 127 pixels long.
|
||||||
|
- FOV: 599×399m — good coverage.
|
||||||
|
- Full-frame sensor captures more light per pixel, better contrast through haze.
|
||||||
|
- Expected: Best image quality. Model may need GSD adjustment (zoom to match 10-20cm range or downscale).
|
||||||
|
- Risk: Gimbal at weight limit may cause jitter on balloon. Integration is complex.
|
||||||
|
|
||||||
|
## Actual Validation Results (analytical)
|
||||||
|
|
||||||
|
1. All three systems can achieve the target 10-20 cm/pixel GSD — validated by calculation
|
||||||
|
2. Trucks at 10-20 cm/pixel occupy ~40-80 pixels in length — sufficient for CNN-based detection models
|
||||||
|
3. Atmospheric haze in sunny conditions over Ukraine plains is typically moderate — dehazing should be effective
|
||||||
|
4. Balloon passive stabilization is the unvalidated risk — needs physical prototyping
|
||||||
|
|
||||||
|
## Counterexamples
|
||||||
|
|
||||||
|
1. **Cloudy/hazy day**: Small-sensor cameras will produce significantly degraded imagery. The Sony full-frame option is more resilient but still affected. Cloud cover completely blocks all optical imaging.
|
||||||
|
2. **Nighttime**: Only A40TR Pro and SIYI ZT30 have thermal cameras for night operation. Others are daylight-only.
|
||||||
|
3. **Fast-moving targets**: At 10km range, even fast vehicles appear slow relative to the camera. Not a concern.
|
||||||
|
4. **Very small targets**: People or small objects at 10-20 cm/pixel would be only a few pixels — below detection threshold. This use case is for trucks/vehicles only.
|
||||||
|
|
||||||
|
## Review Checklist
|
||||||
|
- [x] Draft conclusions consistent with fact cards
|
||||||
|
- [x] No important dimensions missed
|
||||||
|
- [x] No over-extrapolation
|
||||||
|
- [x] Conclusions actionable — user can purchase any recommended system
|
||||||
|
- [ ] Note: Balloon-specific stabilization requires physical validation
|
||||||
|
|
||||||
|
## Conclusions Requiring Revision
|
||||||
|
None — but balloon motion compensation is flagged as the key unknown requiring prototyping.
|
||||||
@@ -0,0 +1,152 @@
|
|||||||
|
# Solution Draft — Gimbal Camera for High-Altitude Balloon (10km)
|
||||||
|
|
||||||
|
## Product Solution Description
|
||||||
|
|
||||||
|
A zoom gimbal camera mounted on a balloon at 10km altitude, producing imagery with 10-20 cm/pixel GSD to match an AI detection model trained on 600-1000m altitude data. The system must detect trucks, vehicles, and tracked machinery. Budget: under $30k.
|
||||||
|
|
||||||
|
The solution consists of: (1) a zoom gimbal camera with documented serial/TCP control protocol, (2) passive anti-rotation and pendulum damping suspension between the balloon and the camera, (3) a companion computer controlling the gimbal via serial/TCP/MAVLink, and (4) optional computational dehazing to improve image quality through 10km of atmosphere.
|
||||||
|
|
||||||
|
```
|
||||||
|
Balloon (10km)
|
||||||
|
│
|
||||||
|
├── Anti-rotation swivel
|
||||||
|
│
|
||||||
|
├── Pendulum damper / shock absorber
|
||||||
|
│
|
||||||
|
└── Camera payload bay (thermally protected)
|
||||||
|
├── Zoom gimbal camera (3-axis stabilized)
|
||||||
|
├── Companion computer (control + image capture)
|
||||||
|
└── Power distribution
|
||||||
|
```
|
||||||
|
|
||||||
|
## Existing/Competitor Solutions Analysis
|
||||||
|
|
||||||
|
| Solution | Altitude | GSD | Price | Notes |
|
||||||
|
|---|---|---|---|---|
|
||||||
|
| UAVOS POD (HAPS) | 15km | 69 cm/pixel | Unknown (>>$30k) | Purpose-built for stratosphere. GSD too coarse for vehicle identification |
|
||||||
|
| Aerostat systems (SKYSTAR, Hemeria) | 500-3500m | Sub-meter | $28k-500k+ | Lower altitude, includes balloon+winch+camera. Purpose-built but wrong altitude range |
|
||||||
|
| Military gimbals (WESCAM MX-10) | Any | Sub-cm to m | $100k-500k+ | Best quality but far exceeds budget and has export restrictions |
|
||||||
|
| DJI Zenmuse H30T | Drone altitude | 5.7 cm @10km | $10,240 | Excellent camera but locked to DJI Matrice drones. Cannot be used on custom balloon platform |
|
||||||
|
|
||||||
|
No off-the-shelf solution exists for a $30k camera on a 10km balloon with 10-20cm GSD. All viable approaches use drone gimbal cameras adapted for balloon mounting.
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
### Component: Zoom Gimbal Camera
|
||||||
|
|
||||||
|
| Solution | Sensor / Resolution | Max FL / GSD@10km | FOV@10km | Integration | Additional Sensors | Weight | Price | Fit |
|
||||||
|
|---|---|---|---|---|---|---|---|---|
|
||||||
|
| **ViewPro Z40K** | 1/2.3" 25.9MP | ~102mm / 10.3 cm | 606×453m | Serial/TCP, ArduPilot ✅ | AI tracking | ~1kg | $3,000-5,000 | ⭐ Best value — highest resolution for price, largest FOV |
|
||||||
|
| **A40TR Pro** | 1/2.8" 5MP | 170mm / 11.6 cm | 297×223m | Serial/TCP, ArduPilot ✅ | Thermal + LRF + AI | ~1.5kg | $7,499-7,999 | ⭐ Best multi-sensor — thermal night ops, MIL-STD-810H, tightest pointing |
|
||||||
|
| **SIYI ZT30** | 1/2.7" 8MP | ~138mm / 12.0 cm | 392×294m | Serial, ArduPilot/PX4 ✅ | Thermal + LRF + wide-angle | ~1.2kg | $6,099-7,309 | Good versatility — 4 sensors, lowest power (9W), wide community support |
|
||||||
|
| **ViewPro A40 Pro** | 1/2.8" 5MP | 170mm / 11.6 cm | 297×223m | Serial/TCP, ArduPilot ✅ | AI tracking | ~1kg | $2,299 | Budget option — proven 40x zoom, lowest cost, but only 5MP/1080p |
|
||||||
|
| **Sony α7RV + 400-800mm + T7** | FF 61MP | 800mm / 4.7 cm | 447×298m | Custom integration ⚠️ | None | ~5kg | ~$10,850 | Best image quality — full-frame, best haze resilience, complex integration |
|
||||||
|
| **Sony RX10 IV + gimbal** | 1" 20MP | 220mm / 11.0 cm | 602×401m | Custom integration ⚠️ | None | ~1.1kg+gimbal | ~$4,200-5,200 | Good sensor quality, wide FOV, but no remote zoom protocol |
|
||||||
|
|
||||||
|
### GSD Calculation Reference
|
||||||
|
|
||||||
|
```
|
||||||
|
GSD = (pixel_pitch × altitude) / focal_length
|
||||||
|
|
||||||
|
Example for Z40K:
|
||||||
|
pixel_pitch = 6.17mm / 5888px = 1.048µm
|
||||||
|
GSD = (0.001048mm × 10,000,000mm) / 102mm = 102.7mm ≈ 10.3 cm/pixel
|
||||||
|
```
|
||||||
|
|
||||||
|
### Component: Passive Stabilization System
|
||||||
|
|
||||||
|
| Solution | Mechanism | Advantages | Limitations | Cost | Fit |
|
||||||
|
|---|---|---|---|---|---|
|
||||||
|
| Anti-rotation swivel + pendulum damper | Mechanical swivel bearing at suspension point, viscous/spring dampers on suspension lines | Proven in aerostat/balloon systems, no power needed, reduces rotation to near-zero | Adds weight (1-3kg), requires custom fabrication | $1,000-3,000 | Recommended baseline |
|
||||||
|
| Passive pendulum (long suspension line) | Increase distance between balloon and payload (5-10m line) | Simple, reduces oscillation frequency | Doesn't eliminate rotation, adds deployment complexity | $200-500 | Supplement to swivel |
|
||||||
|
| Reaction wheel (active) | Motorized flywheel counters rotation torque | Eliminates rotation completely | Adds complexity, weight, and power draw | $2,000-5,000 | For demanding pointing requirements |
|
||||||
|
|
||||||
|
### Component: Companion Computer Integration
|
||||||
|
|
||||||
|
For this project, the existing GPS-Denied system runs on Jetson Orin Nano with MAVLink/MAVSDK. The gimbal camera integration would use the same companion computer architecture:
|
||||||
|
|
||||||
|
| Approach | Protocol | Camera Support | Complexity | Fit |
|
||||||
|
|---|---|---|---|---|
|
||||||
|
| ArduPilot Lua driver (Viewpro) | Viewlink serial | A40 Pro, Z40K, A40TR Pro | Low — use existing ArduPilot driver | Best for Viewpro cameras |
|
||||||
|
| MAVLink Gimbal Protocol v2 | MAVLink serial | SIYI, Viewpro (via proxy) | Low-Medium — standard protocol | Best for SIYI cameras |
|
||||||
|
| Custom serial integration | Manufacturer protocol | Any with serial API | Medium — write custom driver | Fallback for any camera |
|
||||||
|
| USB/HDMI + Gremsy SDK | USB + CAN | Sony + Gremsy T7 | High — separate camera and gimbal control | Only option for Sony approach |
|
||||||
|
|
||||||
|
### Component: Image Preprocessing (Atmospheric Haze Mitigation)
|
||||||
|
|
||||||
|
| Solution | Approach | Advantages | Limitations | Cost | Fit |
|
||||||
|
|---|---|---|---|---|---|
|
||||||
|
| Dark Channel Prior dehazing | Classic computer vision algorithm | Fast, no training needed, well-proven | May introduce artifacts, struggles with sky regions | Free (OpenCV) | Good baseline |
|
||||||
|
| CNN-based dehazing (AOD-Net, DehazeFormer) | Deep learning single-image dehazing | Better quality than classical, handles complex haze | Needs GPU, adds latency (~50-100ms) | Free (open source) | Better quality, adds processing time |
|
||||||
|
| Multi-scale Retinex (MSR) | Contrast enhancement | Simple, fast, improves visibility | Not true dehazing, may amplify noise | Free (OpenCV) | Quick alternative |
|
||||||
|
| No dehazing (sunny weather) | Direct use | No processing overhead | May reduce AI model accuracy in hazy conditions | Free | Acceptable for clear conditions |
|
||||||
|
|
||||||
|
## Recommendations
|
||||||
|
|
||||||
|
### Primary Recommendation: ViewPro Z40K ($3,000-5,000)
|
||||||
|
|
||||||
|
**Rationale**: Best value proposition for this specific use case.
|
||||||
|
- 25.9MP resolution — by far the highest among integrated gimbal cameras in this price range
|
||||||
|
- 10.3 cm/pixel GSD at max zoom — directly matches training data range
|
||||||
|
- 606×453m FOV — covers the largest ground area per frame, meaning more vehicles visible per image
|
||||||
|
- 4K video output for live monitoring
|
||||||
|
- Documented Viewlink serial protocol with existing ArduPilot driver
|
||||||
|
- ~1kg weight, ~15-25W power
|
||||||
|
- $3,000-5,000 leaves ample budget for integration, spares, and contingency
|
||||||
|
|
||||||
|
**Total estimated system cost**: $5,000-8,000 (camera + passive stabilization + integration hardware)
|
||||||
|
|
||||||
|
### Secondary Recommendation: A40TR Pro ($7,499-7,999)
|
||||||
|
|
||||||
|
**When to choose instead**: If you need night/thermal operation, laser ranging for target distance, or require MIL-STD-810H environmental certification. The thermal camera enables 24/7 operation and backup detection when optical imagery is degraded.
|
||||||
|
|
||||||
|
**Trade-off**: 5MP EO resolution is significantly lower than Z40K's 25.9MP, resulting in 4x smaller ground coverage per frame. For pure AI detection in daylight, Z40K is better.
|
||||||
|
|
||||||
|
**Total estimated system cost**: $9,000-12,000
|
||||||
|
|
||||||
|
### Alternative: Sony α7RV + FE 400-800mm + Gremsy T7 (~$10,850)
|
||||||
|
|
||||||
|
**When to choose**: If atmospheric haze proves too degrading for small-sensor cameras, the full-frame sensor provides significantly better contrast and SNR. This is the "maximum image quality" option.
|
||||||
|
|
||||||
|
**Risks**:
|
||||||
|
- Camera+lens weight (3,140g) is at the Gremsy T7 payload limit (3,175g) — virtually no margin
|
||||||
|
- No turnkey integration — requires custom camera control, zoom control, and photo trigger
|
||||||
|
- Sony camera rated 0-40°C only (balloon thermal protection must maintain this range)
|
||||||
|
- Most complex and heaviest system
|
||||||
|
|
||||||
|
**Total estimated system cost**: $13,850-15,850
|
||||||
|
|
||||||
|
## Testing Strategy
|
||||||
|
|
||||||
|
### Integration / Functional Tests
|
||||||
|
- Mount camera on test platform, verify serial/TCP control of zoom, pan, tilt, and photo capture
|
||||||
|
- Verify image capture at different zoom levels and calculate actual GSD against predictions
|
||||||
|
- Test passive stabilization mock-up with simulated balloon motion (pendulum, rotation)
|
||||||
|
- Verify power budget under sustained operation (camera + gimbal + companion computer)
|
||||||
|
|
||||||
|
### Non-Functional Tests
|
||||||
|
- Ground-level test: photograph known-size vehicles from maximum available height and verify AI model detection at target GSD (resize images to simulate 10km GSD)
|
||||||
|
- Atmospheric test: if possible, test from lower altitude (1-2km) and compare image quality with/without dehazing
|
||||||
|
- Duration test: run camera continuously for 4+ hours to verify thermal stability and reliability
|
||||||
|
- Balloon integration test: short tethered balloon flight at lower altitude to validate stabilization and control
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
- NIIRS Civil Reference Guide — https://irp.fas.org/imint/niirs_c/guide.htm
|
||||||
|
- Atmospheric resolution limit — https://opg.optica.org/josa/abstract.cfm?uri=josa-56-10-1380
|
||||||
|
- GSD formula — https://support.pix4d.com/hc/en-us/articles/202558849
|
||||||
|
- Airmobi A40 Pro — https://www.airmobi.com/product/a40-pro-40x-optical-zoom-3-axis-ai-tracking-gimbal-camera/
|
||||||
|
- ViewPro Z40K — https://www.viewprouav.com/product/z40k-single-4k-hd-25-times-zoom-gimbal-camera.html
|
||||||
|
- A40TR Pro — https://www.airmobi.com/product/a40tr-pro-40x-eo-ir-lrf-ai-object-tracking-gimbal-camera/
|
||||||
|
- SIYI ZT30 — https://shop.siyi.biz/products/siyi-zt30
|
||||||
|
- DJI H30T — https://enterprise.dji.com/zenmuse-h30-series/specs
|
||||||
|
- LOONG VT500Rs — https://www.loonguav.com/vt500rs
|
||||||
|
- Sony FE 400-800mm — https://alphauniverse.com/stories/sony-unveils-specialty-400800mm-f6-38-g-oss-super-telephoto-zoom-g-lens/
|
||||||
|
- Gremsy T7 — https://gremsy.com/gremsy-t7-spec
|
||||||
|
- Viewpro Viewlink Protocol — https://www.viewprotech.com/index.php?ac=article&at=read&did=510
|
||||||
|
- ArduPilot Viewpro Driver — https://github.com/ArduPilot/ardupilot/pull/22568
|
||||||
|
- MAVLink Gimbal Protocol v2 — https://mavlink.io/en/services/gimbal_v2.html
|
||||||
|
- UAVOS POD — https://uasweekly.com/2026/02/02/uavos-unveils-stratospheric-earth-observation-payload/
|
||||||
|
- Balloon stabilization — https://iastatedigitalpress.com/ahac/article/5570/galley/5436/view/
|
||||||
|
- Sony RX10 IV — https://www.bhphotovideo.com/c/product/1361560-REG/
|
||||||
|
- Foxtech Seeker-30 TR — https://store.foxtech.com/seeker-30-tr-30x-optical-zoom-camera-with-3-axis-gimbal/
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
I have an balloon flying on the 10 km altitude.
|
||||||
|
I have also AI detection model trained on the annotations of objects taken from 600-1000 m altitude.
|
||||||
|
I want to reuse this model to detect objects taken from the camera on the balloon.
|
||||||
|
For that I want to use some camera with zoom capabilities on a pretty decent gimbal.
|
||||||
|
|
||||||
|
Research for the options for such gimbal camera under $30k
|
||||||
Reference in New Issue
Block a user