自动停车员

这个例子展示了如何构建一个自动泊车代客系统。在本例中,您将了解支持路径规划、轨迹生成和车辆控制的工具和技术。万博1manbetx虽然本例主要关注面向MATLAB®的工作流,但这些工具在Simulink®中也可用。万博1manbetx有关此示例的万博1manbetxSimulink®版本,请参见Simulink的自动泊车服务万博1manbetx

概述

自动停在停车场前面的车是一个具有挑战性的问题。车辆的自动系统预计将接管控制和引导车辆到一个可用的停车位。这种功能利用了多个车载传感器。例如:

  • 用于检测车道标志、道路标志(停车标志、出口标志等)、其他车辆和行人的前、侧摄像头

  • 激光雷达和超声波传感器检测障碍和计算精确的距离测量

  • 超声波传感器用于障碍物检测

  • IMU和用于航迹推算的车轮编码器

车载传感器用于感知车辆周围的环境。感知的环境包括理解道路标记来解释道路规则和推断可行驶区域,识别障碍物,以及探测可用的停车位。

当车辆传感器感知世界时,车辆必须在环境中规划一条通向一个免费停车位的路径,并执行一系列控制动作,以便开车前往该位置。在这样做的同时,它必须对环境的动态变化做出反应,比如行人通过它的路径,并重新调整它的计划。

本例实现了实现这样一个系统所需的功能子集。它的重点是在环境中规划一条可行的路径,并执行遍历该路径所需的操作。本例不包括地图创建和动态避障。

环境模型

环境模型表示环境的映射。对于泊车代客系统,此地图包括可用和占用的停车位、道路标记和障碍物,如行人或其他车辆。占用图是这种形式的环境模型的一种常见表示形式。这种地图通常使用同步定位和测绘(SLAM),通过集成来自激光雷达和相机传感器的观测数据来构建。这个示例集中于一个更简单的场景,其中已经提供了地图,例如,由车辆到基础设施(V2X)系统或俯瞰整个停车场的摄像机提供。它使用一个停车场的静态地图,并假设车辆的自定位是准确的。

本例中使用的停车场示例由三个占用网格层组成。

  • 固定障碍物:这一层包括固定的障碍物,如墙壁、障碍物和停车场的边界。

  • 道路标记:这一层包含与道路标记相关的占用信息,包括停车位的道路标记。

  • 停放的车辆:这一层包含关于哪些停车位已经被占用的信息。

每一层地图都包含不同种类的障碍物,这些障碍物代表了通过它的汽车的不同危险程度。有了这个结构,每一层都可以独立地处理、更新和维护。

加载并显示三个地图层。在每一层中,暗细胞代表被占据的细胞,而亮细胞代表自由细胞。

mapLayers = loadParkingLotMapLayers;plotMapLayers (mapLayers)

为了简单起见,将这三层合并成一个单独的成本图。

costmap = combineMapLayers (mapLayers);图绘制(costmap,“通货膨胀”,“关闭”传说)

合并后的costmap是一个vehicleCostmap对象,它将车辆环境表示为一个二维占用网格。单元格中的每个网格的值都在0到1之间,表示在单元格中导航的成本。障碍物的成本较高,自由空间的成本较低。如果一个单元格的成本高于,则认为它是一个障碍OccupiedThreshold财产,如果它的成本低于免费FreeThreshold财产。

costmap占地75米乘50米的整个停车场区域,划分为0.5米乘0.5米的正方形单元。

costmap.MapExtent% [x,宽度,y,高度],单位为米costmap.CellSize单元格大小(以米为单位)
ans = 0 75 0 50 ans = 0.5000

创建一个vehicleDimensions对象,用于存储自动停车的车辆的尺寸。还要定义车辆的最大转向角。这个值决定了在运动规划和控制过程中转弯半径的限制。

vehicleDims = vehicleDimensions;maxSteeringAngle = 35;%的度

更新VehicleDimensions属性的成本地图碰撞检查器与车辆的尺寸到停车。该设置调整障碍物周围地图的膨胀程度,以适应所停放车辆的大小,确保在停车场可以找到无碰撞的道路。

costmap.CollisionChecker。VehicleDimensions= vehicleDims;

