\documentclass[onecolumn,letterpaper,11pt]{article}

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

\begin{document}

\begin{labcover}
\labtitle{The Dubins Path Utility Library}
\vspace{0.17in}
\labpng{0.45}{figures/dubins.png}
\vspace{0.15in}
\labdate{July 2025}
\vspace{0.1in}
\labauth{Michael Benjamin, mikerb@mit.edu}
\labauth{Department of Mechanical Engineering}
\labauth{MIT, Cambridge MA 02139}
\labtoc{small}
\end{labcover}

\wikidoc{file=Memo.Dubins}
\wikidoc{auth=mikerb@mit.edu}


%====================================================================
\section{Overview}
%====================================================================
The \app{lib\_dubins} MOOS-IvP library is a set of classes and
utilities for creating a Dubins path from an initial start position
and angle (heading), to a destination position and angle. The library
is intended to be used in MOOS apps or Helm behavior that need to
generate this information.  An engineering GUI, \app{dpath}, is also
described here for conveying some of the concepts.

\vspace{0.1in}
\noindent
{\bf Getting the code}: The code and example mission are in the git
repo \var{moos-ivp-dubins}. Send your github account to be invited to
obtain the code.

%================================================================
\section{Dubins Path Components and Options}
%================================================================
here are essentially four possible maneuver paths to transition a
vehicle from any possible starting position and heading, to a target
position and heading:

\begin{packed_enumerate}
\item \var{port-port}: A port turn followed by a straight line,
  followed by a port turn.
\item \var{port-starboard}: A port turn followed by a straight line,
  followed by a starboard turn.
\item \var{starboard-starboard}: A starboard turn followed by a
  straight line, followed by a starboard turn.
\item \var{starboard-port}: A starboard turn followed by a
  straight line, followed by a port turn.
\end{packed_enumerate}

\vspace{0.1in}
\noindent
For an example pair of vehicle positions and headings, the four
possible turns are shown in Figure \ref{fig_dubins_four}.

\vspace{0.1in}
\begin{figure}[H]
  \centering
  \includegraphics[width=0.8\textwidth]{figures/dubins_four.png}
  \caption{{\bf Four Dubins Paths}: From the same starting and
    target positions, four possible Dubins paths are shown. The red
    vehicle is the starting position with the heading shown by the
    arrow. The blue vehicle is the target position. In this case, the
    shortest path is the port-starboard path.}
  \label{fig_dubins_four}
\end{figure}
\vspace{0.1in}

\noindent
Of course some Dubins paths look a bit silly in the above example,
but typically the shortest path, purely by length, is the desired
path. The actual desired path may vary by application and context.
For example, is the goal to maneuver to a trailing position behind
a moving contact? Or to maneuver into a docking position? In most
cases, a Dubins path that crosses in front of the target position
is not desired. 

\vspace{0.1in}
\noindent
In the below example, the purely shortest path, on the left, may
be less desirable than the one on the right which avoids being
on a path driving nearly on a head-on trajectory with the target
position. 

\vspace{0.1in}
\begin{figure}[H]
  \centering
  \includegraphics[width=0.8\textwidth]{figures/dubins_case.png}
  \caption{{\bf Considerations other then Shortest Path}: The path on
    the left is the shortest path from the red position to the blue.
    The one on the right is slightly longer, but avoids being in front
    of the target position.}
  \label{fig_dubins_case}
  \vspace{0.1in}
  \noindent
\end{figure}
\vspace{0.1in}

\noindent
The actual preference depends on context of the designer using the
library. The library simply allows the user to select one of the
four paths, or simply request the shortest path.

%================================================================
\section{The Code}
%================================================================

The code resides in \var{lib\_dubins}. The primary C++ class is
\var{DubinsModel}. It is configured with the required and optional
parameters, and a Dubins path is retrieved.  The core function is to
generate a path from a starting position and angle to a target
position and angle. We will use the term "ownship" and "target" to
mean these positions. The output path will be in the format of a
MOOS-IvP \var{XYSegList}.


%================================================================
\subsection{Required Input}

The required parameters include (a) ownship position and heading,
(b) target position and heading, and (c) ownship turn radius.
Presumably the user knows how to access this information, whether it
be within a MOOS app or Helm behavior. The \app{dpath} engineering
GUI obtains this info from the GUI itself.

\vspace{0.1in}
\noindent
The optional parameters include a configuration choice regarding the
density of points on the turns of the resulting Dubins path, by
default every 10 degrees.

