ego-planner开源代码之启动参数介绍&分析

70 篇文章 15 订阅

1. 源由

ego-planner开源代码之数据流分析工作的延续。

  • 对于算法逻辑的数据流,在前面已经初步做了整理,部分主要模块已经有比较清晰的认识。
  • 从数据流的角度,理解模块的工作逻辑,还是非常直观、简洁的。

如何从系统的角度,思考问题,尤其是一个系统由众多模块组成的复杂体系,要能够整体的理解,反而并不能一下子上手。

反之,若能够将整个系统作为一个模块来理解,入参和出参分别如何对应和理解呢?

2. 逻辑分析

想必经历过Linux 35.5 + JetPack v5.1.3@ego-planner编译安装,并在此基础上运行过仿真模拟,甚至看过uav_simulation代码,那么可以体会下整体上,要在模块基础上,结合各模块的数据流了解整个系统,还是会有很多盲点。

为此,我们另辟蹊径,从仿真模拟的入参配置来看看,这个游戏是如何来玩的!

  • 从应用的角度,复杂场景,往往涉及诸多变量;
  • 从技术的角度,应用场景多,就是条件输入多,同时判断的变量条件就比较多;
  • 从算法的角度,没有算法是万万不能的,但是算法也并非是万能的。只有在满足预设前提,算法才能正确执行;

经常会有人反馈:“研发人员用用都是挺好的,到了客户那里一堆问题。”

从产品的角度:预研算法通常仅仅实现了“阳光”场景的逻辑。换句话说:当入参在某些合理输入情况下,输出是期望结果;当存在异常条件时,由于程序逻辑的不完善、会导致结果混乱甚至宕机发生。

因此,发现问题、研究问题、排除问题、改进方法、解决问题是一种螺旋式的过程,而这个过程通常在工程技术上采用PDCA的方式进行不断完善和优化。

复杂问题简单化的逻辑,就是在合理范围内使用,逻辑上就能复现工程技术带来的结果。或者说算法逻辑能100%复现,当无法复现就需要排除或者找到对应关系,提前规避,确保最终用户的用户体验。

3. 启动参数

废话不多说,直接上正菜!

section 1

  <!-- size of map, change the size inflate x, y, z according to your application -->
  <arg name="map_size_x" value="40.0"/>
  <arg name="map_size_y" value="40.0"/>
  <arg name="map_size_z" value=" 3.0"/>

参数 map_size_xmap_size_ymap_size_z 定义了所使用的三维地图的尺寸。每个参数的含义如下:

  1. map_size_x:定义地图在 X轴 方向上的长度(单位:米)。这里的值设置为 40.0,表示地图在 X轴方向延伸40米。

  2. map_size_y:定义地图在 Y轴 方向上的宽度(单位:米)。这里的值设置为 40.0,表示地图在 Y轴方向延伸40米。

  3. map_size_z:定义地图在 Z轴 方向上的高度(单位:米)。值为 3.0,表示地图在 Z轴方向延伸3米,提供了垂直方向上的规划空间。

注:map_size:当地图大小较大时需要修改,注意目标点不要超过map_size/2,相当于默认当前位置为中心点位置。高级参数里面还有参数可以设置便宜。

section 2

  <!-- topic of your odometry such as VIO or LIO -->
  <arg name="odom_topic" value="/visual_slam/odom" />

该参数用于告诉 ego-planner 该从哪个话题订阅里程计数据,以便获取机器人或无人机的位姿信息。

  1. 注释:
    <!-- topic of your odometry such as VIO or LIO -->
    这句话表示这个参数用于指定机器人里程计的ROS话题,可以是 视觉惯性里程计 (VIO, Visual-Inertial Odometry) 或 激光惯性里程计 (LIO, LiDAR-Inertial Odometry) 等。

  2. 参数定义:
    <arg name="odom_topic" value="/visual_slam/odom" />
    这行代码定义了一个名为 odom_topic 的参数,其值为 /visual_slam/odom,表示里程计信息发布的ROS话题名称是 /visual_slam/odom。ego-planner 会从这个话题中订阅机器人当前的位姿(位置和姿态)信息,用于进行路径规划。

section 3

  <!-- main algorithm params -->
  <include file="$(find ego_planner)/launch/advanced_param.xml">