定义车辆的起始姿势。这个位姿是通过定位获得的,为了简单起见,本例中省略了定位。车辆姿态指定为,在世界坐标中。表示车辆后轴中心在世界坐标系中的位置。表示车辆相对于世界X轴的方向。有关更多细节,请参见自动驾驶工具箱中的坐标系统

currentPose = [4 12 0];% [x, y, theta]

行为层

计划包括将所有相关信息组织成层次结构。每个连续的层负责一个更细粒度的任务。行为层[1]位于这个堆栈的顶部。它负责通过提供一系列导航任务来激活和管理任务的不同部分。行为层从系统所有相关部分收集信息,包括:

  • 定位:行为层检查定位模块,以估计车辆的当前位置。

  • 环境模型:感知和传感器融合系统报告车辆周围环境的地图。

  • 确定停车位:行为层分析地图以确定最近的可用停车位。

  • 查找全局路由:路由模块计算通过从映射服务或V2X基础设施获得的公路网的全局路由。将全球路线分解为一系列的道路链接,可以对每个链接的轨迹进行不同的规划。例如,最后的停车机动要求不同于接近停车位的速度曲线。在更一般的情况下,这对于在有不同限速、车道数和路标的街道上行驶至关重要。

本例没有使用车辆传感器来构建环境地图,而是使用了一个通过V2X通信来自智能停车场的地图。为简单起见,假设该地图采用占用网格的形式,并由V2X提供道路链接和可用停车位的位置。

HelperBehavioralPlanner类模拟行为规划层的接口。的HelperBehavioralPlanner使用地图和全局路由计划创建。本例使用存储在MATLAB表中的静态全局路由计划,但通常由本地停车基础设施或映射服务提供的路由算法确定此计划。全局路线计划被描述为一组车道段,这些车道段要穿越到一个停车位。

加载包含存储在表中的路由计划的mat文件。该表有三个变量:StartPose,EndPose,属性StartPoseEndPose指定段的起始和结束姿态,表示为属性指定段的属性,如速度限制。

data =负载(“routePlan.mat”);routePlan = data.routePlan% #好< NOPTS >
[1×1个结构]56 0 70 19 90[1×1个结构]70 19 90[1×1个结构]70 32 90[1×1个结构]70 32 90[1×1个结构]70 32 90 39 180[1×1个结构]

以当前姿势绘制车辆,并沿着路线计划中的每个目标绘制。

%绘制当前位置的车辆持有helperPlotVehicle (currentPose vehicleDims,“DisplayName的”,目前提出的传说)n = 1:高度(路径图)提取目标路径点vehiclePose = routePlan {n,“EndPose”};%绘制姿势legendEntry = sprintf (“目标%我”n);helperPlotVehicle (vehiclePose vehicleDims,“DisplayName的”,legendEntry);结束持有

创建行为计划者助手对象。的requestManeuver方法从行为计划者请求导航任务流,直到到达目的地。

= HelperBehavioralPlanner(routePlan, maxSteeringAngle);

车辆使用以下步骤导航每个路径段:

  1. 运动规划:使用最优快速探索随机树(RRT*)算法(pathPlannerRRT)。

  2. 路径平滑:使用样条对参考路径进行拟合,使其平滑smoothPathSpline

  3. 轨迹生成:使用以下命令生成速度配置文件,将平滑后的路径转换为轨迹helperGenerateVelocityProfile

  4. 车辆控制:给定平滑的参考路径,HelperPathAnalyzer根据当前车辆的姿态和速度计算参考位姿和速度。提供参考值,lateralControllerStanley计算转向角,以控制车辆的航向。HelperLongitudinalController计算加速和减速命令以保持所需的车辆速度。

  5. 目标检查:检查车辆是否达到了使用的最终位姿helperGoalChecker

在将这些步骤组装成完整的解决方案之前,本示例的其余部分将详细描述这些步骤。

运动规划

给定一个全局路径,运动规划可用于规划通过环境到达每个中间路径点的路径,直到车辆到达最终目的地。每个环节的规划路径必须是可行的和无碰撞的。一个可行的路径是一个可以实现的车辆给定的运动和动态约束施加在它。代客泊车系统涉及低速和低加速度。这使我们可以安全地忽略由惯性效应引起的动态约束。

创建一个pathPlannerRRT对象使用最优快速探索随机树(RRT*)方法配置路径规划器。RRT家族的规划算法通过构建一个连接的、无碰撞的车辆姿态树来寻找路径。位姿通过Dubins或reed - shepp转向系统进行连接,确保生成的路径在运动学上是可行的。

motionPlanner = pathPlannerRRT (costmap,“MinIterations”,1000,“ConnectionDistance”10“MinTurningRadius”,20);

使用。来计划从当前姿势到第一个目标的路径计划函数。返回的driving.Path对象,refPath,是一个可行的、无碰撞的参考路径。

goalPose = routePlan {1,“EndPose”};= plan(motionPlanner, currentPose, goalPose);

参考路径由一系列路径段组成。每个路径段描述用于连接到下一个段的Dubins或reed - shepp操作集。检查路径段。

refPath.PathSegments
ans = 1×6 DubinsPathSegment array with properties: StartPose GoalPose MinTurningRadius motionlength MotionTypes Length

参考路径包含沿途的过渡姿态,表示路径上与从一个机动到下一个机动相对应的点。它们还可以表示方向上的变化,例如,沿着reed - shepp路径从正向移动到反向移动。

从计划的路径中检索过渡姿态和方向。

[transitionpose, directions] =插值(refPath);可视化计划的路径情节(motionPlanner)

除了规划的参考路径外,还要注意地块上的红色区域。这些区域表示成本图的区域,其中车辆的原点(后轴的中心)必须不交叉,以避免碰撞任何障碍。pathPlannerRRT通过检查以确保生成的车辆姿态不位于这些区域,找到避开障碍物的路径。

路径平滑和轨迹生成

由路径规划器生成的参考路径由Dubins或reed - shepp段组成。这两个节段连接处的曲率不是连续的,会导致转向角的突然变化。为了避免这种不自然的运动,并确保乘客的舒适性,路径需要是连续可微的,因此平滑的[2]。平滑路径的一种方法是拟合参数三次样条。样条拟合使您能够生成控制器可以执行的平滑路径。

使用smoothPathSpline拟合参数三次样条通过参考路径中的所有过渡点。样条曲线与车辆的启动和结束航向角近似匹配。

%指定使用约0.1米的间距返回的姿态数approxSeparation = 0.1;%米numSmoothPoses =圆(refPath。长度/ approxSeparation);%返回沿光滑路径的离散姿态= smoothPathSpline(transitionpose, directions, cumlength,);绘制平滑的路径持有hSmoothPath = plot(ref(:, 1), ref(:, 2),“r”,“线宽”2,“DisplayName的”,“平滑路径”);持有

接下来,将生成的平滑路径转换为可以使用速度配置文件执行的轨迹。计算每个路径的速度剖面,作为三个阶段的序列:加速到设定的最大速度,保持最大速度和减速到一个终端速度。的helperGenerateVelocityProfile函数生成这样的速度配置文件。

指定初始速度、最大速度和最终速度,使车辆启动静止,加速到5米/秒的速度,然后停止。

maxSpeed = 5;%在米/秒startSpeed = 0;%在米/秒endSpeed = 0;%在米/秒

生成速度剖面

速度= helperGenerateVelocityProfile(方向、长度、曲率、起始速度、终止速度、最大速度);

refVelocities包含平滑路径上每个点的参考速度。绘制生成的速度剖面。

plotVelocityProfile (cumLengths、refVelocities maxSpeed)

车辆控制与仿真

参考速度,加上平滑的路径,组成了一个可行的轨道,车辆可以遵循。使用反馈控制器跟踪该轨迹。该控制器纠正了由于轮胎打滑和其它噪声来源(如定位误差)引起的轨迹跟踪误差。特别是控制器由两部分组成:

  • 横向控制:调整转向角度,使车辆沿参考路径行驶。

  • 纵向控制:在遵循参考路径时,通过控制油门和刹车来保持所需的速度。

由于这种情况涉及低速,您可以简化控制器,只考虑运动学模型。在本例中,横向控制由lateralControllerStanley函数。纵向控制由辅助系统对象™实现HelperLongitudinalController,根据比例积分定律计算加减速指令。

反馈控制器需要一个模拟器,可以使用合适的车辆模型执行所需的控制器命令。的HelperVehicleSimulatorclass使用以下运动学自行车模型来模拟这样的车辆:

在上面的方程中,表示车辆在世界坐标中的姿态。,,,分别表示后轮速度、后轮加速度、轴距、转向角。前轮位置和速度可通过以下方法获得:

关闭所有的数字closeFigures;创建车辆模拟器【翻译】(成本地图,车价);设置车辆姿态和速度vehicleSim.setVehiclePose (currentPose);currentVel = 0;vehicleSim.setVehicleVelocity (currentVel);配置模拟器来显示轨迹vehicleSim.showTrajectory(真正的);%隐藏车辆仿真图hideFigure (vehicleSim);

创建一个HelperPathAnalyzer目的计算控制器的参考位姿、参考速度和驱动方向。

热分析仪(refpose, ref, directions,)的轴距,vehicleDims.Wheelbase);

创建一个HelperLongitudinalController目标控制车辆的速度并指定采样时间。

sampleTime = 0.05;lonController = HelperLongitudinalController (“SampleTime”,sampleTime);

使用HelperFixedRate对象,以确保反馈控制器的固定速率执行。使用与纵向控制器一致的控制速率。

controlRate = HelperFixedRate (1 / sampleTime);%在赫兹

在达到目标之前,做以下事情:

  • 计算需要跟踪计划轨迹的转向和加速/减速命令。

  • 向模拟器提供控制命令。

  • 记录返回的车辆姿态和速度,以便在下一次迭代中反馈给控制器。

reachGoal = false;~ reachGoal找到路径上的参考位姿和相应的速度[refPose, refVel, direction] = pathAnalyzer(currentPose, currentVel);更新模拟器的驾驶方向updateDrivingDirection (vehicleSim、方向);%计算操舵命令(1)主句为steeringAngle,主句为currentVel,主句为currentVel。“方向”、方向、的轴距,vehicleDims.Wheelbase);计算加速和减速命令lonController。方向=方向;[accelCmd, decelCmd] = lonController(refVel, currentVel);%使用控制器输出模拟车辆驾驶(车辆、仪表、仪表、舵角);检查车辆是否达到目标reachGoal = helperGoalChecker(goalPose, currentPose, currentVel, endSpeed, direction);等待固定速率执行等待(controlRate);%得到当前的姿态和速度的车辆currentPose = getVehiclePose (vehicleSim);currentVel = getVehicleVelocity (vehicleSim);结束%显示车辆仿真图showFigure (vehicleSim);

这样就完成了路线计划的第一阶段,并演示了流程的每个步骤。接下来的部分运行整个路线的模拟器,使车辆接近停车位,最后执行停车操作将车辆放入停车位。

执行完整的计划

现在,将规划过程中前面的所有步骤合并起来,并运行完整路线规划的模拟。这个过程包含了行为计划者。

