Skip to content

Designing your Scenario

Bruce Allen edited this page Jun 23, 2020 · 33 revisions

Your scenario model consists of your network topology and the messages that communicate across it. To define your scenario, identify the ROS2 messages that flow between robots and the configuration of robot network. Then construct your scenario model by creating your communication and network components:

CSV Scenario Communication Setup

We model communication flows between robots by defining ROS2 messages that flow between network nodes using the DDS communication protocol. Communication is sent from publishers and is received by registered subscribers. A publication consists of the publisher's role, the subscription topic name, the size and frequency of the publication of the publication, and QoS properties of the publication. A subscription consists of the subscriber's role, the subscription topic name, and QoS properties of the subscription.

We define communication flows in two steps to reflect the role-based organization of swarms. First we define role-based publications and subscriptions that our Scenario will model. Then we assign robots to these roles, where a given robot runs on a specific network node.

These publisher, subscriber, and robot properties are defined using comma-separated (CSV) entries in Scenario files as follows, where properties consist of role-based publication definitions, role-based subscription definitions, and the names of robots and their role:

  • Publisher - Define publisher subscriptions by role. Also defines the QoS policy (defined below) for publishing the subscription. Publisher entries have this format:

    Publisher, Role, Subscription, Frequency, Size, History, Depth, Reliability, Durability
    

    This example defines a publisher role for a red_team robot where odometry messages are simulated by transmitting 10 bytes at 500 Hz using a QoS policy of keep_last, 0, reliable, volatile:

    Publisher, red_team, odometry, 10, 500, keep_last, 0, reliable, volatile
    
  • Subscriber - Define subscriber subscriptions by role. Also defines the QoS policy (defined below) for the subscription. Subscriber entries have this format:

    Subscriber, Role, Subscription, History, Depth, Reliability, Durability
    

    This example defines a subscriber role for Ground Station GS "robots" for receiving odometry data using a QoS policy of keep_last, 0, reliable, volatile:

    Subscriber, GS, odometry, keep_last, 0, reliable, volatile
    
  • Robot - Define robot names and the role the robots will take:

    Robot, Name, Role
    

    This example assigns robot R1 to the GS role:

    Robot, R1, GS
    

QoS Policy

The QoS policy consists of settings for History, Depth, Reliability, and Durability, see https://index.ros.org/doc/ros2/Concepts/About-Quality-of-Service-Settings/. Here is the QoS syntax for scenario files:

  • History controls history depth. Modes are keep_all and keep_last. For keep_last, use Depth.
  • Depth defines history depth when History mode is keep_last.
  • Reliability regulates reliability of data received. Modes are reliable and best_effort. For reliable, DDS will track transmissions and attempt to repair lost transmissions. For best_effort, DDS will not track transmissions and will not attempt to repair lost transmissions.
  • Durability provides durability by transmitting previously transmitted data to readers that join late. Modes are transient_local and volatile.

Network Property setup

Several GUI tools are available for defining complex network configurations, https://dl.acm.org/doi/10.5555/2685617.2685639, https://ieeexplore.ieee.org/document/7148414?reload=true&arnumber=7148414. We describe working with the miniedit tool because it is packaged with mininet-wifi.

Here are the steps for building the network topology for your Scenario using miniedit:

  • Start the miniedit GUI network editor:

    ~/gits/mininet-wifi/examples/miniedit.py
    
  • Build your scenario's network configuration using the GUI.

  • Save the network configuration as a Python script by opening the File menu and selecting Export level 2 script.

  • Make the saved script compatible with the mininet_runner tool:

    • Open the script with an editor.

    • Comment out the lines at the bottom of function myNetwork which start the command line interpreter and then stop the network:

      # CLI(net)
      # net.stop()
      

      and add this line in its place to return the network object that gets created:

      return net
      
    • While here, you might also wish to rename nodes, change node positions, or rearrange lines to make the code more readable.

    • Save your modified Python script.

Examples

Example1

Define Scenario messages

Here we define a Ground station (GS) role that publishes collected odometry information to each red_team robot:

# Publisher, Role, Subscription, Frequency, Size, History, Depth, Reliability, Durability
Publisher, GS, odometry, 10, 500, keep_last, 0, reliable, volatile

# Subscribers, Role, Subscription, History, Depth, Reliability, Durability
Subscriber, red_team, odometry, keep_last, 0, reliable, volatile

# Robot, Name, Role
Robot, R1, GS
Robot, R2, red_team
Robot, R3, red_team
Robot, R4, red_team
Robot, R5, red_team

Define the Scenario network topology

Using miniedit, create a central station with four stations around it and define ad-hoc links between each:

  • Click the station (laptop) icon
  • Click the five places to drop three stations. You may need to adjust their positions later so they are in range of each other.
  • Click the link (line) icon
  • For each station, click down on one station, drag the cursor, and release the click on another station to connect stations with a link.
  • Click the selection (arrow) icon
  • Right click each link to define the connection type as ad-hoc and to set the source and destination properties for wlan0.
  • Save the network as a Python script by selecting the File menu and selecting Export level 2 script.

The view might look as follows:

Here is the saved file:

#!/usr/bin/python

from mininet.log import setLogLevel, info
from mn_wifi.net import Mininet_wifi
from mn_wifi.node import Station, OVSKernelAP
from mn_wifi.cli import CLI
from mn_wifi.link import wmediumd, adhoc
from mn_wifi.wmediumdConnector import interference
from subprocess import call


def myNetwork():

    net = Mininet_wifi(topo=None,
                       build=False,
                       link=wmediumd,
                       wmediumd_mode=interference,
                       ipBase='10.0.0.0/8')

    info( '*** Adding controller\n' )
    info( '*** Add switches/APs\n')

    info( '*** Add hosts/stations\n')
    sta3 = net.addStation('sta3', ip='10.0.0.3',
                           position='376.0,104.0,0')
    sta5 = net.addStation('sta5', ip='10.0.0.5',
                           position='384.0,373.0,0')
    sta4 = net.addStation('sta4', ip='10.0.0.4',
                           position='204.0,235.0,0')
    sta1 = net.addStation('sta1', ip='10.0.0.1',
                           position='379.0,239.0,0')
    sta2 = net.addStation('sta2', ip='10.0.0.2',
                           position='534.0,235.0,0')

    info("*** Configuring Propagation Model\n")
    net.setPropagationModel(model="logDistance", exp=3)

    info("*** Configuring wifi nodes\n")
    net.configureWifiNodes()

    info( '*** Add links\n')
    net.addLink(sta1, cls=adhoc, ssid='new-ssid', mode='g', channel=1, intf='sta1-wlan0')
    net.addLink(sta2, cls=adhoc, ssid='new-ssid', mode='g', channel=1, intf='sta2-wlan0')
    net.addLink(sta1, cls=adhoc, ssid='new-ssid', mode='g', channel=1, intf='sta1-wlan0')
    net.addLink(sta3, cls=adhoc, ssid='new-ssid', mode='g', channel=1, intf='sta3-wlan0')
    net.addLink(sta1, cls=adhoc, ssid='new-ssid', mode='g', channel=1, intf='sta1-wlan0')
    net.addLink(sta4, cls=adhoc, ssid='new-ssid', mode='g', channel=1, intf='sta4-wlan0')
    net.addLink(sta1, cls=adhoc, ssid='new-ssid', mode='g', channel=1, intf='sta1-wlan0')
    net.addLink(sta5, cls=adhoc, ssid='new-ssid', mode='g', channel=1, intf='sta5-wlan0')

    net.plotGraph(max_x=1000, max_y=1000)

    info( '*** Starting network\n')
    net.build()
    info( '*** Starting controllers\n')
    for controller in net.controllers:
        controller.start()

    info( '*** Starting switches/APs\n')

    info( '*** Post configure nodes\n')

    CLI(net)
    net.stop()


if __name__ == '__main__':
    setLogLevel( 'info' )
    myNetwork()

Edit the file to make it compatible with the mininet runner. Here, we additionally rename station names to robot names, change coordinates of stations, change the plot size, organize the code to be more readable, and remove redundancy:

#!/usr/bin/python

from mininet.log import setLogLevel, info
from mn_wifi.net import Mininet_wifi
from mn_wifi.node import Station, OVSKernelAP
from mn_wifi.cli import CLI
from mn_wifi.link import wmediumd, adhoc
from mn_wifi.wmediumdConnector import interference
from subprocess import call


