MOOS-ivp 实验四 MOOS编程入门(1)

MOOS-ivp 实验四 MOOS编程入门(1)



前言

这一次实验的主要内容就是MOOS编程的入门教学,我现在刚开始看也同样啥也不懂,相信我再看个几天,等到写完这篇文章的时候,应该基本就差不太多了。


一、MOOS概览

一些内容之前有过介绍,我这里只放一些我觉得新的部分和有用的部分,原文实验手册里写的很细,废话也很多。

1.MOSS应用程序结构

在实验三中主要使用的是已经存在的MOOS应用程序,我们对它的改动只不过是在一些参数上进行相关的改动。但是MOOS的所有应用不应该是固定的,只要你想要的修改,你就可以对它进行修改。你可以对其中任何一个app进行重写或者复制重命名,改进出来你想要的功能。或者也可以从头开始构建自己的应用程序结构,这是本次实验内容的重点。
The MOOSApp Key Functions
如上图所示,所有的MOOS应用程序都是由以上三个子类来构成的。

2.定义在MOOSmsg上的便携函数(handy function)(MOOS mail)

在正常的情况下,系统的app主要是用OnNewMail()这个子类来进行消息处理的,除了我们所知道的变量名称之外,我们还可能希望知道相关的量
(1)值是多少
(2)由那些app发布的
(3)什么时间发布的
(4)值的类型,是string型还是double型等等
在我们的示例文件pXRelayTes里,我们调用msg.GetKey() (这个函数在Relayer.cpp中)来对消息进行获取。下面列举的这些方法都可以对消息来进行获取,这注释上都说了各个函数的作用:

// return the name of the message
std::string GetKey();
// return the name of the message (just another way)
std::string GetName();
// check data type is double
bool IsDouble();
// check data type is string
bool IsString();
// return time stamp of message
double GetTime();
// return double val of message
double GetDouble();
// return string value of message
std::string GetString();
// return the name of the process (as registered with the DB) which
posted this notification
std::string GetSource();
// return the name of the MOOS community in which the orginator lives
std::string GetCommunity();

这里稍微解释一下上面std::string是啥意思:
string是C++语言标准模板库(STL)中的一个组成部分,STL中的所有函数类名称(专业点叫标识符)都被存储在一个叫做std的命名空间之中,所以要调用库中的某一个类的时候需要添加头文件,并且使用std命名空间,我们想要使用string类的时候就需要在最开头添加

include<string>
using namespace std;

然后上面那一堆函数都是std类中定义的各种成员函数,但是很多都是标准库里没有的,估计是MOOS系统自己写一些成员函数。
书接正文继续写:
接下来的试验里,会用到到一个MOOS提供的模板,用来生成新的MOOS应用程序的框架代码,下面这个OnNewMail函数的范例就是用这个模板生成的:

bool MyApp::OnNewMail(MOOSMSG_LIST &NewMail)
{
    
    
MOOSMSG_LIST::iterator p;
for(p=NewMail.begin(); p!=NewMail.end(); p++) {
    
    
CMOOSMsg &msg = *p;
#if 0 // Keep these around just for template
string key  = msg.GetKey();
string comm = msg.GetCommunity();
double dval = msg.GetDouble();
string sval = msg.GetString();
string msrc = msg.GetSource();
double mtime = msg.GetTime();
bool  mdbl = msg.IsDouble();
bool  mstr = msg.IsString();
#endif
}
return(true);
}

我先试着理解一下这个代码框架:
for(p=NewMail.begin(); p!=NewMail.end(); p++)
这句话应该是搞了一个for循环,把最开始的mail起始地址给了p,p一直累加,当p不等于终点地址的时候退出。就是iterator类定义的变量p从起始地址一路指到终点地址的过程。
CMOOSMsg &msg = *p;定义了一个CMOOSMsg类型的引用msg,这句代码的意思是把指针p指向的值赋给引用msg,msg就是p指向的那个值的一个别名。搞不懂的参考下面的网站:
C++中int *a; int &a; int & a; int * &a
C/C++中和&的用法
后面的#if 0就是直接注释掉下面的代码了,如果是#if 1的话就是对下面的代码进行编译(不是执行哦,编译不一定执行)。上面模板里有关传入MOOSmessage的典型函数都被注释掉了,如果需要使用的话可以随时将其拿出来进行调用。关于#if详情参考如下网站
C/C++中常见的#if、if、#ifdef、#if define等区别

二、下载moos-ivp-extend树

1.下载

代码如下(示例):

直接下载,下载好后编译添加路径,重启之后在进行检查,前几章讲过,再写一下:
将执行文件添加到路径中去。
首先返回到根目录,之后再执行ls -a查看隐藏文件
找到文件**.bashrc**对其进行编辑,输入vim .bashrc

svn co https://oceanai.mit.edu/svn/moos-ivp-extend/trunk moos-ivp-extend
cd moos-ivp-extend
./build.sh
which pXRelayTest
返回结果类似于说明正确添加路径:
/home/you/moos-ivp-you/bin/pXRelayTest

2.初步了解