%设置车辆姿态回初始起点currentPose = [4 12 0];% [x, y, theta]vehicleSim.setVehiclePose (currentPose);%重置速度currentVel = 0;%米/秒vehicleSim.setVehicleVelocity (currentVel);~ reachedDestination (behavioralPlanner)%请求行为层下一次机动[nextGoal, plannerConfig, speedConfig] = request机动(behavioralPlanner,currentPose currentVel);配置运动规划器configurePlanner (motionPlanner plannerConfig);使用RRT* planner为下一个目标位姿规划一个参考路径refPath = plan(motionPlanner, currentPose, nextGoal);检查路径是否有效。如果规划者未能计算出路径,或由于对映射的更新,路径不是无冲突的系统需要重新计划。这个场景使用一个静态映射,也就是路径%将永远是无碰撞。isreplanneed = ~checkPathValidity(refPath, costmap);如果isReplanNeeded警告('无法找到有效的路径。试图重新计划”。)请求行为计划员重新计划replanNeeded (behavioralPlanner);继续;结束从计划的路径中检索过渡姿态和方向[transitionpose, directions] =插值(refPath);使道路平坦numSmoothPoses =圆(refPath。长度/ approxSeparation);= smoothPathSpline(transitionpose, directions, cumlength,);生成速度剖面速度= helperGenerateVelocityProfile(方向、长度、曲率、起始速度、终止速度、最大速度);%配置路径分析器pathAnalyzer。RefPoses = RefPoses;pathAnalyzer。方向=方向;pathAnalyzer。VelocityProfile = refVelocities;复位纵向控制器重置(lonController);reachGoal = false;执行控制循环~ reachGoal找到路径上的参考位姿和相应的速度[refPose, refVel, direction] = pathAnalyzer(currentPose, currentVel);更新模拟器的驾驶方向updateDrivingDirection (vehicleSim、方向);%计算操舵命令(1)主句为steeringAngle,主句为currentVel,主句为currentVel。“方向”、方向、的轴距,vehicleDims.Wheelbase);计算加速和减速命令lonController。方向=方向;[accelCmd, decelCmd] = lonController(refVel, currentVel);%使用控制器输出模拟车辆驾驶(车辆、仪表、仪表、舵角);检查车辆是否达到目标reachGoal = helperGoalChecker(nextGoal, currentPose, currentVel, speedConfig)。EndSpeed、方向);等待固定速率执行等待(controlRate);%得到当前的姿态和速度的车辆currentPose = getVehiclePose (vehicleSim);currentVel = getVehicleVelocity (vehicleSim);结束结束%显示车辆仿真图showFigure (vehicleSim);

停车操作

既然车辆已经接近停车位,就可以使用专门的停车策略将车辆停在最后的停车位上。这个动作需要穿过一个狭窄的走廊,两边都是停车位的边缘。这种操作通常伴随着超声波传感器或激光扫描仪不断检查障碍。

%隐藏车辆仿真图hideFigure (vehicleSim);

vehicleCostmap使用基于膨胀的冲突检查。首先,目视检查当前使用的冲突检查器。

ccConfig = costmap.CollisionChecker;图绘制(ccConfig)标题(“当前的碰撞检查器”)

碰撞检查是通过膨胀半径在costmap中膨胀障碍物来执行的,并检查上面显示的圆的中心是否位于一个膨胀的网格单元上。最后的停车机动需要一个更精确、更少保守的碰撞检测机制。这通常是通过使用多个(3-5)重叠的圆圈而不是单个圆圈来表示车辆的形状来解决的。

在冲突检查器中使用更多的圆圈,并可视地检查冲突检查器。这样就可以通过狭窄的通道进行规划。

ccConfig。NumCircles = 4;图绘制(ccConfig)标题(“新碰撞检查器”)

更新成本地图来使用这个冲突检查器。

costmap。CollisionChecker = ccConfig;

请注意,膨胀半径已经减少,允许规划师找到一个畅通无阻的路径到停车位。

图绘制(costmap)标题(“更新冲突检查的成本地图”)设置pathPlannerRRT以使用更新的成本图parkMotionPlanner = pathPlannerRRT (costmap,“MinIterations”,1000);定义所需的姿势为停车位,由V2X系统返回parkPose = [36 44 90];preParkPose = currentPose;计算所需的停车机动= plan(parkMotionPlanner,准备姿势,parkPose);%绘制结果停车机动figure plotparking机动(costmap, refPath, preparekpose, parkPose)

一旦发现机动,重复前面的步骤来确定一个完整的计划:平滑路径,生成速度剖面,使用反馈控制器跟踪轨迹。

从计划的路径中检索过渡姿态和方向[transitionpose, directions] =插值(refPath);使道路平坦numSmoothPoses =圆(refPath。长度/ approxSeparation);= smoothPathSpline(transitionpose, directions, cumlength,);设置速度剖面发生器在轨迹结束时停止,限速为每小时5英里速度= helperGenerateVelocityProfile(方向、长度、曲率、电流等);pathAnalyzer。RefPoses = RefPoses;pathAnalyzer。方向=方向;pathAnalyzer。VelocityProfile = refVelocities;复位纵向控制器重置(lonController);reachGoal = false;~ reachGoal找到路径上的参考位姿和相应的速度[refPose, refVel, direction] = pathAnalyzer(currentPose, currentVel);更新模拟器的驾驶方向updateDrivingDirection (vehicleSim、方向);%计算操舵命令(1)主句为steeringAngle,主句为currentVel,主句为currentVel。“方向”、方向、的轴距,vehicleDims.Wheelbase);计算加速和减速命令lonController。方向=方向;[accelCmd, decelCmd] = lonController(refVel, currentVel);%使用控制器输出模拟车辆驾驶(车辆、仪表、仪表、舵角);检查车辆是否达到目标reachGoal = helperGoalChecker(parkPose, currentPose, currentVel, 0, direction);等待固定速率执行等待(controlRate);%得到当前的姿态和速度的车辆currentPose = getVehiclePose (vehicleSim);currentVel = getVehicleVelocity (vehicleSim);结束%显示车辆仿真图closeFigures;showFigure (vehicleSim);