通过这行代码,advanced_param.xml 文件中的参数会被加载到当前的启动文件中,这样 ego-planner 在运行时就会使用这些预先定义的主算法参数。

同时,通过 和之间再次修改参数,覆盖默认advanced_param.xml 文件中的参数。

  1. 注释:
    <!-- main algorithm params -->
    这句话表示接下来引入的是主算法相关的参数配置文件。即,该部分包含用于控制 ego-planner 主算法的参数。

  2. 参数文件引入:
    <include file="$(find ego_planner)/launch/advanced_param.xml">
    这行代码表示将位于 ego_planner 包的 launch 目录中的 advanced_param.xml 文件包含到当前的 launch 文件中。

    • $(find ego_planner):这是 ROS 中的语法,用来找到 ego_planner 包的路径。
    • /launch/advanced_param.xml:表示具体的参数文件路径。

section 3.1

    <arg name="map_size_x_" value="$(arg map_size_x)"/>
    <arg name="map_size_y_" value="$(arg map_size_y)"/>
    <arg name="map_size_z_" value="$(arg map_size_z)"/>
    <arg name="odometry_topic" value="$(arg odom_topic)"/>

复用和传递参数,将原本的 map_size_xmap_size_ymap_size_zodom_topic 重新命名为 map_size_x_map_size_y_map_size_z_odometry_topic,这样便可以在后续代码中使用这些新的名称来引用原始参数的值。这种做法有利于代码的清晰和模块化,使参数的传递更加灵活。

  1. map_size_x_:

    • 通过 value="$(arg map_size_x)",将之前定义的 map_size_x 参数值(例如 40.0)赋值给新的参数 map_size_x_
  2. map_size_y_:

    • 同样,将 map_size_y 的值传递给新的参数 map_size_y_
  3. map_size_z_:

    • map_size_z 的值传递给新的参数 map_size_z_
  4. odometry_topic:

    • 将之前定义的 odom_topic 参数值(如 /visual_slam/odom)传递给 odometry_topic

section 3.2

    <!-- camera pose: transform of camera frame in the world frame -->
    <!-- depth topic: depth image, 640x480 by default -->
    <!-- don't set cloud_topic if you already set these ones! -->
    <arg name="camera_pose_topic" value="/pcl_render_node/camera_pose"/>
    <arg name="depth_topic" value="/pcl_render_node/depth"/>

定义了有关相机位姿和深度图的ROS话题参数,主要用于处理相机的姿态数据和深度图像数据。

  1. 注释:

    • <!-- camera pose: transform of camera frame in the world frame -->: 这句话表示相机位姿话题提供的是相机坐标系在世界坐标系中的变换,即相机在世界中的位置和姿态信息。
    • <!-- depth topic: depth image, 640x480 by default -->: 这句话表示深度话题提供的是深度图像,默认分辨率是 640x480。
    • <!-- don't set cloud_topic if you already set these ones! -->: 这句话表示如果已经设置了相机位姿和深度图像话题,就不要再设置点云话题(cloud_topic),因为这两个信息已经足够生成点云。
  2. 参数定义:

    • <arg name="camera_pose_topic" value="/pcl_render_node/camera_pose"/>: 这个参数 camera_pose_topic 定义了相机位姿信息的话题,话题名称为 /pcl_render_node/camera_pose。在ROS系统中,ego-planner 或其他节点将从该话题订阅相机的位姿(即相机在世界坐标系中的位置和姿态)信息。

    • <arg name="depth_topic" value="/pcl_render_node/depth"/>: 这个参数 depth_topic 定义了深度图像的话题,话题名称为 /pcl_render_node/depth。系统将从这个话题订阅深度图像数据,深度图像通常用于生成三维点云或者帮助路径规划时感知障碍物。

section 3.3

    <!-- topic of point cloud measurement, such as from LIDAR  -->
    <!-- don't set camera pose and depth, if you already set this one! -->
    <arg name="cloud_topic" value="/pcl_render_node/cloud"/>