def myNetwork():

    net = Mininet_wifi(topo=None,
                       build=False,
                       link=wmediumd,
                       wmediumd_mode=interference,
                       ipBase='10.0.0.0/8')

    info( '*** Adding controller\n' )
    info( '*** Add switches/APs\n')

    info( '*** Add hosts/stations\n')
    R1 = net.addStation('R1', ip='10.0.0.1', position='0.0,0.0,0')
    R2 = net.addStation('R2', ip='10.0.0.2', position='1.0,0.0,0')
    R3 = net.addStation('R3', ip='10.0.0.3', position='0.0,1.0,0')
    R4 = net.addStation('R4', ip='10.0.0.4', position='-1.0,0.0,0')
    R5 = net.addStation('R5', ip='10.0.0.5', position='0.0,-1.0,0')

    info("*** Configuring Propagation Model\n")
    net.setPropagationModel(model="logDistance", exp=3)

    info("*** Configuring wifi nodes\n")
    net.configureWifiNodes()

    info( '*** Add links\n')
    net.addLink(R1, cls=adhoc, ssid='new-ssid', mode='g', channel=1, intf='R1-wlan0')
    net.addLink(R2, cls=adhoc, ssid='new-ssid', mode='g', channel=1, intf='R2-wlan0')
    net.addLink(R3, cls=adhoc, ssid='new-ssid', mode='g', channel=1, intf='R3-wlan0')
    net.addLink(R4, cls=adhoc, ssid='new-ssid', mode='g', channel=1, intf='R4-wlan0')
    net.addLink(R5, cls=adhoc, ssid='new-ssid', mode='g', channel=1, intf='R5-wlan0')

    net.plotGraph(min_x=-2, min_y=-2, max_x=2, max_y=2)

    info( '*** Starting network\n')
    net.build()
    info( '*** Starting controllers\n')
    for controller in net.controllers:
        controller.start()

    info( '*** Starting switches/APs\n')

    info( '*** Post configure nodes\n')

#    CLI(net)
#    net.stop()

    return net


if __name__ == '__main__':
    setLogLevel( 'info' )
    myNetwork()

Run the scenario:

Run the example1 scenario using the mininet runner, specifying the example1.csv scenario message configuration file, the example1.py network topology setup script, and the log output file:

cd ~/gits/mininet_testbed
./mininet_runner.bash scenarios/example1.csv scenarios/example1.py _mininet_test_outfile

Plot results:

Plot the results of the example1 scenario simulation:

cd ~/gits/mininet_testbed
./plot_analytics.py _mininet_test_outfile five_reliable -w five_reliable

The example1 scenario is described further in Demos.

OLD

Content below is old.

Using CSV Scenario entries

In the future this option may be removed because everything here can be done with miniedit and having this option adds complexity.

For ad-hoc networks, we can define stations, links, radio propagation, robot mobility and some other properties directly within the CSV file instead of using miniedit by adding CSV entries as described here. These entries are ignored when using GUI-generated code:

  • Stations - Station definitions for each robot such as location for fixed-location stations:

    Station, Name, param=value, ...
    

    For example settings, see addStation in the examples in the mininet-wifi repository.

  • Links - Radio link information for the network link on each robot:

    Link, Name, param=value, ...
    

    For example settings, see addLink in the examples in the mininet-wifi repository.

  • Propagation Model - The radio signal propagation model:

    Propagation Model, param=value, ...
    

    See setPropagationModel in the examples in the mininet-wifi repository.

  • Mobility Model - The mobility model:

    Mobility Model, param=value, ...
    

    See setMobilityModel in the examples in the mininet-wifi repository.

    Alternative to Mobility Model, we can define start and stop points for individual robots using Start Mobility, Mobility, and Stop Mobility, see example usage in the mininet-wifi repository.

  • Plot Graph - How to plot the real-time mobility graph:

    Plot Graph, param=value, ...
    

    See plotGraph in the examples in the mininet-wifi repository.

Examples

CSV-defined communication with GUI-built ad-hoc network

Publisher and subscriber roles are defined for ground station GS and team red_team for robots sta1, sta2, and sta3 in these lines of scenarios/adhoc.csv:

# Publisher, Role, Subscription, Frequency, Size, History, Depth, Reliability, Durability
Publisher, red_team, odometry, 10, 500, keep_last, 0, best_effort, volatile

# Subscriber, Role, Subscription, History, Depth, Reliability, Durability
Subscriber, GS, odometry, keep_last, 0, best_effort, volatile

# Robot, Name, Role
Robot, sta1, GS
Robot, sta2, red_team
Robot, sta3, red_team

