<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">%=====================================================================
\section{The Loiter Behavior}
%=====================================================================
\label{bhv_loiter}
%\index{Loiter Behavior}

A behavior for transiting to and repeatedly traversing a set of
waypoints forming a convex polygon. A similar effect can be achieved
with the Waypoint behavior but this behavior assumes a set of
waypoints forming a convex polygon to exploit certain useful
algorithms discussed below.  It also utilizes the non-monotonic
arrival criteria used in the Waypoint behavior to avoid loop-backs
upon waypoint near-misses. It also robustly handles dynamic exit and
re-entry modes when or if the vehicle diverges from the loiter region
due to external events. t is dynamically reconfigurable to allow a
mission control module to repeatedly reassign the vehicle to different
loiter regions by using a single persistent instance of the behavior.


%=======================================================================
\subsection{Configuration Parameters}

\input{includes/bhv_all_properties}

\vspace{0.15in}
\begin{listing}{Configuration Parameters for the Loiter Behavior}
\label{lst_bhv_loiter}
\small
\renewcommand{\arraystretch}{1.15}
\begin{longtable}{rp{0.7\textwidth}} 

  {\bf Parameter} &amp; {\bf Description} \\  

  \bvar{acquire\_dist}: &amp; Distance to polygon outside which the
  behavior will be in "acquire" mode. Section
  \ref{sec_loiter_acquire_param}. \\
  
  \bvar{capture\_radius}: &amp; The radius tolerance, in meters, for
  satisfying the arrival at a point. Section
  \ref{sec_loiter_radius_params}. \\
  
  \bvar{center\_activate}: &amp; If true, center of polygon is set to
  present position when behavior activates. Section
  \ref{sec_loiter_updates}. \\
  
  \bvar{center\_assign}: &amp; An x,y pair, in meters, indicating a (new) 
  center of the loiter polygon. Section \ref{sec_loiter_updates}. \\ 
  
  \bvar{clockwise}: &amp; If true, loitering is done clockwise (the
  default setting). Section \ref{sec_loiter_clockwise}. \\ 
  
  \bvar{polygon}: &amp; Polygon about which the vehicle will traverse and 
  loiter. Section \ref{sec_loiter_poly}. \\ 
  
  \bvar{post\_suffix}: &amp; A string to add as a suffix to variables
  posted by this behaviors. Section \ref{sec_loiter_suffix_param}. \\
  
  \bvar{radius}: &amp; An alias for \bvar{capture\_radius}. Section
  \ref{sec_loiter_radius_params}. \\
  
  \bvar{slip\_radius}: &amp; An "outer" capture radius. Arrival declared
  when the vehicle is in this range and the distance to the point
  begins to increase. Section \ref{sec_loiter_radius_params}. \\ 
  
  \bvar{speed}: &amp; Speed in meters per second. Section
  \ref{sec_loiter_speed_param}. \\
  
  \bvar{speed\_alt}: &amp; An alternative desired speed (m/s) at which the
  vehicle travels through the points. Applies only when the
  \bvar{use\_alt\_speed} parameter is set to true. The default is -1,
  which indicates internally that it has not been set. Section
  \ref{sec_loiter_speed_alt_param}. \\ (Introduced after release 15.5.) \\

  \bvar{spiral\_factor}: &amp; The degree of spiraling when activated at
  the center of the polygon. Section \ref{sec_loiter_spiral_param}. \\
  
  \bvar{use\_alt\_speed}: &amp; If true then attempt to use the alternate
  speed set with the \bvar{speed\_alt} parameter, if that speed is set
  to a non-negative value. The default is false. Section
  \ref{sec_loiter_speed_alt_param}. \\(Introduced after release
  15.5.)\\
  
  \bvar{visual\_hints}: &amp; Hints for visual properties in variables
  posted intended for rendering. Section \ref{sec_loiter_visual_hints}. \\ 
  
  \bvar{xcenter\_assign}: &amp; A x-value, in meters, indicating a (new) 
  x-position of the loiter polygon. Section \ref{sec_loiter_updates}. \\ 
  
  \bvar{ycenter\_assign}: &amp; A y-value, in meters, indicating a (new) 
  y-position of the loiter polygon. Section \ref{sec_loiter_updates}. \\ 
  
\end{longtable}
\end{listing}
\normalsize

\vspace{0.15in}
\begin{listing}{Example Configuration Block}
\label{lst_bhv_loiter_exmin}

