<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">%====================================================================
\section{The IvP Helm as a MOOS Application}
%====================================================================
\wikisec{grp=moosivp,file=HelmAsMOOS,short=Helm as a MOOS App}
\label{sec_helm_moos}

In this section the helm is discussed in terms of its identity as a
MOOS application - its MOOS configuration parameters, its
\var{Iterate()} loop, its output to the console, and its output in
terms of publications to other applications running in the MOOS
community. The {\em helm state} and {\em all-stop status} are also
introduced since they are the highest level descriptions regarding
helm activity.

%====================================================================
\subsection{Overview}
\label{sec_helm_moos_overview}
The IvP Helm is implemented as the MOOS module called \app{pHelmIvP}.
On the surface it is similar to any other MOOS application - it runs
as a single process that connects to a running \app{MOOSDB} process
interfacing solely by a publish-subscribe interface, as depicted in
Figure \ref{helm_app}. It is configured from a behavior file, or
\var{.bhv} file, in addition to the MOOS file used to configure other
MOOS applications.  The helm primarily publishes a steady stream of
information that drives the platform, typically regarding the desired
heading, speed or depth. It may also publish information conveying
aspects of the autonomy state that may be useful for monitoring,
debugging or triggering other algorithms either within the helm or in
other MOOS processes. The helm can be configured to generate decisions
over virtually any user-defined decision space.

\vspace{0.2in}

\begin{figure}[H]
  \centering 
  \includegraphics[width=0.7\textwidth]{figs_helm/helm-configure.png}
  \caption{{\bf The \app{pHelmIvP} MOOS application}: The IvP Helm is
    implemented as the MOOS application \vvar{pHelmIvP}. The helm is
    configured with two files - the mission file and behavior
    file. Once launched it connects to the \app{MOOSDB} along with
    other MOOS applications performing other functions. Information
    flowing into the helm include both sensor information and command
    and control inputs. The helm produces commands for maneuvering the
    vehicle along with other status information produced by active
    behaviors.}
\label{helm_app}
\end{figure}

\vspace{0.15in}

\index{Behavior Subscriptions}
\index{IvP Behaviors!Subscriptions}
The helm subscribes for sensor information or any other information it
needs to make decisions. This information includes navigation
information regarding the platform's current position and trajectory,
information regarding the position or state of other vehicles, or
environmental information. The information it subscribes for is
prescribed by the behaviors themselves, configured in the \var{.bhv}
file.  In addition to sensor information, the helm also receives some
level of command and control information. For example, in some marine
vehicle configurations, one of the "Other MOOSApp" modules in the
figure is a driver for an acoustic modem over which command and
control information may be relayed.

\pskip

The helm has a couple informative high-level state descriptions, the
{\em helm state} and the {\em all-stop status}, that may be compared
to the operation of an automobile.  Launching the \app{pHelmIvP} MOOS
process is analagous to turning on the car's engine. Putting the helm
in the \var{DRIVE} mode is like shifting the car from "Park" to
"Drive". And the all-stop status refers whether or not the car is
breaking to a stop. The analogy is summarized below.

\begin{figure}[H]
  \centering 
  \includegraphics[width=0.68\textwidth]{figs_helm/car_analogy.png}
  \caption{{\bf The Helm/Automobile Analogy}: The helm and its
    high-level state descriptions, the {\em helm state} and {\em
      all-stop status}, have analogies with the operation of an
    automobile.}
\label{fig_car_analogy}
\end{figure}


%====================================================================
\subsection{The Helm State}
\label{sec_helm_state}
\index{Helm State}
\index{DRIVE@\var{DRIVE}}
\index{PARK@\var{PARK}}
\index{IvP Helm!Helm State}

The highest level interface with the helm is reflected in the {\em
  helm state}.  The helm state may have one of two values, {\em park}
or {\em drive} (except when using a {\em standby helm} described in
Section \ref{sec_standby_helm}) In the {\em drive} mode, the helm is
likely in the process of executing a mission. In the {\em park} mode,
the helm is waiting, likely because it is being asked to wait, but
also because the helm may have noticed something wrong (generated an
all-stop) and subsequently put itself into {\em park} on its own,
awaiting a the chance to return to the {\em drive} state. In this
section we discuss (a) how the helm state is changed, (b) what it is
going on in the helm when it is parked, and (c) how the helm state is
initialized at start-up. At any point in time after the helm is
launched, the helm will post the MOOS variable \mvar{IVPHELM\_STATE}
with either the value \var{"DRIVE"}, \var{"PARK"} or
\var{"MALCONFIG"}. This is posted on each iteration and registering
for this mail is the manner recommended by which other MOOS
applications monitor the helm's heart beat.

\index{Helm State!Transitions}

%------------------------------------------------------------------
\subsubsection{Helm State Transitions}

The helm state may be transitioned by writing to the MOOS variable
\mvar{MOOS\_MANUAL\_OVERIDE}. As Figure \ref{fig_helm_state} depicts,
a value of \var{false}, which is case insensitive, transitions the
helm state into \var{DRIVE}. A value of \var{true} puts it into the
\var{PARK}. When the helm transitions from \var{DRIVE} to \var{PARK}
it makes {\em one} more publication to the helm decision variables,
each with a value zero. This is referred to as the production of an
{\em all-stop posting}, discussed in more detail in a later section.

\index{IvP Domain}

\vspace{0.2in}

\begin{figure}[H]
  \centering 
  \includegraphics[width=0.73\textwidth]{figs_helm/helm_engage.png}
  \caption{{\bf The Helm State of the IvP Helm}: The helm state has a
    value of either \vvar{PARK} or \vvar{DRIVE}, depending on both how
    the helm is initialized and the mail received by the helm after
    start-up on the variable \vvar{MOOS\_MANUAL\_OVERIDE}. The helm
    may also park itself if an all-stop event has been detected.}
\label{fig_helm_state}
\end{figure}

\vspace{0.15in}