%================================================================
\subsection{Output Format}

The output format is in the form of an \var{XYSegList}. This data
structure can be readily posted for viewing to \app{pMarineViewer}.

\vspace{0.1in}
\noindent
The functions returning an \var{XYSegList} are:

\vspace{0.1in}
\begin{fileverb}
XYSegList DubinsModel::getPathPortPort();
XYSegList DubinsModel::getPathPortStar();
XYSegList DubinsModel::getPathStarPort();
XYSegList DubinsModel::getPathStarStar();
XYSegList DubinsModel::getPathShortest();
\end{fileverb}
\vspace{0.1in}

\vspace{0.1in}
\noindent
For convenience, functions returning a vector of \var{XYPoint} are also
supported:

\vspace{0.1in}
\begin{fileverb}
vector<XYPoint> DubinsModel::getPathPortPortPVector();
vector<XYPoint> DubinsModel::getPathPortStarPVector();
vector<XYPoint> DubinsModel::getPathStarPortPVector();
vector<XYPoint> DubinsModel::getPathStarStarPVector();
vector<XYPoint> DubinsModel::getPathShortestPVector();
\end{fileverb}
\vspace{0.1in}

\vspace{0.1in}
\noindent
For convenience, functions returning a string of points is also
supported:

\vspace{0.1in}
\begin{fileverb}
string DubinsModel::getPathPortPortStr();
string DubinsModel::getPathPortStarStr();
string DubinsModel::getPathStarPortStr();
string DubinsModel::getPathStarStarStr();
string DubinsModel::getPathShortestStr();
\end{fileverb}
\vspace{0.1in}




%================================================================
\subsection{Simple Pseudocode Example}

The below is a snippet of code for using the DubinsModel class. Note
that we are vague about how the input parameters are known. 

