<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">\documentclass[onecolumn,letterpaper,11pt]{article}

%=================================================================
\input{common_latex/common_latex_packages}
\input{common_latex/common_latex_definitions}
\input{common_latex/common_latex_help_format}
%=================================================================

\begin{document}

\begin{labcover}
\labtitle{Enabling a MOOS Application for AppCasting}
\vspace{0.1in}
\labdate{June 2018}
\vspace{0.1in}
\labauth{Michael Benjamin, mikerb@mit.edu}
\labauth{Department of Mechanical Engineering}
\labauth{MIT, Cambridge MA 02139}
\labtoc{small}
\end{labcover}

\wikidoc{file=IvPTools.AppcastEnable}
\wikidoc{auth=mikerb@mit.edu}

%=================================================================
\section{Overview}
%=================================================================
\label{sec_appcast_enabling}

In this section we discuss the steps for enabling a new or existing
MOOS application to support appcasting. Much of the requisite
appcasting source code is the same for any application. This is
captured in a new \var{AppCastingMOOSApp} class to minimize appcasting
boilerplate code.  This class, as indicated in
Figure \ref{fig_appcasting_moosapp}, is a subclass of the
common \var{CMOOSApp} class distributed with core MOOS.

\vspace{0.1in}
\begin{figure}[H]
  \centering 
  \includegraphics[width=0.275\textwidth]{figures/fig_appcasting_moosapp.png}
  \caption{On-demand appcasting is implemented in a new CMOOSApp
    subclass called AppCastingMOOSApp.}
  \label{fig_appcasting_moosapp}
\end{figure}
\vspace{0.1in}

\noindent The following is the complete list of required steps:

\begin{packed_itemize}[2]
\item Subclass the \var{AppCastingMOOSApp} superclass,
\item Invoke a pair of superclass methods in the \func{Iterate()} function,
\item Invoke a superclass method in the \func{OnNewMail()} function,
\item Invoke a superclass method in the \func{OnStartUp()} function,
\item Invoke a superclass method when registering for variables,
\item Implement a \func{buildReport()} function where appcasts are formed.
\end{packed_itemize}

\noindent 
In our discussions to follow, a hypothetical \var{YourMOOSApp}
application and class definition is described. The above steps are the
minimum requirements for appcasting, and they are fairly boilerplate,
in most cases a single line of code. To make good use of the
appcasting features, configuration warnings, run warnings and events
may be placed in your application code. This is neither mandatory nor
boilerplate, but really dependent on the application. Nevertheless, a
few rules of thumb discussed:

\begin{packed_itemize}[2]
\item Posting events,
\item Posting run warnings,
\item Posting configuration warnings.
\end{packed_itemize}[2]

%=================================================================
\section{Sub-classing the AppCastingMOOSApp Superclass}
%=================================================================

The first step is to make \var{YourMOOSApp} a subclass of the
\var{AppCastingMOOSApp}. This brings your application class everything
from the traditional \var{CMOOSApp} class as well as the appcasting
features of the \var{AppCastingMOOSApp} class. The only additional
thing besides declaring the superclass is to declare the
\func{buildReport()} function. This virtual function is invoked when
an appcast has been deemed warranted. Appcasts are not typically
generated on each iteration. See the later discussion about {\em
on-demand appcasting}. The contents of the \func{buildReport()}
function are discussed in greater detail in
Section \ref{sec_acma_buildrep}.

\vspace{0.15in}
\begin{listing}{Pseudocode for sub-classing the AppCastingMOOSApp superclass}
\label{lst_acma_subclassing}
\footnotesize
\begin{verbatim}
 1  #include "MOOS/libMOOS/Thirdparty/AppCasting/AppCastingMOOSApp.h" 
 2  
 3  class YourMOOSApp : public AppCastingMOOSApp        // Instead of CMOOSApp
 4  {
 5    // All your normal class declaration stuff
 6     
 7    bool  buildReport();                              // Add this line
 8  };
\end{verbatim}
\end{listing}
\normalsize

%=================================================================
\section{Invoking Superclass Methods in the Iterate() Method}
%=================================================================
\label{sec_acma_iterate}

The next step is to implement \var{YourMOOSApp::Iterate()} to invoke
two superclass functions; one at the very beginning and one at the very
end.  The first superclass function, on line 2 below, does certain
common bookkeeping such as incrementing the counter representing the
number of application iterations, and updating a variable holding the
present MOOS time. The second superclass function, on line 6, invokes
the on-demand appcasting logic discussed previously. If an appcast is 
deemed warranted, it will invoke the \func{buildReport()} function.