在进行下一个实验之前,先快速了解一下关于Relayer MOOS app类的一些定义。下面列出这些内容,也可以在目录moos-ivp-extend/src/pXRelayTest/中找到这些相关内容。

**File Relayer.h
1 #include "MOOS/libMOOS/MOOSLib.h"
2 class Relayer : public CMOOSApp
3 {
    
    
4  public:
5  Relayer();
6  virtual ~Relayer() {
    
    };
7
8  bool OnStartUp();  // Overriding key virtual function
9  bool OnNewMail(MOOSMSG_LIST &NewMail);  // Overriding key virtual function
10  bool Iterate();  // Overriding key virtual functionx
11
12  bool OnConnectToServer();
13  void RegisterVariables();
14
15  void setIncomingVar(std::string s) {
    
    m_incoming_var=s;}
16  void setOutgoingVar(std::string s) {
    
    m_outgoing_var=s;}
17
18  protected:
19  unsigned long int m_tally_recd;
20  unsigned long int m_tally_sent;
21  unsigned long int m_iterations;
22
23  std::string  m_incoming_var;
24  std::string  m_outgoing_var;
25  double  m_start_time_postings;
26  double  m_start_time_iterations;
27 };**

(1)在类声明的第一行,都会声明自己是CMOOSapp的子类,CMOOSapp是一般app的父类。
(2)我们自己定义的类会声明三个关键的虚函数,在8-10行有三个关键的虚函数
(3)编码约定:所有的成员函数都会在成员变量之前进行声明,被覆盖的成员函数在子类特定的成员函数之前进行声明。(这里我搞不懂覆盖是什么意思,为此查了一些资料,搞明白了什么是虚函数和基虚函数覆盖、重载和隐藏的含义)这些主要是C++多态部分的内容,怪我学艺不精,想不起来了)
(4)编码约定:所有的成员变量都用m_进行开头,以便于跟代码中本地声明的变量区分开来
(5)编码约定:所有成员变量都是protect,修改这些变量使用公共成员函数来操作,比如15、16行的那些代码。

三、建立第一个MOOSapp——An Odometry MOOS App

本节内容的重点是建立一个自己的MOOSapp,下面使我们在这里需要实现的目标:
(1)了解如何使用模板脚本从头到尾生成一个moosapp
(2)了解如何在系统中添加moosapp
(3)写一个app,记录AUV行程,这个app叫pOdometry
(4)在Alder例子中测试app,让AUV行驶五十米之后返回然后查看记录的行程
(5)将MOOSapp转化为MOOScasting app

1.创建moosapp

打开目录到moos-ivp-extend/src/.
然后运行指令`

GenMOOSApp Odometry p "Jane Doe"

就可以创建一个moosapp啦,其名称为 Odometry,p是前缀的意思 最后面引号是作者的名字。

2.添加moosapp

我们需要在系统中将我们写好的moosapp 添加进去。打开文件目录moos-ivp-extend/src/CMakeLists.txt
打开这个txt文件
在这里插入图片描述
我们在下面添加我们自己的app名称,上图是已经添加好了的情况。

#==========================================================================
# List the subdirectories to build...
#==========================================================================
ADD_SUBDIRECTORY(lib_behaviors-test)
ADD_SUBDIRECTORY(pXRelayTest)
ADD_SUBDIRECTORY(pExampleApp)
ADD_SUBDIRECTORY(pOdometry)  <-- Add your line here

保存之后接下来打开build文件进行编译

cd moos-ivp-extend
./build.sh

编译完成之后找一下创建的moosapp,得到下面结果说明正确了,如果没找到 看一下文件路径是否添加了或者重启系统重新试一下。

 which pOdometry
 /home/you/moos-ivp-you/bin/pOdometry

四、写自己的moosapp

要写一个简单的moosapp需要完成以下要求:
(1)订阅AUV位置变量NAV_X 和 NAV_Y
(2)程序中反复读取X和Y的位置信息
(3)计算当前位置和之前位置的距离来更新总的路程
(4)将总里程数发布到一个可变的moos变量ODOMETRY_DIST中去

1.完成初步内容

(1)打开以下路径 找到 Odometry.h文件包含上成员变量

bool  m_first_reading;
double m_current_x;
double m_current_y;
double m_previous_x;
double m_previous_y;
double m_total_distance;

在这里插入图片描述

(2)在constructor中完成对变量的初始化,打开Odometry.cpp 对变量进行赋值
在这里插入图片描述
在这里插入图片描述
(3)编辑Odometry.cpp来订阅变量NAV_X 和 NAV_Y
这里因为我不是很懂如何订阅变量,于是在官网找资料在帮助文档中找到了关于MOOS类的相关说明,为了能将实验进行下去,有必要对这篇文档进行仔细的阅读,搞明白各个类的功能以及作用。下面的文章先MOOS类进行学习之后再返回实验。

总结

主要内容是对moos树进行下载以及检查,创建了一个自己的moosapp并将其添加到了系统执行路径中去。最后我们在写第一个app时遇到问题,不知道如何订阅变量。这里需要对moos类进行一下进一步的学习。

猜你喜欢

转载自blog.csdn.net/weixin_44151170/article/details/108874075