Skip to content

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

TaskREsenses / acts with
:wall22two ray-cast wall sensors; differential wheel speeds
:tracking622two eyes × 31 Gaussian bearing sensors; eye-rotation command
:pong / :pong_hitrate462ball-bearing bins; paddle vote/differential
:cartpole (+ hard/swingup/long)824 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 [0,1][0,1] 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 N agents 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) # social
simulate(:forage; node=:falandays_base, n_agents=12, conspecific_vision=false) # blind

Source: 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 [0,1][0,1] 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-offexp(−d/signal_range) over torus distance; signal_range is 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. With signal_gain=1 the receptor sits on the same [0,1][0,1] scale as vision.
  • One-tick delay — emissions made on tick t are heard on t+1 (the observe → actuate order), 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 4

With 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).