Advanced Topics¶
Configuration Directory Layout¶
Each scenario folder contains modular .ini files. The top-level .ini file includes them and defines concrete [Config ...] blocks:
| File | Purpose |
|---|---|
configurations/BlindTx.ini |
Abstract MAC configurations for blind transmission |
configurations/SatDetect.ini |
Abstract MAC configurations for satellite detection mode |
configurations/BandSelection.ini |
Carrier frequency and bandwidth settings |
configurations/Constellations.ini |
Which constellation file to include |
configurations/DevicePositionning.ini |
Terminal deployment (latitude, longitude, radius) |
configurations/Services.ini |
Packet generation rates and service types |
configurations/SimulationLength.ini |
sim-time-limit for each service scenario |
configurations/StatisticRecording.ini |
Which vectors and scalars to record |
Concrete scenarios are assembled by extending multiple abstract configs:
Implementation Details¶
Topology Control (src/Global/Topology_Control/)¶
TopologyControlBase provides the satellite and ground-station registries, link creation/teardown primitives, and the periodic update timer. Subclasses override initTopology() and updateTopology().
ConstellationTopologyControl is the main subclass. On each update cycle it:
- Calls
updateIntraSatelliteLinks()— connects each satellite to the next one in its plane. - Calls
updateInterSatelliteLinks()— connects adjacent planes using the Walker inter-plane spacing parameter (disabled near the poles when usingISLState::DISABLED). - Calls
updateGroundstationLinks()— for each satellite/ground-station pair, computes the elevation usinggetElevationAndDistance()and creates or removes the ground link accordingly. - Calls
updateLoraDevices()— updates the set of satellites currently in view of each terminal; this drives the MAC layer's satellite-detection logic.
The geographic pre-filter (maxGroundRangeDeg) avoids calling the full SGP4 look-angle computation for satellite/station pairs that are obviously too far apart, which significantly reduces CPU time for large constellations.
KiWan MAC (src/Nodes/_10_Terminal/_20_Data_Link/Ter_Dlk_KiWan.h)¶
The MAC maintains a pool of TxServer objects (numConcurrentTx of them). Each server is responsible for one packet and progresses through the states SERVER_FREE → SERVER_SLOT_WAIT → SERVER_DETECTING → SERVER_TRANSMITTING.
When a packet arrives from the application layer, it is assigned to a free server. The server computes the start time of its first slot (aligned to a shared grid base time), schedules eventSlotStart, and waits.
At each slot start the server either transmits immediately (blind mode) or enters the detection sub-state. In detection mode it schedules eventStartDetection, listens for a satellite preamble, and either proceeds to transmission or skips the slot.
The fallback mechanism maintains a sliding window of recent detection outcomes. When the success rate falls below fallbackTargetRatio - fallbackDisableMarginPercent, the server switches to blind transmission for the remaining slots. When the rate recovers above fallbackTargetRatio + fallbackEnableMarginPercent, it re-enables detection (subject to an exponential backoff delay).
Satellite Routing (src/Nodes/_20_Satellite/_30_Network/)¶
Sat_Net_StoreAndForward — handles packets by checking whether any ground station link is currently active. If yes, it forwards the packet directly. If no, it stores it in a Sat_Net_SdrModel FIFO buffer (capacity: maxStoredPackets). When a topology change connects a ground station, a 1 ms forwarding timer paces stored packets out one by one to avoid overloading the packet handler.
Sat_Net_DDRARouting — maintains a cost matrix over the ISL graph (provided by ConstellationTopologyControl::getCostMatrix()). On each topology change it runs Dijkstra from its own node to all destinations. When a link is congested (queue above queueThreshold), it broadcasts a control packet to inform neighbors, which update their local cost matrix and recalculate routes.
Custom Physical Layer (src/Global/Channel/, src/Global/Transceiver/)¶
CustomPHYAnalogModel::computeReceptionPower() computes the received signal power as:
where G_rx(elevation) is evaluated as a·elev² + b·elev + c from the three configurable coefficients.
CustomReceiver then checks the resulting C/N₀ against a threshold (cn0ThresholdForPU) or a CSV lookup table (loadCn0PerMapFile) that maps load and C/N₀ to a packet error rate.
Adding a Custom Antenna Pattern¶
CustomAntenna loads a gain-vs-elevation CSV at initialization. Create the file:
Reference it in the .ini file:
Adding a Custom MAC Scheme¶
- Create a new class inheriting from
Base_MacProtocol(insrc/Global/Base/_20_Data_Link/):
#include "Global/Base/_20_Data_Link/Base_MacProtocol.h"
class MyMac : public Base_MacProtocol {
void handleUpperMessage(cMessage *msg) override;
void handleLowerMessage(cMessage *msg) override;
void handleSelfMessage(cMessage *msg) override;
MacAddress getAddress() override;
};
-
Create the corresponding
.nedfile declaring the module and its parameters. -
Register the module in OMNeT++ by adding
Define_Module(MyMac);in the.ccfile. -
Enable it in the
.inifile:
Adding a Custom Propagation Model¶
Extend CustomPHYPathLoss or LoRaPathLossOulu and override computePathLoss(). Register the new module in a .ned file and enable it:
Batch Simulations¶
Launch all runs for a configuration in parallel:
To check progress:
Parameter count grows combinatorially. Run short tests first to validate configurations before committing to full-length simulations.
Troubleshooting¶
No packets received
- Check that the satellite passes over the terminal during the simulation window. Use the GUI animation to confirm.
- Check the
minimumElevationTermSatthreshold; a value that is too high will reject most passes. - Verify that
NtxandttwDurationare large enough to cover at least one satellite pass.
Simulation crashes on start
- The
results/directory must exist before the simulation runs. Create it:mkdir -p results. - Verify that all
includepaths in the.inifile resolve correctly relative to the scenario folder.
Parameter not taking effect
- OMNeT++ applies parameters in order; later settings override earlier ones. Check that the correct
[Config ...]block is being run. - Use
*.module.param(single star) when targeting a specific level;**.param(double star) matches anywhere.