Toby Schneider edited this page May 26, 2016 · 2 revisions

This page explains the logical flow of sending messages using the WHOI Micro-Modem in the Goby driver MMDriver.

A few things up front:

  • Goby uses index = 0 for all first indices of arrays, vectors, etc. (in conformance with standard programming practices). This is different than the modem with regard to the Packet Frame#. The WHOI Micro-Modem uses Frame# 1, 2, ... whereas Goby uses frames 0, 1, ... Thus all WHOI Micro-Modem frames are one greater than the corresponding Goby frame. Where ambiguous I will use "Goby frame" to mean the frame number used inside of Goby and "modem frame" to mean the WHOI Micro-Modem frame number.

I've split this into two sections as they are treated slightly different:

Local CCCYC (decentralized TDMA)

  1. First of all, everything is kicked off when someone (often goby::acomms::MACManager) calls: virtual DriverBase::handle_initiate_transmission(protobuf::ModemMsgBase* base_msg) = 0

    which calls (via standard C++ virtual inheritance) MMDriver::handle_initiate_transmission(protobuf::ModemMsgBase* base_msg)

    base_msg contains no data, just src (integer 0-127 which equals $CACFG,SRC in this (local) case), dest (integer 0-127), and rate (integer 0-5) for the requested transmission. Data are collected later.

  2. handle_initiate_transmission first caches the proper number of frames using the method cache_outgoing_data. This basically means calling the signal (or callback) signal_data_request(request_msg, &data_msg) N times where N is the number of frames in the request transmission (set in base_msg) (for example N = 8 for base_msg.rate()==5).

    We cache data now (ahead of the actual $CCCYC) for two reasons:

    • The provider of data (often goby::acomms:::QueueManager) may be slow, especially if on-the-fly encoding is done. This way, we can cache all data before starting the $CCCYC with the modem and avoid data timeouts (and use $CCCFG,DTO,1). In the future, I would like to have this pre-fetching initiated some time (say a few seconds) before handle_initiate_transmission is called by goby::acomms::MACManager. This way the TDMA cycle timing can be strictly maintained even the face of a slow data provider.
    • If there are no data to send, the first data_msg (for the first frame) is just returned unmodified (such that data_msg.data().size() == 0) and the $CCCYC is never sent (avoiding wasting power / channel time). Note that later (Goby frame > 0, modem frames > 1) frames can also be returned unmodified on calls to signal_data_request(request_msg, &data_msg) which tells Goby to send a blank frame to the Micro-Modem at that point. The Micro-Modem has a feature where multi-frame messages can be terminated in this fashion and will be sent at that point (without futher $CADRQ).
  3. Now, if the number of cached messages exceeds 0, a $CCCYC is sent using the values provided in base_msg and the ack_requested value of the first data message provided. If number of the cached messages is 0, nothing further is done (i.e. no $CCCYC).

  4. The Micro-Modem will now send the proper number of $CADRQ data requests, which are answered by MMDriver using the data cached above (or if no more data was cached, an empty message to end sending of $CADRQs) via the $CCTXD message. The ACK value is set to the ack_requested value given in the data_msg which must match (i.e. be either true or false) for all frames (a requirement of the WHOI Micro-Modem). It may be sensible to enforce this at the MMDriver level in the future but now it is the responsibility of the data provider to ensure all frames have matching ack_requested fields.

Remote CCCYC (Centralized TDMA or "Polling")

In this case, the transmission cycle (CCCYC + CCTXD) is split between two nodes (the example above has both tasks on a single node). We will call the node initiating the $CCCYC the master and the node sending the data the sender. The added value is here is the ease of controlling (and changing) the TDMA cycle from a ship-based master; the drawback is that the master has no knowledge of the data available for sending.

  1. Thus, on the master, someone calls virtual DriverBase::handle_initiate_transmission(protobuf::ModemMsgBase* base_msg) = 0 where base_msg->src() is the modem ID ($CCCFG,SRC) of the sender. This is ADR1 in the $CCCYC message. (base_msg->dest() is ADR2). Goby MMDriver initiates a $CCCYC with the correct values but does not cache any data (since the master isn't sending data).
  2. The sender receives a $CACYC without having cached data (local_cccyc_==false) since it didn't send the $CCCYC. The sender caches data using the method cache_outgoing_data as described in 2. under the Local CCCYC section above.
  3. These cached data are used to feed the modem $CCTXD values in the same way was described in 4. under the Local CCCYC section above.
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.