\vspace{0.1in}
\begin{fileverb}
  #include "DubinsModel.h"

  DubinsModel model;

  double osx =      // ownship x position obtained
  double osy =      // ownship y position obtained
  double osh =      // ownship heading obtained
  double osr =      // ownship turn radius obtained
  
  double tnx =      // target x position obtained
  double tny =      // target y position obtained
  double tnh =      // target heading obtained

  model.setOSX(osx);
  model.setOSY(osy);
  model.setOSH(osh);
  model.setOSH(15); // 15 meter turn radius

  model.setTNX(osx);
  model.setTNY(osy);
  model.setTNH(osh);
  model.setLead(10); // meters

  XYSegList path = model.getPathShortest()

  Notify("VIEW_SEGLIST", path.get_spec();
  
\end{fileverb}
\vspace{0.1in}

\noindent
In this case, the shortest path is published as a \mvar{VIEW\_SEGLIST},
presumably for rendering in \app{pMarineViewer}


%====================================================================
\subsection{The dpath Engineering GUI}

The \app{dpath} engineering GUI allows a user to interactively modify
the start and target positions and angles, to see the four core Dubins
paths, or just the shortest path. A snippet is shown below in
Figure \ref{fig_dpath}.

\vspace{0.1in}
\begin{figure}[H]
  \centering
  \includegraphics[width=0.8\textwidth]{figures/dpath.png}
  \caption{{\bf The dpath Engineering GUI}: In this GUI the Dubins
    Path variations of traversing from a starting to target position
    can be explored. The vehicle positions and headings may also be
    modified interactively.}
  \label{fig_dpath}
\end{figure}
\vspace{0.1in}

\noindent
Use the \var{Ship} and \var{Target} pull-down menus to see the short-cuts
for modifying the ship and target positions and headings. 

\vspace{0.1in}
\noindent
To start: \var{SHIFT-Arrow} keys to move ownship (red) in the
plane. \var{CTRL-SHIFT-Arrow} keys to move the target position. Use
\var{'m'} and \var{'n'} to change the heading of ownship and \var{CTRL-'m'}
and \var{CTRL-'n'}. See the pull-down menus for the keyboard shortcuts for
all the other actions such as moving ownship, or changing the turn-radius
or lead distance.

%====================================================================
\section{The pDubinsPounce MOOS App}
%====================================================================

The code git repo, \var{moos-ivp-dubins}, contains a simple MOOS app, 
\app{pDubinsPounce}. This app is a simple wrapper for the
Dubins turn library. It subscribes for node reports for ownship and a
single contact, \var{ben}, and publishes a Dubins path from the current
ownship position to the target position and heading (the position and
heading of ben). There is also a \var{dubins-pounce} mission, described
in the next section, which demonstrates the use of this app.

%====================================================================
\subsection{Pub/Sub Interface}

It subscribes for the following MOOS variables:

\vspace{0.1in}

\begin{packed_itemize}
\item \mvar{NODE\_REPORT}: The position of the target location
\item \mvar{NODE\_REPORT\_LOCAL}: The position of ownship
\item \mvar{POUNCE\_RESET}: A request to regenerate a Dubins path
\item \mvar{POUNCE\_RAD\_MOD}: Change turn radius by the given amount
\item \mvar{POUNCE\_LEAD\_MOD}: Change path lead by the given amount
\end{packed_itemize}

\vspace{0.1in}
\noindent
On each iteration it will invoke \var{generatePath()}. The path will be
(re)generated only if \var{post\_pending} is true. This variable will
be true if either (a) a new contact node report has been received with
a different position or heading, or (b) a pounce reset message has been
received.

\vspace{0.1in}
\noindent
When a path is generated, it will be published in the form an updates
message, presumably to a waypoint behavior with a matching variable name
to receive its updates. This variable is a configuration parameter for
\app{pDubinsPounce}. For example:

\vspace{0.1in}
\noindent
\pvar{update\_var = POUNCE\_UPDATE}

\vspace{0.1in}
\noindent
In a waypoint behavior we would expect to see:

\vspace{0.1in}
\noindent
\bvar{updates = POUNCE\_UPDATE}

%====================================================================
\subsection{Configuration Params}

The following configuration parameters are supported:

\vspace{0.1in}
\begin{packed_itemize}
\item \pvar{contact}: The name of the contact used for the target position
\item \pvar{update\_var}: The name of the MOOS variable publishing outgoing paths
\item \pvar{turn\_radius}: The turn radius for Dubins turns
\item \pvar{turn\_lead}: The lead distance applied to Dubins turns.
\end{packed_itemize}

%====================================================================
\newpage
\section{The Dubins Pounce Mission}
%====================================================================

The code git repo, \var{moos-ivp-dubins}, also contains a test
mission, the \var{"dubins-pounce"} mission. It makes use of the
\app{pDubinsPounce} MOOS app. When the mission starts, the vehicle
will be proceeding automatically on an Alpha style waypoint mission,
similar to that in Figure \ref{fig_pounce1}:

\vspace{0.1in}
\begin{figure}[H]
  \centering
  \includegraphics[width=0.8\textwidth]{figures/pounce1.png}
  \caption{The start of the dubins-pounce mission. A vehicle will
    simply proceed around a set of waypoints until commanded to a
  point with a mouse click.}
  \label{fig_pounce1}
\end{figure}
\vspace{0.1in}

\vspace{0.1in}
\noindent
The user can click with either the left or right mouse button, to
command the vehicle to use a waypoint behavior with a path generated
by \app{pDubinsPounce}. The position of the target location is determined
by the mouse click. In this simple example mission, the heading of the
target location will be zero degrees when using the left mouse button. If
clicking with the right mouse button, the heading will borrow the y-mouse
position to use as the requested heading. 

\vspace{0.1in}
\begin{figure}[H]
  \centering
  \includegraphics[width=0.8\textwidth]{figures/pounce2.png}
  \caption{Once a mouse click has been received, a Dubins path will be
    generated and the vehicle will proceed to the target location. It will
    simply station-keep when it arrives.}
  \label{fig_pounce2}
\end{figure}
\vspace{0.1in}

\noindent
At any time while traversing the Dubins path, a new mouse click can be made
and the path will immediately be regenerated. 

\vspace{0.1in}
\begin{figure}[H]
  \centering
  \includegraphics[width=0.8\textwidth]{figures/pounce3.png}
  \caption{Once a mouse click has been received, a Dubins path will be
    generated and the vehicle will proceed to the target location. It will
    simply station-keep when it arrives.}
  \label{fig_pounce3}
\end{figure}
\vspace{0.1in}

\noindent
In this mission there are two sets of buttons. The \var{rad++/--} buttons
will dynamically change the Dubins turn radius. When they are clicked,
a new path will automatically be generated as the vehicle is traversing.
The \var{lead++/--} buttons, will dynamically change the path lead distance
(the straight line leading into the target position). When they are clicked,
a new path will automatically be generated as the vehicle is traversing.

\end{document}

