ROS Navigation Tuning Guide(导航调试指南)

2023-05-16

ROS Navigation Tuning Guide

  • 导航调试指南
    • 准备工作
      • 距离传感器
      • 里程计
      • 定位
    • 速度与加速度的设置
      • 获得最大速度
      • 获得最大加速度
      • 设置最小值
      • XY方向的速度
    • Global Planner
      • 接口
      • 参数
    • Local Planner
      • DWA Local Planner
        • DWA algorithm
        • DWA Local Planner : Forward Simulation
        • DWA Local Planner : Trajactory Scoring
        • DWA Local Planner : Other Parameters
    • Costmap 参数
      • footprint
      • inflation
      • costmap resolution
      • obstacle layer and voxel layer
    • AMCL
      • Header in LaserScan messages
      • Parameters for measurement and motion models
      • Translation of the laser scanner
    • Recovery Behaviors
    • Dynamic Reconfigure
    • 其他
      • 代价地图
      • 局部规划器
    • 实调总结
    • 全局规划
    • 局部规划
      • TrajectoryPlannerROS
      • DWAPlannerROS
    • move_base

导航调试指南

借用前辈郑开宇基本调试指南经验,谈一谈对于配置、调参、优化这些到底应该怎么做,经验之谈.

准备工作

三个组件检查:距离传感器,里程计和定位。

距离传感器

如果机器人没有从其距离传感器(例如激光器)获取信息,那么导航将不起作用。首先确保可以在rviz中查看传感器信息,它看起来相对正确(一般判断激光点是否跟障碍物对齐),并以预期的速度在刷新。
最后确认建图导航中是否为需要的传感器数据topic以及link是否正确。

里程计

里程计是一个很不确定的因素,大部分移动机器人是有编码器的,编码器本身会有少量误差,但是加上轮子摩擦空转、地面不平、机器人驱动结构(二轮差动、四轮差动、全向轮)等因素影响,会累计出很大的误差,尤其是原地旋转,通常情况下可以加入IMU等数据进行融合重新计算里程计数据,如果使用得当,里程计误差便可以控制在很好的范围。然而,又是然而,IMU的安装位置是机械的,如何标定IMU的准确相对位置是困难的,不过通常良好的机械安装会使计算后的里程在可控范围内,所以,使用EKF等融合数据时,一定要保证IMU位置与数据的准确,否则只会让里程计信息雪上加霜。

第一个测试检查角速度是否合理。打开rviz,将坐标系设置为“odom”,显示机器人提供的激光扫描,将该主题的衰减时间设置为高(类似20秒),并执行原地旋转。然后,我看看扫描出来的边线在随后的旋转中如何相互匹配。理想情况下,每次扫描将刚好落在相互的顶端,会重叠在一起,但是有些旋转漂移是预期的,所以我只是确保扫描之间误差,不会超过一度或两度以上。

第二个测试检查线速度是否合理。机器人放置在与距离墙壁几米远地方,然后以上面相同的方式设置rviz。接着我将驱动机器人向墙壁前进,从rviz中聚合的激光扫描看看扫描出来边线的厚度。理想情况下,墙体应该看起来像一个扫描,但我只是确保它的厚度不超过几厘米。如果显示扫描边线的分散在半米以上,但有些可能是错误的测距。

其他的测试角速和线速方法:

线速标定:http://www.ncnynl.com/archives/201701/1217.html
角速标定:http://www.ncnynl.com/archives/201701/1218.html
线速标定:http://www.ncnynl.com/archives/201707/1812.html
角速标定:http://www.ncnynl.com/archives/201707/1813.html

定位

假设里程计和激光扫描仪都能合理地执行,建图和调整AMCL通常并不会太糟糕。首先,运行gmapping或者hector啥的,操控机器人来生成地图。然后使用该地图与AMCL,并确保机器人保持定位。通常是需要设置一个大概的初始位置,稍微移动机器人,就可以看到激光与障碍物对齐了。

速度与加速度的设置

最大/最小速度和加速度是移动基座的两个基本参数,正确设置对优化本地规划器行为有很大帮助.在ROS中有平动和旋转的两种速度/加速度。

加速度与速度,对于规划的影响就很神奇,不同的加速度,速度,最大最小速度,最大加速度,前进速度与转弯速度的组合,各种组合就是会有不一样的效果,想要获得好的效果只能多次尝试不同组合,对于不同的机器人效果也不近相同,还有controller的频率也会影响最后的输出速度。

获得最大速度

通常可以参考移动底盘手册,找到最大速度.还可以订阅odom话题,控制机器人运动,直线运动和原地旋转运动分别可以一个恒定值,便是最大平动速度和旋转速度,为了安全一般我们设置低于最大值.

获得最大加速度

同样可以在手册中找到.若不能再次使用里程计参数,根据机器人到达最大速度的时间,最大速度,位置或角度,可以计算出最大加速度.

设置最小值

这里的最小值我们设置为较大的负值,因为需要机器人后退,以及在任意方向旋转.注意:DWA Local Planner采用机器人最小转速的绝对值.

XY方向的速度

X方向速度为平行于机器人直线运动的方向的速度,与平动速度相同.Y方向速度为垂直于机器人直线运动方向的速度.对于非完整机器人,如两轮差速机器人,需将Y轴方向速度设置为0.

Global Planner

move_base的运行依赖于global planner和local planner.这里有三个nav core::BaseGlobal Planner 的接口: carrot planner, navfn and global planner

接口

  1. carrot planner :最简单的一个.检查到如果给定的目标是障碍物,通过沿向量向后移动机器人和目标点。最终它将这个有效的目标作为一个计划传递给本地规划师或controller。因此,此计划器不执行任何全局操作路径规划。如果你需要你的机器人接近给定的目标,这是很有帮助的。即使目标无法实现。在复杂的室内环境中却不太实际。
  2. navfn and global planner :navfn使用dijkstra的算法找到一个全局路径,该路径在起点和终点。Global Planner是一种更灵活的替代产品。有更多的选择。这些选项包括(1)A*支持(2)切换二次近似(3)切换网格路径。

参数

global planner通常是我们喜欢使用的,下面讨论一些关键参数.并非所有参数在ROS网站,这时使用rqt的参数重新配置程序,可以看到所有参数
rosrun rqt_reconfigure rqt_reconfigure

将参数 allow_unknown(true) use_dijkstra(true) use_quadratic(true) use_grid_path(false)  old_navfn_behavior(false) 设置成默认.如果需要查看potential map,将visualize potential(false)设置成true可能会很有帮助map
除了这些参数外,还有三个未列出的参数实际上决定了计划全局路径的质量。成本因素、中性成本、致命成本。实际上,这些参数也出现在NAVFN中。源代码2有一段解释navfn如何计算成本值。在这里插入图片描述
在这里插入图片描述
navfn cost value的设置:
cost = COST NEUTRAL + COST FACTOR * costmap cost value
costmap cost values的输入值在0到252之间.
在成本中性值为50的情况下,成本系数需要大约为0.8,以确保输入值在输出范围(50到253)上均匀分布。如果成本因素更高,成本值将在障碍物周围有一个高原,然后规划者将(例如)把狭窄走廊的整个宽度视为同样不可取的,因此不会规划沿着中心的路径.
实验证明。将成本系数设置为过低或过高会降低路径的质量。这些路径有不经过每边障碍物的中间,曲率相对平缓。极端中性的成本值也有同样的效果。对于致死成本,即使可行路径明显,将其设置为低值也可能导致无法生成任何路径。图5-10显示了成本因素和中性成本对全球路径规划的影响。绿线是全球规划师制定的全球路径。经过几次实验,我们发现当cost factor=0.55,neutral cost=66,lethal cost=253时,全局路径是比较理想的。

