自动寻路是机器人导航的核心技术,其原理主要涉及机器人与环境之间的复杂信息交互与处理。在自动寻路过程中,机器人依靠先进的传感器系统,如高清摄像头、精密激光雷达和灵敏超声波装置,全方位感知周围环境。这些传感器能够实时捕捉并分析环境中的障碍物、地形变化和关键路标,为机器人提供精确的导航数据。
自动寻路在多个领域发挥着关键作用,从图扑的数据中心机房的自动化巡检系统,到智能机器人的导航系统,再到智慧码头堆场的智能化管理,自动寻路技术无处不在。该功能不仅能规划出最优路线,还能实时考虑障碍物避让等复杂的实际因素,灵活调整路径以确保安全和效率。
乍听之下,自动寻路功能略显复杂,实现过程中也确实涉及了一些算法。在具体实施之前,我们需要先解决两个关键问题:
1. 如何避开场景中的障碍物?
2. 如何计算最佳路径?
针对这两处问题,我们可以利用图扑软件自研 HT for Web 提供的 ht-astar.js 插件。该插件具备初始化网格和自动搜索路径等功能,高效简化了自动寻路的实现过程。
系统分析
场景网格化
先将场景划分成二维网格,障碍物分布于不同的网格单元上,部分较大的障碍物可能会占据多个网格单元。路径计算实际上是分析网格的占用情况,当平台监测到某个网格被占用时,系统会自动寻找择优生成一条绕行路径。
在开发时,首先需要去实例化 ht.Astar.Finder(view, params)。其中 view 可以是 ht.graph.GraphView 或者 ht.graph3d.Graph3dView。params 是一个包含基础属性设置的对象。以下列举了一些 params 的常用参数:
✧simplify:是否启用路径简化。
✧closest:是否启用最近路径优化。
✧nodeRectExtend:扩展节点范围。
✧gridSizeY:网格在 Y 方向上的大小。
✧gridSizeX:网格在 X 方向上的大小。
✧diagonal:是否允许沿对角线方向移动。
✧fastOverlap:是否启用快速监测重叠算法。
✧filter:过滤函数用于在路径计算过程中过滤特定节点。
✧turnPunish:转弯惩罚系数,数值越高表示越倾向于直线路径。
具体代码实现:
const hindrance = dm.getDataByTag(‘hindrance’); const astar = new ht.Astar.Finder(view, { gridSizeX: 50, // 网格 gridSizeY: 50, nodeRectExtend: 50, fastOverlap: false, filter: function (data) { return data.isDescendantOf(hindrance); } });
路径计算
在路径计算过程中,系统需要实时监测每个网格单元的占用状态。若规划的路径遇到被障碍物占用的网格,系统会自动寻找绕行路径,以动态避开障碍物。
在开发过程中,我们需要监听场景背景的点击事件,获取点击位置的坐标。然后,结合起点坐标,通过 astar.findPath(pFrom, pTo) 函数计算出具体路径。计算得到的路径是一组点位数据,可以利用这些数据在场景中绘制出一条路径管道。具体代码实现:
view.mi(function (e) { const { kind, data, event } = e; if (kind === 'clickBackground') { const animOb = view.dm().getDataByTag('people'); // 获取人物节点 let pFrom = animOb.p3(); // 获取人物节点的坐标(起点坐标) pFrom = { x: pFrom[0], y: pFrom[2] }; let position = view.getHitPosition(event); // 根据鼠标事件获取场景中的逻辑坐标 const pTo = { x: position[0], y: position[2] }; const path = astar.findPath(pFrom, pTo); // 获取路径 createPloyline(path); // 生成管道 } }) // 生成管道 createPloyline(){ const points: any = []; path.forEach((p: any, i: number) => { points.push({ x: p.x, y: p.y, e: 0 }); }) const polyline = new ht.Polyline(); polyline.s({ "shape3d": false, }); polyline.setPoints(points); view.dm().add(polyline); }
路径动画
在场景中生成管道后,人物节点可沿此管道移动。人物节点沿管道运动的代码如下:
const animOb = dm.getDataByTag('people'); animOb.playAnimation('walk'); // 示例中人物模型使用的是 fbx 模型,可播放节点上的动画 const length = view.getLineLength(polyline); let moveAnim = null; const params = { delay: 100, duration: 1000 * (length / 200), // 根据管道的长度设定动画周期 easing: function (t) { return t }, action: function (v, t) { var offset = view.getLineOffset(polyline, length * v); if (offset) { var point = offset.point, px = point.x, py = point.y, pz = point.z, tangent = offset.tangent, tx = tangent.x, ty = tangent.y, tz = tangent.z; animOb.lookAt([px + tx, py + ty, pz + tz], 'front'); animOb.p3(px, py, pz); } // 人物运动时,视角始终跟随 view.setCenter([px, py, pz]); view.setEye([px + 400, py + 800, pz + 400]); }, finishFunc: () => { moveAnim = null; // 切换场景视角 view.moveCamera([-84, 3435, 3142], [-28, -821, -160], { duration: 1000 }) animOb.pauseAnimation(); // 暂停人物模型动画 } }; moveAnim = ht.Default.startAnim(params);
优化视觉效果
基于上述,我们已实现了基本的自动寻路功能。在实际项目中仍需提升一定的视觉效果,让展示页面足够美观,我们可以采取以下策略:
- 首先,将管道路径隐藏(使用 polyline.s('transparent.mask', true));
- 随后,利用 ht.Shape 节点并设置贴图来呈现人物的运动轨迹。这样不仅能实现功能,还能大幅增强视觉吸引力。
具体实现代码如下:
createShape(points) { if(uvAnim) uvAnim.pause(); // 创建新的 shape 前将旧shape 的 uv 偏移动画移除 const shape = this.shape = new ht.Shape(); shape.s({ "shape.border.color": "rgb(255,0,0)", "all.visible": false, "all.transparent": true, "top.visible": true, "top.image": "assets/arrow.png", "top.uv.scale": [ length / 500, 1 ], "texture.cache": true, "3d.selectable": true, "3d.editable": false, "3d.movable": false, "3d.visible": true }) dm.add(shape); shape.setThickness(30); shape.setPoints(points); return shape; } // ht.Shape 的 uv 偏移动画 playShapeAnim(shape) { if (!shape) return; const params = { duration: 2000, easing: function (t: number) { return t; }, action: function (v: number, t: number) { shape.s("all.uv.offset", [v, 0]); }, finishFunc: () => { uvAnim = null; uvAnim = ht.Default.startAnim(params); } }; uvAnim = ht.Default.startAnim(params); } const points: any = []; path.forEach((p: any, i: number) => { points.push({ x: p.x, y: p.y, e: 0 }); }) const shape = createShape(points); let uvAnim = null; playShapeAnim(shape); // 执行shape 的 uv 偏移动画
总结
作为开发者的我们,将继续探索和优化自动寻路技术,利用图扑 HT 提供的插件工具,不断提升算法效率和用户体验。通过合理的参数设置、精确的网格划分和智能的路径规划,为各种应用场景提供更加出色的自动寻路解决方案。
您可以至图扑软件官网查看更多案例及效果:
https://www.hightopo.com/demos/index.html
标签:避障,const,路径,网格,ht,shape,可视化,view,3D From: https://www.cnblogs.com/xhload3d/p/18527392