(7-3)D* Lite 算法:可视化的D* Lite路径规系统

7.3  可视化的D* Lite路径规系统

本项目是一个基于D* Lite算法的路径规划器,通过库SFML实现了一个可视化的网格地图界面,用户可以通过左键点击来设置障碍物,右键点击来清除障碍物,并且可以通过键盘上的'R'键来重置地图。DStarLite类实现了D* Lite算法的核心功能,用于在给定的网格地图中计算从起点到目标点的最短路径。CellGrid类用于管理和绘制地图的图形表示。整个项目提供了一个交互式的界面,让用户可以直观地看到路径规划的过程和结果。

实例7-1可视化的D* Lite路径规系统codes/7/DStarLite/

7.3.1  项目介绍

本项目是一个基于D* Lite算法的路径规划器,通过SFML库实现了一个可视化的网格地图界面。用户可以在地图上设置起点、目标点以及障碍物,并观察算法计算出的最短路径。

1. 功能特点

  1. 可视化地图界面:使用SFML库创建了一个可视化的网格地图界面,用户可以直观地看到地图布局和路径规划结果。
  2. 交互式操作:用户可以使用鼠标左键点击设置障碍物,右键点击清除障碍物,并且可以通过键盘上的'R'键来重置地图。
  3. D* Lite算法实现:使用DStarLite类实现了D* Lite算法,用于在给定的网格地图中计算从起点到目标点的最短路径。
  4. 地图管理:使用CellGrid类管理和绘制地图的图形表示,包括起点、目标点、障碍物和路径等。

2. 项目价值

该项目为用户提供了一个直观、实用的路径规划工具,可用于演示和测试D* Lite算法在不同地图场景下的表现。用户可以通过调整地图布局和参数来观察算法的效果,从而更好地理解和学习路径规划算法。

7.3.2  运算符重载

文件util.hpp定义了一些实用函数和运算符重载,主要用于处理 std::pair 类型和 std::vector 类型的操作。

1. 运算符重载

(1)operator+:重载了 + 运算符,用于对两个 std::pair 进行元素相加操作。

(2)operator-:重载了 - 运算符,分为两种情况:

  1. 重载了两个 std::pair 相减的操作。
  2. 重载了单个 std::pair 的取反操作。

这些重载操作使得 std::pair 类型可以直接进行算术运算。

2. 函数arg_min()

函数arg_min()用于返回一个 std::vector 中最小元素的索引。它接受一个 std::vector 类型的参数,并使用函数std::min_element()找到最小元素,然后返回该最小元素的索引。注意,这个函数会复制一份输入的向量,因此如果对输入向量没有修改的需求,可以传递一个常引用来避免不必要的复制。

总的来说,文件util.hpp提供了一些方便的实用函数和运算符重载,以简化对 std::pair 和 std::vector 的操作。文件util.hpp的具体实现代码如下所示。

#ifndef __DSTARLITE_UTIL_HPP__
#define __DSTARLITE_UTIL_HPP__

#include <vector>
#include <utility>
#include <algorithm>

/**
 * @brief 加法重载 `std::pair<T1, T2>`
 *
 * @tparam T1 第一个类型
 * @tparam T2 第二个类型
 * @param p1 第一个 std::pair
 * @param p2 第二个 std::pair
 * @return std::pair<T1, T2> 返回类型为 std::pair<T1, T2>
 */
template<typename T1, typename T2>
std::pair<T1, T2> operator+(const std::pair<T1, T2> &p1, const std::pair<T1, T2> &p2)
{
  return {p1.first + p2.first, p1.second + p2.second};
}

/**
 * @brief 减法重载 `std::pair<T1, T2>`
 *
 * @tparam T1 第一个类型
 * @tparam T2 第二个类型
 * @param p1 第一个 std::pair
 * @param p2 第二个 std::pair
 * @return std::pair<T1, T2> 返回类型为 std::pair<T1, T2>
 */
template<typename T1, typename T2>
std::pair<T1, T2> operator-(const std::pair<T1, T2> &p1, const std::pair<T1, T2> &p2)
{
  return {p1.first - p2.first, p1.second - p2.second};
}

/**
 * @brief 取反运算符进行重载 `std::pair<T1, T2>`
 *
 * @tparam T1 第一个类型
 * @tparam T2 第二个类型
 * @param p std::pair
 * @return std::pair<T1, T2> 返回类型为 std::pair<T1, T2>
 */
template<typename T1, typename T2> std::pair<T1, T2> operator-(const std::pair<T1, T2> &p)
{
  return {-p.first, -p.second};
}

/**
 * @brief 返回向量中最小元素的索引
 *
 * @tparam T 类型
 * @param v 向量
 * @return size_t 返回类型为 size_t
 */
template<typename T> size_t arg_min(std::vector<T> v)
{
  return std::min_element(v.begin(), v.end()) - v.begin();
}

#endif /* __DSTARLITE_UTIL_HPP__ */

在上述代码中,实现了对 std::pair 类型的运算符重载功能,使得在D* Lite算法中对节点的操作更加方便。D* Lite算法中节点的表示通常使用 std::pair 类型,其中第一个元素是节点的坐标,第二个元素是节点的代价值或者其他属性。文件util.hpp提供了函数arg_min(),用于找到向量中最小元素的索引。在D* Lite算法中,经常需要找到最小值对应的索引,比如找到最小代价路径的下一个节点。

7.3.3  优先队列

文件PriorityQueue.hpp 定义了一个优先队列类 PriorityQueue,它是对标准库中的优先队列进行了扩展,增加了一些额外的功能,比如根据元素的值来移除元素。文件PriorityQueue.hpp实现了一个优先队列,这在D* Lite算法中是必需的。D* Lite算法中需要根据节点的代价值来动态调整搜索顺序,优先队列是一种高效的数据结构,用于按照节点的代价值进行排序和访问。

注意:优先队列的实现支持了一些额外的功能,比如根据节点的值来更新其优先级、根据节点的值来移除节点等等。这些功能在D* Lite算法的实现中可能会派上用场,比如在路径规划过程中需要动态更新节点的代价值。

文件PriorityQueue.hpp的具体实现代码如下所示。

#ifndef __DSTARLITE_PRIORITYQUEUE_HPP__
#define __DSTARLITE_PRIORITYQUEUE_HPP__

#include <vector>
#include <utility>
#include <algorithm>

using std::make_heap;
using std::pair;
using std::pop_heap;
using std::push_heap;
using std::vector;

/**
 * @brief 优先队列容器类。在STL实现中添加了“按值删除元素”的功能
 *
 * @tparam Tp 优先级的类型
 * @tparam Te 队列中元素的类型
 */
template<class Tp, class Te> class PriorityQueue
{
 public:
  /**
   * @brief 查看顶部元素的值并返回键值对。
   *
   * @return pair<Tp, Te> {优先级, 元素}
   */
  pair<Tp, Te> top() const
  {
    return data.front();  // 返回 {优先级, 元素} 键值对
  }

  /**
   * @brief 查看顶部元素的键。
   *
   * @return Tp 优先级
   */
  Tp topKey() const
  {
    return data.front().first;  // 仅返回优先级;
  }

  /**
   * @brief 返回当前容器中的元素数量。
   *
   * @return int
   */
  int size() const
  {
    return data.size();
  }

  /**
   * @brief 如果容器为空则返回
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码农三叔

感谢鼓励

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值