Goby v2
|
Table of Contents for goby-acomms: An overview of Acoustic Communications Library.
To get started using the goby-acomms libraries as quickly as possible:
Please visit https://answers.launchpad.net/goby with any questions.
To start on some (hopefully) common ground, let's begin with an analogy to Open Systems Initiative (OSI) networking layers in this table. For a complete description of the OSI layers see http://www.itu.int/rec/T-REC-X.200-199407-I/en.
OSI Layer | Goby-Acomms library component | API class(es) | Example(s) |
Application | Not yet part of Goby | MOOS Application: pAcommsHandler | |
Presentation | dccl: Encoding and decoding | goby::acomms::DCCLCodec | dccl_simple.cpp two_message.cpp chat.cpp |
Session | Not used, sessions are established passively. | ||
Transport | queue: Priority based message queuing | goby::acomms::QueueManager | queue_simple.cpp chat.cpp |
Network | Does not yet exist. All transmissions are considered single hop, currently. Addressing routing over multiple hops is an open and pressing research problem. | ||
Data Link | modemdriver: Modem driver | classes derived from goby::acomms::ModemDriverBase; e.g. goby::acomms::MMDriver | driver_simple.cpp chat.cpp |
amac: Medium Access Control (MAC) | goby::acomms::MACManager | amac_simple.cpp chat.cpp | |
Physical | Not part of Goby | Modem Firmware, e.g. WHOI Micro-Modem Firmware (NMEA 0183 on RS-232) (see Interface Guide) |
Do not take the previous analogy too literally; some things we are doing here for acoustic communications (hereafter, acomms) are unconventional from the approach of networking on electromagnetic carriers (hereafter, EM networking). The difference is a vast spread in the expected throughput of a standard internet hardware carrier and acoustic communications. For example, an optical fiber can put through greater than 10 Tbps over greater than 100 km, whereas the WHOI acoustic Micro-Modem can (at best) do 5000 bps over several km. This is a difference of thirteen orders of magnitude for the bit-rate distance product!
Extremely low throughput means that essentially every efficiency in bit packing messages to the smallest size possible is desirable. The traditional approach of layering (e.g. TCP/IP) creates inefficiencies as each layer wraps the message of the higher layer with its own header. See RFC3439 section 3 ("Layering Considered Harmful") for an interesting discussion of this issue http://tools.ietf.org/html/rfc3439#page-7. Thus, the "layers" of goby-acomms are more tightly interrelated than TCP/IP, for example. Higher layers depend on lower layers to carry out functions such as error checking and do not replicate this functionality.
The second major difference stemming from this bandwidth constraint is that total throughput is often an unrealistic goal. The quality of the acoustic channel varies widely from place to place, and even from hour to hour as changes in the sea affect propagation of sound. This means that it is also difficult to predict what one's throughput will be at any given time.
These two considerations manifest themselves in the goby-acomms design as a priority based queuing system for the transport layer. Messages are placed in different queues based on their priority (which is determined by the designer of the message). This means that the channel is always utilized (low priority data are sent when the channel quality is high) but important messages are not swamped by low priority data. In contrast, TCP/IP considers all packets equally. Packets made from a spam email are given the same consideration as a high priority email from the President. This is a trade-off in efficiency versus simplicity that makes sense for EM networking, but does not for acoustic communications.
The "law of diminishing returns" means that at some point, if we try to optimize excessively, we will end up making the system more complex without substantial gain. Thus, goby-acomms makes some concessions for the sake of simplicity:
A relatively simple component model for the goby-acomms library showing the interface classes :
The Dynamic Compact Control Language (DCCL) provides a structure for defining messages to be sent through an acoustic modem. The messages are configured in Google Protocol Buffers and are intended to be easily reconfigurable, unlike the original CCL framework used in the REMUS vehicles and others (for information on CCL, see http://acomms.whoi.edu/ccl/.
Unlike the encoder / decoder provided with Google Protocol Buffers, each field (which could be a primitive type like double, int32, string or an user-defined embedded message like CTDMessage) of a DCCL message can be encoded using a DCCL built-in or user-defined encoder. This allows the codecs to be matched to the data's physical origins and thus make the most of the limited throughput available by making very small encoded messages.
Detailed documentation for goby-acomms: DCCL (Dynamic Compact Control Language).
The goby-acomms queuing (queue
) component interacts with both the application level process and the modem driver process that talks directly to the modem.
On the application side, queue
provides the ability for the application level process to push DCCL messages to various queues and receive messages from a remote sender that correspond to messages in the same queue (e.g. you have a queue for STATUS_MESSAGE that you can push messages to you and also receive other STATUS_MESSAGEs on). The push feature is called by the application level process and received messages are signaled to all previous bound slots (see Signal / Slot model for asynchronous events).
On the driver side, queue
provides the modem driver with data upon request. It chooses the data to send based on dynamic priorities (and several other configuration parameters). It will also pack as many messages from the user into a single frame from the modem as possible using the DCCLCodec's repeated encoding functionality. Note, however, that queue
will not split a user's data into frames (like TCP/IP). If this functionality is desired, it must be provided at the application layer. Acoustic communications are too unpredictable to reliably stitch together frames.
Detailed documentation for goby-acomms: queue (Message Priority Queuing).
The goby-acomms Modem driver component (modemdriver
) of the Goby-Acomms library provides an interface from the rest of goby-acomms to the acoustic modem firmware. While currently the only driver publicly available is for the WHOI Micro-Modem (and for an example toy modem "ABCDriver"), this component is written in such a way that drivers for any acoustic modem that interfaces over a serial or TCP connection and can provide (or provide abstractions for) sending data directly to another modem on the link should be able to be written. Any one who is interested in writing a modem driver for another acoustic modem should get in touch with the goby project https://launchpad.net/goby and see Writing a new driver.
Detailed documentation for goby-acomms: modemdriver (Driver to interact with modem firmware).
The goby-acomms MAC component (amac) handles access to the shared medium, in our case the acoustic channel. We assume that we have a single (frequency) band for transmission so that if vehicles transmit simultaneously, collisions will occur between messaging. Therefore, we use time division multiple access (TDMA) schemes, or "slotting". Networks with multiple frequency bands will have to employ a different MAC scheme or augment amac for the frequency division multiple access (FDMA) scenario.
The Goby AMAC provides two basic types of TDMA:
Detailed documentation for goby-acomms: amac (Medium Access Control).
The layers of goby-acomms use a signal / slot system for asynchronous events such as receipt of an acoustic message. Each signal can be connected (goby::acomms::connect()) to one or more slots, which are functions or member functions matching the signature of the signal. When the signal is emitted, the slots are called in order they were connected. To ensure synchronous behavior and thread-safety throughout goby-acomms, signals are only emitted during a call to a given component's API class do_work method (i.e. goby::acomms::ModemDriverBase::do_work(), goby::acomms::QueueManager::do_work(), goby::acomms::MACManager::do_work()).
For example, if I want to receive data from queue
, I need to connect to the signal QueueManager::signal_receive. Thus, I need to define a function or class method with the same signature:
At startup, I then connect the signal to the slot:
If instead, I was using a member function such as
I would call connect (probably in the constructor for MyApplication) passing the pointer to the class:
The Boost.Signals library is used without modification, so for details see http://www.boost.org/doc/libs/1_46_0/doc/html/signals.html. Member function binding is provided by Boost Bind http://www.boost.org/doc/libs/1_46_0/libs/bind/bind.html
Google Protocol Buffers are used as a convenient way of generating data structures (basic classes with accessors, mutators). They can also be serialized efficiently, though this is not generally used within goby-acomms. Protocol buffers messages are defined in .proto files that have a C-like syntax:
message MyMessage { optional uint32 a = 1; required string b = 2; repeated double c = 3; }
The identifier "optional" means a proper MyMessage object may or may not contain that field. "required" means that a proper MyMessage always contains such a field. "repeated" means a MyMessage can contain a vector of this field (0 to n entries). The sequence number "= 1" must be unique for each field and determines the serialized format on the wire. For our purposes it is otherwise insignificant. See http://code.google.com/apis/protocolbuffers/docs/proto.html for full details.
The .proto file is pre-compiled into a C++ class that is loosely speaking (see http://code.google.com/apis/protocolbuffers/docs/reference/cpp-generated.html for precise details):
Clearly the .proto representation is more compact and amenable to easy modification. All the Protocol Buffers messages used in goby-acomms are placed in the goby::acomms::protobuf namespace for easy identification. This doxygen documentation does not understand Protocol Buffers language so you will need to look at the source code directly for the .proto (e.g. acomms_modem_message.proto).
Model that gives the sequence for sending a message with goby-acomms:
Model that shows the commands needed to start and keep goby-acomms running: