MOOS程序解析记录(6)uSimMarine解析1

14 篇文章 0 订阅

系列文章目录

提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加
例如:第一章 Python 机器学习入门之pandas的使用


提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档


uSimMarine简介

uSimMarine应用程序是一个简单的3D车辆模拟器,可以根据当前执行器值和车辆先前状态更新车辆状态、位置和轨迹。典型的使用场景有一个与每个模拟车辆相关联的uSimMarine实例,如图所示。

在这里插入图片描述

订阅变量:
NAV_X, NAV_Y, NAV_SPEED, NAV_HEADING, and NAV_DEPTH

发布变量:
DESIRED_RUDDER, DESIRED_THRUST, and DESIRED_ELEVATOR

其具体的配置文件如下,各参数意义可以查询文档获得
在这里插入图片描述

一、Propagating the Vehicle Speed, Heading, Position and Depth

主要对于这些变量的计算依据三个值:
1.前一刻车辆的状态
2.自从上次更新后经过的时间
3.当前执行机构的值:升降舵角、偏航舵角、推进器力矩
4.模型中的参数
.h文件中包含了很多计算的内容

1.Propagating the Vehicle Speed

在这里插入图片描述
车辆的速度主要基于当前的推力值进行计算DESIRED_THRUST,速度也会收到偏转舵DESIRED_RUDDER的影响。还有上一时刻的速度NAV_SPEED,以及最大加速度MAX_ACCELERATION和最大减速度MAX_DECLEARATION的影响。
具体计算步骤如下:
1.计算vi(raw),基于推力的速度值,其中推力值与速度的转化由thrust_map来进行转换,具体的转换表可以在usim的MOOS配置中进行设置
在这里插入图片描述

 double next_speed  = tmap.getSpeedValue(thrust);

2.计算vi(turn),基于vi(raw)和DESIRED_RUDDER计算的值,会比vi(raw)略低,若AUV进行偏转则进行计算,若无偏转则无变化
在这里插入图片描述

  rudder = vclip(rudder, -100, 100);
  double rudder_magnitude = fabs(rudder);
  double vpct = (rudder_magnitude / 100) * 0.85;
  next_speed *= (1.0 - vpct);

3.计算vi(FINAL),基于vi(TURN)以及之前一刻的速度,收到最大加减速的限制。将计算的速度与上一时刻速度进行比较,用时间间隔算出加速度,若跟设定的最大最小速度有偏差,则进行修正。
在这里插入图片描述

if(next_speed > prev_speed) {
    double acceleration = (next_speed - prev_speed) / delta_time;
    if((max_accel > 0) && (acceleration > max_accel))
      next_speed = (max_accel * delta_time) + prev_speed;
  }

  if(next_speed < prev_speed) {
    double deceleration = (prev_speed - next_speed) / delta_time;
    if((max_decel > 0) && (deceleration > max_decel))
      next_speed = (max_decel * delta_time * -1) + prev_speed;
  }

4.设置该速度,并且用于后面关于位置、深度、航向角的计算

  record.setSpeed(next_speed);

此段程序的源码如下:

void SimEngine::propagateSpeed(NodeRecord& record, const ThrustMap& tmap,
			       double delta_time, double thrust,
			       double rudder, double max_accel, 
			       double max_decel)
{
  if(delta_time <= 0)
    return;

  if(m_thrust_mode_reverse) {
    thrust = -thrust;
    rudder = -rudder;
  }

  double next_speed  = tmap.getSpeedValue(thrust);
  double prev_speed  = record.getSpeed();

  // Apply a slowing penalty proportional to the rudder/turn
  rudder = vclip(rudder, -100, 100);
  double rudder_magnitude = fabs(rudder);
  double vpct = (rudder_magnitude / 100) * 0.85;
  next_speed *= (1.0 - vpct);

  if(next_speed > prev_speed) {
    double acceleration = (next_speed - prev_speed) / delta_time;
    if((max_accel > 0) && (acceleration > max_accel))
      next_speed = (max_accel * delta_time) + prev_speed;
  }

  if(next_speed < prev_speed) {
    double deceleration = (prev_speed - next_speed) / delta_time;
    if((max_decel > 0) && (deceleration > max_decel))
      next_speed = (max_decel * delta_time * -1) + prev_speed;
  }
  record.setSpeed(next_speed);
}

