<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}

%===================================================================
% Include common packages, environments, counters etc
\input{common_latex/common_latex_packages}
\input{common_latex/common_latex_lab_format}
\input{common_latex/common_latex_definitions}
%===================================================================

\begin{document}
\wikidoc{file=SDR.LabMOOSProgramming}
\wikidoc{auth=mikerb@mit.edu}

%===================================================================
% Build the Cover Page in an environment style easy for wiki parsing
\begin{labcover}
\labtitle{Lab 07 - Introduction to MOOS Programming}
\vspace{0.1in}
\labpng{0.75}{figs_common/header_sdr.png}
\vspace{0.1in}
\labdate{Fall, 2017}
\vspace{0.1in}
\labauth{Michael Benjamin, mikerb@mit.edu}
\labauth{Henrik Schmidt, henrik@mit.edu}
\labauth{Department of Mechanical Engineering}
\labauth{MIT, Cambridge MA 02139}
\labtoc{footnotesize}
\end{labcover}

%===================================================================
% Add a blank page so first body page is on the right when doubleside
\blankpage

%===================================================================
% Begin the body of the text
%===================================================================
\section{Overview and Objectives}
%===================================================================

In this lab we will produce our own MOOS application. We begin by
downloading an example application complete with it's own build
structure. We proceed by making our first simple MOOS app emphasizing
the usage of the basic MOOS components.  

\subsection{Preliminaries}
\label{prelims}

This lab does assume that you have a working MOOS-IvP tree checked out
and installed on your computer. To verify this make sure that the
following executables are built and findable in your shell path:

\begin{consoleverb}
 $ which MOOSDB
 /Users/you/moos-ivp/bin/MOOSDB
 $ which pHelmIvP
 /Users/you/moos-ivp/bin/pHelmIvP
\end{consoleverb}

\noindent
If unsuccessful with the above, return to the steps in Lab 1:

\pskip
\noindent
\urlxx{http://oceanai.mit.edu/pavlab/pmwiki/pmwiki.php?n=SDR.LabIntro}

%=========================================================================
\subsection{MOOS, MOOS-IvP and Your Applications}

In previous laba we discussed the relationship between MOOS and MOOS-IvP.
The MOOS tree is a body of software distributed as part of the MOOS-IvP 
tree as depicted in Figure \ref{fig_nested_archs}.

\vspace{0.1in}
\begin{figure}[H]
  \centering 
  \includegraphics[width=0.95\textwidth]{figures/nested_moos_3pty.png}
  \caption{{\bf Nested Repositories:} The MOOS-IvP tree contains the
    Oxford MOOS tree and additional modules from MIT including the
    Helm architecture, Helm behaviors and further MOOS
    applications. The set of modules may be expanded with user
    third-party applications or behaviors.}
\label{fig_nested_archs}
\end{figure}

\noindent
MOOS-IvP provides additional MOOS applications, including the IvP Helm
behavior-based architecture, and has C++ build dependencies on the
MOOS libraries. In this lab the focus is on building additional MOOS
applications. Your MOOS apps will have a build dependency on the MOOS
libraries, and you may choose to utilize libraries in the MOOS-IvP
tree.  We start by downloading the \var{moos-ivp-extend} tree which
may be regarded as a template for extending the MOOS-IvP tree with
apps and behaviors. This tree also includes a functioning build
structure to ease the learning curve on C++ build issues for now.



%==========================================================================
\subsection{More MOOS / MOOS-IvP Resources}

We will only just touch the MOOS programming basics today. A few
further resources are worth mentioning for following up this lab with
your own exploration.

\begin{itemize}

\item See the slides from the accompanying lecture which give a bit
  more background into MOOS and MOOS-IvP related to marine robotics.

\item The Programming with MOOS documentation. \newline 
  \urlx{http://oceanai.mit.edu/2.680/docs/ProgrammingWithMOOS.pdf}

\item The moos-ivp.org website documentation. \newline 
  \urlx{http://oceanai.mit.edu/ivpman}

\end{itemize}

%==========================================================================
\subsection{The MOOS Application Structure}

The main idea explored today is the notion and structure of a MOOS
application.  We know from the last lab that MOOS apps publish,
subscribe for, and handle mail passed from one application to another
through the \app{MOOSDB}. In the last lab we worked with existing MOOS apps,
only modifying their functionality through configuration options
provided by the app writer. Even without modifying the code of existing
MOOS apps there are many ways to configure a system for unique domains.
However, the real power of MOOS comes from the fact that no application
is sacred. If you don't like what it does (or doesn't) do, you are free
copy {\em and rename it}, and modify the code to your satisfaction. Or 
you can just build your own application from scratch. This is the focus 
of today's lab.

\pskip

The key components to keep in mind in this lab are shown in Figure
\ref{fig_moos_functions} below. All MOOS apps begin by being a subclass
of the MOOSApp superclass defined in the Oxford MOOS library. The primary
work of the app developer is in writing the three functions shown in the 
figure.

\vspace{0.15in}
\begin{figure}[H]
  \centering 
  \includegraphics[width=0.65\textwidth]{figures/moos_functions.png}
\caption{{\bf The MOOSApp Key Functions:} All MOOS apps are a subclass
  of the MOOSApp superclass. Development mostly boils down to
  overriding the three functions below with the particulars of one's
  own liking.}
\label{fig_moos_functions}
\end{figure}

%---------------------------------------------------------------------
\subsubsection*{Documentation Conventions}

To help distinguish between MOOS variables, MOOS configuration
parameters, and behavior configuration parameters, we will use the
following conventions:

\begin{packed_itemize}[3]
\item MOOS variables are rendered in \mvar{green}, such as
  \mvar{IVPHELM\_STATE}, as well as postings to the \app{MOOSDB}, such
  as \mvar{DEPLOY=true}.
\item MOOS configuration parameters are rendered in \pvar{blue}, such
  as \pvar{AppTick=10} and \pvar{verbose=true}. Except for \pvar{AppTick} and 
  \pvar{CommsTick}, configuration parameters are generally lower case. 
\item MOOS apps and executables generally, are rendered in magenta as with 
 \app{MOOSDB} and \app{GenMOOSApp}.
\item IvP Helm Behavior configuration parameters are rendered in \bvar{brown}, such
  as \bvar{priority=100} and \bvar{endflag=RETURN=true}.
\end{packed_itemize}

\noindent
This convention closely follows the convention used in the helm
documentation.

%==========================================================================
\subsection{Handy Functions Defined on MOOSMsg (MOOS Mail)}

The below methods are defined on an instance of
\var{MOOSMsg}. Typically we are dealing with MOOS messages in the
\var{OnNewMail()} loop of an application.  Besides knowing the name of
the variable, you may also want to know (a) what is its value, (b) by
whom or which app was it posted, (c) when was it posted, (d) is its
value of type string or double, and so on.

\pskip

\noindent 
In our \app{pXRelayTest} example app, we only call \var{msg.GetKey()}
in \var{Relayer.cpp}, but all the below methods are available for
getting the message fields. (See today's lecture notes for a
description of a MOOS Message.)  This information is probably in the
MOOS documentation, but is repeated here for convenience.

\footnotesize
\begin{verbatim}

  // return the name of the message
  std::string GetKey();

  // return the name of the message (just another way)
  std::string GetName();

  // check data type is double
  bool IsDouble();

  // check data type is string
  bool IsString();

  // return time stamp of message
  double GetTime();

  // return double val of message
  double GetDouble();

  // return string value of message
  std::string GetString();

  // return the name of the process (as registered with the DB) which
  posted this notification
  std::string GetSource();

  // return the name of the MOOS community in which the orginator lives
  std::string GetCommunity();
\end{verbatim}
\normalsize

\vspace{0.1in} 
\noindent
Later on in this lab you will see that we provide a template for
generating the skeleton code of a new MOOS app. This is done using the
\cmd{GenMOOSApp} script. This skeleton code will generate the
following \var{OnNewMail()} method:

\vspace{0.1in}
\begin{fileverb}
bool MyApp::OnNewMail(MOOSMSG_LIST &amp;NewMail)
{
  MOOSMSG_LIST::iterator p;
  for(p=NewMail.begin(); p!=NewMail.end(); p++) {
    CMOOSMsg &amp;msg = *p;

#if 0 // Keep these around just for template 
    string key   = msg.GetKey();
    string comm  = msg.GetCommunity();
    double dval  = msg.GetDouble();
    string sval  = msg.GetString();
    string msrc  = msg.GetSource();
    double mtime = msg.GetTime();
    bool   mdbl  = msg.IsDouble();
    bool   mstr  = msg.IsString();
#endif
   }
   return(true);
}
\end{fileverb}

\vspace{0.1in}
\noindent
Note all the typical function calls you may want to make on an incoming 
MOOS message are right there, commented out to start with, but ready
to use if you need them in your application.

\input{./help_mip_extend}


%---------------------------------------------------------------------------
\subsection{A Peek Under the Hood}

Before moving on to write your first app, take a quick look at the
Relayer MOOS app class definition found in
\var{moos-ivp-extend/src/pXRelayTest/}. Note a couple things:

\begin{packed_itemize}[3]
\item The class declaration, on line 1, declares itself to be a
  subclass of CMOOSApp, the general superclass of all MOOS apps.
\item Our class overrides the three key virtual functions of the
  parent class, declared in lines 8-10.
\item Coding convention: All member functions are declared before all
  member variables. Overridden MOOSApp member functions are declared
  before subclass specific member functions.
\item Coding convention: All member variables begin with \var{m\_}, to
  set them apart from locally declared variables in the code.
\item Coding convention: All member variables protected. Setting member
  variables happens through a public member function, e.g., lines 14,15.
\end{packed_itemize}


%+++++++++++++++++++++++++++++++++++
\vspace{0.1in}
\begin{listing}{The file \var{moos-ivp-extend/src/pXRelayTest/Relayer.h}}
\label{block_xrelay}

\footnotesize
\begin{Verbatim}[frame=single]
  1  #include "MOOS/libMOOS/MOOSLib.h"
  2  class Relayer : public CMOOSApp
  3  {
  4   public:
  5    Relayer();
  6    virtual ~Relayer() {};
  7  
  8    bool OnStartUp();                        // Overriding key virtual function
  9    bool OnNewMail(MOOSMSG_LIST &amp;NewMail);   // Overriding key virtual function
 10    bool Iterate();                          // Overriding key virtual function
 11  
 12    bool OnConnectToServer();
 13    void RegisterVariables();
 14
 15    void setIncomingVar(std::string s) {m_incoming_var=s;}
 16    void setOutgoingVar(std::string s) {m_outgoing_var=s;}
 17  
 18   protected:
 19    unsigned long int m_tally_recd;
 20    unsigned long int m_tally_sent;
 21    unsigned long int m_iterations;
 22   
 23    std::string       m_incoming_var;
 24    std::string       m_outgoing_var;
 25    double            m_start_time_postings;
 26    double            m_start_time_iterations;
 27  };
\end{Verbatim}
\normalsize
\end{listing}
\vspace{0.04in}

%======================================================================
\newpage
\section{Build Your First MOOS App - An Odometry MOOS App}
%======================================================================

The Focus of this section is on building your first MOOS App. Your goals are:

\begin{packed_enumerate}[3]
\item Learn how to generate a MOOS application from scratch using a
  template-generating script.
\item Learn how to add the new MOOS application to the build system.
\item Write your new MOOS app, \app{pOdometry}, to calculate the total
  distance traveled by the vehicle.
\item Test your MOOS app by using it in the Alder example mission to 
  have the vehicle return after traveling 50 meters.
\item Convert your MOOS app into an AppCasting MOOS App.
\end{packed_enumerate}

%=====================================================================
\subsection{Part 1: Generating a Template App and Augmenting the Build System}

Your goal in this part is to generate a new application by using a
shell script to generate a full application template. The resulting
template should be buildable immediately without further modification,
but will essentially do nothing meaningful until you add your own
functionality.

%---------------------------------------------------------------------  
\subsubsection{Generate the MOOS App}

To generate the new MOOS app, in a terminal window change directories to
\var{moos-ivp-extend/src/}. From here you should be able to invoke the 
below command:

\vspace{0.1in}
\begin{consoleverb}
 $ GenMOOSApp Odometry p "Jane Doe"
\end{consoleverb}
\vspace{0.1in}

\noindent
The above script, \app{GenMOOSApp}, should be in your shell path under
\var{moos-ivp/bin/}, alongside all the other MOOS applications. The
above script invocation builds a new app called \app{pOdometry}. The third
argument is your name. You can type \app{GenMOOSApp -h} in the future
to remind yourself.

%---------------------------------------------------------------------  
\subsubsection{Add Your New Application to the Build System}

Add your new app to the build system. Edit the file
\var{moos-ivp-extend/src/CMakeLists.txt} and look for the line
referring to \app{pXRelayTest}. Copy that as an example for your new
app. 

\vspace{0.15in}
\begin{Verbatim}[frame=single]
 #==========================================================================
 # List the subdirectories to build...   
 #========================================================================== 
 ADD_SUBDIRECTORY(lib_behaviors-test)
 ADD_SUBDIRECTORY(pXRelayTest)
 ADD_SUBDIRECTORY(pExampleApp)
 ADD_SUBDIRECTORY(pOdometry)
\end{Verbatim}
\vspace{0.15in}

\noindent
Go back and re-run your build script. Check to see that
\app{pOdometry} has been built in your bin directory.

%---------------------------------------------------------------------  
\subsubsection{Add Your Name}


Always put your name at the top of your source code files!  This is a
good practice in general, but even more so in a class setting, or an
open source environment where people are sharing code. It wouldn't
hurt to add the date and organization information too.

%======================================================================
\subsection{Part 2: Writing the Odometry MOOS App}

The goal of this step is to build a new simple MOOS application that calculates
vehicle odometry. It will:

\begin{packed_enumerate}[3]
\item Register for the \mvar{NAV\_X} and \mvar{NAV\_Y} position of  the vehicle.
\item Repeatedly read in the \mvar{NAV\_X} and \mvar{NAV\_Y} position of
  the vehicle.
\item Update the total distance traveled by calculating the distance
  between the present position and the previous position.
\item Post the odometry information in the MOOS variable \mvar{ODOMETRY\_DIST}.
\end{packed_enumerate}

\pskip

\noindent
We will do this in your newly checked out moos-ivp-extend tree. Begin
as follows:

\begin{packed_itemize}[3]

\item Edit \var{Odometry.h} to have six member variables:
 
\vspace{0.15in}
\begin{Verbatim}[frame=single]
 bool   m_first_reading;
 double m_current_x; 
 double m_current_y; 
 double m_previous_x; 
 double m_previous_y; 
 double m_total_distance;
\end{Verbatim}

\item Edit \var{Odometry.cpp} initialize the above member variables, in the 
  class constructor.

\item Edit \var{Odometry.cpp} to register for \msvar{NAV\_X} and \msvar{NAV\_Y}.

\item Edit the \func{Odometry::OnNewMail()} method to handle the
  updated navigation position. Set \var{previous\_x} to
  \var{current\_x}, and \var{current\_x} to the new \msvar{NAV\_X}
  value. Same for Y.

\item Edit \func{Odometry::Iterate()} method to calculate the new
  distance. Handle the special case of the first navigation
  measurement. Post the total distance to the MOOS variable
  \msvar{ODOMETRY\_DIST}.

\item Verify that everything builds...
\end{packed_itemize}

%================================================================
\subsection{Part 3: Use Your pOdometry app in the Alder mission}

The first goal is to just make sure it runs and posts the correct
information.  The second goal is to use the information to alter the
mission behavior.

%----------------------------------------------------------
\subsubsection{Running the Un-modified Alder Mission}

First make sure that you can run the Alder mission. Try it:

\vspace{0.15in}
\begin{consoleverb}
 $ cd moos-ivp-extend/missions/alder
 $ pAntler --MOOSTimeWarp=10 alder.moos
\end{consoleverb}
\vspace{0.15in}

\noindent
It should look something like the video posted at:

\vspace{0.15in}
\begin{figure}[H]
  \centering 
  \includegraphics[width=0.99\textwidth]{educlips/Alder.png}
  \caption{The Alder mission.}
  \label{fig_alder}
  \urlvideo{https://vimeo.com/80730664}{0:13}
\end{figure}

%----------------------------------------------------------
\subsubsection{Run the Alder Mission with pOdometry}

Next we'll add the \app{pOdometry} application to the mission and just
verify it is generating the right output.  Do the following steps:

\begin{packed_itemize}[3]
\item Modify the Alder mission
  (\var{moos-ivp-extend/missions/alder/alder.moos}) to include
  \app{pOdometry} at launch time by editing the \app{Antler} block in the
  alder.moos file.

\item Add \mvar{ODOMETRY\_DIST} to the scope list in
  \app{pMarineViewer}. See the \app{pMarineViewer} documentation to
  see how to do this. It should look something like:

\prevblue
\begin{verbatim}
ProcessConfig = pMarineViewer
{
  AppTick    = 4
  CommsTick  = 4

  ...
  scope = ODOMETRY_DIST    // &lt;-- Add this line
  ...
}
\end{verbatim}
\postverb

\item Re-launch the mission. Now you should be able to see the odometry
distance in the scope field at the bottom of \app{pMarineViewer}. Does
it look correct?

\end{packed_itemize}


%----------------------------------------------------------
\subsubsection{Modify the Alder Mission Using pOdometry}

In the next step, we will modify the alder mission as follows. Instead
of transiting to the waypoint specified in the waypoint behavior, the
vehicle will return home after it has transited 50 meters. We haven't 
covered the Helm yet in class, so some of this we'll take on faith for 
now. 

\pskip
Take a look inside \var{alder.bhv}. This is where the helm is
configured.  The mission is comprised of two instances of a waypoint
behavior. The first transits to a given point and is called
\var{waypt\_to\_point}. It has two conditions, we'll add a third:

\prevbhv
\begin{verbatim}
 condition = RETURN = false
 condition = DEPLOY = true
 condition = (ODOMETRY_DIST &lt; 50)
\end{verbatim}
\postverb

\noindent
The second waypoint behavior is designed to return after the first one
completes. It also has two conditions:

\prevbhv
\begin{verbatim}
 condition = RETURN = true
 condition = DEPLOY = true
\end{verbatim}
\postverb

\noindent
We'll change that to:

\prevbhv
\begin{verbatim}
condition = (RETURN = true) or (ODOMETRY_DIST &gt;= 50)
condition = DEPLOY = true
\end{verbatim}
\postverb


\noindent
After the above modifications, re-launch the mission. It should look something
like:

\vspace{0.15in}
\begin{figure}[H]
  \centering 
  \includegraphics[width=0.99\textwidth]{educlips/AlderWithOdometry.png}
  \caption{The Alder mission running with the pOdometry app.}
  \label{fig_alder_with_odo}
  \urlvideo{https://vimeo.com/80755512}{0:06} \\
\end{figure}


%========================================================================
\subsection{Convert pOdometry to an AppCasting MOOSApp}

The last step will be to convert your \app{pOdometry} application to
be appcast enabled. Follow the instructions from the lecture notes, or
read the documentation for enabling appcasting:

\vspace{0.1in}
\noindent
\urlx{http://oceanai.mit.edu/ivpman/apps/AppcastEnable}

\vspace{0.15in}
\noindent 
The output of your appcast report (in the \func{buildReport()}
function) should simply show the total distance traveled.

\end{document}



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