Local Planner

Local planners依赖于nav core::BaseLocalPlanner interface的接口:
dwa local planner eband local planner teb local planner
它们使用不同算法生成速度命令.我们通常选择DWA.

DWA Local Planner

DWA algorithm

dwa_local_planner采用了Dynamic Window Approach(DWA)算法
算法基本思想:

  • 在机器人控制空间(dx,dy,dta)中离散采样。
  • 对于每个采样速度,从机器人的当前状态执行正向移动模拟,以预测如果在一些(短)时间段内应用采样速度将会发生什么。
  • 从以下方面来评价正向移动模拟产生的每个轨迹:接近障碍物,接近目标,接近全局路径和速度。 放弃非法轨迹(与障碍物相撞的轨迹)。
  • 选择最高得分的轨迹,并将相关速度发送到移动基座。
  • 冲洗并重复

DWA的目标是产生一个(v,ω)对,它表示一个最适合机器人的局部状况。DWA通过搜索下一个时间间隔。这个空间的速度被限制在允许范围内,这意味着机器人必须能够在到达最近的障碍物之前停止。由这些容许速度决定的圆形轨道。而且,DWA只会考虑动态窗口中的速度,该窗口定义为在给定当前平移和旋转速度和加速度的情况下,在下一个时间间隔内可到达的一组速度对。DWA最大化了一个目标函数,这取决于:
(1)抵达目标的进度(2)障碍物空间(3)前进速度产生最佳速度对。

算法摘要:第一步是在动态窗口中的速度空间中采样速度对(v x,v y,ω)。第二步基本上是消除速度(即消除不良轨道),这是不允许的。第三步是使用OBJEC评估速度对.输出轨迹得分的动态函数。第四步和第五步很容易理解,选择当前的最佳速度选项并重新计算。

这个DWA计划依赖于提供障碍信息的本地成本图信息。因此,调整局部成本图的参数对于优化DWA Local planner的行为。接下来,我们将在正向模拟中查看参数,轨迹评分,成本地图等等。

DWA Local Planner : Forward Simulation

前向仿真是DWA算法的第二步。在这一步中,local planner在机器人的控制空间中提取速度样本,并检查这些速度样本所代表的圆形轨迹,最终消除不良速度(轨迹与障碍物相交的速度)。每一个速度样本都被模拟,就好像它被应用到机器人上一个设定的时间间隔,由模拟时间(s)参数控制。我们可以把sim_time看作是机器人以采样速度移动所允许的时间。

实验结果表明,模拟时间越长,计算量越大。另外,当仿真时间变长时,local planner的路径也会变长,这是合理的。下面是一些关于如何调整此sim_time参数的建议。

如果将sim_time设置为一个非常低的值(<=2.0),将导致性能受限,特别是当机器人需要通过狭窄的门口或家具之间的间隙时,因为没有足够的时间来获得实际通过狭窄通道的最佳轨迹。另一方面,由于有了DWA Local planner,所有的轨迹都是简单的圆弧,将sim_time设置为一个非常高的值(>=5.0)将导致不太灵活的长曲线。这个问题并不是不可避免的,因为计划员在每个时间间隔(由控制器频率(hz)控制)后都会主动重新规划,这为小的调整留出了空间。即使对于高性能计算机,4.0秒的值也应该足够。
在这里插入图片描述
除了sim_time之外,其他一些值得关注的参数.

速度样本和其他参数 vy_samplevy_sample决定了在x,y方向要取多少平移速度样本。vy_sample控制旋转速度样本的数量。您希望采集的样本数量取决于您拥有多少计算能力。在大多数情况下,我们倾向于将vy_sample设置为高于平动速度样本,因为转弯通常比直行更复杂。如果将max_vel_y设置为0,则无需在y方向上进行速度采样,因为没有可用的采样。我们选取vy_sample=20,vy_sample=40。

模拟粒度 sim_granularity是在轨迹上的点之间采样的步长。它基本上意味着应该检查轨迹上的点的频率(测试它们是否与任何障碍物相交)。较低的值意味着较高的频率,这需要更多的计算能力。默认值0.025通常足以满足Turtlebot大小的移动基础。

DWA Local Planner : Trajactory Scoring

如上所属,DWA Local Planner 最大化目标函数来获得最佳路径.DWA最大化了一个目标函数,取决于:
(1)抵达目标的进度(2)障碍物空间(3)前进速度产生最佳速度对。

目标函数的成本计算如下:
cost = path distance bias ∗ (distance(m) to path from the endpoint of the trajectory) +
goal distance bias ∗ (distance(m) to local goal from the endpoint of the trajectory) +
occdist scale ∗
(maximum obstacle cost along the trajectory in obstacle cost (0-254))

目标是获得最低的成本。path_distance_bias是Local应保持接近Global planner的程度的权重。高值将使Local planner更喜欢全局路径上的轨迹。

goal_distance_bias是指机器人在任何路径下,都应尝试达到local goal的权重。实验表明,增加该参数可以减少机器人对全局路径的依赖。

occdist_scale是机器人应避免多少障碍物的权重。此参数的高值会导致不确定的机器人卡入到位。目前,对于Scitos G5,我们将path_distance_bias设置为32.0,goal_distance_bias设置为20.0,occdist_scale设置为0.02。它们在仿真方面工作得很好。

DWA Local Planner : Other Parameters

Goal distance tolerance

  • yaw_goal_tolerance(double, default: 0.05)控制器达到目标时的偏航/旋转公差(以弧度表示)
  • xy_goal_tolerance(double, default: 0.10)实现目标时控制器在X&Y距离上的公差(以米为单位)
  • latch_xy_goal_tolerance(bool, default: false)目标公差锁定,如果机器人到达目标xy位置,它将简单地原地旋转,即使在执行此操作时,它最终超出了目标公差。

Oscilation reset 如在通过门口等情况下,机器人可以来回摆动,因为它的本地规划者正在生成通向两个相反方向的路径。如果机器人持续抖动,导航堆栈将让机器人尝试其恢复行为。

  • oscillation_reset_dist(double, default: 0.05)在重置振荡标志之前,机器人必须移动多远(以米为单位)。

Costmap 参数

如上所述,成本图参数的调整对于本地规划者的成功至关重要(不仅对于DWA)。在ROS中,代价地图由静态地图层、障碍地图层和膨胀层组成。静态地图层直接解释提供给导航堆栈的给定静态SLAM地图。障碍物地图层包括二维障碍和三维障碍(三维像素层)。膨胀层是一个障碍物膨胀的地方,用来计算每个二维成本图单元的成本。

此外,还有一个global costmap和一个local costmap。global costmap是通过向导航点提供的地图上的障碍物膨胀而生成的。通过对机器人传感器实时检测到的障碍物进行膨胀,生成local costmap。