\begin{fileverb}
Behavior = BHV_Loiter
{
  // General Behavior Parameters
  // ---------------------------
  name         = transit               // example
  pwt          = 100                   // default
  condition    = MODE==LOITERING       // example
  updates      = LOITER_UPDATES        // example

  // Parameters specific to this behavior
  // ------------------------------------
       acquire_dist = 10               // default
     capture_radius = 3                // default  
    center_activate = false            // default
          clockwise = true             // default
        slip_radius = 15               // default
              speed = 0                // default
      spiral_factor = -2               // default

            polygon = radial:: x=5,y=8,radius=20,pts=8  // example
        post_suffix = HENRY                             // example

      center_assign = 40,50            // example
     xcenter_assign = 40               // example
     ycenter_assign = 50               // example


       visual_hints = vertex_size  = 1             // default
       visual_hints = edge_size    = 1             // default
       visual_hints = vertex_color = dodger_blue   // default
       visual_hints = edge_color   = white         // default
       visual_hints = nextpt_color = yellow        // default
       visual_hints = nextpt_lcolor = aqua         // default
       visual_hints = nextpt_vertex_size = 5       // default
       visual_hints = label        = zone3         // example
}
\end{fileverb}
\end{listing}


%=======================================================================
\subsection{Variables Published}

The below MOOS variables will be published by the behavior during
normal operation, in addition to any configured flags. A variable
published by any behavior may be suppressed or changed to a different
variable name using the \bvar{post\_mapping} configuration parameter
described in Section \ref{sec_bhv_post_mapping}.

\begin{packed_itemize}[2]

  \item \mvar{LOITER\_ACQUIRE}: Posts 1 when in the "acquire" mode, 0
    otherwise.
    
  \item \mvar{LOITER\_DIST\_TO\_POLY}: Current distance, in meters, to
    the loiter polygon.

  \item \mvar{LOITER\_ETA\_TO\_POLY}: Estimated time of arrival to the
    polygon at present speed and trajectory.

  \item \mvar{LOITER\_INDEX}: The index of the vertex in the loiter
    polygon currently heading toward.

  \item \mvar{LOITER\_MODE}: A string indicating details of the
    acquire mode, e.g., \bvar{"acquiring\_external"}.

  \item \mvar{LOITER\_REPORT}: A status string with current mode, current 
    vertex, and prior arrivals. 

  \item \mvar{VIEW\_POINT}: A visual cue for rendering the next point
    in the loiter polygon.

  \item \mvar{VIEW\_POLYGON}: A visual cue for rendering the loiter
    polygon.

\end{packed_itemize}

\noindent
The following are some examples:

\prevgreen
\begin{verbatim}
         LOITER_REPORT = index=5,capture_hits=51,nonmono_hits=0,acquire_mode=false
          LOITER_INDEX = 5
        LOITER_ACQUIRE = 1
   LOITER_DIST_TO_POLY = 2.2
    LOITER_ETA_TO_POLY = 294.4
           LOITER_MODE = stable
          VIEW_POLYGON = edge_size,0.0:vertex_size,0.0:0,-50:0,-150:150,-150:150,-50
\end{verbatim}
\postverb

%=======================================================================
\subsection{Detailed Discussions on Loiter Behavior Parameters}

%----------------------------------------------------------------------
\subsubsection{The \bvar{polygon} Parameter for Setting the Loiter Region}
\label{sec_loiter_poly}

The Loiter behavior is configured with a {\em loiter region}, defined
by a convex polygon. The behavior will influence the vehicle to
repeatedly traverse the set of points on the polygon. The polygon is
specified typically in the behavior configuration block. Any string
that properly defines a convex polygon is acceptable.  The following
two configuration lines, for example, will result in the same polygon.

\prevbhv
\begin{verbatim}
    polygon = 20,-40:40,-75:20,-110:-20,-110:-40,-75:-20,-40:label,Lima

    polygon = format=radial, x=0, y=-75, radius=40, pts=6, snap=1, label=Lima
\end{verbatim}
\postverb

\noindent
Each would produce the polygon shown in Figure \ref{fig_loiter_poly}:

\vspace{0.08in}
\begin{figure}[H]
  \centering 
  \includegraphics[width=0.55\textwidth]{figures/loiter_poly.png}
  \caption{A typical loiter polygon with six vertices.}
  \label{fig_loiter_poly}
\end{figure}

\vspace{0.08in}
\noindent
The shape and position polygon may be alterered dynamically (after the
helm is launched and running) in one of two manners by either
specifying new parameters explicitly, or by tying the loiter position
to the vehicle position when the loiter behavior enters the running
behavior mode.

%----------------------------------------------------------------------
\subsubsection{The \bvar{updates} Parameter for Updating the Loiter Region}
\label{sec_loiter_updates}

