Commit Graph

32 Commits

Author SHA1 Message Date
LittleSam129
c9569164e0 Add protocol/bpsk_radio: reusable BPSK radio primitives
Lab042 cannot reuse the DSP from the earlier labs the way its
specification assumed. Three blockers turned up on inspection:

- importing lab018, lab019 or lab023 creates directories and writes .npy,
  .png and report files at module level, so importing them silently
  re-runs their experiments
- build_radio_frame() takes no arguments and encodes a fixed text message
- decode_radio_frame() returns a status string rather than the payload

So the verified primitives move into a module that is safe to import and
does no work of its own. Function bodies are carried over verbatim, and
the source lab is named above each one:

- from Lab023: bytes_to_bits, bits_to_bytes, bpsk_modulate,
  bpsk_demodulate, estimate_carrier_parameters, correct_phase_and_frequency
- from Lab019: build_frame_marker, find_radio_frame
- from Lab018: root_raised_cosine_taps

build_radio_frame and parse_radio_frame are written fresh here to carry
arbitrary payloads; the on-air structure is unchanged, still preamble,
sync word, length, packet.

Verified against the originals by loading their function definitions in
isolation and comparing outputs: 31 comparisons, no divergence, including
the CFO estimator over random phase and frequency offsets.

End-to-end check with no hardware: a 5828-byte JPEG through fragments,
packets, frames, shaping at 128 samples per symbol and matched filtering
recovers 12 of 12 fragments and reassembles byte-identical.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-10 14:16:32 +03:00
LittleSam129
1e4adc0a98 Lab042: correct the sample rate against the real device
Queried the Pluto over IIO before writing any code. Three findings, one
of which invalidated the specification.

The AD9361 will not sample below 2 083 333 Hz, so the 640 kHz taken from
Lab018 is unreachable by a factor of three. Going lower needs the on-chip
FIR decimator, which would add an untested mechanism to the very first
transmit. Instead raise oversampling from 32 to 128 samples per symbol:
the symbol rate stays at 20 000, rolloff, preamble, sync word and guard
are untouched, and the rate becomes 2 560 000 Hz. Only the device
interface changes, not the signal.

Consequence recorded: the shaping filter grows to 1281 taps, so the
convolution has to go through scipy.signal.fftconvolve.

Also from the device:
- it reports as PlutoSDR Rev.C (Z7010-AD9361) with a single RX and a
  single TX buffer channel, so adi.Pluto is right and the adi.ad9361
  fallback is unnecessary
- the chip is a full AD9361: RX tunes 70 MHz to 6 GHz, TX from 46.9 MHz,
  so the sub-350 MHz target band is available without a firmware hack.
  That closes the open question flagged for Lab044
- firmware is v0.32, left alone for now

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-10 14:06:44 +03:00
LittleSam129
2a7a380875 Lab042: fix a cross-reference broken by renumbering
The TX cyclic buffer row pointed at section 7, which became the signal
parameters when the hardware and environment sections were inserted. It
means the traps section, now 9.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-10 13:38:50 +03:00
LittleSam129
49c7009ca5 Lab042: drop the regulatory framing, keep the technical reasons
The project owner holds the permits for over-the-air work, so legality is
not a constraint this document should be reasoning about.

- retitle the section from "safety requirements" to what it actually
  covers: circuit integrity and not destroying the hardware
- rewrite the antenna rule on its real technical ground. An antenna opens
  a radiating path in parallel with the cable, so the level at the
  receiver stops matching the budget and reflections appear; the value of
  a cable loopback is that everything in it is known
- reframe "no over-the-air" as a scope boundary against Lab044 rather
  than a prohibition
- note in the roadmap that Lab044 is purely a technical choice of band,
  power and antenna

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-10 13:34:07 +03:00
LittleSam129
9f7387ec2c Lab042: attenuator on hand, relax the gain restriction
The bench has an AT30S: 30 dB, SMA, rated to 200 W. That removes the last
hardware blocker and changes the safety analysis.

With 30 dB in line, TX at full 0 dB gain lands at about -23 dBm on the
receiver, some 25 dB below the +2.5 dBm damage threshold. The whole
tx_hardwaregain range is therefore safe, so the staged -60 dB start and
the -30 dB ceiling are no longer needed.

- record the attenuator in the inventory and note that its 200 W rating is
  irrelevant here, attenuation does not depend on level
- replace the interim procedure with a level budget table and a starting
  point of -30 dB, giving about -53 dBm at the receiver
- require a visual check that the attenuator is actually in the path
  before the first transmit
- keep the ban on running without it: it guards against operator error,
  not against the calculated level

Only the environment blocker is left: pyadi-iio and libiio are missing
from the interpreter on PATH.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-10 13:33:24 +03:00
LittleSam129
923e6bec78 Lab042: adapt spec to the actual hardware and environment
Hardware confirmed from a photo of the bench: the device is a Pluto+
(2RX/2TX, Gigabit Ethernet), not the stock ADALM-PLUTO, plus an RTL-SDR
dongle and several antennas. No attenuator on hand.

- record the actual inventory and the Pluto+ differences that matter:
  Ethernet transport, two channels, adi.Pluto first with adi.ad9361 as
  the only permitted fallback
- replace "use an attenuator" with numbers: TX puts out about +7 dBm at
  0 dB, the RX damage threshold is about +2.5 dBm, so give a staged gain
  procedure starting at -60 dB and capped at -30 dB until an attenuator
  arrives
- require the antennas to be physically removed from the bench rather
  than merely left unplugged
- add the environment blocker found on inspection: the interpreter on
  PATH is a standalone Python 3.13.1 without pyadi-iio, libiio or scipy,
  while Lab024a clearly ran somewhere else; identifying and recording
  that environment is now the first task
