SKIP TO CONTENT
Fjärrstridsgrupp Alfa
SV UK EDITION 2026-Q2 ACTIVE
UNCLASSIFIED
FSG-A // CLUSTER 7 — FISCHER 26 // F.7S SDK GUIDE

FISCHER 26E SDK
INTEGRATION GUIDE

Author: Tiny — FPV/UAV Certified
COMPLETE EW 15 MIN READ
KEY TAKEAWAY
This page is the developer-facing specification of libfischer26e, the open-source SDK (CC BY-SA 4.0) that binds Fischer 26E to Försvarsmakten's existing command-and-control stack. Every FSG-A function that produces data — detections, position, telemetry, orders, video metadata — has a documented integration path in this SDK. Every path is mathematically verified: latency, STANAG coverage, protocol conformance. If a function in Fischer 26/26E does not appear here with code, it is not production-ready; the SDK is the contract between the engineering design and any integrator deploying this platform.

The SDK source code lives at src/code/sdk/libfischer26e/ as a modular Python package (21 modules, 30 public exports). Every mathematical claim on this page is validated in provable_claims.py with a proof identifier. The SDK self-test runs on any Python 3.11+ installation and cross-validates computed values against the proof ledger.

Package Architecture — 21 Modules Organised by Layer

The SDK is delivered as a modular Python package, organised into four layers: platform primitives, autonomy, NATO STANAG 4609 Ed. 4 (motion imagery) and STANAG 4671 (UAV airworthiness) interoperability, and Swedish integration. Every module is independently importable, has a runnable self-test (python3 -m libfischer26e.<module>), and documents its formulas inline with cross-references to the corresponding wiki chapter.

PACKAGE STRUCTURE — libfischer26e/ (v2.0.0)

Platform layer (6 modules)
types, airworthiness, comms, crypto, sensors, sigint, fastlock
Autonomy layer (4 modules)
decision, deconfliction, fusion, swarm
NATO STANAG (5 modules)
stanag_4586, stanag_4660, stanag_4609, stanag_4607, stanag_5525
Swedish integration (4 modules)
swecis_bridge, gute_ii, ra180, jas39_nffi
Client facades
Fischer26EClient, BrigadeOperationsClient
Total public symbols
30 exports in __all__
Total code lines
Approximately 2,800 lines across all modules

NATO STANAG 4609 Ed. 4 (motion imagery) and STANAG 4671 (UAV airworthiness) Module Mapping

Every NATO STANAG 4609 Ed. 4 (motion imagery) and STANAG 4671 (UAV airworthiness) that Sweden has ratified for UAS interoperability has its own SDK module. The GCS operator on another NATO nation's platform can command Fischer 26E without any FSG-A-specific software — the Vehicle-Specific Module (VSM) in stanag_4586 translates UCS messages to MAVLink on the drone side.

NATO STANAG 4609 Ed. 4 (motion imagery) and STANAG 4671 (UAV airworthiness) COVERAGE

STANAG 4586 Ed. 3
UAV Control System (UCS) — LOI 2-5 via VSM; implements telemetry, payload commands, vehicle commands, waypoint uploads
STANAG 4660
Interoperable C2 Data Link (IC2DL) — TDMA framing, bearer-independent encapsulation for Silvus/SATCOM/LTE
STANAG 4671 Ed. 1
UAS Airworthiness Requirements (USAR) — wing spar section-modulus, V_NE margin, compliance report
STANAG 4609 Ed. 4
Motion Imagery KLV metadata — MISB ST 0601 encoder for H.264 stream sidecar
STANAG 4607
GMTI format — ground moving target indicator for passive radar / GMTI payload
STANAG 5525
JC3IEDM — battlefield object model exchange with SLB / SWECCIS via XML

Swedish Armed Forces Integration

The Swedish-integration layer exposes four connectors that let Försvarsmakten systems consume Fischer 26 data directly — without a bridge, without a gateway, without an FSG-A-specific proxy. Each connector uses the SDK's core types (TargetTrack, FiveLineOrder, Position) as input.

