AntHocNet 2.6.1
Paper-faithful ant-colony ad hoc routing: the shared core and its adapters
Loading...
Searching...
No Matches
sim.h
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-2.0-only
2// Copyright (C) 2026 Daniel Henrique Joppi
3
4/**
5 * The browser adapter (#544, ADR-0021): an adapter for the shared AntHocNet
6 * core, next to the ns-3 one (and NS-2's, through v1.9.0). It owns what an adapter owns -- the
7 * clock, the RNGs, the timers, the pending-packet queue, a radio -- and
8 * carries out the RouteDecisions the core returns. It never decides a route.
9 *
10 * The radio is a *teaching* model: unit disk (optionally cut by buildings,
11 * or a fixed ISL adjacency), a FIFO transmitter per node with a fixed bit
12 * rate, and a MAC transmit-failure report when a unicast's receiver is out of
13 * range. It is not ns-3 and nothing measured on it is a benchmark number.
14 *
15 * Everything here is plain C++14 on top of core/, so the same sources build
16 * natively and with Emscripten; the native-vs-WASM decision-trace parity test
17 * (web/test/parity.sh) holds the two builds byte-identical.
18 */
19#ifndef AHN_WEB_SIM_H
20#define AHN_WEB_SIM_H
21
22#include <cstdint>
23#include <deque>
24#include <functional>
25#include <map>
26#include <memory>
27#include <queue>
28#include <set>
29#include <string>
30#include <utility>
31#include <vector>
32
36
37namespace ahn_web {
38
40
41/// SplitMix64: tiny, portable, and bit-identical on every platform (integer
42/// arithmetic only; the double is an exact 53-bit scaling).
44public:
45 /// A stream starting from `seed` (every seed is valid).
46 explicit SplitMix64(std::uint64_t seed) : state_(seed) {}
47 /// Next raw 64-bit value.
48 std::uint64_t next();
49 /// Uniform double in [0, 1), from the top 53 bits.
50 double uniform();
51 /// Uniform double in [lo, hi).
52 double uniform(double lo, double hi) { return lo + (hi - lo) * uniform(); }
53 /// Uniform integer in [0, n); 0 when n <= 0.
54 int uniformInt(int n);
55
56private:
57 std::uint64_t state_;
58};
59
60/// A position in metres (z = altitude; 0 on planar worlds).
61struct Vec3 {
62 double x = 0; ///< east
63 double y = 0; ///< north
64 double z = 0; ///< up
65};
66
67/// One straight leg of a node's trajectory: p0 at t0 to p1 at t1.
68struct Leg {
69 double t0; ///< start time (s)
70 double t1; ///< end time (s); 1e18 = forever
71 Vec3 p0; ///< position at t0
72 Vec3 p1; ///< position at t1 (linear in between)
73};
74
75/// How a node moves. Values are part of the JS API (setMobility's `kind`).
76enum class MobilityKind {
77 Static, ///< never moves (until dragged)
78 RandomWaypoint, ///< straight legs to uniform waypoints, optional pause
79 GaussMarkov, ///< correlated speed and heading, 1 s steps, optionally 3-D
80 Manhattan, ///< street grid: straight 0.5, left/right 0.25 at each corner
81 Orbit, ///< circular orbit around the field's centre (satellites)
82 Route, ///< #575: a fixed route (a bus line): waypoint to waypoint, looping
83};
84
85/// A node's mobility model and its parameters.
86struct Mobility {
88 double speedMin = 1; ///< RWP / Manhattan: leg speed lower bound (m/s)
89 double speedMax = 10; ///< RWP / Manhattan: leg speed upper bound (m/s)
90 double pause = 0; ///< RWP: pause at each waypoint (s)
91 double gmMeanSpeed = 10; ///< Gauss-Markov: mean speed (m/s)
92 double gmAlpha = 0.85; ///< Gauss-Markov: memory (0 = random walk, 1 = straight line)
93 bool threeD = false; ///< Gauss-Markov: also move in z
94 double orbitRadius = 0; ///< Orbit: distance from the field's centre (m)
95 double orbitInc = 0; ///< Orbit: inclination (rad)
96 double orbitRaan = 0; ///< Orbit: right ascension of the ascending node (rad)
97 double orbitPhase = 0; ///< Orbit: argument of latitude at t = 0 (rad)
98 double orbitRate = 0; ///< Orbit: angular speed (rad/s)
99 std::vector<Vec3> route; ///< Route: waypoints, driven in order at speedMin, looping
100};
101
102/// sin / cos from arithmetic only (range reduction + Taylor series), so the
103/// native and WASM builds compute bit-identical orbits: libm's transcendental
104/// functions are not guaranteed to round the same on both.
105double detSin(double x);
106double detCos(double x);
107
108/// Where an Orbit puts a node at time t (centre = the field's centre, z = 0).
109Vec3 orbitPosition(const Mobility& m, const Vec3& centre, double t);
110
111/// Which link rule the teaching radio uses.
112enum class ChannelKind {
113 Disk, ///< linked iff within range()
114 Urban, ///< within range() and no building on the line of sight
115 Isl, ///< linked iff an inter-satellite link was added (and not cut)
116 Mixed, ///< #582: ground, air and space in one world (see setMixedChannel)
117};
118
119/// Event kinds of the log the front end animates and the parity test diffs.
120/// Append only: the JS front end and the trace format index these numerically.
121enum class Ev : int {
122 TxAnt = 1, ///< node -> peer (-1 = broadcast); a=AntType, b=dir, v=arrival time
123 RxAnt = 2, ///< node received from peer; a=AntType, b=dir
124 TxData = 3, ///< node -> peer; a=flow, b=seq, v=arrival time
125 Deliver = 4, ///< node = destination; a=flow, b=seq, v=end-to-end delay
126 Drop = 5, ///< node; a=flow, b=seq, peer=DropReason
127 RouteAdd = 6, ///< node; peer=next hop, a=destination
128 RouteDel = 7, ///< node; peer=next hop, a=destination
129 Queue = 8, ///< node; a=flow, b=seq, peer=destination
130 TxFail = 9, ///< node -> peer unicast failed (out of range)
131 NodeDown = 10, ///< node switched off
132 NodeUp = 11, ///< node switched on
133};
134
135/// Why a data packet was lost (the `peer` field of an Ev::Drop event).
136enum class DropReason : int {
137 Ttl = 1, ///< hop limit reached (a loop)
138 QueueTimeout = 2, ///< waited QueueTimeout (3 s) for a route, or queue full
139 HoldCap = 3, ///< a reconvergence hold outlived ReconvHoldCap (200 ms)
140 RepairDiscard = 4, ///< a local repair expired: the core's DiscardPending
141 NodeOff = 5, ///< the holding or receiving node was switched off
142};
143
144/// One entry of the event log (see Ev for what each field means per kind).
145struct LogEvent {
146 double t; ///< simulated time (s)
147 Ev kind; ///< what happened
148 int node; ///< where it happened
149 int peer; ///< the other node, -1 for broadcast, or a DropReason
150 int a; ///< kind-specific (AntType, flow, destination)
151 int b; ///< kind-specific (AntDirection, sequence number)
152 double v; ///< kind-specific (arrival time, end-to-end delay)
153};
154
155/// A constant-bit-rate data flow and its running totals.
156struct Flow {
157 int src; ///< source node
158 int dst; ///< destination node
159 double rate; ///< packets per second
160 double start; ///< first packet (s)
161 double stop; ///< no packets after this (s)
162 int sent = 0; ///< packets originated
163 int delivered = 0; ///< packets that reached dst
164 double delaySum = 0; ///< sum of end-to-end delays of delivered packets (s)
165};
166
167class World;
168
169/// One AntHocNet node: the core logic plus the adapter state around it.
175public:
176 /// Created by World::addNode(); `seed` derives the node's streams.
177 Node(World& w, int id, std::uint64_t seed);
178
179 /// IClock: the world's simulated time.
180 anthocnet::core::Time now() const override;
181 /// IRng: this node's own stream (independent of every other node's).
182 double uniform() override { return rng_.uniform(); }
183 /// IRng: uniform integer in [0, n).
184 int uniformInt(int n) override { return rng_.uniformInt(n); }
185
186 /// IKinematics (ADR-0025): position and the current leg's velocity. Read
187 /// by the core only when Config::shareKinematics is on.
188 bool self(anthocnet::core::Kinematics& out) const override;
189
190 /// IEnergy (#575, #145): the battery's residual fraction, NaN without a
191 /// battery. Read only by the energy metric.
192 double residualEnergyFraction() const override;
193
194 /// IRouterObserver: report-only -- route changes feed the event log.
195 void onRouteChanged(NodeAddress dest, NodeAddress nb, bool added) override;
196
197 /// This node's address (its index in the World).
198 int id() const { return id_; }
199 /// The core state machine (valid after World::start()).
201 /// The core state machine, read-only (inspection).
202 const anthocnet::core::AntRouterLogic& logic() const { return *logic_; }
203
204private:
205 friend class World;
206 /// A data packet, in flight or held in the pending queue.
207 struct Pending {
208 int flow, seq, src, dst, ttl, hops;
209 NodeAddress prev; ///< previous hop (A1 loop exclusion; re-injection)
210 double created, firstQueued, expire;
211 bool reconv; ///< held while a known route re-forms (#21 HOLD_RECONV)
212 };
213
214 World& w_;
215 int id_;
216 SplitMix64 rng_; ///< the core's IRng
217 SplitMix64 timerRng_; ///< adapter timer jitter (as ns-3's m_timerRng)
218 // Mobility is generated lazily but from a per-node stream, so a node's
219 // trajectory never depends on when (or whether) another node was queried.
220 mutable SplitMix64 mobRng_;
221 mutable double gmSpeed_ = 0;
222 mutable Vec3 gmDir_{1, 0, 0};
223 mutable int mhDir_ = 0;
224 mutable bool rwpPaused_ = false;
225 std::unique_ptr<anthocnet::core::AntRouterLogic> logic_;
226 bool up_ = true;
227 double range_ = -1; ///< own radio range (#568); < 0 = the world's
228 double busyUntil_ = 0; ///< FIFO transmitter
229 std::deque<Pending> pending_;
230 std::set<NodeAddress> everRouted_;
231 Mobility mob_;
232 mutable std::vector<Leg> legs_;
233 mutable std::size_t routeIdx_ = 0; ///< Route: the waypoint the current leg ends at
234 double battery0_ = -1; ///< #575: initial energy (J); < 0 = no battery
235 double battery_ = 0; ///< energy left (J)
236 double batteryAt_ = 0; ///< when battery_ was last brought up to date
237 double groundMinSinEl_ = 2; ///< #575: sin(min elevation); > 1 = not a ground station
238 bool satellite_ = false; ///< #582: a satellite on the Mixed channel
239};
240
241/// The whole simulation: nodes, radio, mobility, traffic and the event queue.
242class World {
243public:
244 /// An empty world; `seed` derives every random stream in it.
245 explicit World(std::uint64_t seed);
246
247 // --- scenario construction (before start()) ---------------------------
248 /// Field size in metres (z > 0 enables altitude).
249 void setArea(double x, double y, double z);
250 /// Unit-disk links of radius `range` metres.
251 void setDiskChannel(double range);
252 /// Unit disk cut by the buildings of a blocksX x blocksY street grid.
253 void setUrbanChannel(double range, int blocksX, int blocksY, double streetWidth);
254 /// Links only where addIslLink() says, delay tracking distance.
256 /// Add an inter-satellite link (ChannelKind::Isl, Mixed).
257 void addIslLink(int a, int b);
258 /// #582: ground, air and space nodes in one world. Satellites (see
259 /// setSatellite) link only by their ISLs and to the ground stations that
260 /// see them; every other pair links by the disk rule, in 3-D, with the
261 /// world range `range` for nodes without their own. Unlike the Isl
262 /// channel, a ground station also links to its neighbours by the disk
263 /// rule (a HAPS holds both its ring and its uplink). Every link's delay is
264 /// its length at the speed of light.
265 void setMixedChannel(double range);
266 /// #582: mark `node` as a satellite on the Mixed channel.
268 /// Transmitter bit rate (default 2 Mbit/s).
269 void setBitrate(double bps) { bitrate_ = bps; }
270 /// Independent per-reception loss probability (default 0).
271 void setLossProbability(double p) { loss_ = p; }
272 /// Add a node at (x, y, z); returns its address.
273 int addNode(double x, double y, double z);
274 /// Give `node` its own radio range in metres (#568: a device class). On
275 /// the disk and urban channels two nodes link iff they are within
276 /// min(range_a, range_b). A node never given one uses the world range(),
277 /// so every existing world is unchanged.
278 void setNodeRange(int node, double range);
279 /// `node`'s radio range: its own, else the world range().
280 /// Give `node` a mobility model (Manhattan snaps it to an intersection).
281 void setMobility(int node, const Mobility& m);
282 /// #575: inside the polygon `xy` (x0, y0, x1, y1, ...) and below `top`
283 /// metres, radio range is scaled by `factor` (a canopy, rubble: a drone
284 /// above the trees is not in it). A link uses each end's own scaled
285 /// range; where zones overlap the smallest factor applies.
286 void addAttenuationZone(const std::vector<double>& xy, double factor, double top = 30);
287 /// #575: give `node` a battery of `joules`. It drains at kIdleW all the
288 /// time and kTxW while transmitting, and the node switches off when it is
289 /// empty. Accounting only: it never touches a routing decision.
290 void setBattery(int node, double joules);
291 /// #575: energy left in `node`'s battery (J), or -1 without one.
292 double batteryLeft(int node);
293 /// #575: make `node` a ground station on the satellite (Isl) channel. It
294 /// links to any satellite at least `minElevationDeg` above its horizon,
295 /// the horizon being the plane normal to the Earth's radius through it
296 /// (the Earth's centre is the field's centre, as for orbits).
297 void setGroundStation(int node, double minElevationDeg);
298 /// #582: a jamming zone. While from <= t < until, any disk or urban link
299 /// with an end inside the polygon `xy` (x0, y0, x1, y1, ...), or crossing
300 /// it, fails. The polygon moves at (vx, vy) m/s from `from` on (a fire
301 /// front); (0, 0) holds it still (a jammer). It covers every altitude.
302 /// Satellite links are never jammed.
303 void addJammingZone(const std::vector<double>& xy, double from, double until, double vx = 0,
304 double vy = 0);
305 /// #582: a scripted event -- switch `node` off (up = false) or back on at
306 /// simulated time t (an aftershock, a device restored), as setNodeUp.
307 void scheduleNodeUp(int node, double t, bool up);
308 /// Add a CBR flow; returns its index.
309 int addFlow(int src, int dst, double rate, double start, double stop);
310 /// #579: the link metric every node is built with, by registry name
311 /// ("classic", "sinr", "energy"); false if unknown. Before start() only:
312 /// an upgrade, like a mission knob, never a world's default.
313 bool setLinkMetric(const std::string& name);
314 /// The protocol Config every node is built with -- the core defaults.
315 /// Worlds never change it (ADR-0019); a mission's labelled knob may.
316 anthocnet::core::Config& config() { return config_; }
317
318 /// Build the nodes' core logic and arm their timers and the flows.
319 void start();
320
321 // --- running ----------------------------------------------------------
322 /// Process every event up to simulated time `t` (starts if needed).
323 void advanceTo(double t);
324 /// Current simulated time (s).
325 double now() const { return now_; }
326 /// The seed this world was built from.
327 std::uint64_t seed() const { return seed_; }
328
329 // --- interaction (any time) -------------------------------------------
330 /// Drag `node` to (x, y, z) and pin it there (it stops moving).
331 void moveNode(int node, double x, double y, double z);
332 /// Switch `node` off (its held packets are dropped) or back on.
333 void setNodeUp(int node, bool up);
334 /// Remove an inter-satellite link.
335 void cutIslLink(int a, int b);
336
337 // --- inspection (read-only) -------------------------------------------
338 /// Number of nodes.
339 int nodeCount() const { return static_cast<int>(nodes_.size()); }
340 /// Where `node` is now.
341 Vec3 position(int node) const { return positionAt(node, now_); }
342 /// Whether `node` is switched on.
343 bool nodeUp(int node) const { return nodes_[node]->up_; }
344 /// Whether a and b can hear each other now.
345 bool linkUp(int a, int b) const { return linkUpAt(a, b, now_); }
346 /// Node `i` (for read-only inspection of its core state).
347 const Node& node(int i) const { return *nodes_[i]; }
348 /// The flows and their running totals.
349 const std::vector<Flow>& flows() const { return flows_; }
350 /// Data packets `node` holds waiting for a route.
351 int pendingCount(int node) const { return static_cast<int>(nodes_[node]->pending_.size()); }
352 /// Events since the last clearLog().
353 const std::vector<LogEvent>& log() const { return log_; }
354 /// Forget the logged events (the front end drains them every frame).
355 void clearLog() { log_.clear(); }
356 /// Ant transmissions so far (control overhead).
357 std::uint64_t antTransmissions() const { return antTx_; }
358 /// X-ray (#637): how many ant transmissions the ring keeps.
359 static constexpr std::size_t kXrayRing = 512;
360 /// X-ray (#637): the serialized bytes of ant transmission `id` -- the
361 /// id-th TxAnt event since start(), from 0 -- if it is among the last
362 /// kXrayRing; else empty. A copy kept for inspection: no decision reads it.
363 const std::vector<std::uint8_t>& antBytes(std::uint64_t id) const;
364 /// Street grid blocks along x (Urban).
365 int urbanBlocksX() const { return blocksX_; }
366 /// Street grid blocks along y (Urban).
367 int urbanBlocksY() const { return blocksY_; }
368 /// Street width in metres (Urban).
369 double streetWidth() const { return streetWidth_; }
370 /// Radio range in metres (Disk, Urban).
371 double range() const { return range_; }
372 double nodeRange(int node) const;
373 /// The link rule in use.
374 ChannelKind channel() const { return channel_; }
375 /// #575: the attenuation zones as [factor, n, x0, y0, ... x(n-1), y(n-1), ...].
376 std::vector<double> zonesFlat() const;
377 /// #582: the jamming zones active now, where they are now, as
378 /// [n, x0, y0, ... x(n-1), y(n-1), ...].
379 std::vector<double> jamZonesFlat() const;
380 /// Field size in metres.
381 Vec3 area() const { return area_; }
382
383 /// One trace line per logged event (the parity format).
384 static std::string formatEvent(const LogEvent& e);
385
386private:
387 friend class Node;
388 struct Scheduled {
389 double t;
390 std::uint64_t seq;
391 std::function<void()> fn;
392 };
393 struct Later {
394 bool operator()(const Scheduled& a, const Scheduled& b) const {
395 return a.t > b.t || (a.t == b.t && a.seq > b.seq);
396 }
397 };
398
399 void schedule(double t, std::function<void()> fn);
400 void emit(double t, Ev kind, int node, int peer, int a, int b, double v);
401
402 // mobility
403 void extendLegs(Node& n, double until) const;
404 void armTimers(Node& n);
405 Vec3 positionAt(int node, double t) const;
406 /// Velocity (m/s) of the leg covering t: zero when paused or pinned.
407 Vec3 velocityAt(int node, double t) const;
408 bool linkUpAt(int a, int b, double t) const;
409 bool lineOfSight(const Vec3& a, const Vec3& b) const;
410
411 // timers
412 void helloTimer(int node);
413 void proactiveTimer(int node);
414 void retryTimer(int node);
415 void flowTick(int flow);
416 double jittered(Node& n, double base, bool first);
417
418 // the adapter contract
419 void execute(Node& n, const std::vector<anthocnet::core::RouteDecision>& ds);
420 void sendAnt(Node& n, const anthocnet::core::AntMessage& m, int to);
421 void recvAnt(int node, int from, const std::vector<std::uint8_t>& bytes);
422 void routeData(Node& n, Node::Pending p, int prevHop);
423 void sendData(Node& n, Node::Pending p, int next);
424 void recvData(int node, int from, Node::Pending p);
425 void enqueue(Node& n, Node::Pending p);
426 void flushQueue(Node& n, NodeAddress dst);
427 void discardQueue(Node& n, NodeAddress dst, DropReason why);
428 void purge(Node& n);
429 double txDuration(std::size_t bytes) const { return bytes * 8.0 / bitrate_; }
430 double propagation(int a, int b, double t) const;
431
432 SplitMix64 lossRng_; ///< channel loss draws only
433 std::uint64_t seed_;
435 const anthocnet::core::ILinkMetric* metric_ = nullptr; ///< #579; nullptr = classic
436 Vec3 area_{1000, 1000, 0};
438 double range_ = 250;
439 int blocksX_ = 4, blocksY_ = 4;
440 double streetWidth_ = 20;
441 std::set<std::pair<int, int>> isl_;
442 double bitrate_ = 2e6;
443 double loss_ = 0;
444 std::vector<std::unique_ptr<Node>> nodes_;
445 std::vector<Flow> flows_;
446 std::priority_queue<Scheduled, std::vector<Scheduled>, Later> events_;
447 std::uint64_t seq_ = 0;
448 double now_ = 0;
449 bool started_ = false;
450 std::vector<LogEvent> log_;
451 std::uint64_t antTx_ = 0;
452 std::deque<std::pair<std::uint64_t, std::vector<std::uint8_t>>>
453 xray_; // (id, bytes), oldest first
454
455 struct Zone {
456 std::vector<double> xy;
457 double factor;
458 double top;
459 };
460 std::vector<Zone> zones_; ///< #575 attenuation zones
461 struct JamZone {
462 std::vector<double> xy;
463 double from, until, vx, vy;
464 };
465 std::vector<JamZone> jams_; ///< #582 jamming zones
466 /// Whether a jamming zone active at t holds an end of a-b or crosses it.
467 bool jammed(const Vec3& a, const Vec3& b, double t) const;
468 /// The smallest attenuation factor of the zones containing (x, y), or 1.
469 double rangeFactorAt(const Vec3& p) const;
470 /// Bring `n`'s battery up to now; switch it off when empty.
471 void drainBattery(Node& n, double txSeconds);
472 void batteryTimer(int node);
473 /// Whether ground station g sees satellite s at time t.
474 bool groundSees(int g, int s, double t) const;
475
476 // adapter constants: the ns-3 attribute defaults (anthocnet-routing-protocol.cc)
477 static constexpr double kTimerJitter = 0.05; // TimerJitter
478 static constexpr double kQueueTimeout = 3.0; // QueueTimeout
479 static constexpr double kReconvHoldCap = 0.2; // ReconvHoldCap
480 static constexpr double kRetryInterval = 0.25; // ReactiveRetryInterval
481 static constexpr std::size_t kQueueLen = 64; // RequestQueue maxLen
482 static constexpr int kTtl = 64;
483 static constexpr std::size_t kDataBytes = 64 + 28; // payload + IP/UDP
484 static constexpr int kMacRetries = 7; // failure known after 7 tries
485 // #575 battery draw: the single-antenna 802.11n NIC anthocnet-compare
486 // models (Halperin et al., HotPower'10): idle 0.82 W, transmitting 1.14 W.
487 static constexpr double kIdleW = 0.82;
488 static constexpr double kTxW = 1.14;
489};
490
491} // namespace ahn_web
492
493#endif // AHN_WEB_SIM_H
One AntHocNet node: the core logic plus the adapter state around it.
Definition sim.h:174
double residualEnergyFraction() const override
IEnergy (#575, #145): the battery's residual fraction, NaN without a battery.
int uniformInt(int n) override
IRng: uniform integer in [0, n).
Definition sim.h:184
void onRouteChanged(NodeAddress dest, NodeAddress nb, bool added) override
IRouterObserver: report-only – route changes feed the event log.
bool self(anthocnet::core::Kinematics &out) const override
IKinematics (ADR-0025): position and the current leg's velocity.
anthocnet::core::AntRouterLogic & logic()
The core state machine (valid after World::start()).
Definition sim.h:200
int id() const
This node's address (its index in the World).
Definition sim.h:198
Node(World &w, int id, std::uint64_t seed)
Created by World::addNode(); seed derives the node's streams.
double uniform() override
IRng: this node's own stream (independent of every other node's).
Definition sim.h:182
anthocnet::core::Time now() const override
IClock: the world's simulated time.
const anthocnet::core::AntRouterLogic & logic() const
The core state machine, read-only (inspection).
Definition sim.h:202
SplitMix64: tiny, portable, and bit-identical on every platform (integer arithmetic only; the double ...
Definition sim.h:43
double uniform()
Uniform double in [0, 1), from the top 53 bits.
double uniform(double lo, double hi)
Uniform double in [lo, hi).
Definition sim.h:52
std::uint64_t next()
Next raw 64-bit value.
SplitMix64(std::uint64_t seed)
A stream starting from seed (every seed is valid).
Definition sim.h:46
int uniformInt(int n)
Uniform integer in [0, n); 0 when n <= 0.
The whole simulation: nodes, radio, mobility, traffic and the event queue.
Definition sim.h:242
void start()
Build the nodes' core logic and arm their timers and the flows.
void addIslLink(int a, int b)
Add an inter-satellite link (ChannelKind::Isl, Mixed).
void setNodeUp(int node, bool up)
Switch node off (its held packets are dropped) or back on.
std::uint64_t seed() const
The seed this world was built from.
Definition sim.h:327
int urbanBlocksX() const
Street grid blocks along x (Urban).
Definition sim.h:365
Vec3 area() const
Field size in metres.
Definition sim.h:381
void setIslChannel()
Links only where addIslLink() says, delay tracking distance.
void setNodeRange(int node, double range)
Give node its own radio range in metres (#568: a device class).
void setGroundStation(int node, double minElevationDeg)
#575: make node a ground station on the satellite (Isl) channel.
bool nodeUp(int node) const
Whether node is switched on.
Definition sim.h:343
double batteryLeft(int node)
#575: energy left in node's battery (J), or -1 without one.
void addJammingZone(const std::vector< double > &xy, double from, double until, double vx=0, double vy=0)
#582: a jamming zone.
void setUrbanChannel(double range, int blocksX, int blocksY, double streetWidth)
Unit disk cut by the buildings of a blocksX x blocksY street grid.
void setBattery(int node, double joules)
#575: give node a battery of joules.
void setLossProbability(double p)
Independent per-reception loss probability (default 0).
Definition sim.h:271
static std::string formatEvent(const LogEvent &e)
One trace line per logged event (the parity format).
void setMixedChannel(double range)
#582: ground, air and space nodes in one world.
friend class Node
Definition sim.h:387
void clearLog()
Forget the logged events (the front end drains them every frame).
Definition sim.h:355
const std::vector< std::uint8_t > & antBytes(std::uint64_t id) const
X-ray (#637): the serialized bytes of ant transmission id – the id-th TxAnt event since start(),...
void setDiskChannel(double range)
Unit-disk links of radius range metres.
std::vector< double > zonesFlat() const
#575: the attenuation zones as [factor, n, x0, y0, ... x(n-1), y(n-1), ...].
void addAttenuationZone(const std::vector< double > &xy, double factor, double top=30)
#575: inside the polygon xy (x0, y0, x1, y1, ...) and below top metres, radio range is scaled by fact...
double range() const
Radio range in metres (Disk, Urban).
Definition sim.h:371
static constexpr std::size_t kXrayRing
X-ray (#637): how many ant transmissions the ring keeps.
Definition sim.h:359
int pendingCount(int node) const
Data packets node holds waiting for a route.
Definition sim.h:351
void scheduleNodeUp(int node, double t, bool up)
#582: a scripted event – switch node off (up = false) or back on at simulated time t (an aftershock,...
double nodeRange(int node) const
double now() const
Current simulated time (s).
Definition sim.h:325
int urbanBlocksY() const
Street grid blocks along y (Urban).
Definition sim.h:367
const std::vector< Flow > & flows() const
The flows and their running totals.
Definition sim.h:349
std::uint64_t antTransmissions() const
Ant transmissions so far (control overhead).
Definition sim.h:357
double streetWidth() const
Street width in metres (Urban).
Definition sim.h:369
void advanceTo(double t)
Process every event up to simulated time t (starts if needed).
bool setLinkMetric(const std::string &name)
#579: the link metric every node is built with, by registry name ("classic", "sinr",...
ChannelKind channel() const
The link rule in use.
Definition sim.h:374
int addFlow(int src, int dst, double rate, double start, double stop)
Add a CBR flow; returns its index.
anthocnet::core::Config & config()
The protocol Config every node is built with – the core defaults.
Definition sim.h:316
int nodeCount() const
Number of nodes.
Definition sim.h:339
void setMobility(int node, const Mobility &m)
node's radio range: its own, else the world range().
void setSatellite(int node)
#582: mark node as a satellite on the Mixed channel.
const Node & node(int i) const
Node i (for read-only inspection of its core state).
Definition sim.h:347
void setBitrate(double bps)
Transmitter bit rate (default 2 Mbit/s).
Definition sim.h:269
bool linkUp(int a, int b) const
Whether a and b can hear each other now.
Definition sim.h:345
Vec3 position(int node) const
Where node is now.
Definition sim.h:341
void cutIslLink(int a, int b)
Remove an inter-satellite link.
void moveNode(int node, double x, double y, double z)
Drag node to (x, y, z) and pin it there (it stops moving).
std::vector< double > jamZonesFlat() const
#582: the jamming zones active now, where they are now, as [n, x0, y0, ... x(n-1),...
const std::vector< LogEvent > & log() const
Events since the last clearLog().
Definition sim.h:353
World(std::uint64_t seed)
An empty world; seed derives every random stream in it.
void setArea(double x, double y, double z)
Field size in metres (z > 0 enables altitude).
int addNode(double x, double y, double z)
Add a node at (x, y, z); returns its address.
Source of simulation time (seconds).
Definition ports.h:24
This node's residual energy (#145): the fraction of its initial battery left, 0..1.
Definition ports.h:116
This node's own position and velocity (#573, ADR-0025).
Definition ports.h:105
Source of randomness.
Definition ports.h:33
Optional observer the core notifies of routing events (item 15).
Definition ports.h:127
Built-in teaching scenarios: one per network family, shaped like the repo's presets but scaled down t...
Definition scenarios.h:18
MobilityKind
How a node moves. Values are part of the JS API (setMobility's kind).
Definition sim.h:76
@ Manhattan
street grid: straight 0.5, left/right 0.25 at each corner
@ Orbit
circular orbit around the field's centre (satellites)
@ GaussMarkov
correlated speed and heading, 1 s steps, optionally 3-D
@ Static
never moves (until dragged)
@ Route
#575: a fixed route (a bus line): waypoint to waypoint, looping
@ RandomWaypoint
straight legs to uniform waypoints, optional pause
Vec3 orbitPosition(const Mobility &m, const Vec3 &centre, double t)
Where an Orbit puts a node at time t (centre = the field's centre, z = 0).
Ev
Event kinds of the log the front end animates and the parity test diffs.
Definition sim.h:121
@ NodeDown
node switched off
@ NodeUp
node switched on
@ RouteAdd
node; peer=next hop, a=destination
@ Drop
node; a=flow, b=seq, peer=DropReason
@ Deliver
node = destination; a=flow, b=seq, v=end-to-end delay
@ TxData
node -> peer; a=flow, b=seq, v=arrival time
@ Queue
node; a=flow, b=seq, peer=destination
@ RxAnt
node received from peer; a=AntType, b=dir
@ TxAnt
node -> peer (-1 = broadcast); a=AntType, b=dir, v=arrival time
@ TxFail
node -> peer unicast failed (out of range)
@ RouteDel
node; peer=next hop, a=destination
DropReason
Why a data packet was lost (the peer field of an Ev::Drop event).
Definition sim.h:136
@ HoldCap
a reconvergence hold outlived ReconvHoldCap (200 ms)
@ RepairDiscard
a local repair expired: the core's DiscardPending
@ Ttl
hop limit reached (a loop)
@ NodeOff
the holding or receiving node was switched off
@ QueueTimeout
waited QueueTimeout (3 s) for a route, or queue full
double detSin(double x)
sin / cos from arithmetic only (range reduction + Taylor series), so the native and WASM builds compu...
ChannelKind
Which link rule the teaching radio uses.
Definition sim.h:112
@ Disk
linked iff within range()
@ Mixed
#582: ground, air and space in one world (see setMixedChannel)
@ Urban
within range() and no building on the line of sight
@ Isl
linked iff an inter-satellite link was added (and not cut)
double detCos(double x)
double Time
Simulation time, in seconds.
Definition types.h:24
std::int32_t NodeAddress
Network-layer node address.
Definition types.h:21
A constant-bit-rate data flow and its running totals.
Definition sim.h:156
double rate
packets per second
Definition sim.h:159
int dst
destination node
Definition sim.h:158
double stop
no packets after this (s)
Definition sim.h:161
int sent
packets originated
Definition sim.h:162
double start
first packet (s)
Definition sim.h:160
double delaySum
sum of end-to-end delays of delivered packets (s)
Definition sim.h:164
int delivered
packets that reached dst
Definition sim.h:163
int src
source node
Definition sim.h:157
One straight leg of a node's trajectory: p0 at t0 to p1 at t1.
Definition sim.h:68
double t1
end time (s); 1e18 = forever
Definition sim.h:70
Vec3 p0
position at t0
Definition sim.h:71
double t0
start time (s)
Definition sim.h:69
Vec3 p1
position at t1 (linear in between)
Definition sim.h:72
One entry of the event log (see Ev for what each field means per kind).
Definition sim.h:145
int peer
the other node, -1 for broadcast, or a DropReason
Definition sim.h:149
int b
kind-specific (AntDirection, sequence number)
Definition sim.h:151
int node
where it happened
Definition sim.h:148
int a
kind-specific (AntType, flow, destination)
Definition sim.h:150
double v
kind-specific (arrival time, end-to-end delay)
Definition sim.h:152
double t
simulated time (s)
Definition sim.h:146
Ev kind
what happened
Definition sim.h:147
A node's mobility model and its parameters.
Definition sim.h:86
MobilityKind kind
which model
Definition sim.h:87
double orbitRate
Orbit: angular speed (rad/s)
Definition sim.h:98
double orbitInc
Orbit: inclination (rad)
Definition sim.h:95
double orbitRaan
Orbit: right ascension of the ascending node (rad)
Definition sim.h:96
bool threeD
Gauss-Markov: also move in z.
Definition sim.h:93
double gmAlpha
Gauss-Markov: memory (0 = random walk, 1 = straight line)
Definition sim.h:92
double speedMin
RWP / Manhattan: leg speed lower bound (m/s)
Definition sim.h:88
double gmMeanSpeed
Gauss-Markov: mean speed (m/s)
Definition sim.h:91
double pause
RWP: pause at each waypoint (s)
Definition sim.h:90
double speedMax
RWP / Manhattan: leg speed upper bound (m/s)
Definition sim.h:89
double orbitPhase
Orbit: argument of latitude at t = 0 (rad)
Definition sim.h:97
std::vector< Vec3 > route
Route: waypoints, driven in order at speedMin, looping.
Definition sim.h:99
double orbitRadius
Orbit: distance from the field's centre (m)
Definition sim.h:94
A position in metres (z = altitude; 0 on planar worlds).
Definition sim.h:61
double x
east
Definition sim.h:62
double y
north
Definition sim.h:63
double z
up
Definition sim.h:64
Complete, copyable description of an ant packet.
Definition ant_message.h:48
Maps an observation to a pheromone (goodness; higher == better).
Definition link_metric.h:45
A node's position (m) and velocity (m/s) in the adapter's Cartesian frame (ADR-0025).
Definition types.h:32