Environments & Tasks
The task you pick fixes the Environment and the (n_receptors, n_effectors) the
whole stack is built to — it shapes the assembly and supplies the score. Single-agent
tasks use a PassthroughBody over a TaskWorld; the swarm uses the vision-based
embodied body VENBody — bearing-vision in, movement kinematics out — in a
TorusEnvironment / ForageEnvironment.
Single-agent tasks
| Task | R | E | senses / acts with |
|---|---|---|---|
:wall | 2 | 2 | two ray-cast wall sensors; differential wheel speeds |
:tracking | 62 | 2 | two eyes × 31 Gaussian bearing sensors; eye-rotation command |
:pong / :pong_hitrate | 46 | 2 | ball-bearing bins; paddle vote/differential |
:cartpole (+ hard/swingup/long) | 8 | 2 | 4 state dims × 2 polarities; binary force vote |
Effector semantics are intentionally non-uniform: channel 1 in Pong is not the same
physical quantity as channel 1 in cartpole. And a task here is a test of a capacity, not
a problem to be won (which capacity — wall = avoidance, tracking/pong = pursuit, cartpole =
stabilising an unstable equilibrium — is set out in Concepts).
normalized_score(task, raw) maps each task’s raw metric onto against calibrated
anchors — a null floor and an analytic (or reference) ceiling, each carrying its
provenance. The normalised value is a capacity-indicator (“how far past chance toward the
reference”), so it is comparable across tasks within a ceiling kind; only the raw
scores are not. See Scoring.
Source: src/envs/ (the TaskWorlds), src/tasks/Tasks.jl (TaskSpec), src/tasks/Scoring.jl / Calibration.jl (anchors, calibrate_task).
The swarm
VENBody turns bearing-vision into receptors and VEN kinematics out of effectors: 62
bearing sensors (two eyes × 31 angles) padded to 64 inputs; 3 effectors (e3
forward acceleration, e2−e1 heading acceleration). Coupling is vision — agents
influence each other only by being seen, so the sensor geometry is the interaction
topology; collective order is emergent, not imposed.
Source: src/world/Body.jl (VENBody, sense_agents), src/world/Environments.jl (TorusEnvironment).
The foraging experiment
:forage adds a source the agents can find, sensed via a second bearing-vision
bank (its own gain) alongside the conspecific bank. The headline manipulation is
social vs blind:
- social — agents see each other and the source;
- blind — the same
Nagents see the source but are blind to each other (and don’t collide).
The scientific question: does social vision speed convergence to the source — i.e. do agents use each other’s presence as a guide? Metrics: mean distance-to-source, fraction within a capture radius, and time-to-first-arrival.
simulate(:forage; node=:falandays_base, n_agents=12, conspecific_vision=true) # socialsimulate(:forage; node=:falandays_base, n_agents=12, conspecific_vision=false) # blindSource: src/world/Environments.jl (ForageEnvironment), src/world/Metrics.jl (foraging metrics).
Acoustic signalling
Foraging agents can optionally call to one another. Set signalling=true and each
VENBody grows a fourth effector, :signal — a continuous emission intensity in
that does not move the agent — plus one scalar :acoustic receptor. The receptor reuses a
reserved input slot, so the count stays 128; the reservoir is simply built (128, 4)
instead of (128, 3).
Hearing is loudness only, with no direction — an agent can tell how much calling is happening nearby but not where it comes from. Agent i reads:
heard_i = signal_gain · clamp( Σ_{j ≠ i} emit_j · exp(−d_ij / signal_range), 0, 1 )- Self-excluded (
j ≠ i) — an agent never hears its own call. - Distance fall-off —
exp(−d/signal_range)over torus distance;signal_rangeis the e-folding distance. - Saturates — the
clamp(·, 0, 1)ceiling equals one caller right next to you, so a dense cluster can’t read louder than a single adjacent shout. Withsignal_gain=1the receptor sits on the same scale as vision. - One-tick delay — emissions made on tick t are heard on t+1 (the
observe → actuateorder), a small acoustic propagation lag.
simulate(:forage; node=:falandays_base, n_agents=12, signalling=true, signal_range=3.0, signal_gain=1.0, record=[:effectors]) # emission is effector channel 4With signalling=false (the default) the task is byte-for-byte the base forage experiment,
and non-forage swarms are unaffected.
Source: src/world/Environments.jl (ForageEnvironment hearing), src/world/Morphology.jl / src/world/Body.jl (the :signal effector and :acoustic receptor).