1. Reference Guide

1.1. Simulation Environment

bin.main.merge_results(outfile, resdir, ext='.h5', sheets=None)[source]

Merge a set of simulation results into a single file containing all of them. The resulting file will be stored as an HDF5 file.

Parameters
  • outfile – File path (str or Path object) where the single file will be located

  • resdir – Directory where the results to merge are located

  • ext – Extension of the files in the resdir. Options are ‘.h5’ (default) or ‘.xlsx’

  • sheets – List with the names of the tables to export. Defaults to [‘sent’, ‘arrived’]. Valid names can be found in the DtnAbstractReport and its subclasses.

bin.main.run_simulation(config=None, profile=False, return_env=False)[source]

Main function to trigger a simulation.

Parameters
  • config (dict) – Configuration structure from a YAML file. Use pyyaml to parse a configuration file.

  • parallel (bool) – If False, the function returns 1) the simulation environment, 2) the results, 3) True/False if errors during the simulation validation process If True, then it only returns True or False (3).

  • profile (bool) – If True, the simulation will be profiled. This is incompatible with parallel=True.

Tip

For parallel execution, the environment and results are not returned because they cannot be pickled. Therefore, the inter-process communication would fail.

Tip

If validate is true, then parallel and profile have no effect

bin.main.run_simulations(input_file, build_inputs, ncpu=1, sheets=None, **kwargs)[source]

Run a batch of simulations.

Parameters
  • input_file – Initial config file path (as str or Path object)

  • build_inputs – Function to build the inputs. It will be called internally as configs = build_inputs(d, **kwargs) where d is the dict obtained from load_configuration_file (i.e. load the YAML into dict and apply parsers to validate it). build_inputs must return a list/tuple of config dictionaries

  • ncpu – Number of CPUs to use. Default is 1 (serial execution)

  • sheets – See sheets parameter in merge_results

  • **kwargs

    Passed to build_inputs

class simulator.environments.DtnSimEnvironment.DtnSimEnviornment(config)[source]

Bases: simulator.environments.DtnAbstractSimEnvironment.SimEnvironment

1.2. Core Classes

class simulator.core.DtnCore.LoadMonitor(*args, **kwargs)[source]

Bases: dict

class simulator.core.DtnCore.Simulable(env)[source]

Bases: object

Base class for all simulable objects. It stores the simulation environment, registers this class, and provides utility methods such as accessing the simulation time, epoch, and configuration. It also provides the disp that displays a message if the logger is not active, or logs it otherwise.

property config

Return the configuration structure

disp(msg, *args)[source]

Display a message in the log or sys.out

property epoch

Return current simulation epoch

property t

Return current simulation time

class simulator.core.DtnCore.TimeCounter(*args, **kwargs)[source]

Bases: dict

Essentially equivalent to defaultdict(int). Re-implemented to provide extra functionality

class simulator.core.DtnSegments.LtpCancelSessionSegment(session_id)[source]

Bases: simulator.core.DtnSegments.LtpSegment

This is not equivalent to the cancel sessions in the LTP specification. It is a convenient way to signal the run_ltp_session of either a DtnOutductLTP or DtnInductLTP that there has been an error during transmission of this block and this session should be cancelled and the bundles in the block sent to re-routers.

class simulator.core.DtnSegments.LtpDataSegment(session_id, offset, length, checkpoint=None, report=None)[source]

Bases: simulator.core.DtnSegments.LtpSegment

An LTP Data Segment (see page 16, rfc 5326)

class simulator.core.DtnSegments.LtpReportAcknowledgementSegment(session_id, report_id)[source]

Bases: simulator.core.DtnSegments.LtpSegment

class simulator.core.DtnSegments.LtpReportSegment(session_id)[source]

Bases: simulator.core.DtnSegments.LtpSegment

An LTP Report Segment (see page 17, rfc 5326)

class simulator.core.DtnSegments.LtpSegment(type, session_id)[source]

Bases: simulator.core.DtnCore.Message

Abstract LTP segments that is then specialized into a Data Segment (DS), Report Segment (RS) or Report Acknowledgement Segment (RA). Other segments such as session cancellation or cancellation ack are not defined here.

class simulator.core.DtnQueue.DtnQueue(env, capacity=inf)[source]

Bases: simulator.core.DtnCore.Simulable

New FIFO queue and (if needed) max capacity. To use it:

  1. Create the queue: q = DtnQueue(env, capacity=10)

  2. Put a new element: yield from q.put(item) or yield env.process(q.put(item))

  3. Get an element: yield from q.get(item) or yield env.process(q.get(item))

Tip

Starting in Python 3.3, you can use the yield from construct. Prior to that, you must use the yield env.process(...) form