The variable \mvar{MOOS\_MANUAL\_OVERIDE} contains the mis-spelling of
"override". However, it is a variable that has some legacy presence
in other MOOS applications such as \app{iRemote}. To avoid a situation
where there is an attempt to override the helm, but the request is
ignored because of a (proper) spelling, the helm will also respect
transition requests on the properly spelled variable
\mvar{MOOS\_MANUAL\_OVERRIDE}. This has the drawback however that these
two variables could conceivably have different values in the \app{MOOSDB}.
This is not a problem but could be confusing for someone trying to
infer the helm state by opening a scope on the \app{MOOSDB}, on either the
wrong variable or the two disagreeing variables. In this case the helm
state would be aligned with the variable with the most recent
publication time stamp. In any event, the best way to monitor the helm
state is to scope on the MOOS variable \mvar{IVPHELM\_STATE},
published by the helm itself, or use the \app{uHelmScope} tool.

\pskip

The helm may also automatically transition itself from the \var{DRIVE}
to the \var{PARK} state (but never the other way around), by posting
an all-stop event. All-stop events and the helm are discussed
separately in Section \ref{sec_allstop}. All-stop events are generated
by the helm upon finding that one or more possible error conditions
have been detected during the normal execution of the helm
iteration. If the helm parks due to an all-stop, it may be returned to
the \var{DRIVE} state by another MOOS client posting
\mvar{MOOS\_MANUAL\_OVERIDE=false}, but this is no guarantee that the
helm wouldn't just park again immediately if the same condition
persists that caused the all-stop event.