定义了一个点云测量话题的参数,主要用于从激光雷达(LiDAR)或其他传感器中获取点云数据。

  1. 注释:

    • <!-- topic of point cloud measurement, such as from LIDAR -->: 这句话表示 cloud_topic 是用于获取点云测量数据的ROS话题,数据来源可以是 LiDAR(激光雷达)或者其他提供点云的传感器。
    • <!-- don't set camera pose and depth, if you already set this one! -->: 这句话提醒用户,如果已经设置了 cloud_topic(点云话题),不要再设置相机位姿和深度图像,因为点云数据已经包含了三维空间信息,不需要额外使用相机的位姿和深度数据。
  2. 参数定义:

    • <arg name="cloud_topic" value="/pcl_render_node/cloud"/>: 这个参数 cloud_topic 定义了点云数据的话题名称为 /pcl_render_node/cloud。系统或其他节点会从该话题订阅到点云数据,这些数据通常包含传感器扫描到的环境三维点的信息(即障碍物的位置、形状等)。

section 3.4

    <!-- intrinsic params of the depth camera -->
    <arg name="cx" value="321.04638671875"/>
    <arg name="cy" value="243.44969177246094"/>
    <arg name="fx" value="387.229248046875"/>
    <arg name="fy" value="387.229248046875"/>

定义了深度相机的内参(intrinsic parameters),这些参数是相机的固有属性,用于描述相机的光学特性和几何关系,主要包括焦距和主点(光轴中心)的坐标。

  1. 注释:

    • <!-- intrinsic params of the depth camera -->: 这句话表示接下来定义的参数是深度相机的内参,用于描述相机的内部光学和几何特性。
  2. 参数定义:

    • <arg name="cx" value="321.04638671875"/>: 这是相机主点(principal point)在图像平面上的 X坐标。主点是相机成像平面的中心点(即光轴与成像平面交点)。在这段代码中,主点的 X 坐标为 321.04638671875
    • <arg name="cy" value="243.44969177246094"/>: 这是相机主点在图像平面上的 Y坐标,主点的 Y 坐标为 243.44969177246094
    • <arg name="fx" value="387.229248046875"/>: 这是相机在 X方向 的焦距,单位为像素。焦距表示镜头的光学中心到成像平面的距离,在这里 X 方向的焦距为 387.229248046875 像素。
    • <arg name="fy" value="387.229248046875"/>: 这是相机在 Y方向 的焦距,单位也是像素。在这里 Y 方向的焦距与 X 方向一致,都是 387.229248046875 像素。

section 3.5

    <!-- maximum velocity and acceleration the drone will reach -->
    <arg name="max_vel" value="2.0" />
    <arg name="max_acc" value="3.0" />

定义了无人机在运行过程中能够达到的最大速度最大加速度,用于限制无人机的运动性能。

  1. 注释:

    • <!-- maximum velocity and acceleration the drone will reach -->: 这句话表示接下来定义的参数是无人机的最大速度最大加速度,它们用来限制无人机在飞行时的运动性能。
  2. 参数定义:

    • <arg name="max_vel" value="2.0" />: 这个参数 max_vel 定义了无人机的最大速度,单位是米/秒 (m/s)。这里设置的值为 2.0,表示无人机的飞行速度最大可以达到 2 米/秒。
    • <arg name="max_acc" value="3.0" />: 这个参数 max_acc 定义了无人机的最大加速度,单位是米/秒² (m/s²)。这里设置的值为 3.0,表示无人机的加速度最大可以达到 3 米/秒²。

注:由于飞行环境,以及误差,通过设置速度和加速度最大值可以减少误差,增加稳定性。

  • 最大速度 (max_vel):用于限制无人机的飞行速度,确保在规划路径或执行任务时不会超过指定的速度,保证飞行的稳定性和安全性。
  • 最大加速度 (max_acc):用于限制无人机在加速和减速时的变化率,防止无人机出现过快的加速度变化,影响飞行平稳性。

section 3.6

    <!--always set to 1.5 times grater than sensing horizen-->
    <arg name="planning_horizon" value="7.5" /> 

