当前位置:   article > 正文

海康威视复赛题 ---- 碰撞避免方案(1)

输入一个用户名、密码,判断密码强度。 分四类: 1. 强度0:密码长度小于8|用户名与

题目详情:http://www.cnblogs.com/wlzy/p/7096182.html

复赛题要求机器人之间不允许发生碰撞和相遇,拿到题目后,大体有以下几个解题思路:

方案一:基于侧边停车的碰撞避免算法

  侧边停车是属于一种局部路径规划,只要保证每辆车时时刻刻拥有独立的侧停车位,那么即使发生相遇冲突,也可以及时侧停避让,算法大体描述如下:

定义机器人 占据点属性:    机器人可获取独立侧停车位的最小路径点集。
          预测点属性:    从占据点下个点到路径终点的点集。

开始:
        1.初始化地图map
        2.计算每个机器人的占据点,然后添加到map中相应的占据点队列中
        3.计算每个机器人的预测点和机器人到每个预测点的距离值 ,并添加到map相应的预测点队列中。
        4.检测占据点是否冲突。
        5.遍历每个机器人,检测第一个预测点是否冲突
            若无冲突,继续前进
            有冲突,检测冲突类型:如果是相交冲突,只需简单令其中一个暂停。如果是相遇冲突,根据优先级选择一辆车侧停避让。
        6.死锁检测和处理
结束

 

 

  该算法只需遍历每个机器人的占据点和第一个预测点,执行速度很快,机器人通行效率较高,但是存在以下问题:当机器人较多时,动态移动的机器人可能随时占用其他机器人的侧停车位,使得机器人无法满足调度的基本条件,从而容易导致死锁。

 

  可以通过加长预测点来减少死锁发生的概率,或者添加一些死锁处理算法,但是这只能是治标不治本,总会有遗漏的情况。

 

方案二:基于相遇检测的碰撞避免算法

  为了避免调度陷入死锁状态,提出了一种相遇避免算法,只要时刻检测每个机器人的预测点是否会相遇,若发生相遇则调度使其中部分暂停

  

  1. 定义机器人占据点属性: 机器人当前位置点。
  2. 预测点属性: 从占据点下个点到路径终点的点集。
  3. 开始:
  4. 1.初始化地图map
  5. 2.计算每个机器人的占据点,然后添加到map中相应的占据点队列中
  6. 3.计算每个机器人的预测点和机器人到每个预测点的距离值 ,并添加到map相应的预测点队列中。
  7. 4.检测占据点是否冲突。
  8. 5.遍历每个机器人:
  9. 6.检测第一个预测点是否有冲突,若无则继续走,如有则记录该点中所有机器人到RobotList中。
  10. 7.遍历剩余的预测点:若RobotList中机器人的占据在预测点中被找到,说明该机器人未来路径会发生相遇,立即停止运行。
  11. 若没有机器人机器人占据点,则比较所有冲突机器人到那段路径的距离,距离最小的取得改路径使用权。
  12. 结束。

    算法2已经成功实现了,执行速度还算快,结果稳定无错误。由于添加了相遇检测,彻底避免了机器人在移动过程中相遇的情况,因此只需处理十字路口相交的冲突。

    但是算法2采用的相遇检测机制注定了效率低下,会因为避免相遇而等待大量时间。不过有个优化的解决方案:在机器人执行任务前规划一条较优的路径,这样就能大量减少相遇冲突的等待时间。

 核心代码:

1.冲突地图生成函数

  1. //生成冲突地图
  2. void Dispatch::GenConflict(TreeMsg &msg)
  3. {
  4. msg.Map_map.clear(); //清空冲突地图
  5. //busy机器人冲突点设置
  6. if(msg.RobotBusy_map.empty() == false)
  7. {
  8. map<ZY_UINT32,RobotInfo>::iterator rit;
  9. for(rit = msg.RobotBusy_map.begin();rit != msg.RobotBusy_map.end();rit++)
  10. {
  11. RobotInfo robot_info = rit->second;
  12. //获取占据点 只有一个
  13. map<PointItem,PointInfo>::iterator fit_o1 = msg.Map_map.find(robot_info.Current_Pos.Pos);
  14. if(fit_o1 != msg.Map_map.end()) //在map中存在,添加占据点
  15. {
  16. PointInfo point_info = fit_o1->second;
  17. point_info.OccupyList.insert(RobotInfoP(robot_info,0));
  18. msg.Map_map[robot_info.Current_Pos.Pos] = point_info;
  19. }
  20. else
  21. {
  22. PointInfo point_info;
  23. point_info.OccupyList.insert(RobotInfoP(robot_info,0));
  24. msg.Map_map.insert(map<PointItem,PointInfo>::value_type(robot_info.Current_Pos.Pos,point_info));
  25. }
  26. //获取预测点
  27. if(robot_info.Relative_Pos < robot_info.Route_Size) //为走到终点
  28. {
  29. for(int i=(robot_info.Relative_Pos +1);i <= robot_info.Route_Size;i++)
  30. {
  31. PointItem point_item = robot_info.Route->at(i);
  32. map<PointItem,PointInfo>::iterator fit_p = msg.Map_map.find(point_item);
  33. if(fit_p != msg.Map_map.end())
  34. {
  35. PointInfo point_info = fit_p->second;
  36. point_info.PredictList.insert(RobotInfoP(robot_info,i - robot_info.Relative_Pos));
  37. msg.Map_map[point_item] = point_info;
  38. }
  39. else
  40. {
  41. PointInfo point_info;
  42. point_info.PredictList.insert(RobotInfoP(robot_info,i - robot_info.Relative_Pos));
  43. msg.Map_map.insert(map<PointItem,PointInfo>::value_type(point_item,point_info));
  44. }
  45. }
  46. }
  47. //
  48. robot_info.LastOccupyP = robot_info.Route->at(robot_info.Relative_Pos);
  49. if(robot_info.Relative_Pos < robot_info.Route_Size)
  50. robot_info.FirstPredictP = robot_info.Route->at(robot_info.Relative_Pos+1);
  51. else
  52. robot_info.FirstPredictP = robot_info.Route->at(robot_info.Relative_Pos);
  53. msg.RobotBusy_map[rit->first] = robot_info;
  54. }
  55. }
  56. }

  

 1.冲突检测和调度处理

  1. void Dispatch::ConflictProcess(TreeMsg &msg)
  2. {
  3. //将机器人状态全部置为未更新
  4. {
  5. map<ZY_UINT32,RobotInfo>::iterator rit;
  6. for(rit = msg.RobotBusy_map.begin();rit != msg.RobotBusy_map.end();rit++)
  7. {
  8. RobotInfo robot_info = rit->second;
  9. robot_info.IsUpdated = false;
  10. robot_info.AddTail = false;
  11. msg.RobotBusy_map[rit->first] = robot_info;
  12. }
  13. map<RobotKey,RobotInfo>::iterator rit2;
  14. for(rit2 = msg.RobotIdle_map.begin();rit2 != msg.RobotIdle_map.end();rit2++)
  15. {
  16. RobotInfo robot_info = rit2->second;
  17. robot_info.IsUpdated = false;
  18. robot_info.AddTail = false;
  19. msg.RobotIdle_map[rit2->first] = robot_info;
  20. }
  21. }
  22. if(msg.RobotBusy_map.empty() == false)
  23. {
  24. set<PointItem> IO_CollisionPoint; //出入口出的冲突点
  25. IO_CollisionPoint.clear();
  26. while(1)
  27. {
  28. bool IsChanged = false;
  29. map<ZY_UINT32,RobotInfo>::iterator ritg;
  30. GenConflict(msg); //生冲突处理地图
  31. for(ritg = msg.RobotBusy_map.begin();ritg != msg.RobotBusy_map.end();ritg++)
  32. {
  33. RobotInfo robot_info = ritg->second;
  34. //检测是否更新过
  35. if(robot_info.IsUpdated == true)
  36. continue;
  37. //占据点与占据点冲突检测 忽略出入口冲突
  38. if((msg.Map_map.at(robot_info.LastOccupyP).OccupyList.size() > 1)&&(robot_info.LastOccupyP != Map_In)\
  39. &&(robot_info.LastOccupyP != Map_Out))
  40. {
  41. #ifdef ZYVV_DEBUG
  42. cout<<"OccupyP Error\r\n";
  43. #endif
  44. continue;
  45. }
  46. //若预测点为出入口 则忽略
  47. if((robot_info.FirstPredictP == Map_In)||(robot_info.FirstPredictP == Map_Out))
  48. {
  49. robot_info.Relative_Pos++;
  50. robot_info.Current_Pos.Pos = robot_info.Route->at(robot_info.Relative_Pos);
  51. robot_info.DistToE--;
  52. robot_info.IsUpdated = true;
  53. msg.RobotBusy_map[ritg->first] = robot_info;
  54. IsChanged = true;
  55. GenConflict(msg);
  56. //添加到出入口冲突点
  57. IO_CollisionPoint.insert(robot_info.LastOccupyP);
  58. continue;
  59. }
  60. //预测点和占据点冲突
  61. if(msg.Map_map.at(robot_info.FirstPredictP).OccupyList.empty() == false)
  62. {
  63. //等待
  64. continue;
  65. }
  66. {
  67. //剔除同向预测点
  68. set<RobotInfoP>::iterator rit1;
  69. set<RobotInfoP> predict_listp = msg.Map_map.at(robot_info.FirstPredictP).PredictList;
  70. set<RobotInfoP> predict_listp2 = msg.Map_map.at(robot_info.LastOccupyP).PredictList;
  71. for(rit1 = predict_listp.begin();rit1 != predict_listp.end();)
  72. {
  73. RobotInfoP robot_infop1 = *rit1;
  74. set<RobotInfoP>::iterator rit2;
  75. rit2 = predict_listp2.find(robot_infop1);
  76. if((rit2 != predict_listp2.end())) //若找到并且方向相同
  77. {
  78. RobotInfoP robot_infop2 = *rit2;
  79. if(robot_infop1.pos > robot_infop2.pos)
  80. rit1 = predict_listp.erase(rit1);
  81. else
  82. rit1++;
  83. }
  84. else
  85. rit1++;
  86. }
  87. msg.Map_map[robot_info.FirstPredictP].PredictList = predict_listp;
  88. }
  89. //无预测点冲突 继续前进
  90. if(msg.Map_map.at(robot_info.FirstPredictP).PredictList.size() == 1)
  91. {
  92. //若在出入口,需要避免相遇
  93. if((robot_info.LastOccupyP != Map_In)&&(robot_info.LastOccupyP != Map_Out))
  94. {
  95. robot_info.Relative_Pos++;
  96. robot_info.Current_Pos.Pos = robot_info.Route->at(robot_info.Relative_Pos);
  97. robot_info.DistToE--;
  98. robot_info.IsUpdated = true;
  99. msg.RobotBusy_map[ritg->first] = robot_info;
  100. IsChanged = true;
  101. GenConflict(msg);
  102. continue;
  103. }
  104. else
  105. {
  106. set<PointItem>::iterator fit;
  107. fit = IO_CollisionPoint.find(robot_info.FirstPredictP);
  108. if(fit == IO_CollisionPoint.end()) //未找到,表示不冲突
  109. {
  110. robot_info.Relative_Pos++;
  111. robot_info.Current_Pos.Pos = robot_info.Route->at(robot_info.Relative_Pos);
  112. robot_info.DistToE--;
  113. robot_info.IsUpdated = true;
  114. msg.RobotBusy_map[ritg->first] = robot_info;
  115. IsChanged = true;
  116. GenConflict(msg);
  117. continue;
  118. }
  119. else
  120. {
  121. continue;
  122. }
  123. }
  124. }
  125. //预测点冲突
  126. if(msg.Map_map.at(robot_info.FirstPredictP).PredictList.size() > 1)
  127. {
  128. set<RobotInfoP>::iterator rit;
  129. bool IsWin = true;
  130. set<RobotInfoP> predict_listp = msg.Map_map.at(robot_info.FirstPredictP).PredictList;
  131. //检测相同距离预测点冲突
  132. for(rit = predict_listp.begin();rit != predict_listp.end();rit++)
  133. {
  134. RobotInfoP robot_infop1 = *rit;
  135. if((robot_infop1.pos == 1)&&(robot_infop1.robot_info.Robot_Serial != robot_info.Robot_Serial))
  136. {
  137. if(robot_infop1.robot_info.Robot_Priority > robot_info.Robot_Priority)
  138. {
  139. IsWin == false;
  140. break;
  141. }
  142. }
  143. }
  144. if((IsWin == true)&&((robot_info.Relative_Pos + 1) < robot_info.Route_Size))
  145. {
  146. //检测相遇冲突
  147. for(int i = (robot_info.Relative_Pos + 2); i <= robot_info.Route_Size;i++)
  148. {
  149. //忽略出入口冲突
  150. if((robot_info.Route->at(i) == Map_In)||(robot_info.Route->at(i) == Map_Out))
  151. continue;
  152. set<RobotInfoP>::iterator rit3;
  153. set<RobotInfoP> predict_listp_t = msg.Map_map.at(robot_info.Route->at(i)).PredictList;
  154. set<RobotInfoP> occupy_listp_t = msg.Map_map.at(robot_info.Route->at(i)).OccupyList;
  155. for(rit3 = predict_listp.begin();rit3 != predict_listp.end();)
  156. {
  157. set<RobotInfoP>::iterator t_it;
  158. t_it = occupy_listp_t.find(*rit3);
  159. if(t_it != occupy_listp_t.end()) //预测点被占据 则暂停
  160. {
  161. IsWin = false;
  162. break;
  163. }
  164. else
  165. {
  166. t_it = predict_listp_t.find(*rit3);
  167. if(t_it == predict_listp_t.end()) //冲突预测点中间断开,则移除
  168. {
  169. //rit3 = predict_listp.erase(rit3);
  170. rit3++;
  171. }
  172. else
  173. rit3++;
  174. }
  175. }
  176. if(IsWin == false)
  177. break;
  178. }
  179. }
  180. //赢得预测点,更新机器人运行状态
  181. if(IsWin == true)
  182. {
  183. if((robot_info.LastOccupyP != Map_In)&&(robot_info.LastOccupyP != Map_Out))
  184. {
  185. robot_info.Relative_Pos++;
  186. robot_info.Current_Pos.Pos = robot_info.Route->at(robot_info.Relative_Pos);
  187. robot_info.DistToE--;
  188. robot_info.IsUpdated = true;
  189. msg.RobotBusy_map[ritg->first] = robot_info;
  190. IsChanged = true;
  191. GenConflict(msg);
  192. continue;
  193. }
  194. else
  195. {
  196. set<PointItem>::iterator fit;
  197. fit = IO_CollisionPoint.find(robot_info.FirstPredictP);
  198. if(fit == IO_CollisionPoint.end()) //未找到,表示不冲突
  199. {
  200. robot_info.Relative_Pos++;
  201. robot_info.Current_Pos.Pos = robot_info.Route->at(robot_info.Relative_Pos);
  202. robot_info.DistToE--;
  203. robot_info.IsUpdated = true;
  204. msg.RobotBusy_map[ritg->first] = robot_info;
  205. IsChanged = true;
  206. GenConflict(msg);
  207. continue;
  208. }
  209. else
  210. {
  211. continue;
  212. }
  213. }
  214. }
  215. else
  216. {
  217. continue;
  218. }
  219. }
  220. }
  221. if(IsChanged == false)
  222. break;
  223. }
  224. }
  225. }

  

完整源码:https://github.com/ZyvvL

转载于:https://www.cnblogs.com/wlzy/p/7096387.html

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/536527
推荐阅读
相关标签
  

闽ICP备14008679号