另一种停车方式是回到停车位。当车辆需要倒车到某一位置时,运动规划器需要使用reed - shepp连接方法寻找可行路径。Reeds-Shepp连接允许在规划期间进行反向运动。

指定与倒车泊车动作相对应的泊车姿势parkPose = [49 47 -90];改变连接方式,允许反向运动parkMotionPlanner。ConnectionMethod =“Reeds-Shepp”;

为了找到一个可行的路径,运动规划器需要调整。使用更大的转弯半径和连接距离,以实现平滑的后入。

parkMotionPlanner。MinTurningRadius = 10;%米parkMotionPlanner。ConnectionDistance = 15;复位车辆姿态和速度currentVel = 0;vehicleSim.setVehiclePose (preParkPose);vehicleSim.setVehicleVelocity (currentVel);计算停车机动重新计划= true;replan refPath = plan(parkMotionPlanner, prepare kpose, parkPose);与停车机动相对应的路径小且要求大%精确的操纵。而不是只在过渡的姿势内插,沿路径长度进行更精细的内插。numSamples = 10;stepSize = refPath。长度/ numSamples;length = 0: stepSize: refPath.Length;[transitionpose, directions] =插值(refPath,长度);如果路径包含多个方向切换姿势,则重新计划%或如果路径太长replan = sum(abs(diff(directions)))~=2 || refPath。长度> 20;结束想象停车的动作figure plotparking机动(costmap, refPath, preparekpose, parkPose)

铺平道路

numSmoothPoses =圆(refPath。长度/ approxSeparation);= smoothPathSpline(transitionpose, directions, numsmoothpose, 0.5);生成速度剖面速度= helperGenerateVelocityProfile(方向、长度、曲率、电流等);pathAnalyzer。RefPoses = RefPoses;pathAnalyzer。方向=方向;pathAnalyzer。VelocityProfile = refVelocities;复位纵向控制器重置(lonController);reachGoal = false;~ reachGoal得到当前的驱动方向currentDir = getDrivingDirection (vehicleSim);找到路径上的参考位姿和相应的速度。[refPose, refVel, direction] = pathAnalyzer(currentPose, currentVel);%若车辆改变行驶方向,则复位车辆速度in模拟器和复位纵向控制器如果currentDir ~=方向电流= 0;setVehicleVelocity (vehicleSim currentVel);重置(lonController);结束更新模拟器的驾驶方向。如果车辆改变%行驶方向,复位,返回当前车辆速度为零。currentVel = updateDrivingDirection(vehicle, direction, currentDir);%计算操舵命令(1)主句为steeringAngle,主句为currentVel,主句为currentVel。“方向”、方向、的轴距,vehicleDims.Wheelbase);计算加速和减速命令lonController。方向=方向;[accelCmd, decelCmd] = lonController(refVel, currentVel);%使用控制器输出模拟车辆驾驶(车辆、仪表、仪表、舵角);检查车辆是否达到目标reachGoal = helperGoalChecker(parkPose, currentPose, currentVel, 0, direction);等待固定速率执行等待(controlRate);%得到当前的姿态和速度的车辆currentPose = getVehiclePose (vehicleSim);currentVel = getVehicleVelocity (vehicleSim);结束以快照为例closeFigures;snapnow;%删除模拟器删除(vehicleSim);

结论