\vspace{0.1in}
\begin{listing}{Pseudocode for invoking subclass methods in the \func{Iterate()} method}
\label{lst_acma_iterate}
\footnotesize
\begin{verbatim}
 1  bool YourMOOSApp::Iterate()
 2  {
 3    AppCastingMOOSApp::Iterate();                  // Add this line
 4    
 5    // Do all your normal Iterate stuff
 6  
 7    AppCastingMOOSApp::PostReport();               // Add this line
 8    return(true);
 9  }
\end{verbatim}
\end{listing}
\normalsize


%=================================================================
\section{Invoking a Superclass Method in the OnNewMail() Method}
%=================================================================
\label{sec_acma_onnewmail}

The next step is to implement \var{YourMOOSApp::OnNewMail()} to invoke
a superclass function to have the first opportunity to handle incoming
mail. For example, \msvar{APPCAST\_REQ} mail is handled in the
superclass.  The list of mail messages is passed by reference to the
superclass handler, allowing the \func{AppCastingMOOSApp::OnNewMail()}
function to remove handled messages before returning to the mail
handling implemented in \func{YourMOOSApp::OnNewMail()}. 

\vspace{0.1in}
\begin{listing}{Pseudocode for invoking a superclass method in the \func{OnNewMail()} method}
\label{lst_acma_onnewmail}
\footnotesize
\begin{verbatim}
 1  bool YourMOOSApp::OnNewMail(MOOSMSG_LIST &amp;NewMail)
 2  {
 3    AppCastingMOOSApp::OnNewMail(NewMail);        // Add this line
 4  
 5    // Do all your other normal mail handling.
 6  }
\end{verbatim}
\end{listing}
\normalsize


%=================================================================
\section{Invoking a Superclass Method in the OnStartUp() Method}
%=================================================================
\label{sec_acma_onstartup}

The next step is to implement \func{YourMOOSApp::OnStartUp()} to invoke
a superclass function to perform startup steps needed by the 
\var{AppCastingMOOSApp} superclass. 

\vspace{0.1in}
\begin{listing}{Pseudocode for invoking a superclass method in the \func{OnStartUp()} method}
\label{lst_acma_onstartup}
\footnotesize
\begin{verbatim}
 1  void YourMOOSApp::OnStartUp()
 2  {
 3    AppCastingMOOSApp::OnStartUp();               // Add this line
 4  
 5    // Do all your other startup stuff
 6  }
\end{verbatim}
\end{listing}
\normalsize


%=================================================================
\section{Invoking a Superclass Method When Registering for Variables}
%=================================================================
\label{sec_acma_register}

The next step is to invoke the
\func{AppCastingMOOSApp::RegisterVariables()} wherever variables are
registered in \var{YourMOOSApp} implementation. Many application
developers have, in practice, created a dedicated
\func{registerVariables()} function, typically invoked at the
conclusion of both \func{OnStartUp()} and \func{OnConnectToServer()}. 
The following example is one way to handle this.

\vspace{0.1in}
\begin{listing}{Pseudocode for invoking a superclass method when registering for variables}
\label{lst_acma_register}
\footnotesize
\begin{verbatim}
 1  void YourMOOSApp::registerVariables()
 2  {
 3    AppCastingMOOSApp::RegisterVariables();      // Add this line
 4  
 5    // Do all your other registrations
 6  }
\end{verbatim}
\end{listing}
\normalsize

%=================================================================
\section{Implementing a buildReport Method for Generating AppCasts}
%=================================================================
\label{sec_acma_buildrep}

The \func{buildReport()} function is where appcasts are made! The
action that happens here is unique to the application. The form is
designed by the application developer to reflect the most
meaningful, concise snapshot of the application's present status.
Recall that it is invoked automatically when or if the application
deems an appcast is to be generated.
%Those issues were discussed in Section \ref{sec_on_demand}, and \ref{sec_acma_iterate}.
For the purposes here though, a decision has indeed been made to
generate an appcast, and \func{buildReport()} has been invoked to see
that it happens. A simple example of \func{buildReport()} is shown
below in Listing \ref{lst_acma_bldrep}