In the first case, altering the polygon parameter dynamically is 
accomplished by using the standard \bvar{updates} parameter described
in Section \ref{sec_updates}. For example, the behavior may be
configured to receive new updates by adding the following line to 
its configuration block:

\prevbhv
\begin{verbatim}
  updates = NEW_CONFIG
\end{verbatim}
\postverb

\noindent
Its position may be then moved 75 meters North by posting the following
to the MOOSDB:

\prevgreen
\begin{verbatim}
  NEW_CONFIG = "polygon = format=radial, x=0, y=0, radius=40, pts=6, snap=1, label=Lima"
\end{verbatim}
\postverb

\noindent
Alternatively, if one wants to simply move the polygon to a new \var{(x,y)}
position, the Loiter behavior also implements the \bvar{center\_assign}
configuration parameter. The same shift as above can be made without
the source making the post having to know anything about the other
parameters of the polygon:

\prevgreen
\begin{verbatim}
  NEW_CONFIG = "center_assign = 0,0"
\end{verbatim}
\postverb

\noindent
Likewise, if one simply wants to move the polygon in either the $x$ or 
$y$ direction without knowing anything about the position in the other
direction, the Loiter behavior implements the \bvar{xcenter\_assign} and
\bvar{ycenter\_assign} parameters. Thus the above shift could also be 
accomplished without the source making the post knowing anything about
the current $x$ position of the polygon:

\prevgreen
\begin{verbatim}
  NEW_CONFIG = "ycenter_assign = 0"
\end{verbatim}
\postverb

%----------------------------------------------------------------------
\subsubsection{The \bvar{center\_activate} Parameter for Using the Current Vehicle Position}

The Loiter behavior may also be configured to reset the (x,y) center
position of the loiter polygon to the present position of the vehicle
at the very the moment the behavior transitions from the idle to the
running state. See Section \ref{sec_run_states} for more on behavior
run states. This configuration is declared with the following line in 
the behavior configuration block:

\prevbhv
\begin{verbatim}
  center_activate = true
\end{verbatim}
\postverb

\noindent
This setting is useful if one wants to, for example, send a command to
the vehicle to exit some other mission mode and simply loiter at its
present location until further notice. Of course this configuration 
as well, may also be dynamically toggled through a variable specified
in the \bvar{updates} parameter.

%----------------------------------------------------------------------
\subsubsection{The \bvar{speed} Parameter for Setting the Loiter Speed}
\label{sec_loiter_speed_param}

The desired speed, in meters/second, at which the vehicle travels
through the points.

%----------------------------------------------------------------------
\subsubsection{The \bvar{speed\_alt} and \bvar{use\_alt\_speed} Parameters}
\label{sec_loiter_speed_alt_param}

When the \var{use\_alt\_speed} parameter is set to \var{"true"}, the
loiter behavior will use speed set in the \bvar{speed\_alt} parameter,
if it has been set. By default \bvar{use\_alt\_speed} is \var{"false"}
and \bvar{speed\_alt} is set to $-1$. This provides a convenient way
for other behaviors or apps to periodically influence the loiter
behavior to a different speed. The other behavior or app does not need
to read, remember and reset the loiter behavior back to its original
speed, but can instead just toggle \bvar{use\_alt\_speed} to
\var{false} to return the loiter back to its original speed.

%----------------------------------------------------------------------
\subsubsection{The \bvar{spiral\_factor} Parameter}
\label{sec_loiter_spiral_param}

A value in the range $[0,100]$ indicating the degree to which the vehicle
will spiral out to the polygon if started on the inside. A setting of zero 
indicates it will move directly to the first polygon vertex. This parameter
only relates to the situation of starting inside the polygon. The default
value is 98.

%----------------------------------------------------------------------
\subsubsection{The \bvar{acquire\_dist} Parameter}
\label{sec_loiter_acquire_param}

The \bvar{acquire\_dist} parameter is the distance in meters between
the vehicle and the polygon that will trigger the vehicle to return to
{\em acquire} mode. This notion applies to the case where the vehicle
is both inside and outside the polygon.  The re-acquire algorithms
are different however. The default is 10 meters.


%----------------------------------------------------------------------
\subsubsection{The \bvar{xcenter\_assign} and \bvar{ycenter\_assign} Parameters}
\label{sec_loiter_assign_params}

%----------------------------------------------------------------------
\subsubsection{The \bvar{capture\_radius} and \bvar{slip\_radius} Parameters}
\label{sec_loiter_radius_params}

