CBS多机器人路径规划

CBS多机器人路径规划

   单个机器人通过路径规划、运动控制,能够躲避环境中的障碍物,但会面临一个严峻的问题。当一个场景中存在多辆移动机器人时,即使每个机器人都有避障策略,也很容易就会造成道路拥堵、阻塞的情况,而且会随着机器人数量的增加变得更严峻。就像如果道路没有交通指挥系统,人们就会将有些道路挤得水泻不通,形成死锁的局面。为解决此问题,一种基于冲突的多机器人路径搜索方法(Conflict-Base search)应运而生。

CBS基本操作过程

   CBS由2个搜索过程组成,底层次的搜索过程负责为每个机器人搜索出一条有效路径,高层次的负责检查路径冲突,并选择出其中代价值最小的分支重新进行底层次的路径搜索,直到高层次的搜索过程发现有效路径为止。

高层次的搜索过程

  高层次的搜索过程主要有两个作用:

  1. 检查路径之间的冲突,并生成新的分支;
  2. 选出代价值最小的分支进行低层次的搜索;
      路径之间的冲突分为同一时刻占据同一个节点和同一时刻调换位置两种类型的冲突,如图(1)所示

图1
  当两条路径在n时刻检测到存在冲突的情况时,需要生成两个分支:第一个机器人在n时刻不能进入该节点和第二个机器人在n时刻不能进入该节点。

  在上述两个过程完成后,选择其中代价值最小的节点进行低层次的路径搜索过程。

低层次的搜索过程

  低层次的搜索过程与普通的路径规划方法类似,如Dirkstra、A*等。但其不同之处在于:

  1. 搜索过程中需要考虑额外的约束,即高层次搜索中添加的冲突;
  2. 在搜索过程中需要考虑原地等待的情况;

  由于在搜索过程中需要考虑到等待的情况,因此将时间也做为一个维度加入到路径搜索过程中,通常每次扩展搜索区域时,时间增加一个单位长度。

  通过高低两个搜索过程不断地运行,当问题的复杂程度不高时,能够及时得到比较好的结果。

实例讲解

  以下将通过一个简单的实例讲解CBS的基本过程,实例如图2所示。


图2 初始和目标状态

  CBS的搜索过程如图3所示。


图3 CBS搜索过程

  CBS开始时没有冲突约束,每个机器人按照各自的路径规划,得到节点1所示的路径结果,由于路径产生冲突,需要生成新的分支(节点2和节点3),节点2添加冲突为:1号在1时刻(从0时刻开始)不进入位置3,节点3添加冲突为:2号在1时刻不进入位置3。在约束的作用下进行低层次的搜索,节点2和节点3都搜索到了路径,但发生了新的冲突,由于节点2和节点3的代价值相等,可以从左边的节点(节点2)开始生成新的分支:节点4和节点5,然后对节点4和节点5进行低层次的搜索得到路径,最终节点5得到有效路径,搜索过程可以结束。

待改进的地方

  虽然CBS做为一个比较优秀的多机器人路径规划器,依然存在一些缺点影响它在实际中的应用。

  1. 当环境拥挤,机器人数目多时,计算时间比较长,甚至无解;
  2. 无法判断有些情况是否无解,导致程序无法结束运行,且一直消耗系统内存;
  3. 实际情况下,机器人需要原地旋转、有加减速度、运行存在误差,需要后续进一步处理才能在实际中运行;

推荐资料

  源程序:https://github.com/whoenig/libMultiRobotPlanning
  论文:Conflict-based search for optimal multi-agent pathfinding

  • 26
    点赞
  • 137
    收藏
    觉得还不错? 一键收藏
  • 14
    评论
