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

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

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
    Run python main.py and inspect step 1: define a survey envelope and record contract.
    You will see
    Fictional field=80x80 m; altitude fixed=20 m; speed=5 m/s; Battery=36.0 Wh; reserve=6.0 Wh; travel=0.08 Wh/m. STEP 1 mission envelope frozen
    Why it matters
    The legacy lab requires an envelope before route generation. Declared energy, dwell and reserve assumptions make this classroom simulation reproducible.
    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
    Run python main.py and inspect step 2: inspect route v1 before execution.
    You will see
    leg endpoint site metres hover_s energy_Wh coverage; 1 ( 10, 20) A 22.36 2 2.59 12.5%. STEP 2 v1 manifest ready
    Why it matters
    A route manifest must show geometry, collection actions and their costs. Cumulative coverage here counts sensor records, not area swept by a camera.
    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
    Run python main.py and inspect step 3: reject an overlong v0 and keep the reason.
    You will see
    candidate needed_Wh available_after_reserve_Wh decision; v0 two surveys 52.11 30.00 REJECT. STEP 3 energy gate rejects v0
    Why it matters
    Reserve is a gate, not a battery label. Keeping the rejected double-survey candidate explains why optional scope was removed.
    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
    Run python main.py and inspect step 4: execute v1 and inspect the battery ledger.
    You will see
    leg remaining_Wh return_Wh margin_above_reserve_Wh; 1 33.41 1.99 25.42. STEP 4 normal route reserve PASS
    Why it matters
    Checking return feasibility before each leg prevents accepting a mission only because its final energy total looks plausible. The ledger exposes the remaining margin.
    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
    Run python main.py and inspect step 5: inject a no-fly rectangle and replan v2.
    You will see
    Exclusion x=35..55, y=10..30; Direct B->D intersects exclusion=True: REJECT direct leg. STEP 5 no-fly detour computed
    Why it matters
    Avoidance changes both path length and collection scope. The geometric segment test rejects the blocked path and records the excluded sensor explicitly.
    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
    Run python main.py and inspect step 6: execute the detour and hover-to-collect schedule.
    You will see
    site collected_at_s dwell_s state; A 6.47 2 collected. STEP 6 stress flight logged; coverage incomplete
    Why it matters
    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.
    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
    Run python main.py and inspect step 7: stress the coupled energy and fallback gates.
    You will see
    battery flown_legs collected remaining decision; 36 10/10 7/8 9.22 COMPLETE. STEP 7 energy sensitivity measured
    Why it matters
    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.
    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
    Run python main.py and inspect step 8: transfer skipped work only after the handoff gates.
    You will see
    age=10 battery=24 exclusion=False -> HOLD stale telemetry; owner unchanged; age= 1 battery= 8 exclusion=False -> HOLD return reserve; owner unchanged. STEP 8 handoff gates and ownership recorded
    Why it matters
    Ownership changes only after freshness, reserve and exclusion checks. The accepted handoff queues future work and does not claim a collection that never happened.
    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
    Run python main.py and inspect step 9: reconcile manifest, executed legs and collection records.
    You will see
    normal: planned=9 flown=9 collected=8 coverage=100.0%; stress: planned=10 flown=10 collected=7 coverage=87.5%. STEP 9 validation PASS; re-fly remains explicit
    Why it matters
    The legacy acceptance rule compares planned and executed records. The model passes its checks while the mission decision remains revise because coverage is incomplete.
    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