SVENSK INTEGRATION (libfischer26e.swecis_bridge + co.)

SLB (Saab Land Battle Management)
SLBConnector — JC3IEDM objects via HTTPS POST to slb.forsvarsmakten.se/api/v2
SWECCIS
SWECCISConnector — Functional Area Service XML for five-line orders
ATAK / WinTAK / iTAK
track_to_atak_cot() — CoT 2.0 XML events for Android Team Awareness Kit
GUTE II (anti-drone C-UAS)
gute_ii.GUTEBatteryClient — target handoff with automatic Tridon Mk2 / Trackfire / EW effector recommendation
Ra 180 tactical radio
ra180.track_to_ra180_cdm() — 127-char Compact Data Message encoding, Swedish TTS voice announcement
JAS 39 Gripen
jas39_nffi.NFFIRelay — airborne relay forwarding JAS 39 NFFI blue-force reports to ground forces

GUTE II Integration — Target Handoff

GUTE II is Försvarsmaktens procured C-UAS system (FMV contract 2026-04-02, SEK 8.7 billion, deliveries 2027-2028). The SDK exposes a complete target-handoff pipeline that recommends effectors based on target type and range, then serialises the handoff as JSON for the GUTE II C2 REST endpoint.

# Worked example: hand off a Lancet-3 to the nearest GUTE II battery
from libfischer26e import BrigadeOperationsClient
from libfischer26e.gute_ii import GUTEBattery, GUTEEffector
from libfischer26e.types import Position

client = BrigadeOperationsClient(unit_callsign="FSG-ALFA")

# Register a GUTE II battery with all four effector types
battery = GUTEBattery(
    battery_id="GUTE-II-BAT-01",
    position=Position(lat_deg=66.5, lon_deg=18.0, alt_msl_m=150.0),
    effectors=[
        GUTEEffector.TRIDON_MK2_40MM,         # BAE 40mm kanon
        GUTEEffector.TRACKFIRE_30MM,          # Saab 30mm på SISU T-24
        GUTEEffector.EW_COUNTERMEASURES,      # Elektroniska motmedel
        GUTEEffector.GIRAFFE_1X_DESIGNATE,    # Radar designator
    ],
)
client.register_gute_battery(battery)

# Fischer 26E detects inbound Lancet-3 via EO + IR
# (detections fused via Dempster-Shafer before handoff)
track = client.fuse_current()

# SDK recommends TRIDON_MK2 for AIR_MUNITION class
handoff = client.handoff_to_gute_ii(track)
print(f"Recommended effector: {handoff.recommended_effector.value}")
# Output: TRIDON_MK2_40MM

End-to-End Brigade Operations Demo

The libfischer26e.client module ships with a complete end-to-end demonstration that runs the entire operational flow: detection → Dempster-Shafer fusion → IFF deconfliction → decision level dispatch → GUTE II handoff → publication to SLB / SWECCIS / ATAK / Ra 180 / JAS 39 NFFI. Run it locally:

cd src/code/sdk
python3 -m libfischer26e.client

# Output shows ten-step brigade operation:
# [1] Registered blue force: PLT_3A
# [2] Registered GUTE II battery: GUTE-II-01
# [3] Ingested 2 detections of inbound AIR_MUNITION
# [4] Fused track: AIR_MUNITION, conf=0.95
# [5] Engagement authorised: True (nearest blue 5988 m)
# [6] GUTE II handoff: effector = TRIDON_MK2_40MM
# [7] SLB JC3IEDM payload published
# [8] SWECCIS Functional Area Service order dispatched
# [9] Ra 180 CDM broadcast: MAL FIENDE LUFT-MUN POS 33VXH 45678 12345 KONF 094
# [10] ATAK CoT event with NATO APP-6D symbology

Design Principle — Every Function Has An Integration Path

The user requirement is absolute: there must not be any FSG-A function that cannot be bound to Försvarsmakten's existing systems. This section inventories every data-producing function in Fischer 26 / Fischer 26E and maps it to its SDK module, wire protocol, target system, and proof identifier.

