<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">\documentclass[onecolumn,letterpaper,11pt]{article}

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

\begin{document}

\begin{labcover}
\labtitle{Help Topic: MOOS-IvP Message Handling and Parsing}
\vspace{0.1in}
\labdate{Spring 2020}
\vspace{0.1in}
\labauth{Michael Benjamin, mikerb@mit.edu}
\labauth{Department of Mechanical Engineering}
\labauth{MIT, Cambridge MA 02139}
\labline
\end{labcover}

\wikidoc{file=Help.MIPMsgParse}
\wikidoc{auth=mikerb@mit.edu}

%======================================================================
\section*{MOOS-IvP Message Handling and Parsing}
%======================================================================
\label{sec_moos_message_parse}

There are many books and websites where you find comprehensive
information on STL vectors and strings. Here we aim to lay out a
quick-start cheat sheet so we can get right to the topic of parsing
strings commonly passed as MOOS messages. 

%======================================================================
\subsection*{MOOS Message Passing Conventions}

A common way of sending a MOOS message is to use a comma-separated
list of pair=value components. For example:

\prevgreen[0in]
\begin{verbatim}
 HEALTH_SUMMARY = "temperature=99.1, height=72, weight=175"
\end{verbatim}
\postverb

\noindent
We could have sent the same message more concisely as follows:

\prevgreen[0in]
\begin{verbatim}
 HEALTH_SUMMARY = "99.1,72,175"
\end{verbatim}
\postverb

\noindent
The consumer or recipient of the message could simply have an
understanding that this message has three parts with the components
indicating {\em temperature}, {\em height}, and {\em weight}
respectively. It does make for a shorter message, but it has a few
drawbacks: (a) it is not very human readable, (b) the ordering of the
components is now important, and (c) if the sender wants to send
more information say {\em age}, or less information because perhaps
it doesn't know the weight of the person, then it becomes tricky
how to handle this if the receiver is rigidly expecting the
original 3-tuple. 

\pskip

A convention, at least in our lab, is to prefer the comma-separated list
of parameter=value pairs in the first example above. The message
handling routine on the receiver end then can process the compoents in
any order, and extra unexpected components can be easily handled or
ignored. Message structures tend to {\em grow} over time. By this we
mean for example that a \msvar{HEALTH\_SUMMARY} message today may only
contain the three components above, but somewhere down the road
someone may want to add {\em age}, {\em gender}, etc., and we don't
want any of the original MOOS apps subscribing for this information to
break. There are other ways to accomplish this, e.g., Google Protocol
Buffers, but the convention we describe here also works pretty well in
practice.

\pskip

So the comma-separated list of parameter=value pairs is pretty easy to
construct, and parsing it on the receiver end is also pretty easy but
is a bit more involved.


%====================================================================
\subsection*{Creating a MOOS Message with STL Strings}

By now you have some familiarity with strings in C++. With the advent
of the standard template libarry (STL), the most common way of using
strings is the STL string class.

\vspace{0.08in}
\begin{fileverb}
 #include&lt;string&gt;
 ...
 std::string str = "Hello World";
\end{fileverb}
\vspace{0.08in}

\noindent 
The above style MOOS messages are easy to construct: 

\vspace{0.08in}
\begin{fileverb}
 std::string msg = "temperature=99.1, height=72, weight=175";
\end{fileverb}
\vspace{0.08in}

\noindent
Or, more commonly, if the components are held in local variables, the 
string message may be built up using string concatenation.

\vspace{0.08in}
\begin{fileverb}
 string temperature = "99.1";
 string height = "72";
 string weight = "175";
 ...
 std::string msg;
 msg += "temperature=" + temperature + ",";
 msg += "height=" + height + ",";
 msg += "weight=" + weight;
\end{fileverb}
\vspace{0.08in}

\noindent
The above works, but what if the {\em temperature}, {\em height} and
{\em weight} components were stored locally as a type double instead
of string? You will need to first convert the numerical values to
string values using \func{doubleToString}, \func{intToString}, or
\func{uintToString} functions described on the String Utilities page:

\vspace{0.1in}
 \urlx{http://oceanai.mit.edu/ivpman/help/string_utilities}
\vspace{0.1in}


\noindent
For example:

\vspace{0.08in}
\begin{fileverb}
 double temperature = 99.1;
 double height = 72;
 double weight = 175;
 ...
 std::string msg;
 msg += "temperature=" + doubleToString(temperature,1) + ",";
 msg += "height=" + doubleToString(height,0) + ",";
 msg += "weight=" + doubleToString(weight,0);
\end{fileverb}
\vspace{0.08in}

%========================================================================
\subsection*{Parsing a MOOS Message of Comma-Separated Pairs}
\label{sec_parse_message}

Here are a couple ways of parsing and handling an incoming MOOS message
with the structure of a comma-separated list of parameter=value pairs. For
example:

\vspace{0.1in}
\noindent
\msvar{HEALTH\_REPORT} = "temperature=98.1, weight=178, height=73"
\vspace{0.1in}

\noindent
In the below examples, we assume that an \func{OnNewMail()} function
exists elsewhere that detects an incoming mail message
\msvar{HEALTH\_REPORT}, and invokes the below mail handling
routine. We also assume that this fictitous MOOS App has local string
member variables, \var{m\_temperature}, \var{m\_weight}, and
\var{m\_height}.

\vspace{0.08in}
\begin{fileverb}
 bool MyMOOSApp::handleMailHealthReport(string report)
 {
   vector&lt;string&gt; str_vector = parseString(report, ',');
   for(unsigned int i=0; i&lt;str_vector.size(); i++) {
     string param = biteStringX(str_vector[i], '=');
     string value = str_vector[i];

     if(param == "temperature")
       m_temperature = value; 
     else if(param == "height")
       m_height = value; 
     else if(param == "weight")
       m_weight = value; 

    return(true);
  }
\end{fileverb}
\vspace{0.08in}

\end{document}

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