The Common Demo Application Framework
All demo applications shipped with pyespargos are built on top of a shared common application framework, located in the demos/common directory of the repository.
Instead of every demo re-implementing the same boilerplate (connecting to ESPARGOS devices, calibrating, collecting a CSI backlog, drawing a Qt/QML user interface), the framework provides these building blocks once, so that each demo only has to implement its own signal-processing and visualization logic.
If you write your own ESPARGOS application on top of the demo framework (the fastest way to get started is to copy and modify an existing demo), you get its features for free. This page describes the framework in general and, in particular, how it is configured through YAML configuration files and command-line options.
Structure
The framework is centered on the ESPARGOSApplication base class, which every demo subclasses.
Optional functionality is added through mixins that a demo combines as needed:
ESPARGOSApplication: the base class. Handles command-line argument parsing, YAML configuration loading, QML engine setup, and creation and calibration of the ESPARGOSPool.BacklogMixin: adds aCSIBacklogand a settings panel for it (backlog size, stored CSI fields, packet filters).CombinedArrayMixin: adds support for phase-coherent multi-board combined arrays (see Phase-Coherent Multi-Array Systems), including parsing of the array geometry and per-cable length compensation.SingleCSIFormatMixin: adds selection of a single preamble format (L-LTF, HT20, HT40 or HE20) to work with.
A typical demo therefore starts like this:
from demos.common import ESPARGOSApplication, BacklogMixin, SingleCSIFormatMixin
class EspargosDemoPhasesOverSpace(BacklogMixin, SingleCSIFormatMixin, ESPARGOSApplication):
...
Beyond configuration, the framework also provides a graphical pool drawer for connecting to and calibrating ESPARGOS devices at runtime, so many settings can additionally be changed interactively from the user interface while a demo is running. The remainder of this page focuses on how a demo is configured before it starts, from configuration files and the command line.
Configuration Overview
Every demo is configured from a single nested configuration dictionary that is assembled, in order of increasing precedence, from three sources:
Built-in defaults: sensible defaults defined by the framework and by the individual demo.
A YAML configuration file, loaded with
-c/--config.Command-line option overrides, passed with
-o/--option.
Later sources are deep-merged on top of earlier ones: a source only needs to specify the keys it wants to change, and all other keys keep their previous value. The configuration is grouped into top-level sections:
pool: which ESPARGOS devices to connect to (hosts) and how to operate them: WiFi channel, calibration behavior, RF switch, receiver/FFT gain, MAC filtering, and so on.backlog: CSI backlog settings, i.e.,size, which CSIfieldsto store (lltf,ht20,ht40,he20), and packetfilters(e.g.exclude_11b). Only relevant for demos usingBacklogMixin.combined-array: the geometry of a phase-coherent multi-board array. Only relevant for demos usingCombinedArrayMixin(see Phase-Coherent Multi-Array Systems).generic: framework-wide application settings, such aspreamble_formatandkiosk_mode.app: reserved for settings specific to the individual demo.
To see the complete list of configuration keys and their default values for any demo, run it with --help.
The bottom of the help output lists every available option, for example:
Configuration options for -o/--option (as CLI arguments) or -c/--config (as YAML file):
backlog:
backlog.size: default: 20
fields:
backlog.fields.lltf: default: true
backlog.fields.ht20: default: false
...
pool:
pool.hosts: default: []
pool.channel: default: 13
...
generic:
generic.preamble_format: default: 'auto'
generic.kiosk_mode: default: false
app: default: {}
YAML Configuration Files (-c/--config)
A configuration file is a YAML document whose top level is an object (dictionary) with the same section structure as above.
It is loaded with the -c (or --config) argument and merged on top of the defaults, so you only need to include the sections and keys you actually want to override.
The most common reason to use a configuration file is to describe a combined array, because its geometry is too complex to express on the command line.
Ready-made example configuration files ship in the config directory of the repository:
config/single-espargos-one.yml: a single ESPARGOS One board in its default orientation.config/aperture-kit-6x4.yml: a phase-coherent large-aperture 6 × 4 array built from three boards.
For example, config/single-espargos-one.yml describes a single board:
combined-array:
boards:
espargosone:
host: 192.168.1.2
cable:
length: 0.0
velocity_factor: 0.76
array:
- - "espargosone.0.0"
- "espargosone.0.1"
- "espargosone.0.2"
- "espargosone.0.3"
- - "espargosone.1.0"
- "espargosone.1.1"
- "espargosone.1.2"
- "espargosone.1.3"
Here, the boards section maps a freely chosen board name to its network host and the properties of its reference-signal cable (used for phase compensation, see Phase-Coherent Multi-Array Systems).
The array section is a matrix that lays out the antennas physically: each entry "<board>.<row>.<column>" refers to one antenna of one board and its position in the matrix corresponds to its physical position in the combined array.
To run a demo with a configuration file:
./demos/combined-array/combined-array.py -c config/single-espargos-one.yml
A configuration file is of course not limited to the combined-array section; any configuration key may be set in it, for example:
pool:
channel: 6
secondary_channel: 2
gain:
automatic: false
rx_gain_value: 40
backlog:
size: 64
generic:
kiosk_mode: true
Overriding Options on the Command Line (-o/--option)
Individual configuration options can be set directly on the command line with -o/--option, without editing or creating a configuration file.
Each override has the form -o KEY=VALUE, where KEY is the dotted path to a configuration key and VALUE is the new value.
Overrides are applied on top of both the built-in defaults and any configuration file loaded with -c, so they always take precedence.
The key is a dotted path into the nested configuration. For example,
generic.kiosk_moderefers to thekiosk_modekey inside thegenericsection, andpool.gain.rx_gain_valuerefers torx_gain_valueinsidegaininsidepool.The value is parsed as YAML, so its type is inferred automatically:
true/falsebecome booleans,32an integer,3.5a float,nullbecomesNone, and anything else a string. Lists work too, e.g.pool.hosts=[192.168.1.2,192.168.1.3].Multiple
-ooptions are allowed; each sets one key, and they are applied left to right.
For example, to run a demo in kiosk mode, on WiFi channel 6, with a fixed receiver gain:
./demos/instantaneous-csi/instantaneous-csi.py 192.168.1.2 \
-o generic.kiosk_mode=true \
-o pool.channel=6 \
-o pool.gain.automatic=false \
-o pool.gain.rx_gain_value=40
-o and -c combine naturally: load a base configuration from a file, then tweak individual keys for a single run without modifying the file:
./demos/combined-array/combined-array.py -c config/aperture-kit-6x4.yml -o backlog.size=100
Convenience Command-Line Arguments
For the most frequently used settings, the framework also provides dedicated command-line arguments as shortcuts, so you do not have to spell out the full configuration key.
Which of these are available depends on the mixins a demo uses; run the demo with --help to see its exact set of arguments.
Device hosts (positional argument): for demos that operate on plain, independent arrays, a comma-separated list of host addresses sets
pool.hosts, e.g.instantaneous-csi.py 192.168.1.2,192.168.1.3.-s/--single-array HOST(withCombinedArrayMixin): a shortcut that auto-generates a single-boardcombined-arrayconfiguration for the given host, so you do not need a configuration file just to run a combined-array demo on one board.-b/--backlog-size N(withBacklogMixin): setsbacklog.size.--lltf/--ht20/--ht40/--he20(withSingleCSIFormatMixin): restrict the demo to a single preamble format (generic.preamble_format). Without any of these flags, the format is chosen automatically.
Note
These shortcuts and the corresponding configuration keys control the same underlying settings.
For the handful of settings that have a dedicated argument (device hosts, single-array layout, backlog size and preamble format), prefer the dedicated argument; use -c and -o for everything else.