\vspace{0.2in}
\begin{listing}{Pseudocode for a very simple \func{buildReport()} example}
\label{lst_acma_bldrep}
\footnotesize
\begin{verbatim}
 1  bool YourMOOSApp::buildReport()
 2  {
 3     m_msgs &lt;&lt; "Number of good messages: " &lt;&lt; m_good_message_count &lt;&lt; endl;
 4     m_msgs &lt;&lt; "Number of bad  messages: " &lt;&lt; m_bad_message_count  &lt;&lt; endl;
 5  
 6     return(true);
 7  }
\end{verbatim}
\end{listing}
\normalsize

\noindent
This simple example would generate something similar to the appcast
rendered in Figure \ref{fig_simple_acast1}.

\vspace{0.1in}
\begin{figure}[H]
  \centering 
  \includegraphics[width=0.6\textwidth]{figures/fig_simple_acast1.png}
  \caption{The rendering of a very simple appcast with just two
    message lines, no warnings, and no events. The header bar shows
    the name of the application, the originating MOOS community, the
    number of configuration and run warnings, and the application's
    current iteration counter.}
\label{fig_simple_acast1}
\end{figure}
\vspace{0.1in}


\noindent
Assume for the sake of the example that the two counter variables at
the end of lines 2 and 3 are member variables for the
fictitious \var{YourMOOSApp} class. The member variable \var{m\_msgs}
however is an STL stringstream also declared in
the \var{AppCastingMOOSApp} class, for holding message output. The
primary means of building an appcast is to add successive lines to the
appcast via:

\footnotesize
\begin{verbatim}
   m_msgs &lt;&lt;   &lt;element&gt;   &lt;&lt; endl;
\end{verbatim}
\normalsize
 
\noindent
where \var{&lt;element&gt;} may be a \var{string}, \var{double}, \var{int},
\var{unsigned int}, or any combination joined by the \var{"&lt;&lt;"}
operator. A new line is indicated by tacking on the newline,
\var{"\textbackslash{n}"}, at the end. That's pretty much it, but
there are a few other noteworthy points:

\begin{packed_itemize}[2]

\item Run warnings, configuration warnings, and events are not
  added during \func{buildReport()}, though not strictly prevented. They 
  are more typically added as warnings are discovered, or events occur 
  during the normal mail handling or iterate cycle. 

\item The header lines shown in Figure \ref{fig_simple_acast1} is 
  made automatically by the uMAC tool. They grab information in the
  appcast such as the application name and iteration number. These are
  filled by the boilerplate function calls such
  as \func{AppCastingMOOSApp::Iterate()} described earlier.

\item The appcast is automatically cleared prior to each invocation of
  \func{buildReport()}. Warnings and events however are not cleared as
  discussed earlier.

\item Returning true indicates that the appcast was indeed populated.
  Returning false would result in the appcast not being sent to the terminal
  or published to the MOOSDB. This is useful for some applications that may
  want to apply additional criteria before deciding to appcast.

\item Although report formatting, e.g., columns or tables, is not
  natively supported somehow in the \func{buildReport()} routine, there
  are tools available that facilitate formatting that work easily with
  the \func{buildReport()} interface. They are discussed later in
  Section 99.
\end{packed_itemize}

%=================================================================
\section{Posting Events}
%=================================================================
\label{sec_events}

Events are messages (strings) that the application developer deems to
be noteworthy enough to want to include in appcast output.  An event
may be posted anywhere in the application code with the
\func{reportEvent()} function defined in the \var{AppCastingMOOSApp}
class. A simple example:

\vspace{0.1in}
\small
\begin{verbatim}
   reportEvent("Good msg received: " + message);
\end{verbatim}
\normalsize
\vspace{0.1in}

\noindent
When the appcast is rendered in either a uMAC tool or in the terminal,
the result would look similar to that in Figure
\ref{fig_simple_acast2}.  

\vspace{0.1in}
\begin{figure}[H]
  \centering 
  \includegraphics[width=0.6\textwidth]{figures/fig_simple_acast2.png}
  \caption{The rendering of a simple appcast with two message lines, a
    single run warning, and single event. The header bar shows the
    name of the application, the originating MOOS community, the
    number of configuration and run warnings, and the application's
    current iteration counter.}
\label{fig_simple_acast2}
\end{figure}
\vspace{0.1in}