有许多重要的参数应该设置得尽可能好。

footprint

足迹是移动基地的轮廓。在ROS中,它由一个二维数组表示,其形式为[X 0,Y 0]、[X 1,Y 1]、[X 2,Y 2]、…],无需重复第一个坐标。该足迹将用于计算内接圆的半径和外接圆,以适合机器人的方式进行膨胀.通常为了安全,我们希望轮廓要比机器人真实的形状大.
在这里插入图片描述
要确定机器人的足迹,最简单的方法是参考机器人的图纸。此外,还可以手动拍摄其底部的俯视图。然后使用CAD软件(如SolidWorks)适当地缩放图像,并将鼠标移动到基础轮廓周围,读取其坐标。坐标的原点应该是机器人的中心。或者,你
可以在一张大纸上移动你的机器人,然后画出底座的轮廓。然后选择一些顶点并使用标尺计算出它们的坐标。

inflation

膨胀层由成本在0到255之间的单元组成。每个单元要么被占用,没有障碍,要么是未知的。图13说明了如何计算通货膨胀衰减曲线。

inflation radiuscost scaling factor是决定膨胀的参数。inflation radius控制着零成本点离障碍物的距离。cost scaling factor与单元成本成反比。设置得更高会使衰减曲线更陡.

Pronobis博士建议,最佳的Costmap衰减曲线是一条坡度相对较低的曲线,因此,最佳路径尽可能远离两侧的障碍物。其优点是机器人更喜欢在障碍物中间移动。如图8和图9所示,在相同的起点和目标下,当Costmap曲线陡峭时,机器人倾向于接近障碍物。在图14中,通货膨胀半径=0.55,成本比例系数=5.0;在图15中,通货膨胀半径=1.75,成本比例系数=2.58在这里插入图片描述
在衰减曲线图的基础上,对这两个参数进行设置,使膨胀半径几乎覆盖了腐蚀体,且成本值衰减适中,这意味着降低了cost scaling factor的值。

costmap resolution

本地代价地图和全局代价地图可以分别设置此参数。它们影响计算负载和路径规划。当低分辨率(>=0.05)时,在狭窄的通道中,障碍区域可能会重叠,因此local planner无法找到通过的路径。

对于全局代价地图分辨率,它足以保持与提供给导航堆栈的地图的分辨率相同。如果你有足够的计算能力,你应该看看激光扫描仪的分辨率,因为当使用gmapping创建地图,如果激光扫描仪的分辨率低于您所需的地图分辨率,将会有很多小的“未知点”,因为激光扫描仪无法覆盖该区域,如图16所示。
在这里插入图片描述
例如,Hokuyo URG-04LX-UG01激光扫描仪的公制分辨率为0.01mm。因此,扫描分辨率<=0.01的地图需要机器人旋转几次以清除未知的点。我们发现0.02是一个足够的解决方案。

obstacle layer and voxel layer

这两个层负责在Costmap上标记障碍物。它们可以统称为障碍层。根据Roswiki,障碍层是二维的,而体素层是三维的。根据机器人传感器的数据,对障碍物进行标记(检测)或清除(清除),该传感器具有costmap可订阅的主题。

在ROS实现中,体体素继承了障碍层,它们都通过解析激光扫描或使用PointCloudPointCloud2类型消息发送的数据来获取障碍信息。此外,体素层需要深度传感器,例如作为Microsoft Kinect或Asus Xtion。三维障碍物最终会被投影到二维成本图中用于膨胀。

体素层如何工作 体素是三维立方体(想想三维像素),它在空间中具有一定的相对位置。它可用于与它附近的体积数据或所有物的属性相关联,例如,它的位置是否是障碍物。关于利用体素进行深度相机在线三维重建的研究还比较多。这里有一些。

体素网格是一个ROS包,它提供了一个高效的3D体素网格数据结构的实现,该数据结构存储了三种状态的体素:标记、自由、未知.体素网格占据Costmap区域内的体积。在体素层边界的每次更新过程中,体素层将根据传感器的观察标记或删除体素网格中的某些体素。它还执行光线跟踪,这将在下面讨论。请注意,更新时不会重新创建体素网格,只有在更改本地Costmap的大小时才会更新。

为什么在障碍层和体素层进行光线跟踪?光线跟踪最著名的是渲染逼真的三维图形,所以可能会疑惑为什么在处理障碍物时使用它。一个很大的原因是机器人的传感器可以检测到不同类型的障碍物。看看图17。理论上,我们还能够知道障碍物是硬的还是软的。
在这里插入图片描述
有了以上的理解,让我们研究障碍物层的参数。这些参数是适用于所有传感器的全局过滤参数.

  • max obstacle height:插入成本地图的障碍物的最大高度,单位为米。此参数应设置为略高于机器人的高度。对于体素层,这基本上是体素网格的高度。

  • obstacle range:与机器人的默认最大距离,障碍物将插入成本图中,单位为米。这可以在每个传感器的基础上分开进行。

  • raytrace range:使用传感器数据从地图中对障碍物进行光线跟踪的默认范围,单位为米。这可以在每个传感器的基础上分开进行。

这些参数仅用于体素层(VoxelCostMapPlugin)。

  • origin z:地图的z原点,单位为米。

  • z resolution:地图的Z分辨率,单位为米/格。

  • z voxels:每个垂直列中的体素数量,网格高度为z_resolution * z_voxels

  • unknown threshold:列con中允许的未知单元格数被认为是“已知的”

  • mark_threshold:列中允许的标记单元格的最大数目被认为是“免费的”。

实验观察
实验观察实验进一步阐明了体素层参数的影响。我们使用Asus Xtion Pro作为深度传感器。我们发现X离子的位置决定了“盲区”的范围,即深度传感器看不到任何东西的区域。

此外,仅当障碍物出现在局部代价地图更新范围内时,表示障碍物的体素才会更新(标记或清除)。否则,一些体素信息将保留,它们对Costmap膨胀的影响仍然存在。此外,Z分辨率控制体素在Z轴上的密度。如果它更高,体素层更密集。如果该值太低(例如0.01),所有体素将被组合在一起,因此您将无法获得有用Costmap信息。如果将Z分辨率设置为更高的值,您的目的应该是更好地获取障碍,因此需要增加Z体素参数,该参数控制多少个体素。在每个垂直列中。如果一列中的体素太多,但分辨率不够,这也是无用的,因为每个垂直列都有高度限制。

AMCL

AMCL是一个处理机器人定位的ROS包。它是自适应蒙特卡罗定位(AMCL)的缩写,也称为粒子滤波器定位。这种定位技术的工作原理是这样的:每个样本存储一个代表机器人姿势的位置和方向数据。最初,所有粒子都是随机取样的。当机器人移动时,根据粒子的当前状态以及机器人的动作,采用递归贝叶斯估计对粒子进行重采样。

现在总结几个可能会影响amcl定位精度的问题.
通过实验,我们观察到影响AMCL定位的三个问题。如[Thrun et al.,2005]所述,MCL维持两个概率模型,一个运动模型和一个测量模型。在ROS AMCL中,运动模型对应一个里程计模型,而测量模型对应一个激光扫描模型。根据这一总体理解,我们描述了三个问题分别如下。