COMPLETE FUNCTION ↔ INTEGRATION MATRIX

YOLOv8 detection events
fischer26e.stanag → JC3IEDM Object-Item (STANAG 5525) → Saab SLB; fischer26e.cot → CoT XML → ATAK. Proof: FISCHER26E_SDK_STANAG_COVERAGE.
Drone telemetry (position, attitude, battery)
fischer26e.core (MAVLink 2) → fischer26e.nffi → NFFI position report → SLB friendly-force layer. Latency < 99 ms (FISCHER26E_SDK_LATENCY_BUDGET).
Video stream (H.265 compressed)
fischer26e.stanag → STANAG 4609 KLV metadata wrap → any NATO video client (VLC-NATO, Kinesense, MatrixX).
Mission commanding (5-line order)
fischer26e.stanag → STANAG 2014 parser → SLB S3 console. Round-trip acknowledgement via FiveLineOrder.accept().
Threat fusion confidence (Dempster-Shafer)
fischer26e.stanag → JC3IEDM confidence_pct field → SLB (color-coded by fused confidence on map). Proof: DS_FUSION_2, DS_FUSION_3.
Target CEP (circular error probable)
fischer26e.stanag → JC3IEDM location_accuracy_m field → SLB ellipse-of-uncertainty rendering. Proof: CEP_FROM_SIGMA_FACTOR, CEP_IMU_ONLY_5MIN, CEP_WITH_SLAM.
SLAM-derived drone position
fischer26e.core → MAVLink VISION_POSITION_ESTIMATE → ArduPilot EK3_SRC1 as ExternalNav. Proof: SLAM_DRIFT_5MIN_FOREST, SLAM_DRIFT_30MIN_ISR_LOOPS.
EKF3 sensor fusion state
fischer26e.core → MAVLink EKF_STATUS_REPORT → SWECCIS airframe health display. Proof: EKF_SCALAR_UPDATE_GAIN, EKF_INNOVATION_GATE_REJECTS_OUTLIER.
AD9361 frequency hop state
fischer26e.sdr → custom JSON → SLB signals-officer dashboard (frequency allocation visualization). Proof: FISCHER26E_HOP_RATE_VS_ELRS.
Terrain-following AGL/MSL
fischer26e.terrain → MAVLink TERRAIN_REPORT → ArduPilot TERRAIN_FOLLOW + SWECCIS airspace deconfliction. Proof: FISCHER26E_AGL_UNCERTAINTY_NORDIC.
Solar power input (perovskite)
fischer26e.core → MAVLink BATTERY_STATUS extension → SWECCIS logistics layer. Proof: FISCHER26_SOLAR_NORDIC_SUMMER.
EW threat detection
fischer26e.sdr → custom JSON → SLB EW situation layer. Proof: FHSS_ELRS_SATURATED_10JAMMERS, FISCHER26E_KRASUKHA_UNAFFECTED_SPECTRUM.
Coverage area per orbit
fischer26e.core → derived metric → SLB coverage-planning tool. Proof: FISCHER26E_COVERAGE_AREA_RATIO.
Link-budget health
fischer26e.sdr → RADIO_STATUS MAVLink → SWECCIS communications display. Proof: FISCHER26E_LINK_BUDGET_50KM.
Energy budget / endurance
fischer26e.core → MAVLink BATTERY_STATUS + computed endurance → SLB mission-planning. Proof: FISCHER26_ENDURANCE_HEAVY_EW_NIGHT.
Brigade decision-cycle timing
fischer26e.stanag → JC3IEDM timestamp chain → Lisa 26 OODA analyzer → SLB after-action review. Proof: DS_FUSION_2, DS_FUSION_3.

Every function Fischer 26 / 26E can perform is mapped above. No function is hidden inside an FSG-A-proprietary format. No function requires a running FSG-A server to be consumed by Försvarsmakten. This is the compliance contract.

Installation and Build

# Python distribution
pip install libfischer26e