Tip

You can also explicitly wait for the non-empty event. This is useful because it allows you to pull an element from the queue if multiple conditions occur. Consider the following code:

1
2
3
4
5
6
7
8
9
# Wait until the queue is not empty or a timeout of 2 seconds expires, whichever
# happens first
yield queue.is_empty() | env.timeout(2)

# If the queue is still empty, you are done
if not queue: return

# If queue is not empty, get data
data = yield from queue.get()

Danger

When putting an element in the queue, if yield from is not used, then nothing will happen, even if the capacity for the queue is set to infinity. So, to put an element in the queue you must yield from it. If you have set capacity to infinity, then this operation will never block, but that is the expected behavior

class simulator.core.DtnPriorityQueue.DtnPriorityQueue(env, capacity=inf)[source]

Bases: simulator.core.DtnCore.Simulable

New FIFO queue with priority (least is more priority) and (if needed) max capacity. To use it:

  1. Create the queue: q = DtnPriorityQueue(env, capacity=10)

  2. Put a new element: yield from q.put(item, priority) or yield env.process(q.put(item, priority))

  3. Get an element: yield from q.get(item) or yield env.process(q.get(item))

Tip

Starting in Python 3.3, you can use the yield from construct. Prior to that, you must use the yield env.process(...) form

Tip

The specified capacity is for the sum over all packets regardless of their priority.

Tip

You can also explicitly way for the non-empty event. This is useful because it allows you to pull an element from the queue if multiple conditions occur. Consider the following code:

1
2
3
4
5
6
7
8
9
# Wait until the queue is not empty or a timeout of 2 seconds expires, whichever
# happens first
yield queue.is_empty() | env.timeout(2)

# If the queue is still empty, you are done
if not queue: return

# If queue is not empty, get data
data = yield from queue.get()

Danger

When putting/getting an element in the queue, if yield from is not used, then nothing will happen, even if the capacity for the queue is set to infinity. If that is the case, the put method will never block, but you still need to yield from it.

popleft(priority, check_empty=True)[source]

Pop from the beginning of the queue. NOTE: This pops from the left, get pops from the right

class simulator.core.DtnLock.DtnLock(env)[source]

Bases: simulator.core.DtnCore.Simulable

This class implements a traditional lock in the Simpy world. In this version, there are not priorities.

Usage examples:

  1. To create the lock: lock = DtnLock(env)

  2. To acquire the lock and block until it is ready: yield lock.acquire()

  3. To release the lock: lock.release()

exception simulator.core.DtnLock.DtnLockException[source]

Bases: Exception

class simulator.core.DtnSemaphore.DtnSemaphore(env, green=False)[source]

Bases: simulator.core.DtnCore.Simulable

Semaphore for a simpy simulation

The semaphore controller can turn the semaphore green/red by simply doing semaphore.turn_green() or semaphore.turn_red()

Users that want to cross the semaphore have to first see if it is green by doing: if semaphore.is_red: yield semaphore.green

Users can only wait until the semaphore turns red by doing if semaphore.is_green: yield semaphore.red

Warning

User must always check the state of the semaphore before yielding to green. If you yield an event that has already that has already succeed, it will crash

class simulator.core.DtnSemaphore.DtnSemaphoreOld(env, green=False)[source]

Bases: simulator.core.DtnCore.Simulable

Semaphore for a simpy simulation

The semaphore controller can turn the semaphore green/red by simply doing semaphore.turn_green() or semaphore.turn_red()

Users that want to cross the semaphore have to first see if the semaphore is green. For that they can do if semaphore.red: yield semaphore.green

Warning

User must always check if the semaphore is red before yielding to green. In other words, the if semaphore.red: part is mandatory, if you yield and the semaphore is green, it will crash

1.3. DTN Nodes

class simulator.nodes.DtnNode.DtnNode(env, nid, props)[source]

Bases: simulator.core.DtnCore.Simulable

forward(bundle)[source]

Put a bundle in the queue of bundles to route. Forward should be used the first time that you route a bundle. For bundles that are being re-routed, use limbo instead

Tip

This function never blocks despite the yield from because the input queue has infinite capacity

forward_manager()[source]

This agent pulls bundles from the node incoming queue for processing. It ensures that this happens one at a time following the order in which they are added to the queue. Note that both new bundles and bundles awaiting re-routers will be directed to the in_queue (see forward vs limbo)

forward_to_outduct(neighbor, rt_record)[source]

Called whenever a bundle successfully exits a DtnNeighborManager

initialize()[source]

Initialize the node. Note that his can only be done after the connections have been created.

limbo(bundle, contact_ids)[source]

