uSimMarine应用程序是一个简单的3D车辆模拟器,可以根据当前执行器的值和先前的车辆状态更新车辆的状态、位置和轨迹。典型的使用场景有一个与每个模拟车辆相关联的uSimMarine实例,如图1所示。
图1:uSimMarine的典型用法:在n辆车的模拟中,每辆车都使用uSimMarine的实例。每个模拟车辆通常都有自己专用的MOOS社区。IvP Helm (pHelmIvP)发布高级控制决策。PID控制器(pMarinePID)将高级控制决策转换为低级执行器决策。最后,模拟器(uSimMarine)读取低级执行器的信息以生成新的车辆位置。
这种模拟风格可以与模拟模拟综合方面(包括多个车辆、环境和通信方面)的模拟器形成对比。uSimMarine模拟器只关注一辆车。它订阅车辆导航状态变量:
•导航X,导航Y,导航速度,导航航向,和导航深度以及执行器值
•所需的舵,所需的推力,和所需的电梯。
模拟器容纳了应用于车辆的外部漂移的概念,以粗略地模拟电流或风。这些漂移可以静态设置,也可以由其他MOOS进程动态更改。所述模拟器还可以配置具有表示水流场的简单地理参考数据结构。
在典型的UUV有效载荷自主操作下,模拟器和pMarinePID MOOS模块将不存在。车辆的本机控制器将处理pMarinePID的角色,车辆的本机导航系统(以及车辆本身)将处理模拟器的角色。
2 uSimMarine配置参数uSimMarine配置的参数如下所示。本节的其他部分提供了更详细的描述。具有默认值的参数在下面的括号中表示。
清单2.1:uSimMarine的配置参数
buoyancy rate: 车辆以零速度浮到水面的速度,单位为米/秒。默认值为零。5.4节。
current field: 包含当前字段说明的文件。
current field active: 如果为true,则模拟器使用指定的当前字段。
default water depth: 计算高度时本地水深的默认值(0)。
drift vector:对外部漂移值,方向和幅度。
rotate speed: 外部转速,单位为度/秒(0)
drift x: 应用于x方向的外部漂移值(0)
drift y: 在y方向上施加的外部漂移值(0)
max acceleration:以m为单位的车辆最大加速度=s2(0.5)。
max deceleration: m内车辆的最大减速度=s2(0.5)
max depth rate: 车辆深度变化的最大速率,单位为米/秒。默认值是0.5。5.4节。
max depth rate speed: 达到最大深度速率的车辆速度(2.5)。5.4节。
prefix: 发布的MOOS变量的前缀。默认为USM。
sim pause:如果为true,则暂停模拟。默认为false。
start depth: 以米为单位的初始车辆深度。默认值为零。第四节
start heading:以度为单位的初始车辆航向。默认值为零。第四节。
start pos: 一个完整的起始位置和轨迹说明。第四节。
start speed: 一个完整的起始位置和轨迹说明。第四节。
start x: 车辆x在本地坐标中的初始位置。默认值为零。第四节。
start y: 车辆y在本地坐标中的初始位置。默认值为零。第四节。
thrust factor: 推力和速度之间的标量相关性。默认值是20。
thrust map:推力值和速度值之间的图。8节。
thrust reflect: 如果为真,逆冲正好与正冲相反。默认为false。8节。
turn loss: A范围[0,1]影响转弯时的速度损失。默认值是0.85。
turn rate: A范围[0;100]影响车辆的转弯半径,例如,0是无限的转弯半径。默认值是70。
下面的清单2提供了一个示例MOOS配置块。这也可以通过以下命令从终端窗口获得:
uSimMarine --example or -e
在发布和订阅方面,uSimMarine的接口如下所述。同样的信息也可以通过以下方式从终端获取:
usimMarine --interface or -i
uSimMarine向MOOSDB的主要输出是更新后的车辆位置和轨迹的完整规格,以及其他一些信息:
• APPCAST: 包含一个与终端输出相同的APPCAST报告。只有在appcast查看实用程序收到appcast请求后,才会发布appcast。
• BUOYANCY REPORT: • TRIM REPORT: • USM ALTITUDE: 如果水深已知,以米为单位的更新车辆高度。
• USM DEPTH: 以米为单位更新的车辆深度。5.4节。
• USM DRIFT SUMMARY: 当前总外部漂移的摘要。
• USM HEADING: 以度为单位更新的车辆航向。
• USM HEADING OVER GROUND:更新后的车辆地面航向。
• USM LAT: 更新的车辆纬度位置。
• USM LONG: 更新后的车辆经度位置。
• USM RESET COUNT: 模拟器复位的次数。
• USM SPEED: 以米每秒更新的车辆速度。
• USM SPEED OVER GROUND: 更新的速度超过地面。
• USM X: 更新后的车辆X在本地坐标中的位置。
• USM Y: 更新后的车辆Y在本地坐标中的位置。
• USM YAW: 在弧度更新车辆偏航。
示例USM DRIFT SUMMARY字符串:“ang=90, mag=1.5, xmag=90, ymag=0”。
uSimMarine应用程序将订阅以下MOOS变量:
• APPCAST REQ: 生成和发布新的APPCAST报告的请求,带有报告标准和有效期。请参阅Appcasting的文档。
• DESIRED THRUST(期望推力): 推力器执行器设置,[−100;100]。
• DESIRED RUDDER(所需舵): 舵执行器设置,[−100;100]。
• DESIRED ELEVATOR: 电梯深度设置,[−100;100]。
• USM SIM PAUSED: 模拟暂停请求,true或false。
• USM CURRENT FIELD: 如果为true,则配置的当前字段处于激活状态。
• USM BUOYANCY RATE(USM浮力率): 动态设置零速浮力率。
• ROTATE SPEED(旋转速度): 动态设置外部转速。
• DRIFT X(漂移X): 动态设置X方向的外部漂移。
• DRIFT Y(漂移Y): 动态设置Y方向的外部漂移。
• DRIFT VECTOR(漂移矢量): 动态设置外部漂移方向和幅度。
• DRIFT VECTOR ADD(漂移矢量添加): 动态修改外部漂移矢量。
• DRIFT VECTOR MULT(漂移矢量MULT): 动态修改外部漂移矢量幅度。
• USM RESET(USM复位): 复位模拟器与新的位置,航向,速度和深度。
• WATER DEPTH(水深): 当前车辆位置的水深。
每次迭代,在注意到导航和执行器值的变化后,它以USM X, USM Y, USM SPEED, USM HEADING, USM DEPTH的形式发布一组新的导航状态变量。
uSimMarine应用程序通常由pAntler作为一批进程的一部分启动,但也可以由用户从命令行启动。uSimMarine应用程序的基本命令行用法如下:
模拟器通常配置由以下五个配置参数给出的车辆起始位置、姿态和轨迹:
• start x(起始x)
• start y (起始y)
• start heading (起始方向)
• start speed(起始速度)
• start depth(起始深度)
位置以本地坐标指定,相对于本地基准,或(0;0)的位置。该数据在全局级的.moos文件中指定。航向以度数指定,并与车辆指向的方向相对应。缺省情况下,初始速度和深度为零,并且通常在配置中未指定。或者,同样的五个参数可以用start pos参数设置,如下所示:
start_pos = x=100, y=150, speed=0, heading=45, depth=0
模拟器也可以在其操作期间的任何点重置,通过张贴到MOOS变量USM reset。以下表格的张贴将重置上述相同的五个参数:
USM RESET = x=200, y=250, speed=0.4, heading=135, depth=10
当目标是从几个不同的起始位置观察车辆的行为,并且使用外部MOOS脚本(例如,uTimerScript)从每个期望的起始状态重置模拟器时,这是有用的。
车辆位置在uSimMarine应用程序的每次迭代中更新,基于(a)先前的车辆状态,(b)自上次更新以来经过的时间,∆T, ©当前执行器值,DESIRED RUDDER, DESIRED THRUST和DESIRED ELEVATOR,以及(d)描述车辆模型的几个参数设置。
为了简单起见,这个模拟器按顺序更新车辆的速度、航向、位置和深度。例如,在航向更新之后位置也会更新,并且新航向的更新就好像是整个∆T的车辆航向一样。通过运行具有相当高的MOOS AppTick值的uSimMarine,使∆T的值足够小,可以减轻这种简化带来的误差。
车辆速度的传播主要基于推力的当前值,该值可能会在每次迭代时通过读取MOOS变量DESIRED_THRUST上的传入邮件进行刷新。为了模拟车辆在水中转弯时的小速度损失,新的推力值也可能受到当前方向舵值的影响,该方向舵值由MOOS变量DESIRED_RUDDER参考。新计算的速度还取决于之前输入的MOOS变量NAV_SPEED所记录的速度,以及两个配置参数MAX_ACCELERATION和MAX_DECELERATION的设置。
更新车速的算法如下:
车辆航向的传播主要基于当前的方向舵值,该值在每次迭代时通过读取MOOS变量DESIRED方向舵上的传入邮件而刷新,以及自模拟器先前更新车辆状态以来经过的时间∆T。航向的变化也受到MOOS变量DESIRED THRUST的推力值的影响,也可能受到外部转速的影响。
更新新车辆航向的算法如下:
车辆位置的传播主要基于新计算的车辆航向和速度、前一个车辆位置以及更新前一个车辆位置后经过的时间∆T。
更新新车辆位置的算法如下:
基于几个输入参数,模拟了uSimMarine的深度变化。从一次迭代到下一次迭代变化的主要参数是来自MOOS变量DESIRED ELEVATOR的ELEVATOR执行器值。在任意给定的迭代中,新的车辆深度 z i z_i zi由以下公式确定:
z i = z i − 1 ( ⋅ z i ∗ ∆ t ) z_i=z_{i-1}(\cdot{z} _i*∆t) zi=zi−1(⋅zi∗∆t)
新的车辆深度通过深度变化率 ⋅ z i \cdot z_i ⋅zi,应用于经过的时间∆t来改变,∆t大致相当于uSimMarine配置块中设置的应用间隔。当前迭代的深度变化率由车辆速度和电梯执行器值以及以下三个特定于车辆的模拟器配置参数决定,这些参数允许在模拟车辆的物理特性时发生一些变化。为简单起见,浮力率以米每秒为单位,其中正值表示浮力正的飞行器。最大深度速率和最大深度速率速率参数决定了图2中所示的函数。车速越高,车辆的深度变化率就越高,直到车速不再影响深度变化率的最大速度。实际的深度变化率取决于电梯和车辆的速度。
图2:在给定当前车辆速度的情况下,深度变化率之间的关系。不同的电梯设置决定了不同的曲线,如图所示。
深度变化率, ⋅ v i \cdot v_i ⋅vi的取值如下:
上式中的两个分数分量都被裁剪为[−1;1]。当飞行器处于反向推力和负速度时,这个等式仍然成立。然而,车辆的深度变化率曲线可能不会在正车速和负车速之间对称。浮力率默认为0:025,略正浮力,最大深度率默认为0:5,最大深度率默认为2:0。当前的浮力率可以通过单独的MOOS应用程序发布到可变的浮力率来动态调整。
车辆高度仅基于当前车辆深度和当前车辆位置处的水深度。如果对水深一无所知,则不公布USM高度。模拟器可以配置默认水深:
default water depth = 100
这将允许模拟器产生一些高度信息,如果需要测试USM高度信息的消费者。此外,模拟器在可变USM水深中订阅水深信息,这可以想象由另一个具有访问测深数据和车辆导航位置的MOOS应用程序产生。
当模拟器按照第5.3节提供的公式更新车辆位置时,它会在x和y方向上分别考虑可能的外部漂移,即外部漂移x和外部漂移x。外部漂移可能有两个不同的组成部分;一般应用的漂移,以及由于配置了将漂移向量与本地x和y位置相关的外部文件的电流场而应用的漂移。这些漂移可以用下面讨论的三种方式之一来设定。
An external drift may be configured upon startup by either specifying explicitly the drift in the x and y direction, or by specifying a drift magnitude and direction. Figure 3 shows two external drifts each with the appropriate configuration using either the drift x and drift y parameters or the single drift vector parameter:
外部漂移可以在启动时通过显式指定x和y方向上的漂移,或者通过指定漂移幅度和方向来配置。图3显示了两个外部漂移,每个都有适当的配置,使用漂移x和漂移y参数或单个漂移矢量参数:
图3:外部漂移矢量:两个漂移矢量分别配置了漂移x和漂移y配置参数或其等效的单个漂移矢量参数。
如果由于某种原因,用户错误地使用两种配置样式配置模拟器,那么最后出现在配置块中的配置将是主要配置。如果使用这些参数配置uSimMarine,这些外部漂移将应用于第一次迭代和所有后续迭代,除非动态更改,如下所述。
其他MOOS应用程序可以根据用户和开发人员希望的任何标准动态调整外部漂移。uSimMarine应用程序在这方面为以下MOOS变量注册:DRIFT_X, DRIFT_Y, DRIFT_VECTOR, DRIFT_VECTOR_ADD, DRIFT_VECTOR_MULT.。前三个变量只是覆盖以前流行的漂移,由初始配置或最后收到的有关该漂移的邮件设置。
通过发送到USM_DRIFT VECTOR_MULT,可以使用单个乘法器修改当前矢量的幅度,例如:
DRIFT_VECTOR_MULT = 2
DRIFT_VECTOR_MULT = -1
上面发布的第一个MOOS将使主流漂移向量的大小增加一倍,第二个示例将反转矢量的方向。DRIFT_VECTOR_ADD变量描述要添加到主流漂移矢量的漂移矢量。例如,考虑图3中左侧所示的流行漂移向量,模拟器接收到以下MOOS邮件:
DRIFT_VECTOR_ADD = "262.47, 15.796"
得到的漂移向量将是图3中右侧所示的向量。这个界面为脚本修改漂移矢量打开了大门,如下图所示,它粗略地模拟了给定方向上的阵风,该阵风积聚到一定的量级,然后逐渐消失,最终变成零漂移。
DRIFT_VECTOR_ADD = 137, 0.25
DRIFT_VECTOR_ADD = 137, 0.25
DRIFT_VECTOR_ADD = 137, 0.25
DRIFT_VECTOR_ADD = 137, 0.25
DRIFT_VECTOR_ADD = 137, 0.25
DRIFT_VECTOR_ADD = 137, -0.25
DRIFT_VECTOR_ADD = 137, -0.25
DRIFT_VECTOR_ADD = 137, -0.25
DRIFT_VECTOR_ADD = 137, -0.25
DRIFT_VECTOR_ADD = 137, -0.25
上面的样式脚本在uTimerScript的文档中有描述,其中uTimerScript实用程序用于模拟随机方向和随机量级的阵风。DRIFT *接口也可以被任何第三方MOOS应用程序用于模拟诸如海洋或气流之类的事物。
推力图是一种数据结构,可以用来模拟推力和速度之间的非线性关系。这是在uSimMarine配置块中配置的,thrust map参数包含一个逗号分隔的冒号分隔对列表。分隔列表中的每个元素都是一个单独的映射组件。在每个组件中,冒号左边的值是推力值,另一个值是相应的速度。下面是一个字符串形式的映射示例,如图4所示。
thrust_map = "-100:-3.5, -75:-3.2, -10:-2, 20:2.4, 50:4.2, 80:4.8, 100:5"
图4:推力图:示例推力图由字符串“-100:-3.5,-75:-3.2,-10:-2,20:2.4,50:4.2,80:4.8,100:5”中的七个映射点定义。
推力映射的不可变域为[−100;100],表示100%的正向和反向推力。在此域之外给出的映射对将被忽略。推力映射必须是单调递增的。直觉告诉我们,更大的正推力不会导致飞行器速度变慢,负推力也是如此。由于映射是用如上所述的一对序列配置的,因此会导致非单调映射的一对将被丢弃。所有映射都被创建,就好像它们有一对0:0显式给定。配置中提供的推力值为零的副将被忽略;零推力总是意味着零速度。因此,下面的map配置都等价于上面的map配置,如图4所示:
thrust_map = -120:-5, -100:-3.5, -75:-3.2, -10:-2, 20:2.4, 50:4.2, 80:4.8, 100:5.0, 120:6
thrust_map = -100:-3.5, -75:-3.2, -10:-2, 20:2.4, 50:4.2, 80:4.8, 90:4, 100:5.0
thrust_map = -100:-3.5, -75:-3.2, -10:-2, 0:0, 20:2.4, 50:4.2, 80:4.8, 100:5.0
thrust_map = -100:-3.5, -75:-3.2, -10:-2, 0:1, 20:2.4, 50:4.2, 80:4.8, 100:5.0
在第一种情况下,对"-120:-5"和"120:6"将被忽略,因为它们在[−100;100]域。在第二种情况下,对“90:4”将被忽略,因为它的包含将导致给定前一对“80:4.8”的非单调映射。在第三种情况下,对“0:0”将被有效地忽略,因为它无论如何都隐含在所有映射配置中。在第四种情况下,对“0:1”将被忽略,因为从非零速度到零推力的映射是不允许的。
自域[−100;100]是不可变的,当或如果用户提供的配置没有为- 100或100的推力值提供显式映射时,推力映射会自动更改位。在这种情况下,缺失的映射变成了隐含映射。添加映射100:v,其中v是最近点的速度值。例如,以下两种配置是等价的:
thrust_map = -75:-3.2, -10:-2, 20:2.4, 50:4.2, 80:4.8
thrust_map = -100:-3.2, -75:-3.2, -10:-2, 20:2.4, 50:4.2, 80:4.8, 100:4.8
为方便起见,正推力值与速度值的映射可以反向用于负推力值。这是通过配置uSimMarine的thrust_reflect=true来实现的,该值默认为false。如果推力反射为假,则速度为零映射到所有负推力值。如果thrust_reflect为真,但用户仍然在一个推力映射中提供了一个负推力的映射,那么thrust_reflect指令将被简单地忽略,而使用推力映射。例如,以下两种配置是等价的:
thrust_map = -100:-5, -80:-4.8, -50:-4.2, -20:-2.4, 20:2.4, 50:4.2, 80:4.8, 100:5
thrust_map = 20:2.4, 50:4.2, 80:4.8, 100:5
thrust_reflect = true
由于推力映射只允许产生非单调函数的配置,因此逆映射也(几乎)可以作为从速度到推力的有效映射。我们说“几乎”是因为在推力图中有一个或多个高原的情况下存在歧义,例如:
thrust_map = -75:-3.2, -10:-2, 20:2.4, 50:4.2, 80:4.8
在这种情况下,4:8的速度映射到[80;100]。为了消除这种歧义,在带有方法的c++类中实现的推力映射,在这种情况下返回最小大小的推力。如果速度为4:8(或5),将返回推力值为80。速度为- 3:2时,推力值为- 75。这种消除歧义的方式的动机是,如果推力值为80和100,两者都产生相同的速度,那么人们总是会选择节省较少能量的设置。uSimMarine应用程序不使用反向映射,但在负责在给定所需速度的情况下发布所需推力的应用程序中可能会使用反向映射,例如pMarinePID应用程序。
如果uSimMarine配置时没有显式的thrust_map或thrust_reflect ,则默认行为就像以下两行实际上包含在uSimMarine配置块中一样:
thrust_map = 100:5
thrust_reflect = false
图5:默认推力图:如果没有提供显式配置,则使用此推力图。
选择此默认配置是出于其合理性,并且与用户无法配置推力图的先前版本uSimMarine的行为一致。