定义了无人机路径规划中的**规划视野(planning horizon)**参数,其值通常设置为感知视野(sensing horizon)的1.5倍。planning_horizon 决定了路径规划算法在做出决策时能够看到的范围。规划视野越大,算法能够考虑的路径和障碍物就越多,从而可能提高路径规划的准确性和有效性。通常,这个值需要大于感知视野,以确保规划算法可以在足够的范围内进行有效的决策。

  1. 注释:

    • <!-- always set to 1.5 times greater than sensing horizon -->: 这句话表示 planning_horizon 参数的值应该设置为感知视野(sensing horizon)的1.5倍。感知视野是指无人机能够探测到的最大距离。
  2. 参数定义:

    • <arg name="planning_horizon" value="7.5" />: 这个参数 planning_horizon 定义了路径规划的视野范围,单位是米(m)。在这个配置中,值设置为 7.5,表示路径规划系统考虑的范围是 7.5 米。

section 3.7

    <!-- 1: use 2D Nav Goal to select goal  -->
    <!-- 2: use global waypoints below  -->
    <arg name="flight_type" value="2" />

定义了无人机的飞行模式(flight_type),指定了无人机如何选择飞行目标。

  1. 注释:

    • <!-- 1: use 2D Nav Goal to select goal -->: 这句话表示如果 flight_type 设置为 1,无人机将使用 2D 导航目标(2D Nav Goal)来选择飞行目标。2D 导航目标通常是用户在地图上指定的目标位置。
    • <!-- 2: use global waypoints below -->: 这句话表示如果 flight_type 设置为 2,无人机将使用全局航点(global waypoints)来进行飞行。全局航点是一系列预定义的点,通常用于无人机按照预设的路径进行飞行。
    • 如果设置为 1,无人机将根据用户在地图上选择的2D目标位置来进行导航。
    • 如果设置为 2,无人机将按照预定义的全局航点执行飞行任务。
  2. 参数定义:

    • <arg name="flight_type" value="2" />: 这个参数 flight_type 定义了无人机的飞行模式,其值设置为 2。根据注释中的说明,值为 2 表示无人机将使用全局航点来进行飞行。

section 3.8

    <!-- global waypoints -->
    <!-- It generates a piecewise min-snap traj passing all waypoints -->
    <arg name="point_num" value="5" />

    <arg name="point0_x" value="-15.0" />
    <arg name="point0_y" value="0.0" />
    <arg name="point0_z" value="1.0" />

    <arg name="point1_x" value="0.0" />
    <arg name="point1_y" value="15.0" />
    <arg name="point1_z" value="1.0" />

    <arg name="point2_x" value="15.0" />
    <arg name="point2_y" value="0.0" />
    <arg name="point2_z" value="1.0" />

    <arg name="point3_x" value="0.0" />
    <arg name="point3_y" value="-15.0" />
    <arg name="point3_z" value="1.0" />

    <arg name="point4_x" value="-15.0" />
    <arg name="point4_y" value="0.0" />
    <arg name="point4_z" value="1.0" />

定义了无人机飞行任务中的全局航点,使用这些航点生成的最小跃变轨迹将使无人机在这些点之间飞行时,轨迹尽可能平滑,减少急剧的加速度变化,生成一条经过所有航点的平滑路径。

  1. 注释:

    • <!-- global waypoints -->: 这句话表示以下参数定义了全局航点。
    • <!-- It generates a piecewise min-snap traj passing all waypoints -->: 这句话表示使用这些全局航点生成一条最小跃变轨迹(min-snap trajectory),即生成一条平滑的、尽可能减少加速度变化的路径,经过所有指定的航点。
  2. 参数定义:

    • <arg name="point_num" value="5" />: 这个参数 point_num 定义了全局航点的数量,这里设置为 5,表示有 5 个航点。

    • 接下来的参数定义了每个航点的坐标:

      • <arg name="point0_x" value="-15.0" />

      • <arg name="point0_y" value="0.0" />

      • <arg name="point0_z" value="1.0" />

        • 这三个参数定义了第一个航点的 X、Y 和 Z 坐标,分别为 -15.00.01.0
      • <arg name="point1_x" value="0.0" />

      • <arg name="point1_y" value="15.0" />

      • <arg name="point1_z" value="1.0" />

        • 这三个参数定义了第二个航点的坐标,分别为 0.015.01.0
      • <arg name="point2_x" value="15.0" />

      • <arg name="point2_y" value="0.0" />

      • <arg name="point2_z" value="1.0" />

        • 这三个参数定义了第三个航点的坐标,分别为 15.00.01.0
      • <arg name="point3_x" value="0.0" />

      • <arg name="point3_y" value="-15.0" />

      • <arg name="point3_z" value="1.0" />

        • 这三个参数定义了第四个航点的坐标,分别为 0.0-15.01.0
      • <arg name="point4_x" value="-15.0" />

      • <arg name="point4_y" value="0.0" />

      • <arg name="point4_z" value="1.0" />

        • 这三个参数定义了第五个航点的坐标,分别为 -15.00.01.0