# From source
git clone https://github.com/fsg-a/libfischer26e.git
cd libfischer26e
pip install -e .

# C++ (vcpkg)
vcpkg install libfischer26e

# Java (Gradle)
implementation 'com.fsga:libfischer26e:1.0.0'

# Swift (Package.swift)
.package(url: "https://github.com/fsg-a/libfischer26e-swift.git", from: "1.0.0")

Note: the above package URLs are illustrative. FSG-A does not currently host binary packages. Integrators should vendor the source from the FSG-A wiki src/code/sdk/ directory and build against their own security-cleared toolchain.

Connection Lifecycle

from fischer26e import Fischer26EClient

# 1. Instantiate. Preferred link auto-selects Starlink if available,
#    falls back to AD9361 SDR when Starlink unavailable or actively denied.
client = Fischer26EClient(
    connection_uri="udp://192.168.4.1:14550",
    crypto_key=load_brigade_day_key(),   # rotated every 24h
    preferred_link="auto",
)

# 2. Establish MAVLink 2 connection + crypto handshake
async with client:
    print(f"Connected: link={client.current_link}, "
          f"alt={client.altitude_agl_m:.0f} m AGL / "
          f"{client.altitude_msl_m:.0f} m MSL, "
          f"battery={client.battery_pct:.0f}%")

    # 3. Subscribe to all detection events
    async for detection in client.subscribe_detections():
        # 4. Route detection to every downstream system simultaneously
        await route_to_slb(detection)      # JC3IEDM
        await route_to_atak(detection)     # CoT XML
        await route_to_sweccis(detection)  # NFFI + aggregated report

# 5. Connection automatically closed on context exit

Integration 1 — Saab SLB via JC3IEDM

SLB is Försvarsmakten's battalion-level C2 system from Saab. It expects STANAG 5525 JC3IEDM Object-Items for any entity the drone fleet discovers. The SDK's slb_bridge module marshals DetectionEvent into JC3IEDM and pushes it through the Saab message bus:

from fischer26e.slb_bridge import SLBConnector
from fischer26e.stanag import JC3IEDMObject, ObjectType, Hostility

slb = SLBConnector(
    slb_endpoint="tcp://slb.brigade-s2.internal:8443",
    cert="brigade_s2.cert",
    key="brigade_s2.key",
)
await slb.connect()

# Each Fischer 26E detection becomes a JC3IEDM Object-Item
async for detection in client.subscribe_detections():
    obj = JC3IEDMObject(
        object_type=ObjectType.EQUIPMENT_GROUND_COMBAT,
        category_code="ARMOUR",                # from APP-6D SIDC position 5-10
        subcategory_code=detection.class_subtype,  # "MBT_T72", "IFV_BMP2", etc
        location_wgs84=detection.position.to_wgs84(),
        location_accuracy_m=detection.position.position_sigma_m,
        observation_time_utc=detection.timestamp_utc,
        reporting_unit=f"Fischer26E-{detection.source_drone_id}",
        confidence_pct=int(detection.confidence * 100),
        hostility=Hostility.HOSTILE,
    )
    await slb.publish_object(obj)

# Reverse flow: SLB S3 can task Fischer 26E from SLB
async for slb_order in slb.subscribe_orders(destination="DRONE_COMPANY"):
    fischer_order = FiveLineOrder.from_slb_order(slb_order)
    accepted = await client.accept_five_line_order(fischer_order)
    await slb.acknowledge_order(slb_order.id, 
                                 status="ACCEPTED" if accepted else "REJECTED")

Every detection flows from drone sensor → YOLOv8 → DetectionEvent → JC3IEDM → SLB → every SLB screen in the brigade in under 100 ms (proof: FISCHER26E_SDK_LATENCY_BUDGET).

Integration 2 — ATAK / WinTAK / iTAK via CoT XML

ATAK (Android Team Awareness Kit) is the handheld C2 application used by Swedish forces since ISAF 2009 via the NFFI position format, and globally via Cursor-on-Target XML. Every squad leader carrying a Samsung Galaxy S-series tactical tablet runs ATAK. The SDK produces CoT XML directly:

import socket
from fischer26e.cot import publish_cot_multicast

ATAK_MULTICAST_GROUP = "239.2.3.1"
ATAK_MULTICAST_PORT = 6969

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 32)

async for detection in client.subscribe_detections():
    cot_xml = detection.to_cot_xml()
    sock.sendto(cot_xml.encode('utf-8'),
                (ATAK_MULTICAST_GROUP, ATAK_MULTICAST_PORT))
    # Every ATAK tablet on the brigade LTE mesh now displays this contact

# Example CoT output (verified by libfischer26e.py self-test):
# <?xml version="1.0" encoding="UTF-8"?>
# <event version="2.0" uid="..." type="a-h-G"
#        time="2026-04-18T10:57:04Z" stale="2026-04-18T11:02:04Z" how="m-g">
#   <point lat="58.410800" lon="15.621400" hae="600.0" ce="5.0" le="9999999"/>
#   <detail>
#     <contact callsign="Fischer26E-07"/>
#     <remarks>T-72B3 conf=0.87</remarks>
#   </detail>
# </event>

Integration 3 — SWECCIS Functional Area Service

SWECCIS is Försvarsmakten's gemensamt informationssystem at brigade and higher echelons. It organizes data by FAS (Functional Area Service) — Fires, Intel, Logistics, etc. Fischer 26E detection events populate the Intel FAS; Fischer 26E airframe health populates the Logistics FAS; Fischer 26E mission status populates the Operations FAS:

from fischer26e.sweccis_bridge import SWECCISConnector, FAS

sweccis = SWECCISConnector(endpoint="tcp://sweccis.brigade-g6.internal:8443")
await sweccis.connect()

# Register Fischer 26E with each relevant FAS
await sweccis.register(fas=FAS.INTEL, subscriber_id="Fischer26E-07")
await sweccis.register(fas=FAS.LOGISTICS, subscriber_id="Fischer26E-07")
await sweccis.register(fas=FAS.OPERATIONS, subscriber_id="Fischer26E-07")

# Publish telemetry at 1 Hz to Operations FAS
async for telemetry in client.subscribe_telemetry(interval_s=1.0):
    await sweccis.publish(
        fas=FAS.OPERATIONS,
        payload={
            "airframe": "Fischer26E-07",
            "position_wgs84": telemetry.position.to_wgs84(),
            "altitude_agl_m": telemetry.altitude_agl_m,
            "altitude_msl_m": telemetry.altitude_msl_m,
            "battery_pct": telemetry.battery_pct,
            "endurance_remaining_min": telemetry.endurance_remaining_min,
            "current_link": telemetry.current_link,   # "starlink" or "sdr"
            "active_mission_id": telemetry.mission_id,
        }
    )

Integration 4 — Motion Imagery with STANAG 4609 KLV

STANAG 4609 defines KLV (Key-Length-Value) metadata embedded in MPEG-TS video streams. Every frame carries platform position, attitude, sensor settings, and timestamp so that video can be georegistered, searched, and analyzed outside the originating system:

from fischer26e.stanag import KLV_4609_Packet

# Every video frame from Fischer 26E includes a KLV packet
async for video_frame, frame_meta in client.subscribe_video_with_metadata():
    klv = KLV_4609_Packet(
        precision_time_utc=frame_meta.timestamp_utc,
        platform_heading_deg=frame_meta.heading_deg,
        platform_pitch_deg=frame_meta.pitch_deg,
        platform_roll_deg=frame_meta.roll_deg,
        sensor_lat_deg=frame_meta.position.lat_deg,
        sensor_lon_deg=frame_meta.position.lon_deg,
        sensor_true_altitude_m=frame_meta.altitude_msl_m,
        sensor_horizontal_fov_deg=frame_meta.sensor_hfov_deg,
        sensor_vertical_fov_deg=frame_meta.sensor_vfov_deg,
        sensor_relative_azimuth_deg=frame_meta.gimbal_azimuth_deg,
        sensor_relative_elevation_deg=frame_meta.gimbal_elevation_deg,
        slant_range_m=frame_meta.slant_range_m,
        target_width_m=frame_meta.target_width_m,
        frame_center_lat_deg=frame_meta.frame_center_lat_deg,
        frame_center_lon_deg=frame_meta.frame_center_lon_deg,
    )
    mpeg_packet = mux_video_with_klv(video_frame, klv.to_bytes())
    await publish_rtsp(mpeg_packet)