Put a bundle in the queue of bundles to route (this bundle is re-routed and thus this is equivalent to ION’s limbo). Add the provided contacts as excluded since you already tried to send this bundle through them

Tip

This function never blocks despite the yield from because the input queue has infinite capacity

process_bundle(bundle, first_time=True)[source]
Process this bundle in the node. This entails:
  1. If this node is the destination, you are done

  2. Otherwise, route the bundle

  3. If no routes are available, drop

  4. Otherwise, put the bundle into one or more neighbor queues to await transmission by the corresponding convergence layer

Parameters
  • bundle – The bundle to forward

  • first_time – True if this is the first time this node sees this bundle

class simulator.nodes.DtnCgrNeighborManager.DtnCgrNeighborManager(env, parent, neighbor)[source]

Bases: simulator.core.DtnCore.Simulable

Implements the following functions:

  1. Open/close queue given the contact plan

  2. Transmit overdue mechanism when a bundle exits

  3. Re-routers of bundles due to overbooking

class simulator.nodes.DtnOverbookeableQueue.DtnLockeablePriorityQueue(env, parent)[source]

Bases: simulator.core.DtnCore.Simulable

Implements the locking mechanism for when a contact is not available

class simulator.nodes.DtnOverbookeableQueue.DtnOverbookeableQueue(env, parent)[source]

Bases: simulator.nodes.DtnOverbookeableQueue.DtnLockeablePriorityQueue

Implements the overbooking mechanism

1.4. DTN Connections

class simulator.connections.DtnAbstractConnection.DtnAbstractConnection(env, cid, orig, dest, props)[source]

Bases: simulator.core.DtnCore.Simulable

propagate(message, dest=None)[source]

Simulate propagation delay

exception simulator.connections.DtnAbstractConnection.TransmissionError[source]

Bases: RuntimeError

class simulator.connections.DtnStaticConnection.DtnStaticConnection(env, cid, orig, dest, props)[source]

Bases: simulator.connections.DtnAbstractConnection.DtnAbstractConnection

set_contact_properties()[source]

Set properties of the current contact

class simulator.connections.DtnScheduledConnection.DtnScheduledConnection(env, cid, orig, dest, props)[source]

Bases: simulator.connections.DtnAbstractConnection.DtnAbstractConnection

A connection propagates a data unit from a transmitting node to a receiving node. It implements the following functionality:

  1. Initialization method to set connection properties such as propagation

  2. A non-blocking transmit method, since multiple data units can be sent at the same time.

  3. A propagation time manager that sets the state of the connection (green vs. red as a function of the contact plan).

Tip