section 4

  <!-- trajectory server -->
  <node pkg="ego_planner" name="traj_server" type="traj_server" output="screen">
    <remap from="/position_cmd" to="planning/pos_cmd"/>

    <remap from="/odom_world" to="$(arg odom_topic)"/>
    <param name="traj_server/time_forward" value="1.0" type="double"/>
  </node>

定义了一个名为 traj_server 的 ROS 节点的启动参数。

  1. 注释:

    • <!-- trajectory server -->: 这句话表示接下来配置的是**轨迹服务器(trajectory server)**节点的启动参数。
  2. 节点定义:

    • <node pkg="ego_planner" name="traj_server" type="traj_server" output="screen">:
      • pkg="ego_planner":指定了节点所在的 ROS 包,这里是 ego_planner
      • name="traj_server":节点的名称为 traj_server
      • type="traj_server":节点的类型为 traj_server,即节点的可执行文件名。
      • output="screen":表示将节点的输出信息打印到控制台屏幕上,以便进行调试和监控。
  3. 话题重映射:

    • <remap from="/position_cmd" to="planning/pos_cmd"/>:
      • 这条命令将话题 /position_cmd 重映射到 planning/pos_cmd。即,节点 traj_server 将订阅 planning/pos_cmd,而不是原来的 /position_cmd 话题。
    • <remap from="/odom_world" to="$(arg odom_topic)"/>:
      • 这条命令将话题 /odom_world 重映射到由 odom_topic 参数指定的话题。$(arg odom_topic) 是一个参数引用,意味着 /odom_world 实际上会订阅由 odom_topic 参数定义的话题,如之前配置中的 /visual_slam/odom
  4. 参数设置:

    • <param name="traj_server/time_forward" value="1.0" type="double"/>:
      • 这行设置了名为 traj_server/time_forward 的参数,其值为 1.0,类型为 double。这个参数可能用于控制轨迹服务器的时间前瞻量(即在规划轨迹时考虑的时间范围)。

section 5

  <node pkg="waypoint_generator" name="waypoint_generator" type="waypoint_generator" output="screen">
    <remap from="~odom" to="$(arg odom_topic)"/>        
    <remap from="~goal" to="/move_base_simple/goal"/>
    <remap from="~traj_start_trigger" to="/traj_start_trigger" />
    <param name="waypoint_type" value="manual-lonely-waypoint"/>    
  </node>

定义了一个名为 waypoint_generator 的 ROS 节点的启动参数,确保了 waypoint_generator 节点能够正确地订阅需要的话题,并按照指定的参数进行航点生成。

  1. 节点定义:

    • <node pkg="waypoint_generator" name="waypoint_generator" type="waypoint_generator" output="screen">:
      • pkg="waypoint_generator":指定了节点所在的 ROS 包,这里是 waypoint_generator
      • name="waypoint_generator":节点的名称为 waypoint_generator
      • type="waypoint_generator":节点的可执行文件名为 waypoint_generator
      • output="screen":表示将节点的输出信息打印到控制台屏幕上,以便进行调试和监控。
  2. 话题重映射:

    • <remap from="~odom" to="$(arg odom_topic)"/>:
      • 这条命令将节点中的 ~odom 话题重映射到由 odom_topic 参数指定的话题。$(arg odom_topic) 是一个参数引用,意味着节点将订阅由 odom_topic 参数定义的话题,比如 /visual_slam/odom
    • <remap from="~goal" to="/move_base_simple/goal"/>:
      • 这条命令将节点中的 ~goal 话题重映射到 /move_base_simple/goal。即,节点将从 /move_base_simple/goal 话题接收目标点数据。
    • <remap from="~traj_start_trigger" to="/traj_start_trigger" />:
      • 这条命令将节点中的 ~traj_start_trigger 话题重映射到 /traj_start_trigger。即,节点将从 /traj_start_trigger 话题接收触发信号。
  3. 参数设置:

    • <param name="waypoint_type" value="manual-lonely-waypoint"/>:
      • 这行设置了名为 waypoint_type 的参数,其值为 manual-lonely-waypoint。这个参数可能用于定义航点生成器的工作模式或类型,这里表示采用手动的孤立航点方式。