Header in LaserScan messages

发布到扫描主题的消息类型为sensor msgs/LaserScan。此消息包含一个标题,其字段取决于您使用的特定激光扫描仪。这些字段包括(从消息文档中复制)

  • angle min (float32)扫描开始角度[rad]

  • angle max (float32)结束角度[rad]

  • angle increment(float32) 扫描起始角度[rad]

  • time increment(float32) 时间[秒]-如果扫描仪正在移动,这将用于插入三维点的位置。

  • scan time(float32)扫描间隔时间[秒]

  • range min(float32)最小范围值[m]

  • range max(float32)最大范围值[m]

Parameters for measurement and motion models

AMCL包中列出了有关调整激光扫描仪模型(测量)和里程计模型(运动)的参数。有关完整列表及其定义,请参阅包页面。详细的讨论需要对[Thrun等人,2005]中的MCL算法有很好的理解,这里我们省略了这一点。我们提供了一个微调这些参数的例子,并定性地描述了它们的结果。你使用的实际参数应该取决于你的激光扫描仪和机器人。

为了改善机器人的定位,我们增加了激光Z击和激光sigma击,以包含更高的测量噪声。结果参数为:(此处实验未观察出理想变化)
在这里插入图片描述
在这里插入图片描述
对于激光扫描仪型号,默认参数为:
里程计模型的噪声较小时,粒子相对集中,反之则相对发散

Translation of the laser scanner

有一个从laser linkbase footprintbase link的TF变换,指示激光扫描仪相对于机器人底盘的姿态。如果这种转换不正确,则很可能是本地化行为异常。在这种情况下,我们观察到墙上的激光读数不断变化以及本地化的突然剧烈变化。它非常简单,可以确保转换是正确的;这通常在您的机器人的URDF和SRDF规范中处理。但是,如果您使用的是Rosbag文件,那么您可能需要自己发布转换。

Recovery Behaviors

机器人导航的一个恼人之处是机器人可能会被卡住。幸运的是,导航堆栈内置了恢复行为。即使如此,有时机器人也会尝试完所有回复行为变成静止。因此,我们可能需要找出一个更健壮的解决方案。

恢复行为类型 ROS导航有两种恢复行为。它们是clear_costmap_recoveryrotate_recovery。清除代价地图恢复基本上是将本地代价地图复原为与全局代价地图相同的状态。旋转恢复是通过原地旋转360度来恢复。

解开机器人 有时会因为旋转失败而无法执行旋转恢复。在这一点上,机器人可能会放弃,因为它已经尝试了所有的恢复行为-清除成本图和旋转。在大多数实验中,我们观察到当机器人放弃时,实际上有很多方法可以解开机器人。为了避免放弃,我们不断尝试不同的恢复行为,还有一些额外的目标,比如设定一个非常接近机器人的临时目标,回到以前去过的姿势(即后退)。这些方法的结果是,大大提高了机器人的耐久性,并从我们的实验观察中把它从以前没有希望的狭窄空间中解开。

参数 ROS恢复行为的参数通常可以保留为默认值。对于清晰的成本地图恢复,如果您的sim_time相对较高,这意味着轨迹较长,您可能需要考虑增加reset_distance,以便删除本地代价地图上较大的区域,并且本地规划人员有更好的机会找到路径。
在这里插入图片描述

Dynamic Reconfigure

ROS导航最灵活的一个方面是动态重构,当机器人接近目标时不同的参数设置可能对某些情况更有帮助。然而,没有必要进行大量的动态重构。

例如,我们在实验中观察到的一种情况是,即使在不必要或不好的情况下,机器人也倾向于脱离全局路径。因此我们增加了path_distance_bias。由于高path_distance_bias会使机器人坚持全局路径,这实际上不会导致最终目标由于公差,我们需要一种方法让机器人毫不犹豫地达到目标。我们选择动态减少path_distance_bias,这样当机器人接近目标时,goal_distance_bias会被强调。毕竟,做更多的实验是找到问题并找出解决方案的最终方法。

其他

代价地图

一旦我的机器人满足导航的先决条件,我想确保代价地图的设置和配置正确。我会在如何配置ROS导航教程和costmap_2d文档详细说明,但是我会给出一些我经常做的事情的提示。

如下建议可用来调整代价地图:

  • 确保根据传感器实际发布的速率为每个观测源设置expected_update_rate参数。我通常在这里给出相当的容忍度,把检查的期限提高到我期望的两倍,但是当传感器低于预期速率时,它很容易从导航中接收警告。

  • 为系统适当设置transform_tolerance参数。查看使用tf从“base_link”坐标系到“map”坐标系的转换的预期延迟。我通常使用tf_monitor查看系统的延迟,并将参数保守地设置为关闭。另外,如果tf_monitor报告的延迟足够大,我可能会随时看看导致延迟的原因。这有时会导致我发现关于给定机器人的变换如何发布的问题。

  • 在缺乏处理能力的机器人上,我会考虑关闭map_update_rate参数。然而,在这样做时,我考虑到这将导致传感器数据快速进入代价地图的延迟,这反过来会降低机器人对障碍物的反应速度。

  • 该publish_frequency参数是在rviz可视化costmap有用。然而,特别是对于大型全局地图,该参数可能导致事情运行缓慢。在生产系统中,我考虑降低成本图发布的速度,当我需要可视化非常大的地图时,我确定设置速度真的很低。

  • 是否对代价地图使用voxel_grid或costmap模型的决定在很大程度上取决于机器人具有的传感器套件。调整代价地图为基于3D-based代价地图更多是涉及未知空间的考虑。如果我正在使用的机器人只有一个平面激光,我总是使用costmap模型的地图。

  • 有时,它只能在里程坐标系中运行导航。要做到这一点,我发现最容易做的事情就是我的复制local_costmap_params.yaml文件覆盖global_costmap_params.yaml文件并更改了地图宽度和高度比如10米。如果需要独立的定位性能来调整导航,这是一个简单易行的方法

  • 我倾向于根据机器人的尺寸和处理能力选择我使用的地图的分辨率。在具有很多处理能力并需要适应狭窄空间的机器人,如PR2,我会使用细粒度的地图…将分辨率设置为0.025米。对于像roomba这样的东西,我可能会以高达0.1米的分辨率去降低计算量。

  • Rviz是验证代价地图正常工作的好方法。我通常从代价地图中查看障碍物数据,并确保在操纵杆控制下驱动机器人时,它与地图和激光扫描相一致。这是对传感器数据以合理的方式进入代价地图的合理检查。如果我决定用机器人跟踪未知的空间,主要是这些机器人正在使用voxel_grid模型的代价地图,我一定要看看未知的空间可视化,看看未知的空间被以合理的方式清除。是否正确地从代价地图中清除障碍物的一个很好的检查方法是简单地走在机器人的前面,看看它是否都成功地看到我,并清除我。

  • 当导航包仅运行costmap时,检查系统负载是一个好主意。这意味着提高move_base节点,但不会发送目标点并查看负载。如果计算机在这个时候陷入僵局,我知道如果我想要运行规划器的话,我需要做一些CPU参数调整。

局部规划器