A convergence layer that wants to transmit using a DtnConnection must first do yield self.conn.active.green to ensure the connection is open (see DtnOutductBasic as an example.

Tip

A DtnConnection operates using messages instead of bundles. This is because you could propagate LTP segments, or IP packets.

set_contact_properties(prop)[source]

Set properties of the current contact.

# ================================================================================== # Author: Marc Sanchez Net # Date: 03/14/2019 # Copyright (c) 2019, Jet Propulsion Laboratory. # ==================================================================================

class simulator.connections.DtnScheduledBroadcastConnection.DtnScheduledBroadcastConnection(env, cid, orig, dest, props)[source]

Bases: simulator.connections.DtnAbstractConnection.DtnAbstractConnection

A scheduled connection that, if in view at the same time, propagates data to one or multiple destinations.

This class manages internally all connections from an origin to one or multiple destinations. Therefore, it re-implements __new__ to return an already existing instance if you request an already existing broadcast connection

1.5. DTN Convergence Layers

class simulator.ducts.DtnAbstractDuct.DtnAbstractDuct(env, name, parent, neighbor)[source]

Bases: simulator.core.DtnCore.Simulable

An abstract duct. It operates 2 queues:

  1. in_queue: Queue where all bundles to be sent are placed.

  2. to_limbo: Queue where bundles that fail to be sent by the

    convergence layer are placed. The fail_manager function in this class takes them an puts them in the node’s limbo queue for re-routing.

ack(message)[source]

This is called by a DtnConnection if you transmit something an specify direction equals “ack”. It is more general than LTP, it is a generic mechanism to communicate “backwards” between two ducts (from rx’s induct to tx’s outduct) and no go through the in_queue (that takes message from the upper layer)

do_ack(message)[source]

A duct, by default should not be able to perform ack. See DtnOutductLTP for an example of implementation

abstract radio_error(message)[source]

This function signals an LTP session that it needs to terminate because an error has occurred in the radio. The fail_manager will then be responsible to put the corresponding bundles to the node’s limbo.

abstract property radios

Returns a dictionary with the radios for this duct

send(message)[source]

Pass a message to the duct for transmission This is a non-blocking call.

class simulator.ducts.inducts.DtnInductBasic.DtnInductBasic(env, name, parent, neighbor)[source]

Bases: simulator.ducts.DtnAbstractDuct.DtnAbstractDuct

radio_error(message)[source]

This function signals an LTP session that it needs to terminate because an error has occurred in the radio. The fail_manager will then be responsible to put the corresponding bundles to the node’s limbo.

property radios

Returns a dictionary with the radios for this duct

class simulator.ducts.outducts.DtnOutductBasic.DtnOutductBasic(env, name, parent, neighbor)[source]

Bases: simulator.ducts.DtnAbstractDuct.DtnAbstractDuct

deprecated_run()[source]

DEPRECATED! DOES NOT USE A RADIO AS A SHARED RESOURCE!

radio_error(message)[source]

This function signals an LTP session that it needs to terminate because an error has occurred in the radio. The fail_manager will then be responsible to put the corresponding bundles to the node’s limbo.

property radios

Returns a dictionary with the radios for this duct

run()[source]

Send through a BasicRadio that is shared by all outducts

class simulator.ducts.DtnAbstractDuctLTP.DtnAbstractDuctLTP(env, name, parent, neighbor)[source]

Bases: simulator.ducts.DtnAbstractDuct.DtnAbstractDuct

Abstract LTP duct. It is subclassed by both DtnOutductLTP and DtnInductLTP to provide the following necessary common functionality:

  1. Requirement to re-implement initialize_ltp_session, finalize_ltp_session and run_ltp_session.

  2. A radio to send data through a connection. The type of radio is configurable by the user through the .yaml file.

  3. A fail_manager that will redirect bundles that are not successfully delivered by the radio to the DTN node limbo for re-rerouting

The core concept of LTP is a session, i.e. a process that will take care of sending a block of bundles from the outduct to induct. All re-tx required for a given block are handled by the same session. At any point in time, there can be any number of LTP sessions active since the underlying link can have long delays and therefore you do not want to wait for a session to end before starting another one.

The LTP outduct creates a new session every time a new block of bundles is created. In contrast, an LTP induct creates a new session every time a new LTP Data Segment with a session_id not recognized is received. At the outduct, a session ends when all the data has been sent. At the induct, a session ends when the RA for the last RS has been received.

Critical to this process is having unique session ids. For this purpose, we utilize the hash function available in Python. Note that this could result in non-unique ids due to possible hash collisions. This is mitigated by using the hash of the hex of the memory address of the block if a hash collision is detected. If that method fails, then an exception is raised.

cancel_ltp_session(session_id)[source]

When a radio error occurs, cancel the LTP session that was involved in the transmission of this block. This will be caught by the run_ltp_session in DtnOutductLTP and DtnInductLTP.

Parameters

session_id – Session to cancel

property ltp_sessions

List the current active LTP sessions

property num_sessions

Returns the number of LTP session active

radio_error(message)[source]

Called from DtnAbstractRadio to signal that an error has occurred during the transmission of a message.

Parameters

message (Message) – The message that cause the error

property radios

Returns a dictionary with the radios for this duct

class simulator.ducts.inducts.DtnInductLTP.DtnInductLTP(env, name, parent, neighbor)[source]

Bases: simulator.ducts.DtnAbstractDuctLTP.DtnAbstractDuctLTP

An LTP induct

run_ltp_session(session_id)[source]

Wait for segments to reconstruct a block. If a checkpoint is created, respond with a Report Segment

class simulator.ducts.outducts.DtnOutductLTP.DtnOutductLTP(env, name, parent, neighbor)[source]

Bases: simulator.ducts.DtnAbstractDuctLTP.DtnAbstractDuctLTP

An LTP Outduct

do_ack(segment)[source]

Re-implement to enable reception of Report Segments

get_data_segments(session_id, size, report_id=None)[source]

Create new segments to send size bytes of data from the block bid. This function assumes deferred-acked mode of operations, so a checkpoint is only defined for the last segment.

Parameters
  • session_id – LTP session id (one session per block)

  • size – Size in bytes of the block

Return tuple

(List of segments to transmit, checkpoint segment)

initialize(peer, *args, agg_size_limit=1000000000.0, agg_time_limit=1000000000.0, segment_size=8000000.0, checkpoint_timer=10000000000.0, **kwargs)[source]

Units of inputs are bits and seconds

run()[source]

Creates an LTP block from a set of bundles and sends them

class simulator.ducts.DtnAbstractDuctMBLTP.DtnAbstractDuctMBLTP(env, name, parent, neighbor)[source]

Bases: simulator.ducts.DtnAbstractDuctLTP.DtnAbstractDuctLTP

An abstract Multiband LTP duct. It is subclassed by both DtnOuductMBLTP and DtnInductMBLTP. It extends the capabilities of DtnAbstractDuctLTP by allowing:

  1. Multiple LTP engines that have independent LTP configuration parameters

  2. Mutliple radios, one per band, with its associated queues, data rates and BERs

The generation of unique session ids for a multiband LTP duct is different from an LTP duct. For the latter, you use a hash based function (see DtnAbstractDuctLTP). However, for the multiband case you need the session ids to be sequential and therefore we use a counter object.

The need to have sequential session ids comes from the fact that a segment can arrive at an induct for a session that has already succeeded and is no longer available. Therefore, we use this sequential property to detect this corner case and not re-open a session for a block that has already been delivered to the DTN node.

get_session_id(block)[source]

Utilize a global session counter. This is needed because session ids must be sequential

property radios

Returns a dictionary with the radios for this duct

class simulator.ducts.inducts.DtnInductMBLTP.DtnInductMBLTP(env, name, parent, neighbor)[source]

Bases: simulator.ducts.DtnAbstractDuctMBLTP.DtnAbstractDuctMBLTP

run_ltp_session(session_id)[source]

Wait for segments to reconstruct a block. If a checkpoint is created, respond with a Report Segment

send_through_all(segment)[source]

Send a copy of this segment through all the bands

class simulator.ducts.outducts.DtnOutductMBLTP.DtnOutductMBLTP(env, name, parent, neighbor)[source]

Bases: simulator.ducts.DtnAbstractDuctMBLTP.DtnAbstractDuctMBLTP

do_ack(segment)[source]

Re-implement to enable reception of Report Segments

run()[source]

Creates an LTP block from a set of bundles and sends them. This is the same as for a normal LTP outduct

send_through_all(segment)[source]

Send a copy of this segment through all the frequency bands available

Warning

A new deep copy of the segment is created for each frequency band.

1.6. DTN Radios

class simulator.radios.DtnAbstractRadio.DtnAbstractRadio(env, parent, shared=True)[source]

Bases: simulator.core.DtnCore.Simulable

An abstract radio to transmit messages through a connection

initialize(*args, **kwargs)[source]

Initialize the radio

put(*args, **kwargs)[source]

Put a message in the radio to transmit. This is a non-blocking call

class simulator.radios.DtnBasicRadio.DtnBasicRadio(env, parent, shared=True)[source]

Bases: simulator.radios.DtnAbstractRadio.DtnAbstractRadio

initialize(rate=0, BER=0, J_bit=0, **kwargs)[source]

Initialize the radio

send_through_connection(message, conn, peer, direction)[source]

Send a message through a connection

Parameters
  • message (Message) – The message to send

  • conn – The connection to send the message through

  • peer – The peer duct that will receive the message

  • direction (str) – ‘fwd’ vs. ‘ack’. By default ‘fwd’, use ‘ack’ for the acknowledgement messages of protocols like LTP (from dest to origin).

class simulator.radios.DtnCodedRadio.DtnCodedRadio(env, parent, shared=True)[source]

Bases: simulator.radios.DtnBasicRadio.DtnBasicRadio

Simulate a radio with a given coding scheme. Note that in reality frames are not generated, only the equivalent BER to achieve the specified FER is calculated given the frame size, code rate and mesage size.

This radio is only an approximation. If a message is very short (e.g. 10 bytes), a real radio would aggregate multiple messages into a frame prior to sending anything. This is not modeled in this case, the very short message is sent immediately as is.

initialize(rate=0, FER=0, frame_size=0, code_rate=0, J_bit=0, **kwargs)[source]

Initialize the radio

send_through_connection(message, conn, peer, direction)[source]

Send a message through a connection

Parameters
  • message (Message) – The message to send

  • conn – The connection to send the message through

  • peer – The peer duct that will receive the message

  • direction (str) – ‘fwd’ vs. ‘ack’. By default ‘fwd’, use ‘ack’ for the acknowledgement messages of protocols like LTP (from dest to origin).

# ================================================================================== # Author: Marc Sanchez Net # Date: 03/24/2019 # Copyright (c) 2019, Jet Propulsion Laboratory. # ==================================================================================

class simulator.radios.DtnVariableRadio.DtnVariableRadio(env, parent, shared=True)[source]

Bases: simulator.radios.DtnBasicRadio.DtnBasicRadio

initialize(datarate_file=None, **kwargs)[source]

Initialize the radio

1.7. DTN Routers

class simulator.routers.DtnAbstractRouter.DtnAbstractRouter(env, parent)[source]

Bases: simulator.core.DtnCore.Simulable

An abstract router

find_bundle_priority(bundle)[source]

0=critical, 256=bulk

abstract find_routes(bundle, first_time, **kwargs)[source]

This function is called by the DtnNode to route a bundle

Parameters
  • bundle – Bundle to route

  • first_time – True if this is the first time this is routed

  • kwargs – Arguments specific to each router

Returns

Tuple with the following elements (in this order):

  1. List of RtRecords to use when forwarding this bundle. The contact within the RtRecord will be used to infer which neighbor to forward this bundle towards. If none, return empty list ([]).

  2. List of cids (i.e. list of integers) that indicate which contacts should not be used to forward this bundle. They are provided to the node’s limbo function that adds them to the bundle excluded node. If none, return empty list ([]).

Tip

If the return value of this function is ([], []), then the bundle will be dropped.

class simulator.routers.DtnStaticRouter.DtnStaticRouter(env, parent)[source]

Bases: simulator.routers.DtnAbstractRouter.DtnAbstractRouter

find_routes(bundle, first_time, **kwargs)[source]

This function is called by the DtnNode to route a bundle

Parameters
  • bundle – Bundle to route

  • first_time – True if this is the first time this is routed

  • kwargs – Arguments specific to each router

Returns

Tuple with the following elements (in this order):

  1. List of RtRecords to use when forwarding this bundle. The contact within the RtRecord will be used to infer which neighbor to forward this bundle towards. If none, return empty list ([]).

  2. List of cids (i.e. list of integers) that indicate which contacts should not be used to forward this bundle. They are provided to the node’s limbo function that adds them to the bundle excluded node. If none, return empty list ([]).

Tip

If the return value of this function is ([], []), then the bundle will be dropped.

class simulator.routers.DtnLookupRouter.DtnLookupRouter(env, parent)[source]

Bases: simulator.routers.DtnAbstractRouter.DtnAbstractRouter

Class that implements a router that looks up the route to use based on a pre-computed route schedule. This route schedule is provided as an excel file typically and can be computed using different methods (BFS, CGR+anchoring, CGR+Yen K, etc.)

find_prox_node_list(bundle, opts)[source]

Find all neighbors to send the bundle to. Create a CgrRecord for each option Performs step 2 of find_routes.

find_routes(bundle, first_time, **kwargs)[source]

Find a route for a bundle. This is comprised of four steps:

  1. Building a route list

  2. Down-selecting the route list to find the best option for each neighbor

  3. Selecting the neighbor(s) depending on criticality

  4. Try the route to make sure that you will not miss any future contacts given the current time and backlog for this neighbor. If so, try a re-routers event

select_neighbor_critical_bundle(rt_records)[source]

Select the next neighbors to send a critical bundle to. Performs step 3 of find_routes.

select_neighbor_standard_bundle(rt_records)[source]

Select the next neighbor to send a standard bundle to. Performs step 3 of find_routes.

class simulator.routers.DtnCgrBasicRouter.DtnCgrBasicRouter(env, parent)[source]

Bases: simulator.routers.DtnAbstractRouter.DtnAbstractRouter

Class that implements a basic CGR router. No anchoring mechanism is provided, just the absolute best route is provided. No capacity calculations are provided either

find_best_route(orig, dest, bundle_size, visited, excluded)[source]

Implementation of the Dijkstra algorithm over the contact graph

find_routes(bundle, first_time, **kwargs)[source]

This function is called by the DtnNode to route a bundle

Parameters
  • bundle – Bundle to route

  • first_time – True if this is the first time this is routed

  • kwargs – Arguments specific to each router

Returns

Tuple with the following elements (in this order):

  1. List of RtRecords to use when forwarding this bundle. The contact within the RtRecord will be used to infer which neighbor to forward this bundle towards. If none, return empty list ([]).

  2. List of cids (i.e. list of integers) that indicate which contacts should not be used to forward this bundle. They are provided to the node’s limbo function that adds them to the bundle excluded node. If none, return empty list ([]).

Tip

If the return value of this function is ([], []), then the bundle will be dropped.

1.8. DTN Bundle Generators

class simulator.generators.DtnAbstractGenerator.DtnAbstractGenerator(env, parent, props)[source]

Bases: simulator.core.DtnCore.Simulable

Abstract class for all generators. To subclass it, implement

  1. The initialize method. Typically, use self.props to initialize this generator and then call self.env.process(self.run())

  2. The run method should create Bundles and then call self.parent.forward(bundle) Also, call the self.monitor_new_bundle to record the generation of bundles

generated_data_vol()[source]

Return the total data volume in [bits] generated during the simulation

list_bundles()[source]

Return a pandas.DataFrame index by (bid, cid) that describes all bundles sent by this generator

Tip

To see what information is available per bundle, look at DtnBundle.Bundle.export_vars

abstract predicted_data_vol()[source]

The predicted data volume [bits] that this generator should generate over the course of the simulation

class simulator.generators.DtnFileGenerator.DtnFileGenerator(env, parent, props)[source]

Bases: simulator.generators.DtnAbstractGenerator.DtnAbstractGenerator

predicted_data_vol()[source]

The predicted data volume [bits] that this generator should generate over the course of the simulation

class simulator.generators.DtnFileBroadcaster.DtnFileBroadcaster(env, parent, props)[source]

Bases: simulator.generators.DtnAbstractGenerator.DtnAbstractGenerator

predicted_data_vol()[source]

The predicted data volume [bits] that this generator should generate over the course of the simulation

class simulator.generators.DtnConstantBitRateGenerator.DtnConstantBitRateGenerator(env, parent, props)[source]

Bases: simulator.generators.DtnAbstractGenerator.DtnAbstractGenerator

predicted_data_vol()[source]

The predicted data volume [bits] that this generator should generate over the course of the simulation

class simulator.generators.DtnMarkovBundleGenerator.DtnMarkovBundleGenerator(env, parent, props)[source]

Bases: simulator.generators.DtnAbstractGenerator.DtnAbstractGenerator

predicted_data_vol()[source]

Predicted data volume in [bits]

1.9. DTN Duct Selectors

class simulator.selectors.DtnAbstractDuctSelector.DtnAbstractDuctSelector(env, parent)[source]

Bases: simulator.core.DtnCore.Simulable

An abstract duct selector.

class simulator.selectors.DtnDefaultSelector.DtnDefaultSelector(env, parent)[source]

Bases: simulator.selectors.DtnAbstractDuctSelector.DtnAbstractDuctSelector

The default duct selector. It can only be used for the connection that only have one duct running over them.

Warning

If you try to use this selector in a connection with more than one outduct, an exception will be raised

class simulator.selectors.DtnBundleCriticalitySelector.DtnBandSelectorOld(env, parent)[source]

Bases: simulator.selectors.DtnAbstractDuctSelector.DtnAbstractDuctSelector

class simulator.selectors.DtnBundleCriticalitySelector.DtnBundleCriticalitySelector(env, parent)[source]

Bases: simulator.selectors.DtnAbstractDuctSelector.DtnAbstractDuctSelector

This outduct selector can be used for connections with 2 or 3 simultaneous frequency bands. It behaves as follows:

  1. If 2 frequency bands, they must be named ‘X’ and ‘Ka’. All critical data is sent over the X-band link and the rest over the Ka-band link.

  2. If 3 frequency bands, they must be named ‘X’, ‘Ka’ and ‘opt’. All critical data is sent over the X-band link. Ka-band is used for non-critical data except for “PAO HD Video”, “Sci HD Video” and “Science”, which are sent over the optical link.

class simulator.selectors.DtnDataTypeSelector.DtnDataTypeSelector(env, parent)[source]

Bases: simulator.selectors.DtnAbstractDuctSelector.DtnAbstractDuctSelector

This outduct selector can be used for connections with 2 or 3 simultaneous frequency bands. It behaves as follows:

  1. If 2 frequency bands, they must be named ‘X’ and ‘Ka’. Biomedical and voice data are sent over the X-band link, while the rest goes through Ka-band

  2. If 3 frequency bands, they must be named ‘X’, ‘Ka’ and ‘opt’. Biomedical and voice data are sent over the X-band link. Ka-band is used for non-critical data except for “PAO HD Video”, “Sci HD Video” and “Science”, which are sent over the optical link.

1.10. DTN Reports

class simulator.reports.DtnAbstractReport.DtnAbstractReport(env)[source]

Bases: object

Alias name for this report. When saved, this alias will be used as the name of the report.

abstract collect_data()[source]

Collect the data that needs to be exported by this report :return: pd.DataFrame: Data frame to be exported

simulator.reports.DtnAbstractReport.concat_dfs(data, new_col_names)[source]

Consolidate a dictionary of data frames into one data frame

Parameters
  • data (dict) – {a: df for a, b: df for b}

  • new_col_names (str/tuple) – The name for the column [a, b, …] or columns

Returns

Data frame with numeric index

class simulator.reports.DtnArrivedBundlesReport.DtnArrivedBundlesReport(env)[source]

Bases: simulator.reports.DtnAbstractReport.DtnAbstractReport

collect_data()[source]

Collect the data that needs to be exported by this report :return: pd.DataFrame: Data frame to be exported

class simulator.reports.DtnConnLostBundlesReport.DtnConnLostBundlesReport(env)[source]

Bases: simulator.reports.DtnAbstractReport.DtnAbstractReport

collect_data()[source]

Collect the data that needs to be exported by this report :return: pd.DataFrame: Data frame to be exported

class simulator.reports.DtnConnSentBundlesReport.DtnConnSentBundlesReport(env)[source]

Bases: simulator.reports.DtnAbstractReport.DtnAbstractReport

collect_data()[source]

Collect the data that needs to be exported by this report :return: pd.DataFrame: Data frame to be exported

class simulator.reports.DtnDroppedBundlesReport.DtnDroppedBundlesReport(env)[source]

Bases: simulator.reports.DtnAbstractReport.DtnAbstractReport

collect_data()[source]

Collect the data that needs to be exported by this report :return: pd.DataFrame: Data frame to be exported

class simulator.reports.DtnEnergyReport.DtnEnergyReport(env)[source]

Bases: simulator.reports.DtnAbstractReport.DtnAbstractReport

collect_data()[source]

Collect the data that needs to be exported by this report :return: pd.DataFrame: Data frame to be exported

class simulator.reports.DtnInOutductBundlesReport.DtnInOutductBundlesReport(env)[source]

Bases: simulator.reports.DtnAbstractReport.DtnAbstractReport

collect_data()[source]

Collect the data that needs to be exported by this report :return: pd.DataFrame: Data frame to be exported

class simulator.reports.DtnSentBundlesReport.DtnSentBundlesReport(env)[source]

Bases: simulator.reports.DtnAbstractReport.DtnAbstractReport

collect_data()[source]

Collect the data that needs to be exported by this report :return: pd.DataFrame: Data frame to be exported

class simulator.reports.DtnStoredBundlesReport.DtnStoredBundlesReport(env)[source]

Bases: simulator.reports.DtnAbstractReport.DtnAbstractReport

collect_data()[source]

Collect the data that needs to be exported by this report :return: pd.DataFrame: Data frame to be exported

1.11. DTN Utils

class simulator.utils.DtnArgumentParser.DtnArgumentParser(*args, **kwargs)[source]

Bases: argparse.ArgumentParser

Subclass of Python’s native ArgumentParser that incorporates a function to display warning messages related to the arguments.

error(message: string)[source]

Prints a usage message incorporating the message to stderr and exits.

If you override this in a subclass, it should not return – it should either exit or raise an exception.

warning(message)[source]

Display a warning message related to one of the arguments. The format is consistent with that of errors

Parameters

message (str) – Warning message to display

simulator.utils.DtnArgumentParser.get_argument_parser()[source]

Parse the command-line arguments for this program

Return ArchNetArgumentParser

The argument parser

simulator.utils.DtnArgumentParser.process_arguments(args=None)[source]

Process the arguments of the application and run ArchNet in batch or GUI mode depending on what is specified

Parameters

or dict (None) –

simulator.utils.DtnIO.prepare_contact_plan(orig, dest, cp)[source]

Prepare a contact plan for a connection by filtering out not relevant contacts

Parameters
  • orig – Name of the origin node

  • dest – Name of the destination node

  • cp – Contact plan in dataframe format

Returns

Filtered contact plan as a dataframe

class simulator.utils.DtnTesting.PriorityTransmitter(env, fun, rate=10, prob_blk=0.5, blocking=True)[source]

Bases: simulator.core.DtnCore.Simulable

Basic transmitter for testing. Bundle are just integers to facilitate unique id and counting

class simulator.utils.DtnTesting.Receiver(env)[source]

Bases: simulator.core.DtnCore.Simulable

get(neighbor, bundle)[source]

Just to not break compatibility in DtnNeighborManager

class simulator.utils.DtnTesting.Transmitter(env, fun, rate=10, blocking=True)[source]

Bases: simulator.core.DtnCore.Simulable

Basic transmitter for testing. Bundle are just integers to facilitate unique id and counting

simulator.utils.DtnTesting.random() → x in the interval [0, 1).
simulator.utils.DtnUtils.load_class_dynamically(class_package, module_name, class_name=None)[source]

Load a class dynamically.

Parameters
  • class_package (str) – The entire class package (e.g. simulator.utils)

  • module_name (str) – The module name (e.g. DtnUtils)

  • class_name (str) – The class name. If not provided, assumes same as module_name

..code:

clazz  = find_class_dynamically('simulator.core', 'DtnCore', 'Simulable')
bundle = clazz(*args, **kwargs)

Bundle is now an instance of the class simulator.core.DtnCore.Bundle

simulator.utils.DtnUtils.rnd_time(t0, asstring=True, tfmt='%d-%b-%Y %H:%M:%S %Z')[source]

Return a random date t1 such that t1 in [t0 ; t0 + 1 year]

Parameters

t0 (str/Timestamp) – Reference time

Return str/Timestamp

Random time