section 6

  <!-- use simulator -->
  <include file="$(find ego_planner)/launch/simulator.xml">
    <arg name="map_size_x_" value="$(arg map_size_x)"/>
    <arg name="map_size_y_" value="$(arg map_size_y)"/>
    <arg name="map_size_z_" value="$(arg map_size_z)"/>
    <arg name="c_num" value="200"/>
    <arg name="p_num" value="200"/>
    <arg name="min_dist" value="1.2"/>

    <arg name="odometry_topic" value="$(arg odom_topic)" />
  </include>

包含一个名为 simulator.xml 的 ROS 启动文件,并传递一些参数用于覆盖默认xml文件中的参数,使模拟器能够按照指定的设置进行模拟。

  1. 注释:

    • <!-- use simulator -->: 这句话表示接下来配置的内容是用于启动模拟器
  2. 包含文件:

    • <include file="$(find ego_planner)/launch/simulator.xml">:
      • file="$(find ego_planner)/launch/simulator.xml":指定要包含的启动文件路径。$(find ego_planner) 是 ROS 的一个命令,用于找到 ego_planner 包的位置,然后从该位置加载 launch/simulator.xml 文件。
  3. 参数传递:

    • <arg name="map_size_x_" value="$(arg map_size_x)"/>:
      • 这个参数将 map_size_x_ 传递给 simulator.xml 文件,其值为 $(arg map_size_x)。即,map_size_x_ 的值来自于当前启动文件中的 map_size_x 参数。
    • <arg name="map_size_y_" value="$(arg map_size_y)"/>:
      • 这个参数将 map_size_y_ 传递给 simulator.xml 文件,其值为 $(arg map_size_y)。即,map_size_y_ 的值来自于当前启动文件中的 map_size_y 参数。
    • <arg name="map_size_z_" value="$(arg map_size_z)"/>:
      • 这个参数将 map_size_z_ 传递给 simulator.xml 文件,其值为 $(arg map_size_z)。即,map_size_z_ 的值来自于当前启动文件中的 map_size_z 参数.
    • <arg name="c_num" value="200"/>:
      • 这个参数设置 c_num 的值为 200,可能表示模拟器中使用的某种元素的数量,如障碍物或对象的数量。
    • <arg name="p_num" value="200"/>:
      • 这个参数设置 p_num 的值为 200,可能表示模拟器中使用的另一种元素的数量,如路径点或目标点的数量。
    • <arg name="min_dist" value="1.2"/>:
      • 这个参数设置 min_dist 的值为 1.2,可能表示模拟器中某种元素之间的最小距离或间隔。
    • <arg name="odometry_topic" value="$(arg odom_topic)" />:
      • 这个参数将 odometry_topic 传递给 simulator.xml 文件,其值为 $(arg odom_topic)。即,odometry_topic 的值来自于当前启动文件中的 odom_topic 参数。

section 7

  <include file="$(find ego_planner)/launch/rviz.launch"/>

包含一个名为 rviz.launch 的 ROS 启动文件。

4. 总结

通过这个 simple_run.launch 启动文件,可以了解到除了该文件中的配置参数以外:

  • 引用了一些基础配置文件
  • 引入了一些ROS节点
simple_run.launch
 ├──> traj_server   //[ego-planner开源代码之traj_server数据流分析](https://blog.csdn.net/lida2003/article/details/142312414)
 ├──> waypoint_generator
 ├──> advanced_param.xml
 │   └──> ego_planner_node  //[ego-planner开源代码之ego_planner_node数据流分析](ego-planner开源代码之ego_planner_node数据流分析)
 ├──> simulator.xml
 │   ├──> random_forest
 │   ├──> mockamap_node
 │   ├──> quadrotor_simulator_so3
 │   ├──> nodelet
 │   ├──> odom_visualization
 │   └──> pcl_render_node
 └──> rviz.launch
     └──> rviz