这个例子演示了如何:

  1. 使用RRT*路径规划算法在半结构化环境(如停车场)中规划可行路径。

  2. 使用样条平滑路径,并沿着平滑路径生成速度剖面。

  3. 控制车辆以所需速度沿参考路径行驶。

  4. 通过使用不同的运动规划器设置来实现不同的停车行为。

参考文献

[1] Buehler, Martin, Karl Iagnemma,和Sanjiv Singh。DARPA城市挑战赛:城市交通中的自动驾驶汽车(第1版)。施普林格出版公司,股份有限公司,2009年。

考虑加速度限制的时间最优路径规划。机器人和自动系统。第45卷,第3-4期,2003年,第199-210页。

万博1manbetx支持功能

loadParkingLotMapLayers为停车场加载环境地图层

函数mapLayers = loadParkingLotMapLayers ()% loadParkingLotMapLayers%负荷占用图对应的3层-障碍,道路标记和使用过的斑点。mapLayers。StationaryObstacles = imread (“stationary.bmp”);mapLayers。路标= imread (“road_markings.bmp”);mapLayers。ParkedCars = imread (“parked_cars.bmp”);结束

plotMapLayers包含地图层的Plot结构

函数plotMapLayers (mapLayers)% plotMapLayers在一个图形窗口中绘制多个地图层。figure cellOfMaps = cellfun(@ im补体,struct2cell(maplayer),“UniformOutput”、假);蒙太奇(cellOfMaps“大小”[1元素个数(cellOfMaps)),“边界”,5 [5],“ThumbnailSize”, [300 NaN])标题(“地图图层-固定的障碍物、道路标记和停放的车辆”)结束

combineMapLayers将地图图层合并成一个单独的成本地图

函数costmap = combineMapLayers (mapLayers)% combineMapLayers将地图层结构合并成一个单独的汽车地图。combinedMap = mapLayers。StationaryObstacles + mapLayers。路标+mapLayers.ParkedCars;combinedMap = im2single (combinedMap);res = 0.5;%米costmap = vehicleCostmap (combinedMap,“CellSize”res);结束

configurePlanner使用指定的设置配置路径规划器

函数configurePlanner (pathPlanner配置)% configurePlanner配置路径规划器对象,路径规划器,设置指定%在结构配置。=字段字段名(配置);n = 1: numel(字段名)如果~ strcmpi(字段名{n},“IsParkManeuver”) pathPlanner.(fieldNames{n}) = config.(fieldNames{n});结束结束结束

plotVelocityProfile情节速度剖面

函数plotVelocityProfile (cumPathLength、refVelocities maxSpeed)% plotVelocityProfile绘制生成的速度剖面%绘制参考速度沿路径长度情节(cumPathLength refVelocities,“线宽”2);绘制一条线来显示最大速度持有线([0;cumPathLength(结束)],[maxSpeed; maxSpeed],“颜色”,“r”)举行设置轴限制缓冲= 2;xlim ([0 cumPathLength(结束)]);ylim([0 maxSpeed + buffer])%添加标签包含(“累积路径长度(m)”);ylabel (“速度(米/秒)”);添加图例和标题传奇(“速度剖面”,的最高速度)标题(生成速度剖面的)结束

closeFigures

函数closeFigures ()关闭所有的数字,除了模拟器的可视化找到所有的图形对象figHandles = findobj (“类型”,“图”);i = 1:长度(fight andles)如果~ strcmp (figHandles . name(我),“自动代客泊车”)密切(figHandles (i));结束结束结束

plotParkingManeuver在成本图上显示生成的停车操作

函数plotparking机动(costmap, refPath, currentPose, parkPose)% plotParkingManeuver%在成本地图上绘制生成的停车机动。绘制成本图,不包括膨胀的区域。情节(costmap“通货膨胀”,“关闭”)在成本地图上的地块参考停车机动持有情节(refPath“DisplayName的”,“停车策略”)标题(“停车策略”)通过设置轴向限制,可缩放到停车机动lo = min ([currentPose (1:2);parkPose (1:2)]);你好= max ([currentPose (1:2);parkPose (1:2)]);缓冲= 6;%米xlim([lo(1)-buffer hi(1)+buffer]) ylim([lo(2)-buffer hi(2)+buffer])结束

另请参阅

功能

对象

相关的话题