MicroModemDriverDataFlow - GobySoft/goby GitHub Wiki
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)
-
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, justsrc
(integer 0-127 which equals $CACFG,SRC in this (local) case),dest
(integer 0-127), andrate
(integer 0-5) for the requested transmission. Data are collected later. -
handle_initiate_transmission
first caches the proper number of frames using the methodcache_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 inbase_msg
) (for example N = 8 forbase_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) beforehandle_initiate_transmission
is called bygoby::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 thatdata_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 tosignal_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).
- The provider of data (often
-
Now, if the number of cached messages exceeds 0, a $CCCYC is sent using the values provided in
base_msg
and theack_requested
value of the first data message provided. If number of the cached messages is 0, nothing further is done (i.e. no $CCCYC). -
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 theack_requested
value given in thedata_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 matchingack_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.
- Thus, on the master, someone calls
virtual DriverBase::handle_initiate_transmission(protobuf::ModemMsgBase* base_msg) = 0
wherebase_msg->src()
is the modem ID ($CCCFG,SRC) of the sender. This is ADR1 in the $CCCYC message. (base_msg->dest()
is ADR2). GobyMMDriver
initiates a $CCCYC with the correct values but does not cache any data (since the master isn't sending data). - 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 methodcache_outgoing_data
as described in 2. under the Local CCCYC section above. - 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.