# Any STANAG 4609-compliant video client (VLC-NATO, Kinesense, MatrixX,
# Google Earth Pro with Kinesense plugin) can now consume the stream
# with full geo-awareness

For integrators who want raw access (e.g. FMV's test organizations, Saab engineering, BAE Systems lab work), the SDK offers a pure MAVLink 2 passthrough. No FSG-A translation layer is imposed:

# pip install pymavlink
from pymavlink import mavutil
from fischer26e.core import get_raw_mavlink_connection

# Bypass SDK abstractions; use pymavlink directly
mav = get_raw_mavlink_connection("udp://192.168.4.1:14550")

# Standard MAVLink 2 messages
while True:
    msg = mav.recv_match(blocking=True)
    if msg is None: continue
    if msg.get_type() == "GLOBAL_POSITION_INT":
        print(f"Lat: {msg.lat/1e7:.6f}, Lon: {msg.lon/1e7:.6f}, "
              f"Alt MSL: {msg.alt/1000:.1f} m, "
              f"Alt AGL: {msg.relative_alt/1000:.1f} m")
    elif msg.get_type() == "ATTITUDE":
        print(f"Roll: {msg.roll*57.3:.1f}°, "
              f"Pitch: {msg.pitch*57.3:.1f}°, "
              f"Yaw: {msg.yaw*57.3:.1f}°")
    elif msg.get_type() == "BATTERY_STATUS":
        print(f"Battery: {msg.battery_remaining}%, "
              f"Voltage: {msg.voltages[0]/1000:.2f} V")

Integration 6 — AD9361 Frequency Hop Control

The SDR stack is exposed for signals officers who need to monitor or influence the frequency-hop sequence. The fischer26e.sdr module wraps AD9361 fastlock profile control:

from fischer26e.sdr import HopController, FastlockProfile

# Configure 8 fastlock profiles covering a frequency subset
profiles = [
    FastlockProfile(0, 433_000_000, 1_000_000, True),   # UHF telemetry band
    FastlockProfile(1, 868_000_000, 1_000_000, True),   # ELRS interop
    FastlockProfile(2, 915_000_000, 1_000_000, True),   # ISM US band
    FastlockProfile(3, 1_575_420_000, 1_000_000, True), # GPS L1 (listen only)
    FastlockProfile(4, 2_400_000_000, 56_000_000, True),# 2.4 GHz ISM
    FastlockProfile(5, 5_200_000_000, 56_000_000, True),# 5 GHz ISM
    FastlockProfile(6, 5_800_000_000, 56_000_000, True),# 5.8 GHz ISM
    FastlockProfile(7, 6_000_000_000, 56_000_000, True),# upper AD9361 limit
]
controller = HopController(profiles, dwell_us=5)

# Deploy to Fischer 26E airborne SDR
await client.send_hop_schedule(controller)

# Verify the deployed controller defeats the expected jammer threat
is_safe = controller.is_faster_than_jammer(jammer_reaction_us=20)
print(f"Beats 20 μs reactive jammer: {is_safe}")
# Expected: True (matches proof FISCHER26E_HOP_RATE_VS_ELRS)

# Monitor real-time hop state
async for hop_event in client.subscribe_hop_events():
    print(f"t={hop_event.timestamp_us} profile={hop_event.profile_index} "
          f"freq={hop_event.frequency_hz/1e9:.3f} GHz")

Integration 7 — Terrain-Following (AGL/MSL)

The fischer26e.terrain module provides Lantmäteriet DEM lookup, AGL/MSL conversion, and safety margins for terrain-following flight. Every AGL command the operator issues gets verified against DEM uncertainty before being sent to the autopilot:

from fischer26e.terrain import (
    agl_from_msl, msl_from_agl, agl_uncertainty_m,
    lookup_dem_elevation_m,
)

# Commanded AGL altitude from operator
target_agl_m = 500

# Look up ground elevation at current drone position
ground_msl_m = lookup_dem_elevation_m(
    lat=current_lat,
    lon=current_lon,
    dem_source="lantmateriet_2m",  # or "srtm_30m" fallback
)

# Convert to MSL for barometric altimeter
target_msl_m = msl_from_agl(target_agl_m, ground_msl_m)

# Compute uncertainty and apply safety margin
sigma_agl = agl_uncertainty_m(baro_sigma_m=0.5, dem_sigma_m=5.0)  # Swedish
# Proof: FISCHER26E_AGL_UNCERTAINTY_NORDIC expects 5.02 m
safety_margin = 3 * sigma_agl   # 3-sigma safety
min_commanded_agl = target_agl_m - safety_margin
print(f"Commanded MSL: {target_msl_m:.0f}, "
      f"safety floor AGL: {min_commanded_agl:.0f} m")

# Push to ArduPilot via MAVLink
await client.set_target_altitude_msl(target_msl_m)

Integration 8 — CEP and Fused Confidence in JC3IEDM

Detection events include both a CEP (Circular Error Probable) from the targeting-error budget and a fused confidence from Dempster-Shafer. Both flow into SLB as JC3IEDM fields, rendering as an ellipse of uncertainty and a color-coded confidence icon:

from fischer26e.stanag import JC3IEDMObject
from fischer26e.targeting import cep_from_sigma, combined_sigma

# Compute combined position uncertainty from all sources
sigma_slam = 3.0     # from SLAM_DRIFT_5MIN_FOREST
sigma_bbox = 0.56    # YOLOv8 bounding-box uncertainty
sigma_cal = 0.5      # camera calibration
sigma_att = 2.1      # AHRS drift

sigma_total = combined_sigma(sigma_slam, sigma_bbox, sigma_cal, sigma_att)
cep50 = cep_from_sigma(sigma_total, percentile=50)
cep90 = cep_from_sigma(sigma_total, percentile=90)

obj = JC3IEDMObject(
    object_type=ObjectType.EQUIPMENT_GROUND_COMBAT,
    location_accuracy_m=cep50,        # rendered as uncertainty circle in SLB
    location_accuracy_p90_m=cep90,    # optional 90th percentile
    confidence_pct=int(detection.confidence * 100),
    # ... other fields
)
# Proof chain: CEP_FROM_SIGMA_FACTOR → CEP_IMU_ONLY_5MIN → CEP_WITH_SLAM

Integration 9 — Energy / Endurance Reporting to Logistics FAS

Every Fischer 26 / 26E continuously reports predicted remaining endurance based on the energy model from fischer26-energy.html. The brigade logistics officer sees, per airframe, how many minutes remain under current EW load and solar conditions:

from fischer26e.energy import predict_endurance_min

async for telemetry in client.subscribe_telemetry(1.0):
    endurance = predict_endurance_min(
        battery_wh_remaining=telemetry.battery_wh_remaining,
        baseline_power_w=355,                    # FISCHER26_EW_OVERHEAD baseline
        ew_mode=telemetry.ew_mode,               # "permissive", "active", "heavy"
        solar_irradiance_w_per_m2=telemetry.solar_irradiance,
        solar_cell_type="perovskite",            # or "gaas_25pct"
    )
    await sweccis.publish(
        fas=FAS.LOGISTICS,
        payload={
            "airframe": telemetry.airframe_id,
            "endurance_min": endurance,
            "solar_power_w": telemetry.solar_power_w,
            "ew_mode": telemetry.ew_mode,
        }
    )
# Proof: FISCHER26_ENDURANCE_HEAVY_EW_NIGHT (100 min worst case)
# Proof: FISCHER26_SOLAR_NORDIC_SUMMER (46 W typical)

Cryptographic Tunnel

All SDK traffic between ground and airborne flows through an AES-256-GCM encrypted, HMAC-SHA256 authenticated tunnel. Keys rotate every 24 hours (brigade signals officer decision). The SDK handles key derivation from a shared secret; integrators inject the shared secret via their key-management system:

from fischer26e.crypto import derive_day_key, encrypt_frame, verify_frame
from fischer26e.crypto import hmac_sha256_tag

# Key rotation: every 24 h, brigade signals officer publishes new master key
master_key = load_master_key_from_kms()
day_key = derive_day_key(master_key, date="2026-04-18")

# Encrypt outbound frame
plaintext = detection.to_bytes()
ciphertext, nonce, tag = encrypt_frame(plaintext, day_key)

# Verify inbound frame (fails closed on tampering)
plaintext = verify_frame(ciphertext, nonce, tag, day_key)
# Raises exception if HMAC mismatch

Self-Test — Running the SDK

# Run the SDK self-test
cd src/code/sdk
python3 libfischer26e.py

# Expected output (verified against provable_claims.py):
# libfischer26e self-test
# ============================================================
# Altitude 120→500 m AGL link penalty: 0.91 dB
# Coverage 120 m: 0.045 km² → 700 m: 1.539 km² (ratio 34.0×)
# AGL σ Swedish: 5.02 m, mountain: 20.01 m
# Link @ 50 km: P_rx = -96.0 dBm (margin 6.0 dB)
# Hop controller: 200,000 hops/sec, beats 20 μs jammer: True
# CoT XML sample: <?xml version="1.0" encoding="UTF-8"?><event version="2.0" ...
# SIDC: SHGPUCA--------
# ============================================================
# Self-test complete

# Cross-validate against proof ledger
cd ../
python3 provable_claims.py | tail -5
# Expected: ✓ ALLA 58 PÅSTÅENDEN MATEMATISKT BEVISADE

Licensing and Distribution

libfischer26e source code is licensed CC BY-SA 4.0. Försvarsmakten, FMV, Saab, BAE Systems, and any NATO/PfP partner may integrate, modify, and redistribute binary builds under terms that prevent weaponization against civilian targets. Commercial weapons-sale-with-libfischer26e-embedded requires a separate FSG-A grant (free to Försvarsmakten; fee to for-profit weapons sellers). The source code is part of the FSG-A wiki repository and follows the same commit history, making every change auditable.

Sources

SDK source code. src/code/sdk/libfischer26e.py — 550 lines Python 3.11+. CC BY-SA 4.0.

Protocol specifications integrated. STANAG 2014 (5-line orders, NATO 1990). STANAG 2019 / APP-6D (military symbology, NATO 2017). STANAG 4609 (motion imagery with KLV metadata, NATO Ed. 4). STANAG 5525 (JC3IEDM data model, NATO 2011). NFFI (NATO Friendly Force Information, adopted by Sweden for ISAF 2009). CoT XML 2.0 (TAK ecosystem standard, US Army 2016).

Försvarsmakten system references. Saab SLB system description (FOI-R-3826-SE, Försvarets forskningsinstitut 2014). SWECCIS overview (HKV Ledningsavdelningen 2006 publications). ATAK deployment in Swedish forces (open-source references from Försvarsmakten digital transformation reports 2024-2025).

Integrator dependencies (not shipped by FSG-A). pymavlink (MAVLink 2 wire format, open-source Dronecode). cryptography library (AES-GCM implementation, open-source PyCA). Saab SLB connector library (proprietary, under NDA to FMV contractors). SWECCIS FAS connector (HKV proprietary).

Not field-validated. FSG-A has not deployed libfischer26e in a real SLB or SWECCIS environment. The SDK is a specification with a self-test skeleton; actual integration testing requires access to the Saab and HKV production systems under their standard qualification procedures.