File scenarios/adhoc.py was created as shown above, with station coordinates modified so the stations are in range.

This is then run by typing the following:

cd ~/gits/mininet_testbed
./mininet_runner.bash -s scenarios/adhoc.py scenarios/adhoc.csv adhoc_output_log

where the -s option instructs mininet_runner.py to only use publisher, subscriber, and robot definitions and to take network setup instructions from the Python setup script.

Once enough data is collected, analysis may be performed by typing

cd ~/gits/mininet_testbed
./plot_analytics.py adhoc_output_log adhoc_example

CSV-defined communication and ad-hoc network

In the future this option may be removed because everything here can be done with miniedit and having this option adds complexity.

Because the ad-hoc network only has station nodes, it can be defined completely in CSV file scenarios/adhoc.csv:

# Publisher, Role, Subscription, Frequency, Size, History, Depth, Reliability, Durability
Publisher, red_team, odometry, 10, 500, keep_last, 0, best_effort, volatile

# Subscriber, Role, Subscription, History, Depth, Reliability, Durability
Subscriber, GS, odometry, keep_last, 0, best_effort, volatile

# Robot, Name, Role
Robot, sta1, GS
Robot, sta2, red_team
Robot, sta3, red_team

# Station, Name, param=value, ...
Station, sta1, position=10;10;0, range=100
Station, sta2, position=50;10;0, range=100
Station, sta3, position=90;10;0, range=100

# Link, Name, param=value, ...
Link, sta1, cls=adhoc, intf=sta1-wlan0, ssid=adhocNet, mode=g, channel=5, ht_cap=HT40+
Link, sta2, cls=adhoc, intf=sta2-wlan0, ssid=adhocNet, mode=g, channel=5
Link, sta3, cls=adhoc, intf=sta3-wlan0, ssid=adhocNet, mode=g, channel=5, ht_cap=HT40+

Propagation Model, model=logDistance, exp=4

Example 1

Because scenarios/example1 only has station nodes, it is defined completely in a CSV file. It defines one ground station that publishes odometry data and four red team robots that subscribe to odometry data:

# Publisher, Role, Subscription, Frequency, Size, History, Depth, Reliability, Durability
Publisher, GS, odometry, 10, 500, keep_last, 0, reliable, volatile

# Subscribers, Role, Subscription, History, Depth, Reliability, Durability
Subscriber, red_team, odometry, keep_last, 0, reliable, volatile

# Robot, Name, Role
Robot, R1, GS
Robot, R2, red_team
Robot, R3, red_team
Robot, R4, red_team
Robot, R5, red_team

# Station, Name, param=value, ...
Station, R1, range=100, position=0;0;0
Station, R2, range=100, position=1;0;0
Station, R3, range=100, position=0;1;0
Station, R4, range=100, position=-1;0;0
Station, R5, range=100, position=0;-1;0

# Link, Name, param=value, ...
Link, R1, cls=adhoc, intf=R1-wlan0, ssid=adhocNet, mode=g, channel=5, ht_cap=HT40+
Link, R2, cls=adhoc, intf=R2-wlan0, ssid=adhocNet, mode=g, channel=5, ht_cap=HT40+
Link, R3, cls=adhoc, intf=R3-wlan0, ssid=adhocNet, mode=g, channel=5, ht_cap=HT40+
Link, R4, cls=adhoc, intf=R4-wlan0, ssid=adhocNet, mode=g, channel=5, ht_cap=HT40+
Link, R5, cls=adhoc, intf=R5-wlan0, ssid=adhocNet, mode=g, channel=5, ht_cap=HT40+

Propagation Model, model=logDistance, exp=4
Plot Graph, min_x=-2, min_y=-2, max_x=2, max_y=2

zzzzzzzzzzzz Here we show an example of using miniedit to define the ad-hoc network that is similar to the example at ~/gits/mininet-wifi/examples/adhoc.py:

zzzzzzzzzz

  • Build the adhoc example:
    • Click the station (laptop) icon
    • Click three places to drop three stations. You may need to adjust their positions later so they are in range of each other.
    • Click the link (line) icon
    • For each station, click down on one station, drag the cursor, and release the click on another station to connect stations with a link.
    • Click the selection (arrow) icon
    • Right click each link to define the connection type as ad-hoc and to set the source and destination properties for wlan0.
    • Save the network as a Python script by selecting the File menu and selecting Export level 2 script.