- renumber sections and align the TX gain figure with the safety section

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-10 13:03:17 +03:00
LittleSam129
3d14c75365 Lab042: add hardware loopback specification
Specification for the first transmission through real hardware. The
project has no TX call anywhere across Lab001-Lab041, so the whole chain
exists but has never been connected to a transmitter.

Scope is deliberately minimal: get a JPEG through a cable loopback on a
single PlutoSDR and see the picture. Single device means TX and RX share
a reference clock, which removes the carrier offset and clock drift that
the receiver chain handles weakest.

- reuse Lab018 signal parameters unchanged, so hardware is the only new
  variable
- reuse image_fragments, packet, build_radio_frame, find_radio_frame
- list the first-time traps: cyclic TX buffer, sample scaling, RX started
  after TX, undersized RX buffer, automatic gain, receiver saturation
- define acceptance criteria and required measurements
- state explicitly what is out of scope: retransmission, erasure coding,
  higher rate, two devices, over-the-air

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-10 11:39:39 +03:00
LittleSam129
28227e4228 Add quick gate and independent review pipeline
Introduce tools/quick_gate.py: a one-second check that parses every file
in protocol, tests and tools, imports each protocol module, and runs the
functional tests of the labs that need no experiment data.

Wire it to a PostToolUse hook so edits under protocol or tests are checked
automatically, and add two read-only review agents with slash commands that
drive them: verifier for independent re-derivation of results, adversary for
unsafe-state hunting in control, failsafe, session and reset code.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-07 17:33:46 +03:00
LittleSam129
7d122b53ed Lab041: remove non-modelled metrics and cite value sources
Audit found seven numbers in simulate_trial that were neither modelled by
Lab041 nor traceable to their claimed source. Video fraction 0.910 did not
match Lab040 (0.9603); base queue length 31 did not match Lab040 (36-38).

- drop video/telemetry/control delivered fractions and queue length: these
  belong to Lab037 and Lab040 and are not modelled here
- drop lab041_traffic_impact.png, which plotted only those metrics
- drop negative_speed_cases and speed_limit_exceeded_cases, never computed,
  along with the tautological asserts that checked them
- bind braking parameters to the Lab039 nominal profile via named constants
  instead of the literals 0.250 and the divisor 6.0
- cite Lab038 as the source of the transferred video and telemetry loads
- rewrite the invariants section: nine architecture-derived properties now
  carry functional-check references, five unmeasurable ones move to their
  own section
- extend check 04 with negative speed and the 15 m/s boundary
- state explicitly what the matrix rolls, what the architecture fixes and
  what is not modelled at all

Regenerated: 180 combinations, 24/24 checks, five CSV and seven PNG.
Six columns removed, no retained value changed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-07 17:32:51 +03:00
LittleSam129
e18200225b Lab041: correct generated Git status wording 2026-08-07 10:50:42 +03:00
LittleSam129
f26d7d74ef Lab041: add session and restart safety 2026-08-05 14:14:24 +03:00
LittleSam129
88addff5b6 Lab040: add persistent emergency intent and safe reset 2026-08-05 13:12:49 +03:00
LittleSam129
b3ebe1637f Lab039: model two-stage failsafe braking 2026-08-05 11:44:43 +03:00
LittleSam129
23cfdf581b Lab038: add control failsafe and emergency acknowledgement 2026-08-04 14:06:50 +03:00
LittleSam129
50e45ca611 Lab037: evaluate control repetition on lossy link 2026-08-04 13:18:49 +03:00
LittleSam129
3e0ef5666e Lab036: validate long-duration video scheduling 2026-08-03 17:10:17 +03:00
LittleSam129
22c2eeab8c Lab035: add proactive video frame admission 2026-08-03 15:42:16 +03:00
LittleSam129
b63e36abdb Lab034: evaluate stale video frame dropping 2026-08-03 13:17:55 +03:00
LittleSam129
21751f41dd Lab033: add priority link scheduler 2026-08-03 12:21:49 +03:00
LittleSam129
3dbb7afa83 Lab032: evaluate FEC block parameters 2026-07-29 12:47:10 +03:00
LittleSam129
2ac1571c40 Lab031: evaluate FEC packet interleaving 2026-07-29 12:25:51 +03:00
LittleSam129
edab87b5d2 Lab030: add packet erasure FEC 2026-07-29 11:40:37 +03:00
LittleSam129
f8575f4de3 Lab029B: simulate time-based burst losses 2026-07-27 16:28:54 +03:00
LittleSam129
a2dd58a44b Lab029: simulate packet loss and channel errors 2026-07-27 15:29:39 +03:00
LittleSam129
04ce66fdfe Lab028: add video packetization and CRC reassembly 2026-07-27 13:46:01 +03:00
LittleSam129
78258b5355 Lab027: optimize synchronized ROI video stream 2026-07-24 17:54:27 +03:00
LittleSam129
6d49036066 Lab026: benchmark low-bitrate video and 4-bit encoding 2026-07-24 11:56:41 +03:00
LittleSam129
557b082f2b lab025_wfm_audio_100_1mhz 2026-07-22 17:29:07 +03:00
LittleSam129
f3a11b29b3 Merge branch 'repair/project-layout' 2026-07-22 14:20:11 +03:00
LittleSam129
35cb25fccc Create lab024a_pluto_rx_100mhz.npy 2026-07-22 11:24:05 +03:00
LittleSam129
1ff04b12b9 Repair project layout and fix Lab024B spectrum detection 2026-07-21 13:51:41 +03:00
LittleSam129
acf7a76546 initial commit 2026-07-20 13:58:58 +03:00