\noindent
Recall that only a limited number of events are retained. Older events
are dropped once a maximum amount is exceeded. The default event list
size is eight, but this may be overridden for a particular application
with the following parameter setting in the applications MOOS
configuration block:

\prevblue
\begin{verbatim}
   max_appcast_events = 25
\end{verbatim}
\postverb

\noindent The event list size may be set to at most 100.
 
%=================================================================
\section{Posting Run Warnings}
%=================================================================
\label{sec_run_warnings}

Run warnings are similar to events, but they convey that something may
have gone wrong.  A run warning may be posted anywhere in the
application code with the \func{reportRunWarning()} function
defined in the \var{AppCastingMOOSApp} class. A simple example:

\vspace{0.1in}
\small
\begin{verbatim}
   reportRunWarning("Bad msg received: " + message);
\end{verbatim}
\normalsize
\vspace{0.1in}

\noindent
The appcast structure and uMAC tools are implemented such that run
warnings are more easily brought to the attention of the
operator. This is due to the following reasons:

\begin{packed_itemize}[2]
\item When an appcast has a run warning, the uMAC utilities will
  indicate so by turning the text red, as in Figure
  \ref{fig_umac_rwarnings}.  Even when the focus of the uMAC utility
  is not on the particular appcast containing the run warning, the
  menu items for the appcast and vehicle will be rendered red.  In
  Figure \ref{fig_umac_rwarnings} for example, the menu browser focus
  is on vehicle \var{archie} and the \app{uFldMessageHandler}
  application.  The red highlights also indicate there is a run
  warning on another application on \var{archie}, and there is also a
  run warning on vehicle \var{charlie}.
\item An appcast request to an application may specify the reporting
  threshold to be \var{"run\_warning"}.  In this case an application
  will repeatedly choose not to publish an appcast unless a new run
  warning has been generated.
  %as discussed in Section \ref{sec_appcast_thresh}.
\item The uMAC tools also keep a running tally of run warnings for
  each vehicle and each application under the column labeled
  \var{"RW"} as shown in Figure \ref{fig_umac_rwarnings}.
\end{packed_itemize}

\vspace{0.1in}
\begin{figure}[H]
  \centering 
  \includegraphics[width=0.65\textwidth]{figures/fig_umac_rwarnings.png}
  \caption{The uMAC tools will highlight an application that has
    produced an appcast with a run warning. If the run warning
    occurred on a node not currently in focus, e.g., charlie in the
    figure, the node itself is highlighted.  The user can then select
    the other node to view the application generating the run
    warning.}
\label{fig_umac_rwarnings}
\end{figure}
\vspace{0.1in}

\noindent
Recall that only a limited number of run warnings are retained. Unlike
events where the older ones are dropped once a maximum has been
exceeded, old run warnings are never dropped. After the maximum has
been reached, the generic warning \var{"Other Run Warnings"} is simply
incremented.  The default list size is ten, but this may be overridden
for a particular application with the following parameter setting in
the applications MOOS configuration block:

\prevblue
\begin{verbatim}
   max_appcast_run_warnings = 50
\end{verbatim}
\postverb

\noindent The run warning list size may be set to at most 100.

%=================================================================
\section{Posting Configuration Warnings}
%=================================================================
\label{sec_config_warnings}

Configuration warnings are similar to run warnings but they are
typically only posted during the application startup, when the mission
configuration file is read.  A configuration warning may be posted
with the \func{reportConfigWarning()} function defined in the
\var{AppCastingMOOSApp} class. A simple example:

\vspace{0.1in}
\small
\begin{verbatim}
   reportConfigWarning("Problem configuring FOOBAR. Expected a number but got: " + str);
\end{verbatim}
\normalsize
\vspace{0.1in}