\bvar{radius}: The radius tolerance, in meters, for satisfying
  the arrival at a waypoint. As soon as the vehicle is within this
  distance to the waypoint the waypoint behavior begins operating on
  the next waypoint in the sequence, or completes and posts its
  endflags if there are no more waypoints.

\bvar{slip\_radius}:As the vehicle progresses toward a waypoint,
  the sequence of measured distances to the waypoint decreases
  monotonically. The sequence becomes non-monotonic when it hits its
  waypoint or when there is a near-miss of the waypoint arrival
  radius. The \bvar{slip\_radius}, a.k.a, the \bvar{nm\_radius}, short
  for {\em non-monotonic radius} is an arrival radius distance within
  which a detection of increasing distances to the waypoint is
  interpreted as a waypoint arrival.  This distance would have to be
  larger than the arrival radius to have any effect (see Figure
  \ref{fig_nonmono}). As a rule of thumb, a distance of twice the
  arrival radius is practical.


%----------------------------------------------------------------------
\subsubsection{The \bvar{post\_suffix} Parameter}
\label{sec_loiter_suffix_param}

The \bvar{post\_suffix} parameter names a string to be added as a
suffix to each of the status variables posted by the behavior
(\mvar{LOITER\_REPORT}, \mvar{LOITER\_INDEX}, \mvar{LOITER\_ACQUIRE},
\mvar{LOITER\_DIST2POLY}). By default, the suffix is the empty string
and the variables will be posted as above.  When multiple Loiter
behaviors are configured in the helm it may help to distinguish the
posted variabes by a suffix. A given suffix of \msvar{"FOO"} would
result in the posting of \mvar{LOITER\_INDEX\_FOO} for example. The
extra \var{'\_'} character is inserted automatically.



%----------------------------------------------------------------------
\subsubsection{The \bvar{clockwise} Parameter for Setting the Loiter Direction}
\label{sec_loiter_clockwise}

The user may configure the direction the vehicle traverses the loiter
polygon by setting the parameter:

\prevbhv
\begin{verbatim}
  clockwise = &lt;value&gt;
\end{verbatim}
\postverb

\noindent
The possible case insensitive settings for \var{&lt;value&gt;} are
\var{"true"}, \var{"false"}, \var{"best"}. In the first two cases, the
directions are explicitly set and will not vary regardless of the pose
of the vehicle with respect to the polygon. In the case where
\bsvar{clockwise=best}, the direction is re-evaluated once, whenever
the behavior run state transitions from idle to running.  Thus the
direction depends on the pose relative position to the polygon at that
particular point in time. This is shown in the lower case in Figure
\ref{fig_loiter_clockwise} below.

\vspace{0.1in}
\begin{figure}[H]
  \centering 
  \includegraphics[width=0.65\textwidth]{figures/loiter_clockwise.png}
  \caption{{\bf The Loiter Direction.} The polygon traversal direction
    is determined by the \bvar{clockwise} configuration parameter. It
    may be explicitly set as shown on the top, or determined at run
    time when the behavior becomes non-idle as shown on the bottom.}
\label{fig_loiter_clockwise}
\end{figure}
\vspace{0.1in}


Regardless of the prevailing direction, as the vehicle is transiting
to the loiter polygon, the behavior will influence the vehicle toward
the vertex that allows for the smoothest entry, given the chosen
direction. If the polygon were a perfect circle, the vehicle would
approach on one of the two tangent lines.


%----------------------------------------------------------------------
\subsubsection{The \bvar{visual\_hints} Parameter}
\label{sec_loiter_visual_hints}

Although the primary output of the Loiter behavior an IvP Function, a
number of visual properties are also published for convenience in
mission monitoring.  This includes both the loiter polygon and the
point on the polygon the behavior is presently progressing
toward. These visual artifacts have default properties in size and
color that may be altered to the user's preferences. These preferences
are configurable through the \bvar{visual\_hints} parameter. Each 
parameter below is used in the following way by example:

\vspace{0.1in}
\begin{fileverb}
 visual_hints = vertex_size=3, edge_size=2
 visual_hints = vertex_color=khaki
\end{fileverb}
\vspace{0.1in}


\begin{packed_itemize}[1]
\item \bvar{vertex\_size}: The size of vertices rendered in the
  loiter polygon. The default is 1.
\item \bvar{edge\_size}: The width of edges rendered in the
  loiter polygon. The default is 1.
\item \bvar{vertex\_color}: The color of vertices rendered in the
  loiter polygon. The default is "dodger\_blue".
\item \bvar{edge\_color}: The color of edges rendered in the
  loiter polygon. The default is "white".
\item \bvar{nextpt\_color}: The color of the point rendered as the 
  present next waypoint. The default is "yellow".