%------------------------------------------------------------------
\subsubsection{What Is and Isn't Happening when the Helm is Parked}

When the helm state is \var{PARK}, the MOOS application loop depicted
in Figure \ref{fig_cmoosapp} carries on.  The \var{OnNewMail()}
continues to be called and new mail is read and dealt with exactly as
it would if the helm state were \var{DRIVE}. The \var{Iterate()} loop,
however, is truncated to virtually a no-op, with the only action being
the output of a heartbeat character to the console if the helm is
configured to do so (Section \ref{launching_helm}). No behavior code
is called whatsoever. The helm iteration counter, a key index in the
\app{uHelmScope} output, is also suspended despite the fact that
technically the \var{Iterate()} loop continues to be called.

%------------------------------------------------------------------
\subsubsection{Initializing the Helm State at Process Launch Time}
\index{IvP Helm!Initial Helm State}
\index{Helm State!On Helm Start-Up}
\index{Helm State!\var{START\_IN\_DRIVE}}

The helm, by default, is configured to be initiallly in \var{PARK}
upon start-up. By setting the parameter \pvar{start\_in\_drive=true} in
the mission file configuration block, the helm will indeed be in the
\var{DRIVE} upon start-up.  This feature was found to have practical
use in UUV operations to allow for rebooting of the autonomy computer
to automatically launch the helm, in \var{DRIVE} and ready to accept
field commands. This feature should be used with caution, and it may
be phased out in a later software release.

%====================================================================
\subsection{Helm All-Stop Events and All-Stop Status}

\label{sec_allstop}
\index{All-Stop}
\index{IVPHELM\_ALLSTOP@\var{IVPHELM\_ALLSTOP}}
\index{IvP Helm!All-Stop}

An {\em all-stop event} is something that brings the vehicle to a
full-stop, with typically zero-speed, zero-depth commanded. The {\em
  all-stop status} is simply a string describing {\em why} the vehicle
is at an all-stop.  Sometimes an all-stop indicates a problem, e.g.,
missing critical sensor information.  Sometimes a vehicle may just
stop as part of the mission, e.g., coming to the surface for a GPS
fix. The all-stop status message can be used to discern the two types
of situations. In the automobile analogy, an all-stop is equivalent to
hitting the car's breaks with the intent to stop completely.  An
all-stop event will result in the following:

\begin{itemize}
\item Zero-values will be posted for all decision variables,
  \mvar{DESIRED\_SPEED=0}, \mvar{DESIRED\_DEPTH=0}, etc.

\item The helm will possibly transition into \var{PARK}.  By default
  the helm is configured to remain in the \var{DRIVE} upon an all-stop
  event, but if configured instead with \pvar{park\_on\_allstop}
  \psvar{= true}, the helm will indeed park upon an all-stop.

\item The reason for the all-stop will be posted to MOOS variable
  \mvar{IVPHELM\_ALLSTOP}. The value of this variable will be
  \var{"clear"} if there are no all-stop events that have occurred
  since the helm has entered the \var{DRIVE} state.
\end{itemize}

\noindent
The reasons for all-stop may be:

\begin{itemize}

\item No behaviors are active. The helm has absolutely no opinion
  about any of its decision variables. In this case, the following 
  would be posted: \mvar{IVPHELM\_ALLSTOP} \msvar{="NothingToDo"}.

\item Some behaviors are active, but decisions are missing on one or
  more mandatory decision variables. In this case, the following would
  be posted: \mvar{IVPHELM\_ALLSTOP} \msvar{="MissingDecVars"}.

\item When the vehicle is parked due to manual override, the following
  would be posted: \mvar{IVPHELM\_ALLSTOP} \msvar{="ManualOverride"}.

\item One of the behaviors has determined an all-stop is warranted for
  some reason. For example, a waypoint behavior that cannot determine
  own-platform's current position would declare an all-stop.  In this
  case, the following would be posted:
  \mvar{IVPHELM\_ALLSTOP} \msvar{="BehaviorError"}. 
\end{itemize}

\noindent
To gain further insight on an all-stop caused by a behavior error, the
nature of the error is expressed in a separate posting to the MOOS
\mvar{BHV\_ERROR} variable. It's possible that more than one behavior
error occurred in the helm iteration where the all-stop event
occurred, in which case there would be multiple postings to the
\mvar{BHV\_ERROR} variable. When the vehicle is in \var{DRIVE} and
operating free of an all-stop, the all-stop status is reflected by
\mvar{IVPHELM\_ALLSTOP} \msvar{="clear"}.

%====================================================================
\subsection{Parameters for the pHelmIvP MOOS Configuration Block }
\label{helm_parameters}
\index{IvP Helm Parameters}

The following configuration parameters are defined for the helm.
The parameter names are case insensitive.

\vspace{0.15in}

\begin{listing}{Configuration Parameters for pHelmIvP}

\renewcommand{\arraystretch}{1.1}
\begin{longtable}{rp{0.76\textwidth}} 
\label{lst_phelmivp_params}

\pvar{allow\_park}: &amp; If false, the helm cannot be put into
\var{PARK}. This parameter is not mandatory. The default is true.
Section \ref{hparam_allowpark}. \\

\pvar{behaviors}: &amp; The name and location of the behavior configuration
file. This parameter is not mandatory, but typically it is
used. Technically the helm can be launched from the command line and
provided the behavior file on the command line. Section
\ref{hparam_behaviors}. \\

\pvar{ivp\_behavior\_dir}: &amp; A directory to look for dynamically loaded
behaviors. This parameter is not mandatory, since the directory
information may also be handled using a shell environment variable.
Section \ref{hparam_bhvdir}. \\

\pvar{community}: &amp; Global MOOS parameter. Determines ownship
name. This parameter is mandatory, but it is provided outside the helm
configuration block and used by other applications.  Section
\ref{hparam_community}. \\

\pvar{park\_on\_allstop}: &amp; If true helm will park on all-stop. This
parameter is not mandatory and the default is false. Secttion
\ref{hparam_allowpark}. \\

\pvar{domain}: &amp; The decision space for the IvP Solver. This parameter
is mandatory. Section \ref{hparam_domain}. \\

\pvar{hold\_on\_app}: &amp; A list of MOOS apps to wait for before the
helm publishes postings from behaviors' \var{onHelmStart()} function
calls. Available after Release 17.7.x. Section \ref{hparam_hold_on_app}. \\

\pvar{ok\_skew}: &amp; The tolerance on the age, in seconds, of incoming
mail before rejected as being too old. This parameter is not
mandatory. Section \ref{hparam_okskew}. \\

\pvar{other\_override\_var}: &amp; The parameter names an additional MOOS
variable acting as \mvvar{MOOS\_MANUAL\_OVERIDE}. This parameter is
not mandatory. Section \ref{hparam_otherover}. \\

\pvar{start\_in\_drive}: &amp; Determines whether or not the helm is in
override mode at start-up. This parameter is not mandatory. The
default is false. Secton \ref{hparam_astart}. \\

\pvar{helm\_prefix}: &amp; Add a prefix to all the \var{DESIRED\_*} helm output.
For example \pvar{helm\_prefix=FOO\_} would result in \mvar{FOO\_DESIRED\_SPEED}
and so on. Introduced after Release 19.8.x \\

\pvar{verbose}: &amp; Determines verbosity of terminal output - \pvar{quiet}, 
\pvar{terse}, or \pvar{verbose}. This parameter is not mandatory. The 
default is \pvar{verbose}. Section \ref{hparam_verbose}. \\ 

\end{longtable}
\end{listing}


\vspace{0.05in}

%------------------------------------------------------------------
\subsubsection{The \pvar{allow\_park} Parameter}
\label{hparam_allowpark}
\index{IvP Helm!Helm State}
\index{IvP Helm!Manual Override}

Optional. By setting this parameter to \var{false}, the helm cannot be
manually overriden (parked) once it has been put into
\var{DRIVE}. This can be dangerous and should be carefully considered,
and thus the default is \var{true}. This option was implemented based
on experiences with launching UUV autonomy missions and preventing an
inadvertent park due to a remote login to the vehicle. There was a
tendency for some users to use \app{iRemote} upon remote login to
interact with MOOS, and \app{iRemote} posts
\mvar{MOOS\_MANUAL\_OVERIDE} \msvar{=true} upon launch and connection
to the \app{MOOSDB}.

%------------------------------------------------------------------
\subsubsection{The \pvar{behaviors} Parameter}
\label{hparam_behaviors}
\index{Behavior Files!Loading}

Optional (sort of). The parameter names the behavior file, i.e.,
\var{*.bhv} file, on the local file system from which the helm
behaviors are read.  More than one file may be specified on separate
lines, and the helm will read in all files almost as if they were one
single file. This is technically an optional parameter because a
behvior file could be provide on the command line. A behavior file
must be specified via one means or the other.  If a behavior file is
specified {\em both} on the command line and in the \app{pHelmIvP}
configuration block with this parameter, they will both be used to
configure the helm behaviors.


%------------------------------------------------------------------
\subsubsection{The \pvar{behavior\_dir} Parameter}
\label{hparam_bhvdir}
\index{Behavior Files!Loading}

Optional. The parameter names a directory in the local files system
where the helm is to look for dynamically loadable behaviors (as
opposed to default set built in statically to the helm). Authors
augmenting the helm with their own behaviors will need to specify the
location of those behaviors with this parameter. More than one line 
may be provided, each specifying a different directory location.

%------------------------------------------------------------------
\subsubsection{The \pvar{community} Parameter}
\label{hparam_community}
\index{MOOS!Community}

This parameter is defined at the "global" level outside of any MOOS
process' configuration block. See Section \ref{moos_config}. The helm
reads this parameter and uses its value as the name associated with
"ownship". It is a mandatory parameter.

%------------------------------------------------------------------
\subsubsection{The \pvar{park\_on\_allstop} Parameter}
\label{hparam_park_on_allstop}
\index{Helm State!Relation to All-Stop}
\index{IvP Helm!Helm State}
\index{IvP Helm!All-Stop}

Optional. By setting this parameter to \var{true}, the helm will
park when an all-stop event occurs.  The default setting is
\var{false}.

%------------------------------------------------------------------
\subsubsection{The \pvar{domain} Parameter}
\label{hparam_domain}
\index{IvP Domain}

Mandatory. This parameter prescribes the decision space of the
helm. It consists of one line per decision variable. Each line
contains a colon-separated list of four fields. Field one is the
domain variable name, field two is the lower bound value, field three
is the higher bound value, and field four is the number of points in
the domain. For example \pvar{domain} \psvar{= speed:0:3:16} shown in
Listing \ref{helmivp_block} indicates a domain variable called
"speed", with a lower and upper bound 0 and 3 meters/second
respectively. Since there are 16 points, the speed choices are 0, 0.2,
0.4, ..., 2.8, 3.0.  The helm requires that a decision be made on all
listed variables on each iteration of the control loop. If a variable
is used by some behaviors but is not necessarily involved in all
decisions, it can be declared as optional. For example
\psvar{domain=speed:0:3:16:optional}.

%------------------------------------------------------------------
\subsubsection{The \pvar{ok\_skew} Parameter}
\label{hparam_okskew}
\index{Skew|see{MOOS Messages, Skew}}
\index{MOOS Messages!Skew}

Optional.  This parameter sets the allowable skew tolerated by the
helm for receiving incoming mail messages. If a clock skew is detected
greater than this value, the message will be ignored. A check for
skews can be disabled by setting \var{ok\_skew=any}. The default
value is 60 seconds.

%------------------------------------------------------------------
\subsubsection{The \pvar{other\_override\_var} Parameter}
\label{hparam_otherover}

Optional.  This parameter names a MOOS variable the helm will regard
as being synonomous with the two default variables accepted for manual
override, \mvar{MOOS\_MANUAL\_OVERRIDE}, and the legacy mispelling of
this variable, \mvar{MOOS\_MANUAL\_OVERIDE}.


%------------------------------------------------------------------
\subsubsection{The \pvar{start\_in\_drive} Parameter}
\label{hparam_astart}
\index{Helm State!\var{start\_in\_drive}}

Optional. This parameter is set to either \var{true} or
\var{false}. The default is \var{false} as the helm normally starts in
\var{PARK} and needs to receive MOOS mail on the variable
\mvar{MOOS\_MANUAL\_OVERIDE} with the value of this variable set to
\var{false}. When \pvar{start\_in\_drive} is set to \var{true}, the
helm is in the \var{DRIVE} state upon start-up. The issue of helm
state was discussed in more detail in Section \ref{sec_helm_state}.

%------------------------------------------------------------------
\subsubsection{The \pvar{hold\_on\_app} Parameter}
\label{hparam_hold_on_app}

Optional. Available after Release \var{17.7.x}. This parameter names
one or more MOOS apps that the helm will monitor in the
\var{DB\_CLIENTS} list.  Once it has seen each named app at least
once, the helm will release all mail generated by behaviors through
their \var{onHelmStart()} function.

\vspace{0.1in}
\noindent
This may be useful for behaviors that produce configuration
information to other support applications. Examples include the
\app{pBasicContactMgr} and \app{pTaskManager} application. These apps
need to be told by the behaviors the nature of alerts that may be
generated, potentially resulting in spawned behaviors. If the
behaviors produce multiple postings of the same MOOS variable, and
those postings occur before the intended recipient apps have come on
line (connected to the MOOSDB), then they may only receive the last
piece of mail. With this utility, the helm will wait until all named
apps are connected before posting the \var{onHelmStart()} mail.

\vspace{0.1in}
\noindent
The parameter may take a comma-separated list of apps, or multiple
lines may be provided. The following two styles are equivalent:

\noindent
\pvar{hold\_on\_app = pBasicContactMgr, pTaskManager}

\noindent
and

\noindent
\pvar{hold\_on\_app = pBasicContactMgr} \newline
\pvar{hold\_on\_app = pTaskManager}


%------------------------------------------------------------------
\subsubsection{The \pvar{verbose} Parameter}
\label{hparam_verbose}
\index{IvP Helm!Console Output}

Optional. This parameter affects how much information is written to
the terminal on each iteration of the helm. The possible values are
{\em verbose}, {\em terse}, or {\em quiet}. The {\em verbose} setting
will write a brief helm report to the terminal on each iteration. With
the {\em terse} setting minimal output will be produced, a '*'
character when not producing helm commands, and a '\$' character when
active and healthy. With the {\em quiet} setting, no output at all
will be written to the terminal. The default value is {\em
  terse}. This setting can be changed after the helm is started by
changing the value of
\mvar{HELM\_VERBOSE} in the \app{MOOSDB}.

%------------------------------------------------------------------
\subsubsection{An Example pHelmIvP MOOS Configuration Block }
Below is an example configuration block for the helm.  
\vspace{0.1in} 

\begin{listing}{An example \var{pHelmIvP} configuration block}
\label{helmivp_block}
\scriptsize
\begin{verbatim}
  1 //-------- pHelmIvP configuration block  -------------
  2 ProcessConfig = pHelmIvP
  3 {
  4   AppTick    = 4   // Defined for all MOOS processes
  5   CommsTick  = 4   // Defined for all MOOS processes
  6
  7   domain     = course:0:359:360
  8   domain     = speed:0:3:16
  9   domain     = depth:0:500:101
 10   	
 11   behaviors  = foobar.bhv  
 12   verbose    = terse
 13   ok_skew    = ANY
 14
 15   start_in_drive  = false
 16   allow_park      = true
 17   park_on_allstop = false
 18 }
\end{verbatim}
\end{listing}
\normalsize
\vspace{0.1in}

\noindent
The \pvar{AppTick} and \pvar{CommsTick} parameters are defined for all
MOOS processes (see \cite{new03}) and specify the frequency in which
the helm process iterates and communicates with the \app{MOOSDB}. The 
\var{community} parameter is not included in the configuration block
because it is specified at the global level in the mission file.

%====================================================================
\subsection{Launching the Helm and Output to the Terminal Window}
\label{launching_helm}
\index{IvP Helm!Console Output}

The helm can be launched either directly from the command line, 
or from within Antler. On the command line the usage is as follows:

\footnotesize
\begin{verbatim}
  Usage: pHelmIvP file.moos [file.bhv]...[file.bhv]     
         [--help|-h] [--version|-v]                     
                                                      
  [file.moos] Filename to get MOOS config parameters.   
  [file.bhv]  Filename to get IvP Helm config paramters.
  [-v]        Output version number and exit.           
  [-h]        Output this usage information and exit.   
\end{verbatim}
\normalsize

\noindent
If no behavior file is specified in the \var{.moos} file then a
behavior file must be given on the command line. Multiple behavior
files may be provided. Order of the arguments do not matter - command
line arguments ending in \var{.bhv} will be read as behavior files,
and those ending with \var{.moos} as MOOS files. The specification of
behavior files may also be split between references in the \var{.moos}
file and the command line. The duplicate specification of a single
file will simply be ignored.  Typical start-up output to the terminal
is shown in Listing \ref{helm_output} below.

\vspace{0.12in}

\begin{listing}{Example start-up output generated by the pHelmIvP process}
\label{helm_output}
\scriptsize
\begin{verbatim}
 0  ****************************************************
 1  *                                                  *
 2  *       This is MOOS Client                        *
 3  *       c. P Newman 2001                           *
 4  *                                                  *
 5  ****************************************************
 6  
 7  ---------------MOOS CONNECT-----------------------
 8    contacting a MOOS server localhost:9000 -  try 00001 
 9    Contact Made
10    Handshaking as "pHelmIvP"
11    Handshaking Complete
12    Invoking User OnConnect() callback...ok
13  --------------------------------------------------
14  
15  The IvP Helm (pHelmIvP) is starting....
16  Loading behavior dynamic libraries....
17      Loading directory: /Users/mikerb/project-colregs/src/lib_behaviors-colregs
18  Loading behavior dynamic libraries - FINISHED.
19  Number of behavior files: 1
20  Processing Behavior File: bravo.bhv  START
21      Successfully found file: bravo.bhv
22      InitializeBehavior: found static behavior BHV_Loiter
23      InitializeBehavior: found static behavior BHV_Loiter
24      InitializeBehavior: found static behavior BHV_Waypoint
25      InitializeBehavior: found static behavior BHV_Timer
26  Processing Behavior File: bravo.bhv  END
27  pHelmIvP is Running:
28  	 AppTick   @ 4.0 Hz
29  	 CommsTick @ 4 Hz
30  	 Time Warp @ 1.0 
31  $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
\end{verbatim}
\end{listing}
\normalsize

\vspace{0.12in}

The output in lines 0-13 are standard output generated by a MOOS
process launched and successfully connected to a running \app{MOOSDB}. Lines
15-30 are start-up output generated unique to the helm and the
particular user usage.  Behaviors used by the helm are either static
or dynamic. Static behaviors are compiled in to the pHelmIvP
executable. Dynamic behaviors are brought in at run time via shared
libraries compiled separately. The helm looks for an environment
variable \var{IVP\_BEHAVIOR\_DIRS} for a colon-separated list of
directories to search for shared libraries. If this variable is not
set, or if one or more of the directories are not legitimate
directories, an error message will indicate so between what is
otherwise line 16 and 18 in Listing \ref{helm_output}. This kind of
error may not actually be problematic if the behaviors specified in
the behavior file can all be otherwise successfully found.

\pskip

For each specified behavior file, the information shown in lines 20-26
is generated to the terminal. For each behavior configuration in a
given \var{.bhv} file, a single line is output as in lines 22-25
indicating that the behavior type is recognized and it is configured
properly.  \index{Behavior Files!Syntax checking} A single
unrecognized behavior or improper configuration will result in (a) an
error message indicating the offending line number and file name, (b)
the output of the actual offending line, and (c) immediate
disconnection of the process from the \app{MOOSDB} and exit. (Tip: If the
helm is launched with Antler an error during start-up will result in
the closing of the \app{pHelmIvP} console window which makes it hard
to catch useful error output for debugging.  In this case, the helm
should just be launched outside of Antler in its own terminal window.)

\pskip

The output on line 31 of Listing \ref{helm_output}, a series of dollar
sign characters, indicates for each character, the completion of a
single helm iteration - a heartbeat output. This is the output when
the \pvar{verbose} parameter is set to the default setting of
\var{terse}. When set to \var{quiet} no output is generated at
all. When set to \var{verbose}, a short multi-line report is generated
for each iteration. An example is shown below in Listing
\ref{helm_summary}:

\vspace{0.12in}

\begin{listing}{An example helm iteration report generated by an active helm}
\label{helm_summary}
\scriptsize
\begin{verbatim}
 1  Iteration: 161  ******************************************
 2  Helm Summary  ---------------------------
 3  loiter_a did NOT produce an obj-function
 4  loiter_b produces obj-function - time:0.00 pcs: 9.00000 pwt: 100.00000
 5  waypt_return did NOT produce an obj-function
 6  loiter_timer did NOT produce an obj-function
 7  Number of Objective Functions: 1
 8  DESIRED_SPEED:  2.10
 9  DESIRED_COURSE:  145.00
10  (End) Iteration: 161  ******************************************
\end{verbatim}
\end{listing}
\normalsize

\vspace{0.1in}

On each iteration the Helm Summary indicates which behaviors produced
objective functions (lines 2-5), and for those that did, it indicates
the CPU time needed to generate the function, the number of pieces in
the piecewise linear IvP function, and its priority weight. Following
this, the decision rendered for current iteration is output with one
line per decision variable (lines 7-8). This is a very thin summary of
what is going on within the helm and it should be noted that the
\app{uHelmScope} tool is a much better suited for monitoring helm
activity and debugging. 


%====================================================================
\subsection{Publications and Subscriptions for IvP Helm}
\index{Publications and Subscriptions!pHelmIvP}

The IvP Helm, like any MOOS process, can be specified in terms of its
interface to the \app{MOOSDB}, i.e., what variables it publishes and
what variables it subscribes for. It is impossible to provide a
complete specification here since the helm is comprised of behaviors,
and the means to include any number of third party behaviors. Each
behavior is able to post variable-value pairs, published to the
\app{MOOSDB} by the helm on behalf of the behavior at the end of the
iteration. Likewise, each behavior may declare to the helm any number
of MOOS variables it would like the helm to register for on its
behalf. Barring these variables, published and subscribed for by the
helm on behalf of individual behaviors, this section addresses the
remaining portion of the helm's publish - subscribe interface.

%------------------------------------------------------------------
\subsubsection{Variables published by the IvP Helm}
\label{sec_helm_pubs}
\index{IvP Helm!Publications}

Variables published by the IvP Helm are summarized below. 

\vspace{0.05in}

\begin{packed_itemize}[2]
\item \mvar{IVPHELM\_SUMMARY}: Produced on each iteration of the helm
  for consumption by the \app{uHelmScope} application,
  \cite{url_uhelmscope}.  It contains information on the current helm
  iteration regarding the number of IvP functions created, create
  time, solve time, which behaviors are active, running, idle, and the
  decision ultimately produced during the iteration. The summary does
  not include every component in each summary. Components that have
  not changed in value since the prior summary are dropped from the
  present summary. This is motivated by the goal to reducing the log
  file footprint for the helm.

\item \mvar{IVPHELM\_STATEVARS}: Produced periodically by the helm for
  consumption by the \var{uHelmScope} application,
  \cite{url_uhelmscope}. It contains a comma-separated list of MOOS
  variables involved in preconditions of any behavior, i.e., variables
  affecting behavior run states.

\item \mvar{IVPHELM\_DOMAIN}: Produced once by the helm at start-up
  for consumption by the \var{uHelmScope} application. It contains the
  specification of the IvP Domain in use by the helm.

\item \mvar{IVPHELM\_MODESET}: Produced once by the helm at start-up
  for consumption by the \var{uHelmScope} application. It contains the
  specification of the Hierarchical Mode Declarations, if any, in use
  by the helm.

\item \mvar{IVPHELM\_STATE}: Written by the helm on each iteration of
  the \app{pHelmIvP} MOOS application, regardless of whether the helm
  is in the \var{DRIVE} state or not.  (see Section
  \ref{sec_helm_state}). It is either \var{"DRIVE"} or
  \var{"PARK"}. This is the recommended MOOS variable for
  regarding as a "heartbeat" indicator of the helm.

\item \mvar{HELM\_IPF\_COUNT}: Produced on each iteration of the helm.
  It contains the number of IvP functions involved in the solver on
  the current iteration.

\item \mvar{CREATE\_CPU}: The CPU time in seconds used in total by all
  behaviors on the current iteration for constructing IvP functions.
 
\item \mvar{LOOP\_CPU}: The CPU time in seconds used by the IvP solver
  in the current helm iteration.

\item \mvar{BHV\_IPF}: The helm will publish this variable for each
  active behavior in the current iteration. It contains a string
  representation of the IvP function produced by the behavior. It is
  used for visualization by the \app{uFunctionVis} application, and 
  for logging and later playback and analysis.

\item \mvar{PLOGGER\_CMD}: This variable is published with the below
value to ensure that the \app{pLogger} application logs the \var{.bhv}
file along with the other data log files and the \var{.moos} file.
\end{packed_itemize}

\footnotesize
\begin{verbatim}
  "COPY_FILE_REQUEST = filename.bhv"
\end{verbatim}
\normalsize

\begin{packed_itemize}[2]
\item \mvar{DESIRED\_*}: Each of the decision variables in the
  IvPDomain provided in the helm configuration will have a separate
  posting prefixed by \msvar{DESIRED\_} as in \msvar{DESIRED\_SPEED}. One
  exception is that the variable \var{course} will be converted to
  \var{heading} for legacy reasons.

\item \mvar{BHV\_WARNING}: Although this variable may never be posted, 
it is the default MOOS variable used when a behavior posts a warning. 
A warning may be harmless but deserves consideration.

\item \mvar{BHV\_ERROR}: Although this variable may never be posted, 
it is the default MOOS variable used when a behavior posts what it
considers a fatal error - one that the helm will interpret as a 
request to generate the equivalent of ALL-STOP.
\end{packed_itemize}

\noindent
In addition to the above variables, the helm will post any
variable-value pair on behalf of a behavior that makes the
request. These include endflags, runflags, idleflag, activeflags and
inactiveflags.

%------------------------------------------------------------------
\subsubsection{Variables Subscribed for by the IvP Helm}
\index{IvP Helm!Subscriptions}
\label{sec_helmsubs}

Variables subscribed for by the IvP Helm are summarized below:

\vspace{0.1in}

\begin{packed_itemize}[2]
\item \mvar{MOOS\_MANUAL\_OVERIDE}: When set to \var{true}, usually by
  a third-party application such as \app{iRemote}, of from a
  command-and-control communication, the helm may relinquish control.
  If the helm was configured with \pvar{active\_start} \psvar{= true},
  it will not relinquish control (this may be changed).

%\item \var{RESTART\_HELM}: When the helm receives mail on this
%  variable, regardless of value, it will re-read the \var{.moos} file
%  and subsequently the \var{.bhv} file. 

\item \mvar{HELM\_VERBOSE}: Affects the console output produced by the
  helm. Legal values are \var{verbose}, \var{terse}, or \var{quiet}.
  See Section \ref{launching_helm}.

\item \mvar{HELM\_MAP\_CLEAR}: When received, the helm clears an
  internal map that is used to surpress repeated duplicate postings.
  See Section \ref{auto_filter}. 
\end{packed_itemize}

\noindent
In addition to the above variables, the helm will subscribe for any
variable-value pair on behalf of a behavior that makes the
request. This includes, but is not limited to, variables involved in
the \bvar{condition} and \bvar{updates} parameters available generally
for all behaviors.


%====================================================================
\subsection{Using a Standby Helm}
\label{sec_standby_helm}

A {\em standby helm} refers to the launching of a second helm running
alongside another otherwise normally-configured primary helm. This is
done to mitigate the risk associated with the possible failure of the
primary helm. Both helms are instances of the \app{pHelmIvP} MOOS
application configured with a different mission and/or
behaviors. Presumably the standby helm is configured with a simpler,
more conservative set of behaviors focused on the safe recovery of a
vehicle. Although provisions are generally made during vehicle
operations to detect a missing helm heartbeat, in situations such as
the operation of a UUV under ice, it is not acceptable to simply have
a vehicle halt and come to the surface. An attempt should be made to 
execute a simpler mission to return the vehicle to a safe location
for recovery. 

\pskip

Use of a standby helm is as simple as adding a second configuration
block in the \var{.moos} configuration file. The Kilo mission in
Section \ref{exmissions_s11} demonstrates a mission using the standby
helm. Declaring a second helm as a standby helm requires a single
additional line of the form

\small
\begin{verbatim}
  STANDBY = N
\end{verbatim}
\normalsize

\noindent
where \var{N} is the number of seconds a standby helm will tolerate an
absent primary helm heartbeat before taking control from away the
primary helm. See Listing \ref{lst_kilo_helms} for an example. {\em Once
  a standby helm take-over is triggered, the take-over is
  irreversible.}

%------------------------------------------------------------------
\subsubsection{Two Types of Helm Failure, the Causes, and Detection}

What does a helm crash mean, and how might it happen? A crash is
result of code that causes the process to quit unexpectedly and
without warning. A line as simple as \var{assert(0);} in the code
would be sufficient to replicate a crash, but the cause of a crash
could be much more subtle due referencing memory not properly
allocated and so on. The other type of helm failure is a helm that
{\em hangs}. This refers to the scenario where the helm enters a piece
of code that takes too long or never finishes execution. This could be
as trivial as reaching the line \var{while(1);} somewhere in the
code. Either type of failure is serious. Despite the fact that we have
never experienced these failures in any field exercise on any vehicle,
the sudden disappearance of the helm process should be considered and
handled as gracefully as possible.

\pskip

How is a helm failure detected? The helm produces a heartbeat message
on each iteration by posting to the variable \pvar{IVPHELM\_STATE}. If
the helm is configured to iterate four times per second, suspicion of
failure could begin anytime after a quarter of a second passes without
a posting to this variable. Under typical helm CPU load with common
standard behaviors, the quarter second interval should be sufficient
to finish the iteration. There are additional factors to consider
however. There may be other processes on the machine dominating the
CPU, thus challenging the helm to do its work in the expected
time. There may be a periodic behavior calculation, such as
recalculating a long path of waypoints, that may cause a spike in CPU
cycles needed by the behavior. As a rule of thumb, the interval of
time with the absence of a heartbeat, should arguably be two seconds
or more before declaring a helm failure. This interval is directly
configurable, as the parameter \var{N}, in the \pvar{standby}\psvar{=N}
configuration line.

%------------------------------------------------------------------
\subsubsection{Handling a Helm Crash with the Standby Helm}

A helm {\em crash} is the easier of the two failure cases to
handle. The process is simply gone and no longer publishes to the
\app{MOOSDB}. Of course the other MOOS processes, including the standby
helm, have no way of knowing simply through their MOOS mailbox
whether or not the primary helm is gone or just delayed. In either 
case the sequence of events is the following:

\begin{enumerate}

\item The standby helm detects the absence of heartbeat for more than 
\var{N} seconds.

\item On the very same iteration, the standby helm posts
  \mvar{IVPHELM\_STATE} \msvar{= DRIVE+} rather than
  \mvar{IVPHELM\_STATE} \msvar{= STANDBY} which it had been posting on
  every iteration up until now. It also begins posting a desired helm
  decision on this iteration.

\end{enumerate}

The standby helm has all the same functionality as the primary helm,
modulo the behavior and mission configuration. It will be in the
\var{DRIVE} state only if not manually overridden. If
\mvar{MOOS\_MANUAL\_OVERRIDE=true} when the standby helm takes over, it
will be in initially in \var{PARK}, not \var{DRIVE}. It will post
\mvar{IVPHELM\_STATE}\mvar{=PARK+}. Note the standby helm will append the
\var{'+'} character to the helm state string to help other
applications and the user discern that the helm state being posted is
from a standby helm that has taken control.

\pskip

The Kilo example mission in Section \ref{exmissions_s11} walks through
a simulated helm crash. The output of the helm(s) prior to and after
the standby takeover is discussed in Figure \ref{fig_kilo_uxms_three}.

%------------------------------------------------------------------
\subsubsection{Handling a Hung Helm with the Standby Helm}

Handling a helm that has {\em hung} requires a bit more consideration.
The tricky part is that quite possibly the hung helm is only {\em
  temporarily} hung, and at some point it will become unhung and may
operate for a single iteration as if it is still the helm in charge. Two
helms, with different missions, both thinking they are in charge! The 
sequence of events is summarized below:

\begin{enumerate}

\item The standby helm detects the absence of heartbeat for more than
\var{N} seconds.

\item On the very same iteration, the standby helm posts
  \mvar{IVPHELM\_STATE} \msvar{= DRIVE+} rather than
  \mvar{IVPHELM\_STATE} \msvar{= STANDBY} which it had been posting on
  every iteration up until now. It also begins posting a desired helm
  decision on this iteration.

\item Some time later, the original primary helm finishes its iteration
   and posts a helm decision, e.g., a set of postings to the helm
   decision variables, \mvar{DESIRED\_HEADING} etc.

\item On the next iteration of the original primary helm it notices
  that another helm has posted a non-standby heartbeat, e.g., a
  posting to \mvar{IVPHELM\_STATE} not equal to \var{"STANDBY"}.

\item The original primary helm posts an all-stop and
  \mvar{IVPHELM\_STATE} \msvar{= DISABLED}.  It is the last time it
  will post a heartbeat or helm decision.

\item The standby helm continues to be in control posting helm 
  decisions oblivious to the former primary helm's epiphany and
  temporary influence.

\end{enumerate}

The key issue in this scenario is that the original primary helm does
indeed post a helm decision when it becomes un-hung even though the
standby helm may have long ago taken over and may be posting a sequence
of helm decisions completely at odds with the decision posted by the
newly awakened un-hung primary helm. 

\pskip

No assumptions can be made about the MOOS process listening to the 
sequence of helm decisions. It may be payload interface process, 
or a native PID controller, or some other process responsible for 
converting helm decisions to lower level actuator commands. The 
assumption that {\em is} made here is that a one-time aberation in
the sequence in helm decisions is tolerable. This aberation is not
going to result in an actuator breaking due to a sudden change in
the command sequence such as high-speed, zero-speed, high-speed.

\pskip

It's also worth noting that original primary helm, upon awakening and
learning it is no longer in control, does indeed post one more helm
decision, an all-stop decision (\mvar{DESIRED\_SPEED} \msvar{=
  0}). This is done to ensure that an all-stop decision, that may have
been put into effect by the standby helm, is not superceded by the
output of the original primary helm's final helm decision made upon
wakeup.

%------------------------------------------------------------------
\subsubsection{Activity of the Standby Helm While Standing By}

In the standby state the helm will do nothing in its iterate loop
other than post a heartbeat character to the terminal if configured to
do so. It will not call on any behaviors to do anything. The helm will
however read and process all of its otherwise subscribed for mail.  In
particular it will monitor for postings to \mvar{IVPHELM\_STATE}, and
will initiate a take-over when it hasn't received such mail for
\var{N} seconds. Note the standby helm also publishes to this
variable, \mvar{IVPHELM\_STATE} \msvar{= STANDBY}, but ignores mail
originating from itself.

\pskip

The helm will also read and process all other mail in its inbox,
updating the helm's information buffer.  The helm's information buffer
is described in detail in Section \ref{sec_ibuff}. Note that the
information buffer also keeps a {\em history} of postings to a
particular variable so that normally a behavior may process multiple
postings if multiple postings were made to the \app{MOOSDB} between helm
iterations.  This history is cleared by the helm at the end of each
helm iteration.  When the helm is in the standby state it will also
clear the history after each iteration even though the behaviors have
not been given the chance to access this history. This is to ensure
that the information buffer history doesn't grow without bound while
in standby mode. For example, if the standby and primary helm are
both configured with a waypoint behavior and the primary helm visits 
half the points at the point of a helm crash, the standby helm's 
waypoint behavior would start with the first waypoint.

%------------------------------------------------------------------
\subsubsection{Activity of the Primary Helm After Take-Over}

A primary helm that has been taken over is refered to as a {\em
  didsabled} helm. It will post only once \mvar{IVPHELM\_STATE}
\msvar{= DISABLED}. The helm process lives on however doing next to
nothing. It does not read its mail, and the iterate loop simply posts
a heartbeat character (\var{'!'}) to the terminal if configured to do
so, with the helm configuration parameter \psvar{verbose=terse}.

%====================================================================
\subsection{Automated Filtering of Successive Duplicate Helm Publications}
\label{auto_filter}
\index{IvP Helm!Duplication Filter}
\index{Duplication Filter}

The helm implements a "duplication filter" to drastically reduce the
amount of mail posted by the helm on behalf of behaviors. This filter
has been noted to reduce the overall log file size seen during
in-water exercises by 60-80\%. Reductions at this level noticably
facilitate the use of post-mission analysis tools and data
archiving. For the most part this filter is operating behind the
scenes for the typical helm user. However, knowledge of it is indeed
relevant for users wishing to implement their own behaviors, and we
discusss it here to explain a bit what is behind the variable
\mvar{HELM\_MAP\_CLEAR} to which the helm subscribes, and listed above
in Section \ref{sec_helmsubs}.

%------------------------------------------------------------------
\subsubsection{Motivation for the Duplication Filter}

The primary motivation of implementing the duplication filter is to
reduce the amount of unnecessary mail posted by the helm on behalf
behaviors, and thereby greatly reduce the size of log files and
facilitate the post-mission handling of data. By unnecessary we mean
successive variable-value pairs that match exactly in both fields.
Surely there are cases when a behavior developer may not want this
filter, and there are simple ways to bypass the filter for any post.
But in most cases, successive duplicate posts are just redundant and
unnecessary. 

%------------------------------------------------------------------
\subsubsection{Implementation and Usage of the Duplication Filter}
\index{Behavior-Posts}

The helm keeps two maps (STL maps in C++), one for string data and one
for numerical data: 

\footnotesize
\begin{verbatim}
   KEY --&gt; StringValue
   KEY --&gt; DoubleValue
\end{verbatim}
\normalsize

\noindent
The two maps correspond to the double and string message types in MOOS
(see Section \ref{sec_moosmsg}).  The
\var{KEY} is typically the MOOS variable name. Inside a behavior
implementation, the following four functions are available:

\footnotesize
\begin{verbatim}
    void postMessage(string varname, string value, string key="");
    void postMessage(string varname, double value, string key="");
    void postBoolMessage(string varname, bool value, string key="");
    void postIntMessage(string varname, double value, string key="");
\end{verbatim}
\normalsize

\noindent
These functions are available in all behavior implementations because
they are defined in the IvPBehavior superclass, of which all behaviors
are subclasses. Before the helm posts a message to the \app{MOOSDB}
the filter is applied by a simple check to its map to determine if
there is a value match on the given key. If a match is made, the post
will not be made to the \app{MOOSDB} on the behavior's behalf. The
\func{postIntMessage()} function is merely a convenience version of the
\func{postMessage()} function that rounds the variable value to the
nearest integer to further reduce posts when combined with the filter.
The \func{postBoolMessage()} ultimately posts a string value
\var{"true"} or \var{"false"}.

\pskip

The default value of the {\em key} parameter is the empty string, and
in most cases this parameter can be ommitted without disabling the
duplication filter. This is because the \var{KEY} used by the caller
is only part of the key actually used by the duplication filter. The
actual key is the concatenation of (a) the behavior name, (b) the
variable name, and (c) the key passed by the caller. Thus the default
value, the empty string, still results in a decent key being used by
the filter. The key is augmented by the behavior name because often
there is more than one behavior posting messages on same variable.
The optional key parameter is used for two reasons. First, it can be
used to further distinguish posts within a behavior on the same
variable name. Second, when the key value has the special value
\var{"repeatable"}, then no key is used and the duplication filter is
disabled for that variable posting.

\pskip

\noindent
Two additional convenience functions are availble:

\footnotesize
\begin{verbatim}
    void postRepeatableMessage(string varname, string value);
    void postRepeatableMessage(string varname, double value);
\end{verbatim}
\normalsize

\noindent
A posting of \var{postRepeatableMessage("FOO", 100)} is equivalent to
\var{postMessage("FOO", 100, "repeatable")}.

%------------------------------------------------------------------
\subsubsection{Clearing the Duplication Filter}

Occasionally a user, or another MOOS application in the same community
as the helm, may want to "clear" the map used by the helm to
implement its duplication filter. This can be done by writing to
variable \mvar{HELM\_MAP\_CLEAR}, with any value. This may be necessary
for the following reason. Suppose a GUI application subscribes for the
variable \mvar{VIEW\_SEGLIST} which contains a list of line segments
for rendering. If the viewer application is launched {\em after} the
variable is published, the application will only receive the most
recent mail on the variable \mvar{VIEW\_SEGLIST}. There may be
publications to this variable, made prior to the most recent
publication, that are relevant to the GUI application at launch time.
Those publications for the variable \mvar{VIEW\_SEGLIST} may not be the
most recent from the perspective of the \app{MOOSDB}, but they may be
the most recent from the perspective of a particular behavior in the
helm. By clearing the filter, it gives each behavior the chance to
once again have all of its variable-value posts made to the
\app{MOOSDB}. In the \app{pMarineViewer} application, a publication to
\mvar{HELM\_MAP\_CLEAR} is made upon start-up.  Clearing the filter
will only clear the way for the next post for a given variable. It
will not result in the publishing to the \app{MOOSDB} of the contents of the
maps used by the filter.

%\noindent
%\begin{table}[bh]
%\renewcommand{\arraystretch}{1.1}
%\begin{minipage}[c]{0.95\textwidth}
%  \centering
%  \mbox{
%  \footnotesize
%\begin{tabular}{p{1.0\textwidth}}
%  {\bf Historical Note:} The \var{uHelmScope} tool was developed 
%  in the early summer of 2008. Implementing the \var{uHelmScope} tool
%  meant the addition of the \var{IVPHELM\_*} variables published by the
%  helm. During field exercises in GLINT'08 later that summer with NURC
%  in Italy, the problem of log file bloat reared its ugly head. The 
%  Duplication Filter was implemented on that cruise, put into use only
%  during the last few days of exercises. The log files archived for 
%  those few weeks were huge, save the last few days.
%\end{tabular}
%\normalsize}
%\end{minipage}
%\label{t_hist}
%\end{table}

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