上面标注了前面分析过的node代码,正因为有这么多的代码数据流(模块)没有进行分析,所以才导致我们在分析模拟的时候感觉总是缺了什么,理不清楚来龙去脉。

后续我们将随着时间的推移,逐步的分析上面node的数据流。

5. 附录

5.1 PDCA 戴明循环

PDCA(Plan-Do-Check-Act)循环,也被称为戴明循环,是一种持续改进质量管理的工具,用于优化流程和解决问题。它帮助企业和个人通过反复评估和改进来达到更好的成果。以下是PDCA四个阶段的介绍:

  1. Plan(计划)

    • 在这个阶段,确定需要改进的问题或目标,分析现状,设定目标,并制定一个行动计划来解决问题或实现目标。计划中应包括具体的行动步骤、时间表和所需资源。
  2. Do(执行)

    • 根据计划实施行动,按照步骤执行任务。这一阶段强调小范围实验性地执行,以减少潜在的风险。如果可能,先在较小范围内试点,验证计划的可行性。
  3. Check(检查)

    • 执行完毕后,对结果进行检查和评估。通过数据和事实来衡量计划是否有效,是否达到预期目标。分析执行过程中的问题和偏差,并记录下来。
  4. Act(行动)

    • 如果计划有效,则将其标准化,并在更大范围内实施。如果计划不完全有效,找出问题的根源,并修改计划,重新开始PDCA循环。这个阶段的关键是总结经验教训,持续改进。

PDCA 循环的核心是通过反复迭代,持续提升流程效率和质量。这一工具广泛应用于生产管理、质量控制、项目管理等领域。

5.2 相机内参

相机内参(也称为相机内部参数或内参矩阵)描述了相机成像过程中的固有特性,用于将3D世界坐标转换为2D图像坐标。相机内参反映了相机的光学和几何属性,用于将深度相机捕捉到的二维图像数据转化为三维空间坐标。这些参数通常在将图像坐标转换为三维坐标时使用,是路径规划或3D重建等应用的关键参数。

  1. 焦距 (focal length, f):描述相机镜头的光学放大倍数。通常在图像坐标系中,它以像素单位表示,并分为两个分量。定义了相机成像时的缩放关系,影响图像中物体的投影比例,用于将像素坐标转换为物理空间中的距离。

    • f x f_x fx:水平方向的焦距。
    • f y f_y fy:垂直方向的焦距。
  2. 主点 (principal point):图像中光轴与成像平面的交点,也就是图像的中心点。由于制造误差,主点通常不在图像的正中心。表示成像平面上光轴的中心位置,用于确定相机的视场中心。

    • c x c_x cx:主点的水平坐标。
    • c y c_y cy:主点的垂直坐标。
  3. 畸变系数 (distortion coefficients):由于镜头的光学特性,图像可能会出现径向和切向畸变。内参还包括这些畸变的校正参数,常见的畸变包括:

    • 径向畸变:使图像中直线向外或向内弯曲。
    • 切向畸变:由于镜头与成像平面不完全平行,导致图像的畸变。

这些参数通常以矩阵形式表示为3x3的内参矩阵(相机矩阵):

K = ( f x 0 c x 0 f y c y 0 0 1 ) K = \begin{pmatrix} f_x & 0 & c_x \\ 0 & f_y & c_y \\ 0 & 0 & 1 \end{pmatrix} K= fx000fy0cxcy1

通过相机内参矩阵,3D世界坐标可以转换为2D图像平面上的像素坐标,这对计算机视觉中的各种任务(如立体视觉、SLAM等)至关重要。

注:实际标定可以通过拍摄棋盘格图像,并用校准软件进行计算获取相关参数。用于立体视觉和SLAM应用的传感器设计厂家也会在传感设备出厂时进行校准和记录(可通过特殊命令获取生产校准参数)。

5.3 Field of View 感知视野

感知视野(Field of View,简称 FOV)是指传感器(例如相机、激光雷达等)在某一时刻能够覆盖和检测到的空间范围。它描述了传感器可以“看到”或“感知”到的环境区域,通常以角度或弧度来表示。感知视野在计算机视觉、机器人、无人驾驶等领域中非常重要,特别是对于传感器数据的处理和环境感知。

