移动机器人不同运动模型的仿真
这个例子展示了如何在一个环境中建模不同的机器人运动学模型并进行比较。
定义具有运动约束的移动机器人
有许多方法可以建立移动机器人的运动学模型。所有这些都说明了车轮速度与机器人状态的关系:[x y theta]
,因为xy -坐标和机器人标题,θ
,以弧度表示。
独轮车运动学模型
表示移动机器人车辆运动学最简单的方法是用独轮车模型,它的轮速由围绕中心轴旋转设定,并可以绕其z轴旋转。差分驱动和自行车运动学模型在不考虑车速和车首速等约束条件的情况下,均归结为独轮车运动学模型。
独轮车= unicycle运动学(“VehicleInputs”,“VehicleSpeedHeadingRate”);
差动驱动运动学模型
差动驱动模型使用后驱动桥来控制车辆速度和扬程率。驱动桥上的轮子可以向两个方向旋转。由于大多数移动机器人都有一些与低级车轮指令的接口,该模型将再次使用车辆速度和航向速率作为输入,简化车辆控制。
微分驱动器=微分驱动器运动学(“VehicleInputs”,“VehicleSpeedHeadingRate”);
为了将其行为与独轮车模型区分开来,在差动驱动运动学模型中添加轮速速度约束
diffDrive。WheelSpeedRange = [-10 10]*2*pi;
自行车运动模型
自行车模型将机器人视为类似汽车的模型,有两个轴:一个后轴驱动轴和一个绕z轴旋转的前轴。自行车模型是在这样的假设下工作的:每个轴上的轮子可以被建模为一个单独的、居中的轮子,前轮的方向可以像自行车一样直接设定。
自行车运动学(“VehicleInputs”,“VehicleSpeedHeadingRate”,“MaxSteeringAngle”π/ 8);
其他模型
阿克曼运动学模型是一种改进的类车模型,假定阿克曼转向。在大多数类似汽车的车辆中,前轮不会绕同一轴转动,而是在稍微不同的轴上转动,以确保它们围绕车辆转弯的中心沿同心圆行驶。这种转弯角度的差异被称为阿克曼转向,在实际车辆中通常由一个机制强制执行。从车辆和车轮运动学的角度来看,它可以通过将转向角作为速率输入来强制执行。
carLike = ackermannKinematics;
设置仿真参数
这些移动机器人将遵循一组路径点,这些路径点旨在显示由不同的运动学引起的一些差异。
路点= [0 0;0 10;10 10;5 10;11日9;4 5];定义总时间和采样率sampleTime = 0.05;%采样时间[s]tVec = 0:sampleTime:20;%时间数组initPose =[路径点(1,:)';0);%初始位姿(x y)
创建一个车辆控制器
车辆使用Pure Pursuit控制器沿着一组路径点行驶。给定一组路径点、机器人当前状态和一些其他参数,控制器输出车辆速度和航向速率。
定义控制器。每个机器人都需要自己的控制器controller1 = controllerPurePursuit(“锚点”锚点,“DesiredLinearVelocity”3,“MaxAngularVelocity”, 3 *π);controller2 = controllerPurePursuit(“锚点”锚点,“DesiredLinearVelocity”3,“MaxAngularVelocity”, 3 *π);controller3 = controllerPurePursuit(“锚点”锚点,“DesiredLinearVelocity”3,“MaxAngularVelocity”, 3 *π);
使用ODE求解器模拟模型
对模型进行了模拟导数
函数更新状态。本例使用常微分方程(ODE)求解器来生成一个解。另一种方法是使用循环更新状态,如差动驱动机器人的路径跟踪.
由于ODE求解器要求将所有输出作为单个输出提供,因此纯追击控制器必须封装在将线速度和航向角速度输出为单个输出的函数中。一个helper的例子,exampleHelperMobileRobotController
是用于那个目的的。示例助手还确保机器人在目标的指定半径内停止。
goalPoints =路点(end,:)';goalRadius = 1;
数值
为每种类型的模型调用一次。导数函数计算初始状态为的状态输出initPose
.每个导数接受相应的运动学模型对象,当前机器人姿态,以及该姿态控制器的输出。
计算运动控制下每个运动学模型的轨迹[tUnicycle,unicyclePose] = ode45(@(t,y)derivative(unicycle,y,exampleHelperMobileRobotController(controller1,y,goalPoints,goalRadius)),tVec,initPose);[tbike,bicyclePose] = ode45(@(t,y)derivative(bicycle,y,exampleHelperMobileRobotController(controller2,y,goalPoints,goalRadius)),tVec,initPose);[tDiffDrive,diffDrivePose] = ode45(@(t,y)derivative(diffDrive,y,exampleHelperMobileRobotController(controller3,y,goalPoints,goalRadius)),tVec,initPose);
阴谋的结果
ODE求解器的结果可以很容易地在单个图上查看plotTransforms
将所有轨迹的结果同时可视化。
姿态输出必须首先转换为平移和四元数的索引矩阵。
unicycleTranslations = [unicyclePose(:,1:2) 0(长度(unicyclePose),1)];unicycleot = axang2quat([repmat([0 0 1],length(unicyclePose),1) unicyclePose(:,3)]);bicycleTranslations =[自行车姿势(:,1:2)零(长度(自行车姿势),1)];bicycleRot = axang2quat([repmat([0 0 1],length(bicyclePose),1) bicyclePose(:,3)]);diffDriveTranslations = [diffDrivePose(:,1:2)零(长度(diffDrivePose),1)];diffDriveRot = axang2quat([repmat([0 0 1],length(diffDrivePose),1) diffDrivePose(:,3)]);
接下来,可以绘制所有转换的集合并从顶部查看。独轮车机器人、自行车机器人和差动机器人的路径分别为红色、蓝色和绿色。为了简化图,只显示每10个输出。
图绘制(锚点(:1),锚点(:,2),“kx - - - - - -”,“MarkerSize”, 20);持有所有plotTransforms (unicycleTranslations (1:10:,:), unicycleRot(1:10:最终,),“MeshFilePath”,“groundvehicle.stl”,“MeshColor”,“r”);plotTransforms (bicycleTranslations (1:10:,:), bicycleRot(1:10:最终,),“MeshFilePath”,“groundvehicle.stl”,“MeshColor”,“b”);plotTransforms (diffDriveTranslations (1:10:,:), diffDriveRot(1:10:最终,),“MeshFilePath”,“groundvehicle.stl”,“MeshColor”,“g”);视图(0,90)