基于图书馆的移动机器人路径规划和避障能力DWA算法【附代码】
✨ 本团队擅长数据搜集与处理、建模仿真、程序设计、仿真代码、EI、SCI写作与指导毕业论文、期刊论文经验交流。✅ 专业定制毕设、代码✅如需沟通交流查看文章底部二维码1基于路径点采样和动态障碍物运动预测的改进DWA评价函数针对图书馆中密集书架形成的狭窄通道以及读者和推车等动态障碍物提出了一种改进的动态窗口法。其核心在于评价函数的重构加入了路径点采样项和障碍物运动预测项。传统DWA只评估末端轨迹点与目标点的方位和间隙而改进算法在预测时间范围内均匀选取5个路径点采样计算每个采样点与全局规划路径的横向偏差和与最近障碍物的距离将这些采样的平均值作为路径跟踪惩罚和碰撞风险的衡量。动态障碍物预测采用线性卡尔曼滤波器估计行人或推车在未来1.2秒内的位置和速度并以扩张椭圆模型表示其占据区域。椭圆长轴沿运动方向长半轴为预测速度模的0.5倍加0.2米短半轴为0.4米。评价函数中引入软约束当机器人轨迹的某采样点与障碍物占据椭圆重叠时碰撞代价指数增长。速度采样采用自适应密度在靠近全局路径的方向附近加密采样在偏离方向稀疏采样以保证实时性。仿真中图书馆环境建模为60米×35米的栅格地图有20排2米高书架。在10个随机运动读者场景下改进DWA的行驶路径平均长度为52.1米比传统DWA的57.4米缩短9.2%与动态障碍物的最小距离均值从0.23米提高至0.37米安全性大幅提升且未出现停滞现象。机器人运行速度曲线平滑加速度变化率降低23%。2融合RRT*预处理与虚拟力场的全局局部协同规划为了解决单纯局部规划在书架间死胡同易陷入局部极小的问题提出了一个双阶段协同架构。离线阶段利用RRT*算法对静态图书馆地图进行一次全局规划生成一条连接起点和终点的参考路径并以0.1米间隔重采样形成密集的路径点序列存储为二进制文件。在线阶段改进DWA作为局部规划器的同时引入虚拟力场将全局路径转化为引力场将书架边缘和动态障碍物转化为斥力场。斥力场的强度与距离的三次方成反比有效范围限制在0.6米内。改进之处在于当机器人当前位置与全局路径点的横向偏差超过0.4米时引力场强度暂时加倍形成拉回机制确保机器人不脱离全局走廊。同时在评价函数中额外引入一个书架走廊边界约束即若机器人采样轨迹将导致两侧书架距离均小于0.25米则该轨迹的代价设为无穷大强制机器人保持在通道中央行驶。在仿真中协同规划器成功穿越所有书架走廊没有任何一次偏离预定通道或冲入书架缝隙单次任务从启动到目标点的平均耗时从38.2秒降至30.5秒效率提升20.1%路径平滑度指标也明显改善。3基于ARM边缘计算模块与视觉标签的实时部署验证在实体TurtleBot3机器人上部署了该协同规划系统并增强了定位鲁棒性。在图书馆天花板上布置了Apriltag视觉标签阵列借助机器人搭载的鱼眼摄像头进行视觉定位矫正里程计累积误差。标签检测算法采用基于Canny边缘和四边形拟合的快速检测器运行在主频1.8GHz的ARM Cortex-A72边缘计算模块上平均检测延迟为22ms。视觉定位结果与激光里程计通过扩展卡尔曼滤波器融合输出100Hz的位姿估计。改进的DWA和协同规划算法以C编写运行在ROS框架下实时规划循环周期为80ms。在真实图书馆环境进行了为期两周的测试设置了白天有人流和夜间无人两种场景机器人执行还书任务共计280次。测试结果显示定位均方根误差为0.09米任务成功率达到98.2%。在一次遇到读者突然从书架间走出的事件中机器人成功急停并重新规划避让碰撞风险被完全化解。该部署验证了算法在实际动态、密集障碍场景中的有效性为图书馆自动化提供了可靠的技术基础。import numpy as np # 改进DWA评价函数Python原型 def improved_dwa_scores(traj, global_path, obs_predictions, dt0.2): # traj: Nx3 状态序列 waypoints global_path N_sample 5 indices np.linspace(0, len(traj)-1, N_sample, dtypeint) lateral_dev 0; min_dist_to_obs 1e6 for idx in indices: pt traj[idx,:2] # 横向偏差 diffs np.linalg.norm(waypoints[:,:2]-pt, axis1) closest_idx np.argmin(diffs) if closest_idx1 len(waypoints): seg waypoints[closest_idx1,:2]-waypoints[closest_idx,:2] vec pt - waypoints[closest_idx,:2] t np.dot(vec, seg)/np.dot(seg, seg) lateral np.linalg.norm(vec - t*seg) else: lateral diffs[closest_idx] lateral_dev lateral # 动态障碍物距离 for pred in obs_predictions: center, vel, ax1, ax2 pred # 椭圆参数 rel_pos pt - center angle np.arctan2(vel[1], vel[0]) rot_mat np.array([[np.cos(angle), np.sin(angle)],[-np.sin(angle), np.cos(angle)]]) rel_rot np.dot(rot_mat, rel_pos) ellipse_dist (rel_rot[0]**2)/(ax1**2) (rel_rot[1]**2)/(ax2**2) if ellipse_dist 1.0: # 在椭圆内代价极高 min_dist_to_obs min(min_dist_to_obs, 0.0) else: min_dist_to_obs min(min_dist_to_obs, 1.0-ellipse_dist) heading_score np.dot(traj[-1,:2]-traj[0,:2], waypoints[-1,:2]-traj[0,:2]) return -0.4*heading_score 0.3*lateral_dev - 0.3*min_dist_to_obs # RRT*全局路径预处理 def rrt_star_path(start, goal, grid, iterations2000): nodes [start]; edges []; costs[0] for _ in range(iterations): rand_point np.random.rand(2)*[grid.shape[1], grid.shape[0]] nearest_idx np.argmin([np.linalg.norm(n-rand_point) for n in nodes]) new_point steer(nodes[nearest_idx], rand_point, step0.5) if not collides(new_point, nodes[nearest_idx], grid): continue near_indices [i for i,n in enumerate(nodes) if np.linalg.norm(n-new_point)1.0] min_cost costs[nearest_idx]np.linalg.norm(new_point-nodes[nearest_idx]) min_parent nearest_idx for nidx in near_indices: if costs[nidx]np.linalg.norm(new_point-nodes[nidx]) min_cost: min_cost costs[nidx]np.linalg.norm(new_point-nodes[nidx]) min_parent nidx nodes.append(new_point); costs.append(min_cost); edges.append((min_parent, len(nodes)-1)) return extract_path(nodes, edges, start, goal)如有问题可以直接沟通