Your first system - norwegianblues/norwegianblues GitHub Wiki

Introduction

The main feature of Parrot is that it allows you to instantiate and connect a number of communicating nodes. For now, we will not dive into exactly what a node is, but suggest you think of a node as a device in the sentence "connected devices".

The simplest example of connected devices is two devices directly connected by a wire, e.g. RS232 serial connection. This situation is shown in the picture below.

The goal of this tutorial is to set up a system like this and send data from one node to another.

Let's try it!

Open up a terminal window and step into the directory you unpacked in the Quick start step. If everything went well you should see the following layout of directories (only showing the parts that is interesting for the moment):

├── Platform
│   ├── core
│   ├── pool
│   └── web
└── parrot-launcher

The first thing to do is to add the directory containing parrot-launcher to your PATH, and verify that you can use it (assuming you're at the top of project):

$ export PATH=$PWD:$PATH
$ parrot-launcher -h

Usage: parrot-launcher [options] <config_file>
<config_file> path could be absolute or relative. 
Valid options are:
 -b <module> Specify a non-default module responsible for the communication backplane.
 -d          Debug mode. Increased verbosity. Will start with PyDebugger (pdb) enabled.
             Useful for checking import of nodes. Press CTRL-D to continue starting.
 -i          Set up environment and drop into interactive python shell.
 -h          Print this help text and exit

To start with, create a new directory tutorial1 somewhere, and step into it. The first thing you need to do is to describe the system in the above figure in a configuration file. Create a file tutorial1.json and enter the following (minimal) configuration:

{
    "version":1,
    "description": "Tutorial 1: Two nodes communicating over a serial link.",
    "nodes": {},
    "links": {},
    "networks": {}
}

As you might have guessed, we use JSON to describe the system. Here we have the four top-level items that every configuration file needs; description – a string with a concise description of the configuration, nodes – a set containing all the node definitions (currently empty), links – a set of link definitions (also empty), and networks – a set of different networks to be used in the simulation (empty as well). Don't worry too much about the content of and syntax to use for these four items - we'll come to that later. Despite the simplicity of this configuration, it is fully functional:

$ parrot-launcher tutorial1.json 

Starting HODCP platform ...
HODCP_ROOT is: /Users/you/parrot
WORKDIR is   : /Users/you/parrot
Python is    : /usr/bin/python
Python dirs  : /Users/you/parrot/Platform/core:/Users/you/parrot/Platform/pool/nodes
Backplane    : Default
Config file  : tut1.json

========================================
Tutorial 1: Two nodes communicating over a serial link.
========================================
[Core] Platform running.

^C
[Core] User stopped simulation, attempting cleanup

First HODCP produced some diagnostic information, like the paths used to look for files etc., in order to help track down problems. The follows the system description from the configuration file, and finally there are some log output from the system. Since there were no nodes defined in the configuration file, the system doesn't do much and we had to use CTRL-C to stop the simulation.

Now, lets have a look at how to create nodes. To begin with, a node is identified by a Uniform Resource Name, URN, and in the figure above we have chosen the names "1" and "2" for the nodes, and thus the URNs are "urn:hodcp:node:1", and "urn:hodcp:node:2", respectively. The nodes are connected by a uni-directional link, with node 1 sending data to node 2.

One of the ideas behind HODCP is to grow a pool of re-usable components, and in fact, there are two suitable node types available for use in this tutorial; comm_source – a node that wakes up every two seconds and sends the current time and date in plain text over it's serial port, and comm_sink – a node that receives characters on it's serial port and displays them. A node definition on its own looks like:

"urn:hodcp:node:1": {
	"class": "comm_source",
	"config": {}
}

where the key is the URN of the node, and is value is a dictionary specifying the type of node, and configuration information for the node. Right now we don't pass any specific configuration to the node. We can now finalize the configuration file, with node definitions for node 1 and 2, and a link definition (that is almost self explanatory) at the end.

{
    "version": 1,
    "description": "Tutorial 1: Two nodes communicating over a serial link.",
    "nodes": {
        "urn:hodcp:node:1": {
            "class": "comm_source",
            "interfaces": {
                "ser0": {}
            },
            "config": {}
        },
        "urn:hodcp:node:2": {
            "class": "comm_sink",
            "interfaces": {
                "ser0": {}
            },
            "config": {}
        }
    },
    "links": {
        "urn:hodcp:node:1:ser0":"urn:hodcp:node:2:ser0"
    },
    "networks": {}
}

This time we get the following output when running the system (cutting out diagnostics and some logging):

$ ./parrot-launcher tutorial1.json 

Starting HODCP platform ...
[SNIP]
Config file : Platform/pool/configs/tutorial1.json

========================================
Tutorial 1: Two nodes communicating over a serial link.
========================================
[Core] Platform running.
[urn:hodcp:node:1] comm_source.configure()
[urn:hodcp:node:2] comm_sink.configure()
[urn:hodcp:node:2] comm_sink.activate()
[urn:hodcp:node:1] comm_source.activate()
[urn:hodcp:node:2] 2013-05-29 10:20:48.896991
[urn:hodcp:node:2] 2013-05-29 10:20:50.898439
[urn:hodcp:node:2] 2013-05-29 10:20:52.899705
^C
[Core] User stopped simulation, attempting cleanup

Mission accomplished!

Next steps

Proceed to Build-an-emulated-node or A-complex-example

⚠️ **GitHub.com Fallback** ⚠️