感知视野的具体定义

  • 水平视野 (Horizontal FOV, HFOV):传感器在水平方向上可以感知的最大角度范围。
  • 垂直视野 (Vertical FOV, VFOV):传感器在垂直方向上可以感知的最大角度范围。

感知视野可以用角度来衡量,例如常见相机的水平视野可能在60度到120度之间。FOV越大,表示传感器能覆盖的范围越广;但较大的FOV可能会带来较大的失真,特别是在边缘区域。

感知视野的影响因素

  1. 传感器的物理属性:例如,镜头的焦距会直接影响相机的视野大小。焦距短(广角镜头)会提供较大的视野,而焦距长(长焦镜头)会提供较小的视野。
  2. 安装位置和角度:相机或传感器的安装高度、倾斜角度等都会改变其感知的范围和视野角度。
  3. 传感器类型:不同传感器的感知视野不同。例如,激光雷达的FOV和相机的FOV有很大区别。

感知视野的大小影响了机器人、无人机或自动驾驶车辆的感知能力,决定了它们能够覆盖多少环境信息来进行决策和控制。

Ego-Planner是一个基于ROS的路径规划器,它可以在给定的地图和起点、终点信息下,生成一条可行的路径。以下是Ego-Planner的代码框架: 1. 首先需要定义一个EgoPlanner类,其中包含了一些必要的成员变量和函数。 ```c++ class EgoPlanner { private: ros::NodeHandle nh_; ros::Subscriber sub_map_; ros::Subscriber sub_pose_; ros::Subscriber sub_goal_; ros::Publisher pub_path_; nav_msgs::OccupancyGrid map_; geometry_msgs::PoseStamped start_; geometry_msgs::PoseStamped goal_; public: EgoPlanner(); // 构造函数 ~EgoPlanner(); // 析构函数 void mapCallback(const nav_msgs::OccupancyGrid::ConstPtr& msg); // 地图回调函数 void poseCallback(const geometry_msgs::PoseStamped::ConstPtr& msg); // 当前位置回调函数 void goalCallback(const geometry_msgs::PoseStamped::ConstPtr& msg); // 目标位置回调函数 void plan(); // 路径规划函数 }; ``` 2. 在构造函数中,需要完成ROS节点的初始化、订阅和发布话题的设置。 ```c++ EgoPlanner::EgoPlanner() { nh_ = ros::NodeHandle("~"); sub_map_ = nh_.subscribe("map", 1, &EgoPlanner::mapCallback, this); sub_pose_ = nh_.subscribe("pose", 1, &EgoPlanner::poseCallback, this); sub_goal_ = nh_.subscribe("goal", 1, &EgoPlanner::goalCallback, this); pub_path_ = nh_.advertise<nav_msgs::Path>("path", 1); } ``` 3. 在地图、当前位置和目标位置的回调函数中,需要将接收到的信息保存到对应的成员变量中。 ```c++ void EgoPlanner::mapCallback(const nav_msgs::OccupancyGrid::ConstPtr& msg) { map_ = *msg; } void EgoPlanner::poseCallback(const geometry_msgs::PoseStamped::ConstPtr& msg) { start_ = *msg; } void EgoPlanner::goalCallback(const geometry_msgs::PoseStamped::ConstPtr& msg) { goal_ = *msg; } ``` 4. 在路径规划函数中,需要调用路径规划算法,生成一条可行的路径,并将路径发布出去。 ```c++ void EgoPlanner::plan() { // 调用路径规划算法,生成一条可行的路径 std::vector<geometry_msgs::PoseStamped> path = pathPlanning(map_, start_, goal_); // 将路径发布出去 nav_msgs::Path path_msg; path_msg.header.frame_id = "map"; path_msg.header.stamp = ros::Time::now(); path_msg.poses = path; pub_path_.publish(path_msg); } ``` 5. 在主函数中,创建EgoPlanner对象,并进入ROS循环。 ```c++ int main(int argc, char** argv) { ros::init(argc, argv, "ego_planner"); EgoPlanner planner; ros::Rate rate(10); while (ros::ok()) { planner.plan(); ros::spinOnce(); rate.sleep(); } return 0; } ``` 以上就是Ego-Planner的代码框架,其中路径规划算法需要根据具体情况进行选择和实现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值