\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}
%===================================================================
\setcounter{tocdepth}{2}
%===================================================================

\begin{document}
\wikidoc{file=MCA.Lab07MOOSProgramming}
\wikidoc{auth=mikerb@mit.edu}
\helplevelsubsec


%===================================================================
% Build the Cover Page in an environment style easy for wiki parsing
\begin{labcover}
\labtitle{Lab 7 - Introduction to MOOS Programming}
\vspace{0.1in}
\labpng{0.42}{figures/longfellow_rnd.png}
\vspace{0.1in}
\labdate{June, 2026}
\vspace{0.1in}
\labauth{Michael Benjamin, mikerb@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

%===================================================================
\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.

\vspace{0.1in}
\noindent
Topics:

\begin{labinfo}
\begin{packed_itemize}[2]
\item Extending MOOS-IvP with your own tree and your own new MOOS App
\item MOOS App primary methods: Iterate, OnNewMail, OnStartUp
\item MOOS App Message Structure and Parsing
\item Integrating your MOOS App into a mission
\end{packed_itemize}
\end{labinfo}

%---------------------------------------------------------------------
\subsection*{Assignments/Milestones}

There are four milestones (assignments) in this lab. You can consider
yourself done when all four have been completed. There are a few
additional option tasks provided at the end if you have time.

\begin{packed_itemize}[2]
\item The moos-ivp-extend tree is downloaded, built, added to shell path
\item Build the pOdometry app. It should measure total vehicle odometry
  as the platform moves through the water, and publishes this information
  to the MOOSDB. It should respond to a reset MOOS message, resetting
  the odometry value to zero. 
\item Run a simple mission using the pOdometry app to return a vehicle
  home automatically when it reaches an odometry distance. 
\item Modify the mission to reset the odometry automatically upon
  return, triggering the vehicle to re-deploy once again until the
  target odometry distance has been achieved.
\end{packed_itemize}


%===================================================================
\section{Background Info on Writing MOOS Applications}
%===================================================================

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

In the previous lab 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}. MOOS-IvP provides additional MOOS
applications, including the IvP Helm behavior-based architecture, and
has C++ build dependencies on the MOOS libraries. Today 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. You likely have already downloaded and
built this tree if you finished the last part of the previous lab.

\vspace{0.1in}
\begin{figure}[H]
  \centering 
  \includegraphics[width=0.85\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}

%==========================================================================
\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 application author. 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.

\vspace{0.1in}
\noindent
The key components to keep in mind in today's 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.3in}
\begin{figure}[H]
  \centering 
  \includegraphics[width=0.55\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}

%==========================================================================
\subsection{A Template OnNewMail() function with Utilities for Mail Parsing}

In this lab we ask that you create a new MOOS app by starting with a
template MOOS app using the \cmd{GenMOOSApp\_Appcasting} script. This
skeleton code will generate the following \var{OnNewMail()} method:

\vspace{0.1in}
\begin{fileverb}
bool MyApp::OnNewMail(MOOSMSG_LIST &NewMail)
{
  MOOSMSG_LIST::iterator p;
  for(p=NewMail.begin(); p!=NewMail.end(); p++) {
    CMOOSMsg &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. (Everything between the 
\var{if 0} and \var{endif} is ignored by the compiler, so these lines
have the same effect as comment lines.)

%========================================================================
\section{Assignment 1: Download and Build the moos-ivp-extend Tree}
%======================================================================

If you have not yet obtained the \var{moos-ivp-extend} tree, please
read through the following: 

\vspace{0.1in}
\noindent
\mvar{Green Lab:} \urlg{MCP.MOOSIvPExtend # Getting the moos-ivp-extend tree} 

\vspace{0.1in}
\noindent
Add the \var{bin/} directory of this tree to your shell path. If you
need help in modifying your shell path, see the section on this
in the following: 

\vspace{0.1in}
\noindent
\mvar{Green Lab:} \urlg{MCP.GrnShellEnv # Shell Environment and Aliases}


%======================================================================
\section{Assignment 2: 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{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}
\label{sec_gen_moosapp}

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_AppCasting Odometry p "Jane Doe"
\end{consoleverb}
\vspace{0.1in}

\noindent
The above script, \app{GenMOOSApp\_AppCasting}, should be in your
shell path under \var{moos-ivp/scripts/}. You may need to add this
directory to your shell path if you haven't done so already. The
directory \var{moos-ivp/bin/} is very likely already in your path. But
here we need to add this sister directory to your path.

\vspace{0.1in}
\noindent
The above script invocation builds a new app called
\app{pOdometry}. The third argument is your name. You can type
\app{GenMOOSApp\_AppCasting -h} in the future to remind yourself.

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

Always, always, 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.

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

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{fileverb}
 #==========================================================================
 # List the subdirectories to build...   
 #========================================================================== 
 ADD_SUBDIRECTORY(lib_behaviors-test)
 ADD_SUBDIRECTORY(pXRelayTest)
 ADD_SUBDIRECTORY(pExampleApp)       
 ADD_SUBDIRECTORY(pOdometry)                 <-- Add your line here
\end{fileverb}
\vspace{0.05in}

%======================================================================
\subsection{Verify Skeleton pOdometry has Built}
\label{sec_path}

Go back and re-run your build script. Check to see that
\app{pOdometry} has been built, and is in your bin directory (e.g.,
\var{moos-ivp-you/bin)}.

\vspace{0.1in}
\noindent
Verify that \app{pOdometry} is in your shell path with:

\vspace{0.1in}
\begin{consoleverb}
  $ which pOdometry
  $ /home/you/moos-ivp-you/bin/pOdometry
\end{consoleverb}
\vspace{0.1in}

\noindent
If the \cmd{which} function returns no value, then either the binary
\app{pXRelayTest} was not built or you haven't successfully augmented
your shell path. See above in Section \ref{sec_assign1} for tips on how
to remedy the problem.



%======================================================================
\subsection{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}.
\item The posted odometry distance should be consistent regardless of
  the AppTick of the \app{pOdometry} app. You can check this by
  changing the AppTick of your app while leaving the AppTick of
  \app{uSimMarineV22} unchanged.
\end{packed_enumerate}

\vspace{0.1in}
\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 at least the 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}

\noindent
You may of course use further member variables if you see the need. 

\item Edit \var{Odometry.cpp} to 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.

\item Edit the \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}

\noindent
There is one common "gotcha" in this lab. Keep in mind that the
\msvar{NAV\_X} and the \msvar{NAV\_Y} variables are being published by
the \app{uSimMarineV22} application. This application is running at 10Hz
and producing on average 10 incoming mail messages for your
\app{pOdometry} app. If your \app{pOdometry} app is running at the
default rate of 4Hz, then on average your app will have 2-3 incoming
mail messages on each iteration. If you find that your odometry
calculations only reflect about half of the actual distance traveled,
reconsider how you are calculating the length of new legs.

%================================================================
\section{Assignment 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.

\vspace{0.1in}
\noindent
{\bf NOTE:} Depending on when you cloned the \var{moos-ivp-extend} tree,
you may need to ensure that all references to \app{uSimMarine} are replaced
with \app{uSimMarineV22} and all references to \app{pMarinePID} are replaced
with \app{pMarinePIDV22}, in the \var{alder.moos} file.

%================================================================
\subsection{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}

%================================================================
\subsection{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:

\vspace{0.1in}
\begin{fileverb}
ProcessConfig = pMarineViewer
{
  AppTick    = 4
  CommsTick  = 4

  ...
  scope = ODOMETRY_DIST    // <-- Add this line
  ...
}
\end{fileverb}
\vspace{0.1in}

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


%================================================================
\subsection{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. 

\vspace{0.1in}
\noindent
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:

\vspace{0.1in}
\begin{fileverb}
//----------------------------------------------
Behavior = BHV_SimpleWaypoint
{
  name      = waypt_to_point
  pwt       = 100
  condition = RETURN = false
  condition = DEPLOY = true
  condition = (ODOMETRY_DIST < 50)         // <-- Add this line

  endflag   = RETURN = true

  speed      = 2.0   // meters per second
  radius     = 8.0
  ptx        = 100
  pty        = -50
}
\end{fileverb}
\vspace{0.1in}

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

\vspace{0.1in}
\begin{fileverb}
 condition = RETURN = true
 condition = DEPLOY = true
\end{fileverb}
\vspace{0.1in}

\noindent
We'll change that to:

\vspace{0.1in}
\begin{fileverb}
condition = (RETURN = true) or (ODOMETRY_DIST >= 50)
condition = DEPLOY = true
\end{fileverb}
\vspace{0.1in}

%================================================================
\subsection{Verify Your pOdometry Works}

After the above modifications, re-launch the mission. Demonstrate to
one of the TAs that your \app{pOdometry} works. 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}

%========================================================================
\section{Assignment 4: Resetting the Odometer}
%========================================================================

Your \app{pOdometry} app should also register for the MOOS variable
\mvar{RESET\_ODO}. When this mail is received with value \var{"true"},
it should reset the odometry running distance to zero.

\vspace{0.1in}
\noindent
Modify your Alder mission to (a) have the return behavior post an
end flag of \mvar{RESET\_ODO=true} when it returns home, and (b)
have the vehicle subsequently re-deploy after it has returned home
and its odometer has been reset. It should do this endlessly.


%======================================================================
\newpage
\section{Some Hints for Debugging}
%======================================================================

There are a few common methods for debugging a MOOS App, and we'll
have more to say about this during the semester. But here are a few
methods. The third method described below is a new feature added only
in the last six months and is probably you most powerful option.

%======================================================================
\subsection{Run the Logger}

If your Alder mission is not yet including \app{pLogger}, you will need to
add it to your mission for these steps.

\vspace{0.1in}
\noindent
To add \app{pLogger} to your mission, add it the Antler config block
with the additional line:

\vspace{0.1in}
\begin{fileverb}
  Run = pLogger @ NewConsole = false
\end{fileverb}
\vspace{0.1in}

\vspace{0.1in}
\noindent
You will also need a configuration block for \app{pLogger} in the same mission file,
e.g., \var{alder.moos}. The below block should work fine:

\vspace{0.1in}
\begin{fileverb}
ProcessConfig = pLogger
{
  AppTick   = 8
  CommsTick = 8

  AsyncLog = true
  WildCardLogging = true
}
\end{fileverb}
\vspace{0.1in}

%======================================================================
\subsection{Debugging with Additional MOOS Publications}

In this lab, the primary output of your app is the variable
\mvar{ODOMETRY\_DIST}. You are free to publish as many other variables
as you like, to perhaps reveal any intermediate calculations, or other
information. For example you can publish \mvar{LEG\_DIST} if you are
calculating the distance one leg at a time.

\vspace{0.1in}
\noindent
To utilize this method, you will need to either (a) scope on this
additional variable while the mission is running, or (b) examine the
variable from the log file after the mission is complete. The latter
method gives you more time to ponder the values. To examine the
log file, you can use \cmd{aloggrep}, along the lines of:

\vspace{0.1in}
\begin{consoleverb}
$ aloggrep logfile.alog ODOMETRY_DIST LEG_DIST
\end{consoleverb}
\vspace{0.1in}

\vspace{0.1in}
\noindent
Or you can open \cmd{alogview} and scope on the above two variables using the
\var{VarHist} pull-down menu. See the documentation for \app{alogview}. Either
point your browser to:

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

\vspace{0.1in}
\noindent
Or, on the command line, just type the below, and your browser should take you there.

\vspace{0.1in}
\begin{consoleverb}
$ alogview --web
\end{consoleverb}
\vspace{0.1in}

%======================================================================
\subsection{Debugging with Terminal Output, Method 1}

Another powerful method for debugging is to add \var{cout} statements
to your code, to show intermediate values. So, for example, instead of
publishing \mvar{LEG\_DIST} as a MOOS variable, you can instead add
something like this to your code:

\vspace{0.1in}
\begin{fileverb}
double leg_dist = ...
cout << "Leg dist: " << leg_dist << endl;
\end{fileverb}
\vspace{0.1in}

\noindent
To see this output, you would need to launch your app with a terminal
window open, OR remove your app from the Antler block and run it
separately from another terminal window. So in the first terminal
window:

\vspace{0.1in}
\begin{consoleverb}
$ ./launch.sh
\end{consoleverb}
\vspace{0.1in}

In the second terminal window:

\vspace{0.1in}
\begin{consoleverb}
$ pOdometry file.moos
\end{consoleverb}
\vspace{0.1in}

\noindent
Make sure you use the same \var{.moos} file in both launches. And note
that if you launch your mission with a time warp, \app{Antler} will
generate a \var{file.moos++} mission file with the proper time
warp. You would then need to launch your app with the same
\var{.moos++} file to get the same time warp.

%======================================================================
\subsection{Debugging with Terminal Output, Method 2 (Recommended)}

If you have successfully created your app as an AppCasting MOOS App,
then there is another simpler option for debugging with terminal
output.

\vspace{0.1in}
\noindent
As above, inject your code with \var{cout} statements to produce what
you would like. But rather than running your app in a separate
Terminal window, simply add the below line to the configuration block
for your app:

\vspace{0.1in}
\begin{fileverb}
app_logging = log
\end{fileverb}
\vspace{0.1in}

\noindent
This will log all the terminal output from your app in the \var{alog}
file. Then you can view your terminal output by launching
\app{alogview}. Once this is launched, select \var{AppLog} from the
pull-down menu, select the vehicle name, and select your app from the
list. You should then be able to see all your terminal output.


%======================================================================
\newpage
\section{Additional Exercises}
%======================================================================

%======================================================================
\subsection{Adding Terminal Output to your App for Debugging}

At some point you will need to debug a faulty app. A powerful tool for
doing this is to generate terminal output (\var{cout} commands). In
this exercise we will generate some simple output and show how we can
view this output {\em after} the mission has completed using the
\app{alogview} tool.


\begin{packed_itemize}
\item Make sure your app is AppCast enabled if it is not already.
\item Add terminal output in your app to show each new \mvar{NAV\_X}
  and \mvar{NAV\_Y} received, e.g., \newline \var{cout << "nav\_x: "
    << value << endl;}

  
\item Add terminal output in your app to show each new value of
  \mvar{ODOMETRY\_DIST} calculated.
\item Enable app logging by setting \var{app\_logging=log} in the
  \app{pOdometry} configuration block of your misssion file.
\item Run your mission to completion.
\item Find the alog file and launch \app{alogview} on this alog file.
\item Select \var{AppLog} from the pull-down menu and confirm that you
  can see your terminal output.
\end{packed_itemize}

\vspace{0.1in}
\noindent
Note that some of this functionality could also be achieved by
generating AppCasting output. This is not a replacement for that. One
advantage of AppLogging is that terminal output can be captured
regardless of the level of code being executed. The \var{cout} call
may be used in code that is called by your app several levels down.

%======================================================================
\subsection{Adding Run-Time Checks for Steady Nav Information}

Another powerful tool for developing robust apps is the use of run
time err checking. AppCasting MOOS Apps support this with the
\var{reportRunWarning()} function. In this exercise:

\begin{packed_itemize}
\item Add a timestamp (a new member variable) to note when the latest
  \mvar{NAV\_X} or \mvar{NAV\_Y} was received.
\item If an interval of 10 seconds or more passes, without receiving
  new NAV info, generate a run warning.
\item Retract this warning when or if the NAV info resumes.
\item To test this, run the Alder mission as normal. In another
  terminal window, type \var{killall uSimMarineV22}. This will halt
  the NAV info. Verify the run warning appears in your Odometry app.
\item Then, also in a separate terminal window in your Alder mission,
  restart the simulator with \var{uSimMarineV22 alder.moos}.
\item  Show a TA.
\end{packed_itemize}

%======================================================================
\subsection{Bonus: Configure the Staleness Threshold}

To gain some experience with configuration parameters:

\begin{packed_itemize}
\item Add a configurtion parameter to set the staleness threshold to
  something else besides the above default of 10 seconds.
\item You will need to make this value a variable in your MOOS App
  instead of the the hard-coded \var{"10"} as before.
\item Perform a check on the configuration parameter that it is a
  number greater than zero. If a user provides a faulty number in the
  mission file, produce a configuration warning.
\item Show a TA.  
\end{packed_itemize}

%======================================================================
\subsection{Bonus: Configurable Units}

Parameters that may be configured at {\em launch-time} are sometimes
also configurable at {\em run-time}. There are many reasons for
this. The two most-common reasons are (1) a parameter setting {\em
  augments} a set of parameters given at launch-time, with additional
components that become known at run-time. (2) a parameter setting may
involve the verbosity of output, perhaps in toggling on/off the
publication of a MOOS variable providing debugging output. The need
for debugging verbosity may change during run-time.

\vspace{0.1in}
\noindent
In this last bonus exercise, the task is to augment the \app{pOdometry}
app with the ability to configure an additional publication of odometry
distance in any arbitrary units provided either at configuration time
or at run-time.

\end{document}