\item \bvar{nextpt\_lcolor}: The color of the label for the point
rendered as the present next waypoint. The default is "aqua".
\item \bvar{label}: The label of rendered for the loiter polygon.

\end{packed_itemize}

\noindent
Rendering of vertices or the next waypoint may be shut off with a size of zero, 
and labels may be shut off with the special color "invisible". For a list 
of legal colors, see Appendix \ref{app:colormap}.


%=======================================================================
\subsection{The Loiter Acquisition Mode}

When the Loiter behavior is running (non-idle), it behaves differently
depending on where the vehicle is in relation to the loiter polygon.
The behavior has a notion of (a) when it is progressing in a "stable"
manner around the polygon and (b) when it is trying to move the
vehicle back to (a). The difference between the two is solely
determined by whether or not the vehicle is within some {\em acquire
  distance} from the loiter polygon. This distance is set with the
behavior configuration parameter:

\prevbhv
\begin{verbatim}
  acquire_dist = &lt;distance&gt;
\end{verbatim}
\postverb

%\index{Loiter Behavior! Loiter Polygon Zones}
\noindent
The \var{&lt;distance&gt;} component must simply be a non-negative value. A
value of zero should work fine, but essentially disables some useful
ways in which the behavior may be coordinated with other parts of the
mission. This relationship is shown in Figure
\ref{fig_loiter_mode_boundaries}.

\vspace{0.1in}
\begin{figure}[H]
  \centering 
  \includegraphics[width=0.55\textwidth]{figures/loiter_mode_boundaries.png}
  \caption{{\bf The Loiter Polygon Zones:} The Loiter behavior regards
    itself to be in one of three distinct possible zones relative to
    the polygon boundary - {\em stable}, {\em internal}, {\em
      external}, depending on the setting of the \bvar{acquire\_dist}
    parameter as shown.}
  \label{fig_loiter_mode_boundaries}
\end{figure}

\vspace{0.1in}

%\index{Loiter Behavior! Loiter Mode}

When the vehicle is {\em not} within the stable zone, it is trying to
acquire the polygon in one of four distint manners, depending on
whether (a) the vehicle is internal or external and (b) whether it is
"acquiring" the polygon for the first time, or whether it is
"recovering" from having drifted out of the stable zone.  The idea is
depicted in Figure \ref{fig_loiter_mode_examples}.

\vspace{0.1in}
\begin{figure}[H]
  \centering 
  \includegraphics[width=0.95\textwidth]{figures/loiter_mode_examples.png}
  \caption{{\bf Loiter Modes}: The behavior is one of five possible
    modes, {\em stable}, {\em acquiring\_external}, {\em
      recovering\_external}, {\em recovering\_internal}, or {\em
      acquiring\_internal}.}
  \label{fig_loiter_mode_examples}
\end{figure}
\vspace{0.1in}

The current loiter mode is published by the behavior in the MOOS
variable \mvar{LOITER\_MODE}. As with any MOOS variable published
by a behavior, this may be remapped to a different variable of the
users liking with the \bvar{post\_mapping} configuration parameter.

\pskip

When the behavior is in any loiter mode other than the stable mode, it
recalculates on each iteration which vertex it should be heading
toward, the {\em approach vertex}. In the case of an external
approach, the chosen vertex should remain steady unless there are
external forces such as wind or current, or if the vehicle changes its
aspect to the polygon significantly as it is executing a turn. In the
case of an internal approach, the approach vertex will likely change
during the approach, outward toward the polygon boundary, creating a
pseudo outward spiral trajectory. Note that re-evaluating the approach
vertex is not the same as re-evaluating the traversal direction of the
polygon. The latter is only re-evaluated dynamically if the behavior
is configured with \bvar{clockwise}\bsvar{=best}, and then only when
the behavior becomes non-idle.


%-----

The circumstance most common for triggering the acquire mode is the
initial assignment to the vehicle to loiter at a new given region in
the X,Y plane. This assignment {\em could} occur while the vehicle
happens to already be within the polygon for a number of reasons.
Furthermore, the vehicle could be driven off the polygon loiter
trajectory due to environmental (wind or current) forces or the
temporary dominance of other vehicle behaviors such as collision
avoidance or tracking of another vehicle.

Once the behavior enters the acquire mode, it remains in this
mode until arriving at the first waypoint (defined by the arrival
and non-monotonic radii settings), after which it switches to 
normal mode until the acquire mode is re-triggered or the behavior
run conditions are no longer met. There is currently no "complete"
condition for this behavior other than a time-out which is
defined for all behaviors.





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