CBS算法是一种针对多机器人路径规划问题的算法,其核心思想是将多机器人的路径规划问题分解为单机器人的路径规划问题,并利用冲突检测和冲突消解来解决整个问题。下面是一个基于C++语言实现的多机器人CBS算法的示例代码: ```c++ #include <iostream> #include <vector> #include <queue> using namespace std; // 定义机器人结构体 struct Robot { int id; // 机器人编号 int start; // 起点编号 int goal; // 终点编号 vector<int> path; // 路径 }; // 定义冲突结构体 struct Conflict { int time; // 冲突时间 int robot1; // 机器人1编号 int robot2; // 机器人2编号 int location; // 冲突位置 }; // 定义节点结构体 struct Node { vector<Robot> robots; // 机器人集合 vector<Conflict> conflicts; // 冲突集合 int cost; // 路径长度 bool operator<(const Node &n) const { return cost > n.cost; } }; // 定义地 vector<vector<int>> map; // 定义机器人集合和终点集合 vector<Robot> robots; vector<int> goals; // 定义冲突检测函数 bool detect_conflict(int time, int robot1, int robot2, vector<Robot> &robots) { int loc1 = robots[robot1].path[time]; int loc2 = robots[robot2].path[time]; if (loc1 == loc2) { return true; } for (int i = time + 1; i < robots[0].path.size(); i++) { int next_loc1 = robots[robot1].path[i]; int next_loc2 = robots[robot2].path[i]; if (next_loc1 == next_loc2) { return true; } if (next_loc1 == loc2 && next_loc2 == loc1) { return true; } loc1 = next_loc1; loc2 = next_loc2; } return false; } // 定义冲突消解函数 void resolve_conflict(int time, int robot1, int robot2, vector<Robot> &robots) { Robot &r1 = robots[robot1]; Robot &r2 = robots[robot2]; int loc1 = r1.path[time]; int loc2 = r2.path[time]; if (loc1 == loc2) { return; } // 交换位置 if (r1.goal == loc2 && r2.goal == loc1) { swap(r1.goal, r2.goal); swap(r1.path, r2.path); return; } // 机器人1等待 if (r1.goal == loc2) { r1.path.insert(r1.path.begin() + time, loc1); return; } // 机器人2等待 if (r2.goal == loc1) { r2.path.insert(r2.path.begin() + time, loc2); return; } // 交叉 for (int i = time + 1; i < r1.path.size(); i++) { if (r1.path[i] == loc2 && r2.path[i] == loc1) { r1.path.insert(r1.path.begin() + i, loc1); return; } if (r2.path[i] == loc1 && r1.path[i] == loc2) { r2.path.insert(r2.path.begin() + i, loc2); return; } } } // 定义A*算法函数 int astar(int robot, int start, int goal) { vector<int> g(map.size(), INT_MAX); vector<int> f(map.size(), INT_MAX); vector<int> parent(map.size(), -1); priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq; g[start] = 0; f[start] = g[start] + heuristic(start, goal); pq.push({f[start], start}); while (!pq.empty()) { int curr = pq.top().second; pq.pop(); if (curr == goal) { int cost = 0; while (parent[curr] != -1) { int prev = parent[curr]; cost += distance(curr, prev); curr = prev; } return cost; } for (int i = 0; i < map[curr].size(); i++) { int next = map[curr][i]; int dist = distance(curr, next); int h = heuristic(next, goal); if (g[curr] + dist < g[next]) { g[next] = g[curr] + dist; f[next] = g[next] + h; parent[next] = curr; pq.push({f[next], next}); } } } return INT_MAX; } // 定义CBS算法 int cbs() { Node n; n.robots = robots; for (int i = 0; i < robots.size(); i++) { n.cost += astar(i, robots[i].start, robots[i].goal); } priority_queue<Node> pq; pq.push(n); while (!pq.empty()) { Node curr = pq.top(); pq.pop(); if (curr.conflicts.empty()) { return curr.cost; } Conflict c = curr.conflicts[0]; vector<Node> children; for (int i = 0; i < 2; i++) { Node child = curr; int robot = (i == 0 ? c.robot1 : c.robot2); int goal = (i == 0 ? robots[c.robot1].goal : robots[c.robot2].goal); for (int j = c.time; j < child.robots[0].path.size() && child.robots[robot].path[j] != goal; j++) { child.robots[robot].path[j] = child.robots[robot].path[c.time]; } child.robots[robot].path.erase(child.robots[robot].path.begin() + c.time + 1, child.robots[robot].path.end()); child.robots[robot].goal = goal; child.cost = 0; for (int j = 0; j < robots.size(); j++) { child.cost += astar(j, child.robots[j].start, child.robots[j].goal); } children.push_back(child); } for (int i = 0; i < children.size(); i++) { bool valid = true; for (int j = 0; j < children[i].robots.size(); j++) { for (int k = j + 1; k < children[i].robots.size(); k++) { if (detect_conflict(c.time, j, k, children[i].robots)) { valid = false; Conflict new_c = {c.time, j, k, children[i].robots[j].path[c.time]}; children[i].conflicts.push_back(new_c); } } } if (valid) { pq.push(children[i]); } } } return INT_MAX; } int main() { // 初始化地 map = vector<vector<int>>(10, vector<int>(10, 1)); // 初始化机器人和终点 Robot r1 = {0, 1, 9, {1}}; Robot r2 = {1, 9, 1, {9}}; Robot r3 = {2, 1, 9, {1}}; Robot r4 = {3, 9, 1, {9}}; robots.push_back(r1); robots.push_back(r2); robots.push_back(r3); robots.push_back(r4); goals = {9, 1, 9, 1}; // 调用CBS算法 int cost = cbs(); cout << "Total cost: " << cost << endl; return 0; } ``` 在上述代码中,我们首先定义了机器人和冲突的结构体,然后定义了冲突检测和冲突消解的函数,以及A*算法的函数。最后,我们定义了CBS算法的函数,并在主函数中调用该函数来解决多机器人路径规划问题。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值