2.Propagating the Vehicle Heading

和速度类似,航向角也收到DESIRED_RUDDER和DESIRED_THRUST的影响
计算算法如下:
1.计算∆θi(RAW),受到当前的rudder值影响,TURN_RATE转弯速率可以在配置文件中进行设置。
在这里插入图片描述

  // Step 1: Calculate raw delta change in heading
  double delta_deg = rudder * (turn_rate/100) * delta_time;

2.计算∆θi(THRUST),会根据∆θi(RAW)和当前的推力THRUST进行调整,推力大于百分之五十时,航向角变化增加,小于百分之五十时变化减小
在这里插入图片描述

并且会根据推力的方向改变航向角的变化方向。

在这里插入图片描述

  // Step 2: Calculate change in heading factoring thrust
  delta_deg = (1 + ((thrust-50)/50)) * delta_deg;

3.计算∆θi(EXTERNAL),航向角变化可能会受到外部转速ROTATE_SPEED的影响,
在这里插入图片描述

  // Step 3: Calculate change in heading factoring external drift
  delta_deg += (delta_time * rotate_speed);

4.最后需要对新的航向角进行计算,使其范围在【0,360】

在这里插入图片描述

  // Step 4: Calculate final new heading in the range [0,359]
  double prev_heading = record.getHeading();
  double new_heading  = angle360(delta_deg + prev_heading);
  record.setHeading(new_heading);
  record.setYaw(-degToRadians(angle180(new_heading)));

源码如下:

void SimEngine::propagateHeading(NodeRecord& record,
				 double delta_time, 
				 double rudder,
				 double thrust,
				 double turn_rate,
				 double rotate_speed)
{
  // Assumption is that the thruster and rudder are on the same
  // actuator, e.g., like the kayaks, or typical UUVs. A rotated
  // thruster contributes nothing to a turn unless the prop is 
  // moving.
  double speed = record.getSpeed();
  if(speed == 0) 
    rudder = 0;

  if(m_thrust_mode_reverse) {
    thrust = -thrust;
    rudder = -rudder;
  }

  // Even if speed is zero, need to continue on in case the 
  // torque is non-zero.
  rudder    = vclip(rudder, -100, 100);
  turn_rate = vclip(turn_rate, 0, 100);
  
  // Step 1: Calculate raw delta change in heading
  double delta_deg = rudder * (turn_rate/100) * delta_time;

  // Step 2: Calculate change in heading factoring thrust
  delta_deg = (1 + ((thrust-50)/50)) * delta_deg;

  // Step 3: Calculate change in heading factoring external drift
  delta_deg += (delta_time * rotate_speed);

  // Step 4: Calculate final new heading in the range [0,359]
  double prev_heading = record.getHeading();
  double new_heading  = angle360(delta_deg + prev_heading);
  record.setHeading(new_heading);
  record.setYaw(-degToRadians(angle180(new_heading)));
}

3.Propagating the Vehicle Position

车辆位置的传播主要基于新计算的车辆方向和速度、以前的车辆位置,以及自更新以前的车辆位置以来所经过的时间来进行计算的
步骤如下:
1.计算用于更新新车辆位置的车辆方向 θ¯,和速度v,并将方向转换为弧度
在这里插入图片描述
其中s和c意义如下,该式子可以解决角度换算的问题,1和360的平均值为0而不是180
在这里插入图片描述
2.根据航向、速度和运行时间计算新位置xi和yi,考虑到在海上航行中,0度为正北,90度为正东的习惯差异,计算是在此基础上得出的也就是说,从海洋到传统三角的映射如下:0◦→90◦,90◦→0,180◦→270◦,270◦→180◦
在这里插入图片描述
3.最后一步是考虑到可能存在的任何外部漂移,从上面调整x和y位置。
在这里插入图片描述
源码如下:

void SimEngine::propagateHeading(NodeRecord& record,
				 double delta_time, 
				 double rudder,
				 double thrust,
				 double turn_rate,
				 double rotate_speed)
{
  // Assumption is that the thruster and rudder are on the same
  // actuator, e.g., like the kayaks, or typical UUVs. A rotated
  // thruster contributes nothing to a turn unless the prop is 
  // moving.
  double speed = record.getSpeed();
  if(speed == 0) 
    rudder = 0;

  if(m_thrust_mode_reverse) {
    thrust = -thrust;
    rudder = -rudder;
  }

  // Even if speed is zero, need to continue on in case the 
  // torque is non-zero.
  rudder    = vclip(rudder, -100, 100);
  turn_rate = vclip(turn_rate, 0, 100);
  
  // Step 1: Calculate raw delta change in heading
  double delta_deg = rudder * (turn_rate/100) * delta_time;

  // Step 2: Calculate change in heading factoring thrust
  delta_deg = (1 + ((thrust-50)/50)) * delta_deg;

  // Step 3: Calculate change in heading factoring external drift
  delta_deg += (delta_time * rotate_speed);

  // Step 4: Calculate final new heading in the range [0,359]
  double prev_heading = record.getHeading();
  double new_heading  = angle360(delta_deg + prev_heading);
  record.setHeading(new_heading);
  record.setYaw(-degToRadians(angle180(new_heading)));
}

4.Propagating the Vehicle Depth

根据一些输入参数,模拟了uSimMarine的深度变化。从一个迭代到下一个迭代的主要参数变化是ELEVATOR升降舵角的值,从MOOS变量DESIRED_ELEVATOR。在任何给定的迭代中,新的车辆深度zi由下面的式子进行计算
在这里插入图片描述
每次新的深度由过去的深度加上深度变化率乘以时间间隔来进行计算。
而深度变化率则由AUV的速度、升降舵角的值以及三个关于物理模拟的变量决定,这三个变量为:1.buoyancy_rate以米每秒作为单位,当该值大于0时说明AUV正处于正浮力
2.max_depth_rate最大深度变化率
3.max_depth_rate_speed最大深度速度变化率
上面两个变量将会影响深度变化率,其具体影响如下图所示:
在这里插入图片描述
AUV会在高速行驶的情况下有更快的深度变化率,直到到达最大速度上限后,速度不再影响深度变化率。真实情况下的深度变化率取决于升降舵角和AUV的速度。深度变化率公式如下:
在这里插入图片描述
据此写成的深度仿真代码如下所示:

//--------------------------------------------------------------------
// Procedure: propagateDepth

void SimEngine::propagateDepth(NodeRecord& record,
			       double delta_time,
			       double elevator_angle, 
			       double buoyancy_rate,
			       double max_depth_rate, 
			       double max_depth_rate_speed)
{
  double speed = record.getSpeed();
  double prev_depth = record.getDepth();
  elevator_angle = vclip(elevator_angle, -100, 100);
  if(speed <= 0) {
    double new_depth = prev_depth + (-1 * buoyancy_rate * delta_time);
    record.setDepth(new_depth);
    record.setPitch(0.0);
  }
  else {
    double pct = 1.0;
    if(max_depth_rate_speed > 0) {
      pct = (speed / max_depth_rate_speed);
      if(pct > 1.0)
	pct = 1.0;
    }
    if(pct < 0)
      pct = -1 * sqrt(-1 * pct);
    else
      pct = sqrt(pct);
    double depth_rate = pct * max_depth_rate;
    double speed = record.getSpeed();
    double pitch_depth_rate = - sin(record.getPitch())*speed;
    double actuator_depth_rate = (elevator_angle/100) * depth_rate;
    double total_depth_rate = (-buoyancy_rate) +  pitch_depth_rate + actuator_depth_rate;

    double new_depth = prev_depth + (1 * total_depth_rate * delta_time);
    record.setDepth(new_depth);

    // Pitch added by HS 120124

    double pitch =0 ;
    if (speed > 0 && (fabs(pitch_depth_rate+actuator_depth_rate) <= speed))
      pitch = - asin((pitch_depth_rate+actuator_depth_rate)/speed);
    record.setPitch(pitch);
  }
    
  if(record.getDepth() < 0)
    record.setDepth(0);
}

4.Propagating the Vehicle Altitude

默认的水深为100米,水深完全由当前AUV的位置所决定

default water depth = 100

总结

提示:这里对文章进行总结:

其他内容基本上类似,后面有时间再继续写

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值