Skip to content

Plan a UAV sensor-collection mission

Measure per-leg coverage and battery use, reject an overlong route, replan around an exclusion and validate a handoff.

Blueprint Bina: I want you to inspect the failed case and the record that explains the next decision., your practice guide

Blueprint Bina: I want you to inspect the failed case and the record that explains the next decision.
Predict the reading, then compare it with the measurement.

Python 3 in your browser (JupyterLite)

Python · no install

Tier 2 · Web · paste-in setup · No account

Version tested: Python 3.12.7 / Pyodide 0.27.6 in JupyterLite 0.6.4; Chromium 148.0.7778.96; captureSource playwright:jupyterlite. Date: 2026-09-10.

Open the notebook in your browser and run each Python cell; no install or account is needed.

Three ways to run: use JupyterLite here with no install; run main.py locally from the downloadable lab folder; or open the same notebook in Google Colab.

Open in your browser (new tab)

Steps

Screens captured against Python 3 in your browser (JupyterLite) Python 3.12.7 / Pyodide 0.27.6 in JupyterLite 0.6.4; Chromium 148.0.7778.96; captureSource playwright:jupyterlite on 2026-09-10; the tool may have moved on — the text steps are the contract.

  1. 1 Step 1

    Do
    In the JupyterLite notebook, run the Step 1 cell to define a survey envelope and record contract.
    You will see
    Input: execute notebook step 1 with the record’s unchanged fixture, seed, and parameters. Observed: Fictional field=80x80 m; altitude fixed=20 m; speed=5 m/s Observed: Battery=36.0 Wh; reserve=6.0 Wh; travel=0.08 Wh/m Observed: Hover=0.3 Wh/s; dwell=2 s; manoeuvre allowance=0.2 Wh/leg
    Why it matters
    Expected: STEP 1 mission envelope frozen from this deterministic notebook step. Interpretation: The legacy lab requires an envelope before route generation. Declared energy, dwell and reserve assumptions make this classroom simulation reproducible. Action: Run python main.py and inspect step 1: define a survey envelope and record contract. Boundary: this local fixture is not a live device, network, or site measurement.
    JupyterLite step 1 showing the executed Python and its observed result.
    Step 1 · Python 3 in your browser (JupyterLite); numbered callout added to a real capture. Enlarge screenshot (new tab)
  2. 2 Step 2

    Do
    In the JupyterLite notebook, run the Step 2 cell to inspect route v1 before execution.
    You will see
    Input: execute notebook step 2 with the record’s unchanged fixture, seed, and parameters. Observed: Inspect route v1 before execution Observed: 1 ( 10, 20) A 22.36 2 2.59 12.5% Observed: 2 ( 30, 20) B 20.00 2 2.40 25.0%
    Why it matters
    Expected: STEP 2 v1 manifest ready from this deterministic notebook step. Interpretation: A route manifest must show geometry, collection actions and their costs. Cumulative coverage here counts sensor records, not area swept by a camera. Action: Run python main.py and inspect step 2: inspect route v1 before execution. Boundary: this local fixture is not a live device, network, or site measurement.
    JupyterLite step 2 showing the executed Python and its observed result.
    Step 2 · Python 3 in your browser (JupyterLite); numbered callout added to a real capture. Enlarge screenshot (new tab)
  3. 3 Step 3

    Do
    In the JupyterLite notebook, run the Step 3 cell to reject an overlong v0 and keep the reason.
    You will see
    Input: execute notebook step 3 with the record’s unchanged fixture, seed, and parameters. Observed: Reject an overlong v0 and keep the reason Observed: v0 two surveys 52.11 30.00 REJECT Observed: v1 one survey 26.06 30.00 ACCEPT
    Why it matters
    Expected: STEP 3 energy gate rejects v0 from this deterministic notebook step. Interpretation: Reserve is a gate, not a battery label. Keeping the rejected double-survey candidate explains why optional scope was removed. Action: Run python main.py and inspect step 3: reject an overlong v0 and keep the reason. Boundary: this local fixture is not a live device, network, or site measurement.
    JupyterLite step 3 showing the executed Python and its observed result.
    Step 3 · Python 3 in your browser (JupyterLite); numbered callout added to a real capture. Enlarge screenshot (new tab)
  4. 4 Step 4

    Do
    In the JupyterLite notebook, run the Step 4 cell to execute v1 and inspect the battery ledger.
    You will see
    Input: execute notebook step 4 with the record’s unchanged fixture, seed, and parameters. Observed: Execute v1 and inspect the battery ledger Observed: 1 33.41 1.99 25.42 Observed: 2 31.01 3.08 21.93
    Why it matters
    Expected: STEP 4 normal route reserve PASS from this deterministic notebook step. Interpretation: Checking return feasibility before each leg prevents accepting a mission only because its final energy total looks plausible. The ledger exposes the remaining margin. Action: Run python main.py and inspect step 4: execute v1 and inspect the battery ledger. Boundary: this local fixture is not a live device, network, or site measurement.
    JupyterLite step 4 showing the executed Python and its observed result.
    Step 4 · Python 3 in your browser (JupyterLite); numbered callout added to a real capture. Enlarge screenshot (new tab)
  5. 5 Step 5

    Do
    In the JupyterLite notebook, run the Step 5 cell to inject a no-fly rectangle and replan v2.
    You will see
    Input: execute notebook step 5 with the record’s unchanged fixture, seed, and parameters. Observed: Inject a no-fly rectangle and replan v2 Observed: Exclusion x=35..55, y=10..30 Observed: Direct B->D intersects exclusion=True: REJECT direct leg
    Why it matters
    Expected: STEP 5 no-fly detour computed from this deterministic notebook step. Interpretation: Avoidance changes both path length and collection scope. The geometric segment test rejects the blocked path and records the excluded sensor explicitly. Action: Run python main.py and inspect step 5: inject a no-fly rectangle and replan v2. Boundary: this local fixture is not a live device, network, or site measurement.
    JupyterLite step 5 showing the executed Python and its observed result.
    Step 5 · Python 3 in your browser (JupyterLite); numbered callout added to a real capture. Enlarge screenshot (new tab)
  6. 6 Step 6

    Do
    In the JupyterLite notebook, run the Step 6 cell to execute the detour and hover-to-collect schedule.
    You will see
    Input: execute notebook step 6 with the record’s unchanged fixture, seed, and parameters. Observed: A 6.47 2 collected Observed: B 12.47 2 collected Observed: D 25.28 2 collected
    Why it matters
    Expected: STEP 6 stress flight logged; coverage incomplete from this deterministic notebook step. Interpretation: A detour can be safe while failing the data goal. Hover receipts show which seven sites were collected and why the eighth needs a later re-flight. Action: Run python main.py and inspect step 6: execute the detour and hover-to-collect schedule. Boundary: this local fixture is not a live device, network, or site measurement.
    JupyterLite step 6 showing the executed Python and its observed result.
    Step 6 · Python 3 in your browser (JupyterLite); numbered callout added to a real capture. Enlarge screenshot (new tab)
  7. 7 Step 7

    Do
    In the JupyterLite notebook, run the Step 7 cell to stress the coupled energy and fallback gates.
    You will see
    Input: execute notebook step 7 with the record’s unchanged fixture, seed, and parameters. Observed: 36 10/10 7/8 9.22 COMPLETE Observed: 30 7/10 5/8 13.09 HOLD before unsafe leg Observed: 24 5/10 3/8 13.49 HOLD before unsafe leg
    Why it matters
    Expected: STEP 7 energy sensitivity measured from this deterministic notebook step. Interpretation: Lower battery and higher travel cost can invalidate the same geometry. A stopped simulation is a failed gate, not a completed mission; the remaining return budget is shown. Action: Run python main.py and inspect step 7: stress the coupled energy and fallback gates. Boundary: this local fixture is not a live device, network, or site measurement.
    JupyterLite step 7 showing the executed Python and its observed result.
    Step 7 · Python 3 in your browser (JupyterLite); numbered callout added to a real capture. Enlarge screenshot (new tab)
  8. 8 Step 8

    Do
    In the JupyterLite notebook, run the Step 8 cell to transfer skipped work only after the handoff gates.
    You will see
    Input: execute notebook step 8 with the record’s unchanged fixture, seed, and parameters. Observed: age=10 battery=24 exclusion=False -> HOLD stale telemetry; owner unchanged Observed: age= 1 battery= 8 exclusion=False -> HOLD return reserve; owner unchanged Observed: age= 1 battery=24 exclusion=True -> HOLD exclusion active; owner unchanged
    Why it matters
    Expected: STEP 8 handoff gates and ownership recorded from this deterministic notebook step. Interpretation: Ownership changes only after freshness, reserve and exclusion checks. The accepted handoff queues future work and does not claim a collection that never happened. Action: Run python main.py and inspect step 8: transfer skipped work only after the handoff gates. Boundary: this local fixture is not a live device, network, or site measurement.
    JupyterLite step 8 showing the executed Python and its observed result.
    Step 8 · Python 3 in your browser (JupyterLite); numbered callout added to a real capture. Enlarge screenshot (new tab)
  9. 9 Step 9

    Do
    In the JupyterLite notebook, run the Step 9 cell to reconcile manifest, executed legs and collection records.
    You will see
    Input: execute notebook step 9 with the record’s unchanged fixture, seed, and parameters. Observed: normal: planned=9 flown=9 collected=8 coverage=100.0% Observed: stress: planned=10 flown=10 collected=7 coverage=87.5% Observed: Manifest/trace agreement: PASS; reserve/return margins: PASS
    Why it matters
    Expected: STEP 9 validation PASS; re-fly remains explicit from this deterministic notebook step. Interpretation: The legacy acceptance rule compares planned and executed records. The model passes its checks while the mission decision remains revise because coverage is incomplete. Action: Run python main.py and inspect step 9: reconcile manifest, executed legs and collection records. Boundary: this local fixture is not a live device, network, or site measurement.
    JupyterLite step 9 showing the executed Python and its observed result.
    Step 9 · Python 3 in your browser (JupyterLite); numbered callout added to a real capture. Enlarge screenshot (new tab)

Chapter checks

These questions refer to the chapter’s examples. Use the return links to review their answers.

  1. A UAV must inspect a long fence line after high winds, needing repeated boundary records and short close-ups at damage, not a full field map. Which mission pattern is the best starting point?

    Return to the chapter’s knowledge check
  2. A UAV must inspect a long fence line after high winds. The team needs repeated boundary records and short close-up checks at damaged sections, not a full map of the surrounding field. Which mission pattern is the best starting point?

    Return to the chapter’s knowledge check

Caution

This is a fictional, fixed-altitude planning model, not flight-control software. Battery coefficients and the 2 m geometric clearance are teaching assumptions, not aircraft performance or operating limits. Coverage counts collected sensor records. No live aircraft is controlled.

Return to Practice: UAV Missions and Avoidance · Browse Labs