\noindent
There is a second way to post a configuration warning. This second
method takes as an argument the original full configuration parameter
line found in the mission file. Before posting the configuration
warning it checks to see if the parameter was something that likely
was handled by the superclass. This prevents the application from
reporting that \psvar{AppTick=10"} is an unknown parameter for example.

\vspace{0.1in}
\small
\begin{verbatim}
   reportUnhandledConfigWarning(original_full_config_line);
\end{verbatim}
\normalsize
\vspace{0.1in}

\noindent
The appcast structure and uMAC tools are implemented such that configuration
warnings are more easily brought to the attention of the
operator. This is due to the following reasons:

\begin{packed_itemize}[2]
\item When an appcast has a configuration warning, the uMAC utilities
  will indicate so by turning the text green, as in Figure
  \ref{fig_umac_cwarnings}.  Even when the focus of the uMAC utility
  is not on the particular appcast containing the config warning, the
  menu items for the appcast and vehicle will be rendered green.  In
  Figure \ref{fig_umac_cwarnings} for example, the menu browser focus
  is on the \var{shoreside} and the \app{uTimerScript} application
  application.  The green highlights indicate there is a configuration
  warning in the \app{uFldShoreBroker} application and on other
  applications on \var{archie}, \var{charlie}, and \var{ernie}.
\item The uMAC tools also keep a running tally of configuration warnings for
  each vehicle and each application under the column labeled
  \var{"CW"} as shown in Figure \ref{fig_umac_cwarnings}.
\end{packed_itemize}


\vspace{0.1in}
\begin{figure}[H]
  \centering 
  \includegraphics[width=0.65\textwidth]{figures/fig_umac_cwarnings.png}
  \caption{The uMAC tools include will highlight an application that
    has produced an appcast with a configuration warning. If the
    configuration warning occurred on a node not currently in focus,
    e.g., archie, charlie, or ernie in the figure, the node itself is
    highlighted.  The user can then select the other node to view the
    application generating the warning.}
\label{fig_umac_cwarnings}
\end{figure}
\vspace{0.1in}


\noindent
Like run warnings and events, configuration warnings are limited in number
to prevent runaway growth in the size of an appcast over time. The limit
however is large, 100, and fixed. Presumably the number of configuration 
warnings is limited by the number of possible configuration parameters for 
an application, and large number of configuration warnings usually indicates
that a mission should be halted and fixed before moving on.

\pskip

The example code in Listing \ref{lst_acma_onstart} below is an example 
\func{OnStartUp()} method showing the intended scenarios of reporting 
configuration warnings. 

\vspace{0.2in}
\begin{listing}{Pseudocode example for \func{OnStartUp()} configuration warning handling}
\label{lst_acma_onstart}
\footnotesize
\begin{verbatim}
  1  bool YourMOOSApp::OnStartUp()
  2  {
  3    AppCastingMOOSApp::OnStartUp();
  4    
  5    STRING_LIST sParams;
  6    if(!m_MissionReader.GetConfiguration(GetAppName(), sParams))
  7      reportConfigWarning("No config block found for " + GetAppName());
  8    
  9    STRING_LIST::iterator p;
 10    for(p=sParams.begin(); p!=sParams.end(); p++) {
 11      string orig  = *p;
 12      string line  = *p;
 13      string param = toupper(MOOSChomp(line, "="));
 14      string value = line;
 15  
 16      if(param == "FOO") {
 17        bool handled = handleConfigFOO(value);
 18        if(!handled) 
 19          reportConfigWarning("Problem with configuring FOO: " + value);
 20      }
 21      else if(param == "BAR") 
 22        bool handled = handleConfigBAR(value);
 23        if(!handled) 
 24          reportConfigWarning("Problem with configuring BAR: " + value);
 25      }
 26    
 27      else
 28        reportUnhandledConfigWarning(orig);
 29    }
 30    return(true);
 31  }
\end{verbatim}
\end{listing}
\normalsize

\vspace{0.1in}
\noindent
There are a few issues worth noting in this example:
\begin{packed_itemize}[2]

\item A check is made that the application actually has a
  configuration block. This is done on lines 5-6, and catches a common
  bug with newly minted mission files.

\item Checks are made that known parameters have legal values. This is
done for the parameters \psvar{FOO} in lines 15-19 and \psvar{BAR} in
lines 20-24 in Listing \ref{lst_acma_bldrep}. In each case an
external handler is invoked, e.g., \func{handleConfigFOO(value)} on
line 16, which returns a Boolean indicating whether the parameter
value was proper or not. If not, a configuration warning is reported
as on lines 18 and 23.

\item A final case is handled (lines 26-27) if the present parameter
  is not matched by any of the previous cases. This catches the common
  mistake of mis-spelling the parameter
  name. The \func{reportUnhandledConfigWarning()} function is used
  rather than the \func{reportConfigWarning()} function. The former
  function takes the whole original configuration line as input and
  checks to see if the parameter was a parameter handled at the
  superclass level. This prevents the generation of a warning for a
  line like \psvar{AppTick=5}.
\end{packed_itemize}

\end{document}

</pre></body></html>