如果通过代价地图的操作令人满意,我将继续调整局部规划器参数。在具有合理加速度限制的机器人上,我通常使用dwa_local_planner,对于那些具有较低加速度限制的机器人,并且可以从每个步骤考虑到加速限制的,我将使base_local_planner。调整dwa_local_planner比调整base_local_planner更为愉快,因为它的参数是动态可配置的。为导航包添加dynamic_reconfigure也已经在计划中。针对规划器的提示:

  • 对于给定的机器人最重要的是,正确设置了加速度限制参数。如果这些参数关闭,只能期望来自机器人的次优行为。如果我不知道机器人的加速度极限是什么,我会花点时间写出一个脚本,让电机以最大平移和旋转速度命令运行一段时间,看看报告的里程计速度(假设里程会给出合理的估计),并从中得出加速度极限。合理设置这些参数可以节省很多时间。

  • 如果我正在使用的机器人具有低加速度限制,我确保我正在运base_local_planner,其中dwa设置为false。将dwa设置为true后,我还将确保根据处理能力将vx_samples参数更新为8到15之间的值。这将允许在展示中生成非圆形曲线。

  • 如果我正在使用的机器人的定位并不是很好,我将确保将目标公差参数设置得比我想象的要高一些。如果机器人具有较高的最小旋转速度以避免在目标点的振荡,那么我也将提高旋转公差。

  • 如果我使用低分辨率的CPU原因,我有时会提高sim_granularity参数,以节省一些周期。

  • 我实际上很少发现自己改变了path_distance_bias和goal_distance_bias(对于base_local_planner这些参数被称为pdist_scale和gdist_scale)参数在计划者上非常多。当我这样做时,通常是因为我试图限制本地规划器自由,让计划的路径与除NavFn以外的全局规划器合作。将path_distance_bias参数增大,将使机器人更紧密地跟随路径,同时以快速向目标向前移动。如果这个值设置得太高,机器人将会拒绝移动,因为移动的代价大于停留在路径上的位置。简单来说就是让实际移动更接近全局路径还是本地路径。

  • 如果我想以聪明的方式介绍代价函数,我将确保将meter_scoring参数设置为true。这使得它在代理函数中的距离以米而不是单元格,也意味着我可以调整一个地图分辨率的代价函数,并且当我移动到他人时期望合理的行为。此外,您现在可以通过将publish_cost_grid参数设置为true来显示本地计划程序在rviz中生成的代价函数。(这不管怎么说,从来没有把它放入文档,我会很快到那个时候)。考虑到以米为单位的代价函数,我可以计算出移动1米的成本与目标平衡的成本的折衷。这倾向于给我一个如何调整东西的体面的想法。

  • 轨迹从其端点得分。这意味着将sim_time参数设置为不同的值可能对机器人的行为有很大的影响。我通常将此参数设置在1-2秒之间,其中设置更高可以导致稍微平滑的轨迹,确保乘以sim_period的最小速度小于目标的两倍。否则,机器人将倾向于在其目标位置的范围之外的位置旋转,而不是朝向目标移动。

  • 精确的轨迹模拟也取决于距离测距的合理速度估计。这来自于dwa_local_planner和base_local_planner都使用这种速度估计以及机器人的加速度限制来确定规划周期的可行速度空间。虽然来自测距的速度估计不一定是完美的,但确保其至少接近得到最佳行为是重要的。

注:非原创,总结

实调总结

比较好的测试建图的方式,是对闭环回环进行建图,观察闭环效果,有可能两侧是不对称的,效果就不太好,多次建图效果不一样,对于规则闭环算法会有一定的校准但是非常有限,效果不好.建图过程中控制适当速度,尽量不要走直线,尤其是在特征变化较少的长廊中,车可能会认为自己没动,导致定位发生偏移,好的时候会自动校准,不好的时候会直接建一张新的图发生重叠.反向建图进行补全,为了避免失败概率,正向先保存一次,反向因为需要补全的特征太少,很容易发生偏移,能够即使校准是好的,失败时便挂了,反向完成闭环时也非常容易发生问题,实验中直接在错误的方向建了重叠的地图,越错越严重.地图中的黑点可以直接用修图工具抹掉,在local中同样可以识别,让地图更加完美.

在建图完成的情况下

首先确定amcl定位是否准确,粒子发散与集中,转动机器人,粒子会聚合,能够观察到定位是否准确(frame可能需要换)原地转会不会飘

调整move_base 参数尽量从默认值开始,观察,根据机器人情况更改一些基础参数,观察效果,继续调整,遇到速度值太小,车不动dwa_local_planner无法直接规划路线,需要等待一会开始recover,或者推一下才能开始规划,尝试调大效果好一些

加速度值大小,如加速度太小转弯慢,弯会很大,距离近或者方向相反就会绕远

效果不理想,有可能时定位跟不上

rosrun rqt_reconfiger rqt_reconfiger 手动调整参数(文件名不对tab)

rosrun rviz rviz -d rospack find rbx1_nav/sim.rviz

local_costmap算法更改效果改善

y轴速度的影响,给y轴速度值,车起速会直接冲出去,给为零之后,车会先往前一小段再转弯,但是会稳定流畅很多,不会很猛,适当调整速度与加速度的值,可以让车的运动稳定流畅.

全局地图与本地地图全部更新效果好于只更新本地地图,会导致膨胀效果不好,车还是会冲进半径不能完全绕开,同时更新两个的同时,调整两个膨胀半径大小,找到车比较合适的避障大小.

第一次调试遇到遇到问题:
思考解决办法:occdist_scale 与goal_distance_bias权重的设置会影响路径,膨胀半径与成本系数的合理设置,影响成本曲线,在尽量使膨胀半径覆盖更新区域的同时,让成本值衰减适中.

全局规划

关于全局规划,默认插件有两个可选项,globle_planner

局部规划

在ROS中经常使用的局部规划器,有base_local_plannerdwa_local_planner,两者之间有什么区别,引用ROS answers中一个回答。如果简单来看,两者属并列关系,其实就是选择使用TrajectoryPlannerROS还是DWAPlannerROS,下边插件的引入应该是再熟悉不过了,注意看前缀,一个是dwa_local_planner/DWAPlannerROS,另一个是base_local_planner/TrajectoryPlannerROS所以是两个完全没有主从关系的,其中base_local_planner也是包含dwa选项的,不过通常还是使用独立的DWA模块。

  <arg name="base_local_planner" default="dwa_local_planner/DWAPlannerROS"/>
  <arg name="base_local_planner" default="base_local_planner/TrajectoryPlannerROS"/>

TrajectoryPlannerROS

关于两个规划器,DWAPlanner相对来说是更加细致,参数更多,也更加敏感,所以也相对更加难调,TrajectoryPlanner我会在什么时候用呢,有项目急着交,DWA又跑不出好的效果,换上立马就能跑,但是很多细节还是不够理想,推荐还是使用DWA,接下来会对DWA的参数介绍,以及一些实际调试过程中总结的经验。

DWAPlannerROS

