45 explicit SplitMix64(std::uint64_t seed) : state_(seed) {}
184 int id()
const {
return id_; }
194 int flow, seq, src, dst, ttl, hops;
196 double created, firstQueued, expire;
207 mutable double gmSpeed_ = 0;
208 mutable Vec3 gmDir_{1, 0, 0};
209 mutable int mhDir_ = 0;
210 mutable bool rwpPaused_ =
false;
211 std::unique_ptr<anthocnet::core::AntRouterLogic> logic_;
213 double busyUntil_ = 0;
214 std::deque<Pending> pending_;
215 std::set<NodeAddress> everRouted_;
217 mutable std::vector<Leg> legs_;
258 double now()
const {
return now_; }
260 std::uint64_t
seed()
const {
return seed_; }
272 int nodeCount()
const {
return static_cast<int>(nodes_.size()); }
278 bool linkUp(
int a,
int b)
const {
return linkUpAt(a, b, now_); }
280 const Node&
node(
int i)
const {
return *nodes_[i]; }
282 const std::vector<Flow>&
flows()
const {
return flows_; }
286 const std::vector<LogEvent>&
log()
const {
return log_; }
298 double range()
const {
return range_; }
312 std::function<void()> fn;
315 bool operator()(
const Scheduled& a,
const Scheduled& b)
const {
316 return a.t > b.t || (a.t == b.t && a.seq > b.seq);
320 void schedule(
double t, std::function<
void()> fn);
321 void emit(
double t,
Ev kind,
int node,
int peer,
int a,
int b,
double v);
324 void extendLegs(
Node& n,
double until)
const;
325 void armTimers(
Node& n);
326 Vec3 positionAt(
int node,
double t)
const;
327 bool linkUpAt(
int a,
int b,
double t)
const;
328 bool lineOfSight(
const Vec3& a,
const Vec3& b)
const;
331 void helloTimer(
int node);
332 void proactiveTimer(
int node);
333 void retryTimer(
int node);
334 void flowTick(
int flow);
335 double jittered(
Node& n,
double base,
bool first);
338 void execute(
Node& n,
const std::vector<anthocnet::core::RouteDecision>& ds);
340 void recvAnt(
int node,
int from,
const std::vector<std::uint8_t>& bytes);
341 void routeData(
Node& n, Node::Pending p,
int prevHop);
342 void sendData(
Node& n, Node::Pending p,
int next);
343 void recvData(
int node,
int from, Node::Pending p);
344 void enqueue(
Node& n, Node::Pending p);
345 void flushQueue(
Node& n, NodeAddress dst);
348 double txDuration(std::size_t bytes)
const {
return bytes * 8.0 / bitrate_; }
349 double propagation(
int a,
int b,
double t)
const;
354 Vec3 area_{1000, 1000, 0};
357 int blocksX_ = 4, blocksY_ = 4;
358 double streetWidth_ = 20;
359 std::set<std::pair<int, int>> isl_;
360 double bitrate_ = 2e6;
362 std::vector<std::unique_ptr<Node>> nodes_;
363 std::vector<Flow> flows_;
364 std::priority_queue<Scheduled, std::vector<Scheduled>, Later> events_;
365 std::uint64_t seq_ = 0;
367 bool started_ =
false;
368 std::vector<LogEvent> log_;
369 std::uint64_t antTx_ = 0;
372 static constexpr double kTimerJitter = 0.05;
373 static constexpr double kQueueTimeout = 3.0;
374 static constexpr double kReconvHoldCap = 0.2;
375 static constexpr double kRetryInterval = 0.25;
376 static constexpr std::size_t kQueueLen = 64;
377 static constexpr int kTtl = 64;
378 static constexpr std::size_t kDataBytes = 64 + 28;
379 static constexpr int kMacRetries = 7;
One AntHocNet node: the core logic plus the adapter state around it.
int uniformInt(int n) override
IRng: uniform integer in [0, n).
void onRouteChanged(NodeAddress dest, NodeAddress nb, bool added) override
IRouterObserver: report-only – route changes feed the event log.
anthocnet::core::AntRouterLogic & logic()
The core state machine (valid after World::start()).
int id() const
This node's address (its index in the World).
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).
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).
SplitMix64: tiny, portable, and bit-identical on every platform (integer arithmetic only; the double ...
double uniform()
Uniform double in [0, 1), from the top 53 bits.
double uniform(double lo, double hi)
Uniform double in [lo, hi).
std::uint64_t next()
Next raw 64-bit value.
SplitMix64(std::uint64_t seed)
A stream starting from seed (every seed is valid).
int uniformInt(int n)
Uniform integer in [0, n); 0 when n <= 0.
The whole simulation: nodes, radio, mobility, traffic and the event queue.
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).
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.
int urbanBlocksX() const
Street grid blocks along x (Urban).
Vec3 area() const
Field size in metres.
void setIslChannel()
Links only where addIslLink() says, delay tracking distance.
bool nodeUp(int node) const
Whether node is switched on.
void setUrbanChannel(double range, int blocksX, int blocksY, double streetWidth)
Unit disk cut by the buildings of a blocksX x blocksY street grid.
void setLossProbability(double p)
Independent per-reception loss probability (default 0).
static std::string formatEvent(const LogEvent &e)
One trace line per logged event (the parity format).
void clearLog()
Forget the logged events (the front end drains them every frame).
void setDiskChannel(double range)
Unit-disk links of radius range metres.
double range() const
Radio range in metres (Disk, Urban).
int pendingCount(int node) const
Data packets node holds waiting for a route.
double now() const
Current simulated time (s).
int urbanBlocksY() const
Street grid blocks along y (Urban).
const std::vector< Flow > & flows() const
The flows and their running totals.
std::uint64_t antTransmissions() const
Ant transmissions so far (control overhead).
double streetWidth() const
Street width in metres (Urban).
void advanceTo(double t)
Process every event up to simulated time t (starts if needed).
ChannelKind channel() const
The link rule in use.
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.
int nodeCount() const
Number of nodes.
void setMobility(int node, const Mobility &m)
Give node a mobility model (Manhattan snaps it to an intersection).
const Node & node(int i) const
Node i (for read-only inspection of its core state).
void setBitrate(double bps)
Transmitter bit rate (default 2 Mbit/s).
bool linkUp(int a, int b) const
Whether a and b can hear each other now.
Vec3 position(int node) const
Where node is now.
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).
const std::vector< LogEvent > & log() const
Events since the last clearLog().
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).
Optional observer the core notifies of routing events (item 15).
Built-in teaching scenarios: one per network family, shaped like the repo's presets but scaled down t...
MobilityKind
How a node moves. Values are part of the JS API (setMobility's kind).
@ 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)
@ RandomWaypoint
straight legs to uniform waypoints, optional pause
Vec3 orbitPosition(const Mobility &m, const Vec3 ¢re, 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.
@ NodeDown
node switched off
@ 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).
@ 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.
@ Disk
linked iff within range()
@ Urban
within range() and no building on the line of sight
@ Isl
linked iff an inter-satellite link was added (and not cut)
double Time
Simulation time, in seconds.
std::int32_t NodeAddress
Network-layer node address.
A constant-bit-rate data flow and its running totals.
double rate
packets per second
double stop
no packets after this (s)
int sent
packets originated
double start
first packet (s)
double delaySum
sum of end-to-end delays of delivered packets (s)
int delivered
packets that reached dst
One straight leg of a node's trajectory: p0 at t0 to p1 at t1.
double t1
end time (s); 1e18 = forever
Vec3 p1
position at t1 (linear in between)
One entry of the event log (see Ev for what each field means per kind).
int peer
the other node, -1 for broadcast, or a DropReason
int b
kind-specific (AntDirection, sequence number)
int node
where it happened
int a
kind-specific (AntType, flow, destination)
double v
kind-specific (arrival time, end-to-end delay)
double t
simulated time (s)
A node's mobility model and its parameters.
MobilityKind kind
which model
double orbitRate
Orbit: angular speed (rad/s)
double orbitInc
Orbit: inclination (rad)
double orbitRaan
Orbit: right ascension of the ascending node (rad)
bool threeD
Gauss-Markov: also move in z.
double gmAlpha
Gauss-Markov: memory (0 = random walk, 1 = straight line)
double speedMin
RWP / Manhattan: leg speed lower bound (m/s)
double gmMeanSpeed
Gauss-Markov: mean speed (m/s)
double pause
RWP: pause at each waypoint (s)
double speedMax
RWP / Manhattan: leg speed upper bound (m/s)
double orbitPhase
Orbit: argument of latitude at t = 0 (rad)
double orbitRadius
Orbit: distance from the field's centre (m)
A position in metres (z = altitude; 0 on planar worlds).
Complete, copyable description of an ant packet.