目前只针对差动结构的移动机器人进行总结,全向轮可类比经验,接下来有点干~

  1. 参数表:
    熟记都有哪些参数可调。
  acc_lim_x: 1.5                #x方向的加速度极限,单位为 meters/sec^2 (double, default: 2.5)
  acc_lim_y: 2.5                #                                  (double, default: 2.5)
  acc_lim_th: 2.4               #角加速度极限,单位为 radians/sec^2 (double, default: 3.2)

#The velocity when robot is moving in a straight line
  max_vel_trans: 0.35           #机器人最大平移速度的绝对值 (double, default: 0.55)
  min_vel_trans: 0.01           #                       (double, default: 0.1)
  max_vel_theta: 0.8            #最大角速度的绝对值,单位为 rad/s (double, default: 1.0)
  min_vel_theta: 0.15           #                             (double, default: 0.4)

#Robot Configuration Parameters
  max_vel_x: 0.35               #机器人在x方向的速度极限,单位为 meters/sec^2 (double, default: 0.55)
  min_vel_x: -0.05               #                                        (double, default: 0.0)

  max_vel_y: 0.1                #                                          (double, default: 0.1)
  min_vel_y: -0.1               #                                          (double, default: -0.1)

#Goal Tolerance Parametes 
  yaw_goal_tolerance: 0.03      #(double, default: 0.05)
  xy_goal_tolerance: 0.07       #(double, default: 0.10)
  latch_xy_goal_tolerance: true #如果锁定目标公差且机器人到达目标xy位置,机器人将简单地旋转到位,即使它在目标公差的范围内结束。
                                 #(bool, default: false)
#Forward Simulation Parameters
  sim_time: 1.7                 #给定轨迹上的点之间的间隔尺寸,单位为 meters (double, default: 1.7)
  sim_granularity: 0.025        # (double, default: 0.025)
  vx_samples: 3                 #样本数 (integer, default: 3)
  vy_samples: 10                 #(integer, default: 10)
  vth_samples: 20               #角速度的样本数 (integer, default: 20)
  controller_frequency: 20.0    #调用该控制器的频率 (double, default: 20.0)

#Trajectory Scoring Parameters
  path_distance_bias: 32.0      #控制器靠近给定路径的权重 (double, default: 32.0)
  goal_distance_bias: 24.0      # 控制器尝试达到其本地目标and控制着速度的权重。(double, default: 24.0)
  occdist_scale: 0.01           #控制器尝试避免障碍物的权重 (double, default: 0.01)
  forward_point_distance: 0.325 #从机器人中心点到另一个得分点的距离 (double, default: 0.325)
  stop_time_buffer: 0.2         #机器人在碰撞前必须停止的时间 (double, default: 0.2)
  scaling_speed: 0.25           #缩放机器人足迹的速度的绝对值,单位为m/s (double, default: 0.25)
  max_scaling_factor: 0.2       #缩放机器人足迹的最大因子 (double, default: 0.2)
  publish_cost_grid: false      # (bool, default: false)

#Oscillation Prevention Parameters
  oscillation_reset_dist: 0.05  #机器人必须运动多少米远后才能复位震荡标记 (double, default: 0.05)

#Debugging
  publish_traj_pc : true        #将规划的轨迹在RVIZ上进行可视化
  publish_cost_grid_pc: true    #将代价值进行可视化显示 (bool, default: false)
  #是否发布规划器在规划路径时的代价网格.如果设置为true,那么就会在~/cost_cloud话题上发布sensor_msgs/PointCloud2类型消息
  1. 估计应用场景中需要的相关速度值
    最大速度
    首先把max_vel_transmax_vel_xmax_vel_theta三个速度最大值减小,角速度通常在1.0左右,平移速度与x方向速度设置相同在0.5左右,根据不同的最大速度,将加速度最大值减小,合适的加速度还和机器人的驱动密切相关,加速能力,控制周期等,不过加速度控制在大概范围就好,初步调试中相对保守的速度值,可以有效避免飞车,碰撞,毕竟机器人还是很贵的。其次平移加速度与旋转加速度的比例也会影响导航避障的表现
    最小速度
    (1)首先min_vel_trans这个参数,它的默认速度是0.1,再通过实际表现会发现,一个较小的最小平移速度是必须的,具体它会影响低速行驶的状态,尤其是到达目标点时,最小速度过大会导致越过目标点,始终无法到达,建议可以尝试在0-0.1之间寻找合适的大小。
    (2) min_vel_x,这个参数巧妙的地方在于,是否要有负值,也就是是否允许倒车,实际使用中过高的倒车速度是极其诡异的,并且通常机器人的激光传感器都不是360度,无法避开后边的障碍物,使用过得机器人唯有turtlebot3是设置了一定的负值的,那是不是设置为0就可以,当然。但是在我的调参过程中发现,机器人在180度左右的转向,且两侧障碍物状况类似时,会出现左右摆动无法选择方向的问题,一度无解,偶然情况下我设置了0.05的后退速度,发现每次转弯会先往后退一点,然后转向也变得很好了,或许这就是玄学吧~
    (3)min_vel_theta,这个参数没有那么多道道,就是找一个相对较小的值就可以了,一般0.1、0.2都可以,默认0.4会导致最小速度过大过大,无法准确到达目标点。
    对于全向轮底盘,还需要考虑y方向的速度、加速、采样等。
  2. 目标误差
    xy方向与角度允许的误差,这个就根据自己机器人大概的精度设置就可以,多试几次就可以
    latch_xy_goal_tolerance:锁定目标,这个参数可以理解为如果机器人确定自己到达那个位置点(具体指,如base_footprint与目标点坐标在误差范围对齐了),但是方向还不对,如果设置为true,这时候就可以原地旋转到达目标角度,及时产生位置上的误差就不再移动。我一般是都设置为true,具体看机器人实际表现吧。
  3. 向前仿真
    这部分是非常重要的一部分
    sim_time:仿真时间,local planner会按频率向前预测,具体计算时间跟机器人上位机性能有关系,不同时间会发现预测的距离也不同了,时间越长预测距离越远,但是对障碍物的躲避变得不灵活,默认1.7,在实验中我设置到了2.0,表现还不错
    三个方向采样数量:对于不同性能的上位机,能够高速计算的点数量有区别,在大多数机器人实验中,x方向默认3表现良好,增大后主要表现为速度变化更加频繁细腻,但是整体速度相对会降低,所以我更倾向相比小一些的x值;同样对于差动轮底盘,有无y方向采样值表现并不明显;旋转采样通常设置默认表现良好
    controller_frequency:控制器频率,关于这个参数,我在不同机器人上使用了不同的参数,较高大概就是10-20,低的时候5,有些机器人使用高频率会导致机器人限制在非常低的移动速度,如果运算性能不够还会导致卡顿现象,具体可能与机器人驱动控制频率等也有关系,目前还未找到具体原因,后续更新记录
  4. 轨迹打分
    这部分只调整三个参数
    cost =  path_distance_bias * (distance to path from the endpoint of the trajectory in meters) 
    + goal_distance_bias * (distance to local goal from the endpoint of the trajectory in meters) 
    + occdist_scale * (maximum obstacle cost along the trajectory in obstacle cost (0-254)
    
    path_distance_bias:控制器尝试到达给定轨迹的权重
    goal_distance_bias: 控制器尝试到达本地目标点的权重,同时控制速度
    occdist_scale:控制器尝试避开障碍物的权重
    多数情况下可以保持默认,观察规划出的路径,若机器人出现移动轨迹与规划轨迹、理想轨迹差别较大,同时出现避障困难等情况,可以适当调整,避障权重过大会导致路径规困难,容易出现卡顿,陷入较窄区域等问题

move_base

recovery_behaviors: true     # 是否允许恢复行为,恢复行为为原地旋转
shutdown_costmaps: false     # 当move_base进入inactive状态时候,决定是否停用节点的costmap (bool, default: false)
controller_frequency: 20.0   # 以Hz为单位的速率运行控制循环并向基座发送速度命令 (double, default: 20.0)
planner_patience: 5.0        # 在空间清理操作执行前,路径规划器等待多长时间(秒)用来找出一个有效规划 (double, default: 5.0)
controller_patience: 20.0    # 在空间清理操作执行前,控制器会等待多长时间(秒)用来找出一个有效控制  (double, default: 15.0)
conservative_reset_dist: 3.0 # 当在地图中清理出空间时候,距离机器人几米远的障碍将会从costmap清除  (double, default: 3.0)
planner_frequency: 5.0       # 全局路径规划器loop速率 (double, default: 0.0)
oscillation_timeout: 10.0    # 执行修复操作之前,允许的震荡时间是几秒  (double, default: 0.0)
oscillation_distance: 0.2    # 机器人需要移动多少距离才算作没有震荡 (double, default: 0.5)

recovery_behaviors:通常根据机器人形状,以及使用的场景是否宽阔来考虑是否允许原地旋转的恢复行为,有时候不规则机器人靠近墙做恢复行为是比较危险的,容易发生碰撞,相比圆形机器人不会有这个问题
controller_frequency:与之前的控制频率是同一个,不在同一层级,这个更高,设置这个即可
planner_frequency:全局路径规划器更新频率,当机器在避障表现较好时,设置一个小频率,可以锦上添花,如果本身local问题很大,再一直更新global路径,会出现离原先最优路径越来越远,直到陷入局部障碍物陷阱
conservative_reset_dist:实验中发现局部地图经常会有移动障碍物遗留,并且不会去除,只有在移动后才能清除,部分只能在恢复行为后清除,所以有一个插件是专门用来做local障碍物清除的
剩余参数用于无法行动之后的恢复行为,震荡表示机器人在很短的距离反复运动,可以设置距离、时间来判断是否为震荡以及多久后执行恢复操作
关于空间清理我还得再研究研究~

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ROS Navigation Tuning Guide(导航调试指南) 的相关文章

  • STM32F4-ADC-常规通道-转换模式配置-总结

    STM32F4 ADC常规通道转换的模式配置 模式选择 此寄存器定义 xff1a 是否自动循环 这两个寄存器定义 xff1a Scan mode xff08 是否轮询序列 xff09 和Discontinuous mode xff08 是否
  • 单片机 裸机 架构

    以前是 while xff08 1 xff09 43 软件定时器 43 中断标志 的框架 xff0c 现在的项目我想尝试一下新的框架 xff0c 简单来说是 主状态机 43 大量子状态机 43 软件定时器 的方式 xff0c 这其中状态机和
  • USART---串口发送数据

    xfeff xfeff while USART1 gt SR amp 0X40 61 61 0 等待发送结束 解析 xff1a USART1 gt SR xff1a 串口 状态 寄存器 USART1 gt SR amp 0X40 即串口状态
  • STM32---串口初始化

    u8 USART RX BUF USART REC LEN 接收缓冲 最大USART REC LEN个字节 bit15 xff0c 接收完成标志 bit14 xff0c 接收到0x0d bit13 0 xff0c 接收到的有效字节数目 u1
  • stm32---RS485初始化

    u8 RS485 RX BUF 64 接收缓冲 最大64个字节 u8 RS485 RX CNT 61 0 接收到的数据长度 函数 xff1a RS485 Init 功能 xff1a 串口初始化配置 参数 xff1a Baud 波特率 备注
  • 定时器0,中断,控制LED闪烁(1s亮,1s灭)---2018-11-07

    include lt reg52 h gt include lt stdio h gt define uchar unsigned char define uint unsigned int sbit LED 61 P2 2 void ti
  • AM2322温湿度传感器(地址0XB8)---I2C总结(I2C_ModBus协议)

  • 数码管---共阳---共阴---段选码---位选码---总结

    共阴极 xff1a 位选为低电平 xff08 即0 xff09 选中数码管 各段选为高电平 xff08 即1接 43 5V时 xff09 选中各数码段 0 f 共阴数码管段选 表 xff0c 无小数点 xff1a unsigned char
  • ubuntu怎样通过终端打开firefox?

    1 直接输入firefox 按回车 2 首先打开火狐浏览器 xff0c 鼠标移到屏幕最顶端 xff0c 出现菜单栏 工具栏 xff0d xff0d 附加组件选项 如下图所示 也可以在火狐浏览器界面 使用快捷键 shift 43 Ctrl 4
  • 重新认识 IP地址

    目录 一 什么是网段划分 二 如何分配子网中的IP xff1f 三 IP地址的分类 1 早期划分方式 1 早期分类方式 2 早期分类的局限性 2 CIDR划分 xff08 子网掩码划分 xff09 1 基本思路 2 实现方式 四 IP地址的
  • Linux服务器下抓包工具tcpdump分析

    概述 说到抓包分析 xff0c 最简单的办法莫过于在客户端直接安装一个Wireshark或者Fiddler了 xff0c 但是有时候由于接口调用无法在客户端抓包 xff0c 只能在服务器上抓包 xff0c 这种情况下怎么办呢 xff1f 本
  • MATLAB 常用转义字符

    MATLAB常用转义字符收录如下 Single quotation mark nbsp Percent character nbsp Backslash nbsp a Alarm nbsp b Backspace nbsp f Form f
  • 利用MATLAB解决人工神经网络模拟预测问题研究

    利用MATLAB解决人工神经网络模拟预测问题研究 nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp 人工神经网络根据模仿人脑的工作原理抽象出来的一种算法 人工神经网络 artigicial neutral ne
  • Visual Studio 2008学习过程(之一)起步

    以前 xff0c 在使用MATLAB开发一些软件 xff0c 虽然它的数值计算方面的功能很强大 xff0c 但是界面不是很好看 xff0c 很难做出来漂亮的软件 xff0c 所以萌生了用VS和MATLAB联合编程的想法 这样可以使软件更加强
  • 如何用servlet写网页访问量计数器?

    如何用servlet写网页访问量计数器 xff1f 1 原料 l MyEclipse l Tomcat l html 2 步骤 1 新建工程 项目栏鼠标右键 New Web Project xff0c 这里我起名为 xff1a myexm4
  • 提示:请安装TCP/IP协议.error=10106。解决方案

    有朋友使用电脑的时候会出现如下错误 xff0c 如何解决该问题是本文写作的目的 提示错误 xff1a 图 1 解决 方案 xff1a 1 删除两个注册表选项 xff1b 按下windows键 43 R键 xff0c 输入regedit xf
  • 防止头文件被重复包含

    前言 为了避免同一个文件被include多次 xff0c C C 43 43 中有两种方式 xff0c 一种是 ifndef方式 xff0c 一种是 pragma once方式 方式一 xff1a ifndef SOMEFILE H 或写为
  • 有趣的网站分享——pornhub风格生成器

    寄语 要说logo设计 xff0c pornhub的logo设计让人印象深刻 xff0c 黑底白字 xff0c 配上一小撮橙色 xff0c 给人极强的冲击力 这不 xff0c 有一个有意思的程序员弄了一个网站 xff0c 专门生成pornh
  • 大小端存储问题

    1 什么是数据的高低位 数据的高位在左 xff0c 低位在右 2 什么是内存的高低位 2 什么是大端存储 小端存储 简单记就是 xff1a 小端 xff1a 低低 xff08 数据低位在内存低位 xff09 大端 xff1a 高低 xff0
  • 【A星算法的优化方案】

    当地图很大的时候 xff0c 或者使用A星算法的寻路频率很高的时候 xff0c 普通的A星算法就会消耗大量的CPU性能急剧下降 xff0c 普通的A星性能还是不过关 接下来我们讲讲A星寻路在遇到性能瓶颈时的优化方案 一 长距离导航 当距离很

随机推荐

  • Java工具类:String与DateTime类型的相互转换

    1 String 转 DateTime 在转换之前需要引入 hutool 依赖 String datestr 61 34 2022 5 19 34 DateTime datetime 61 DateUtil parse datestr 2
  • Iterator迭代器的一般用法

    Iterator迭代器的一般用法 迭代器 xff08 Iterator xff09 迭代器是一种设计模式 xff0c 它是一个对象 xff0c 它可以遍历并选择序列中的对象 xff0c 而开发人员不需要了解该序列的底层结构 迭代器通常被称为
  • socket编程---fgets和fputs函数使用理解

    这一节是继续上一节socket05的讨论 xff0c 来探讨在使用socket进行通信中遇到的一些函数使用理解误区 1 fgets的使用注意点 在写socket通信 xff08 代码见上一篇中 xff0c 只是将sendbuf和recvbu
  • Tarjan算法详细讲解

    Tarjan算法讲解的博客网上找到三篇比较好的 现在都转载了 个人只研究了第一篇 正如博主所说 讲的标比较详细 清晰 剩下两篇也可以看一下 卿学姐视频讲解 https www bilibili com video av7330663 以下内
  • 中文乱码在线恢复网站

    乱码恢复
  • GCC自带的一些builtin内建函数

    title GCC自带的一些builtin内建函数 date 2021 02 27 18 57 00 description 一些GCC自带的内建 bulitin 函数的接口及实现 一 GCC内建函数 最近在刷 leetcode 的时候遇到
  • Shell脚本实用小技巧-教你屏蔽执行命令的所有显示信息,包含错误信息

    前言 xff1a 在Linux中 xff0c 有个 dev null的东西 xff0c 人们一般称之为黑洞 xff0c 大概的意思就是东西就像黑洞一样 xff0c 任何东西丢进去都会消失 xff0c 那么下面就开始进行一些小案例去认识一下这
  • MPU6050应用详解

    MPU6050应用详解 最近项目上要用到 MPU6050 陀螺仪 xff0c 以前没有接触过它 虽然在网上很容易就可以找到了需要的代码 实现了一部分功能 但是却还是对陀螺仪的工作原理不太了解 xff0c 它的代码也需要分析一下 xff0c
  • protobuf详解

    1 protobuf 简介 protobuf protocol buffer 是谷歌内部的混合语言数据标准 通过将结构化的数据进行序列化 串行化 xff0c 用于通讯协议 数据存储等领域和语言无关 平台无关 可扩展的序列化结构数据格式 我们
  • 白泽知识讲堂 | printf漏洞介绍

    引子 Hello各位小伙伴们 xff0c 白泽又和大家见面了 大家还记得自己写的第一个C语言程序吗 xff1f 那是我们和代码爱情的起点 xff0c 一眼万年 没错 xff0c 就是那个耳熟能详的Hello World 1 include
  • Linux生成core文件相关配置,core文件调试示例

    1 生成core文件系统配置 使用ulimit c命令可以查看当前系统对于core文件的配置 xff0c 0表示不生成core文件 xff1b 不为0的数字a表示限制core文件大小不超过a xff0c 单位是k xff1b unlimit
  • Ubuntu 手动配置DNS

    使用ping命令测试百度域名时发现 xff0c 无法解析这个域名 xff0c 说明当前系统上没有配置DNS服务器 配置DNS服务器的方式主要有以下两种 xff1a 目录 1 修改DNS配置文件 etc resolv conf 2 修改网卡配
  • STM32启动文件详解

    启动文件使用的 ARM 汇编指令汇总 启动程序源码注释 点此下载 1 Stack 栈 Stack Size EQU 0x00000400 AREA STACK NOINIT READWRITE ALIGN 61 3 Stack Mem SP
  • Motorola_MSB_LSB

    声明 xff1a 如果涉及侵权 xff0c 请联系本人删除侵权内容 声明 xff1a 本文由本人以以往工作经验为依据 xff0c 总结而得 xff0c 如果错误 xff0c 欢迎指正 xff0c 便于后人参考 xff0c 少走弯路 如果图片
  • 虚拟机怎么安装vmware tools

    这篇文章主要为大家详细介绍了VMware Workstation12安装Ubuntu和VMware Tools教程 具有一定的参考价值 xff0c 感兴趣的小伙伴们可以参考一下 之前我通过百度经验上的过程来安装Ubuntu16 xff0c
  • MySQL数据库改名的三种方法

    MySQL数据库改名的三种方法 前不久去面试 xff0c 被问到Innodb引擎的表如何改数据库名 xff0c 当时我也只回答了MyISAM改如何操作 xff0c 被一些细节问题打败 xff0c 真是操蛋 如果表示MyISAM那么可以直接去
  • C语言详解 FILE文件操作

    1 需要了解的概念 需要理解的知识点包括 xff1a 数据流 缓冲区 文件类型 文件存取方式 1 1 数据流 xff1a 指程序与数据的交互是以流的形式进行的 进行C语言文件的存取时 xff0c 都会先进行 打开文件 操作 xff0c 这个
  • wifi提速技巧:十大方法瞬间提升wifi速度

    手机wifi速度慢真是很让人苦恼 xff0c 有什么有效的wifi提速方法吗 当然有啦 绿茶小编今天就为大家带来了提升wifi速度的十大方法 xff0c 能激活wifi表现 xff0c 提升无线网络哦 xff0c 快来看看吧 十大方法瞬间提
  • 如何消除步进电机的噪音与振动TMC

    步进电机的噪音来自哪里 由于步进电机由于结构简单 控制方便 安全性高 成本低 停止时候力矩大 在低速情况下不需要减速机就可以输出很大的力矩 相比直流无刷和伺服电机 步进电机不需要复杂的控制算法也不需要编码器反馈情况下可以实现位置控制 被用在
  • ROS Navigation Tuning Guide(导航调试指南)

    ROS Navigation Tuning Guide 导航调试指南准备工作距离传感器里程计定位 速度与加速度的设置获得最大速度获得最大加速度设置最小值 xff38 xff39 方向的速度 Global Planner接口参数 Local