这个例子展示了如何在不同的环境下建立不同的机器人运动学模型并进行比较。
有许多方法来移动机器人的运动学模型。所有决定了车轮速度如何与机器人状态:[X Y的2θ
作为xy -坐标和机器人的航向,THETA
在弧度。
最简单的表示移动机器人车辆运动学的方法是使用独轮车模型,该模型通过围绕中心轴的旋转来设定车轮速度,并且可以围绕z轴旋转。当输入不考虑车速和车辆航向率等约束条件时,差速器和自行车运动学模型均可简化为单轮运动学。
独轮车= unicycleKinematics (“VehicleInputs”,“VehicleSpeedHeadingRate”);
差动驱动模型使用后驱动轮轴以控制车辆速度和头速率。在驱动桥车轮可以在两个方向旋转。由于大多数移动机器人具有一些接口到低级别轮的命令,该模型将再次使用车辆速度和航向率作为输入,以简化的车辆控制。
diffDrive = differentialDriveKinematics (“VehicleInputs”,“VehicleSpeedHeadingRate”);
为了区别于独轮车模型的行为,在差速器运动学模型中增加了车轮速度速度约束
diffDrive。WheelSpeedRange = [-10 10]*2*pi;
所述的自行车模型将机器人作为汽车状模型具有两个轴:一个后驱动桥,和一前桥,大约z轴匝。假设在每个车轴的车轮可以被建模为一个单一的,中心轮下的自行车模型的工作原理,并且该前轮标题可以直接设置,像自行车。
自行车= bicycleKinematics(“VehicleInputs”,“VehicleSpeedHeadingRate”,“MaxSteeringAngle”,PI / 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 THETA)
车辆使用一个纯追踪控制器跟随一组航路点。给定一组路径点、机器人当前状态和一些其他参数,控制器输出车辆速度和航向速率。
%定义的控制器。每个机器人都需要有自己的控制器控制器1 = controllerPurePursuit(“锚点”锚点,“DesiredLinearVelocity”3,“MaxAngularVelocity”,3 *π);controller2 = controllerPurePursuit (“锚点”锚点,“DesiredLinearVelocity”3,“MaxAngularVelocity”,3 *π);controller3 = controllerPurePursuit(“锚点”锚点,“DesiredLinearVelocity”3,“MaxAngularVelocity”,3 *π);
该机型使用的是模拟衍生物
功能来更新状态。此示例使用常微分方程(ODE)求解,以产生溶液。另一种方式是使用一个循环来更新状态,如图中路径跟踪的差分驱动机器人。
由于ODE求解器要求将所有输出作为单个输出提供,因此纯跟踪控制器必须封装在一个函数中,该函数将线速度和航向角速度作为单个输出输出。助手一个例子,exampleHelperMobileRobotController
,用于该目的。示例助手还确保机器人在目标的指定半径内停止。
goalPoints =路标点(最终,:)”;goalRadius = 1;
数值
为每种类型的模型调用一次。导数函数计算初始状态为的状态输出initPose
。每个导数接受相应的运动学模型对象、当前机器人位姿以及控制器在该位姿下的输出。
%计算轨迹的运动控制下的每个运动模型[tUnicycle, unicyclePose] =数值(@ (t, y)导数(独轮车,y, exampleHelperMobileRobotController(管理员一y goalPoints goalRadius)), tVec, initPose);[tBicycle, bicyclePose] =数值(@ (t, y)导数(自行车,y, exampleHelperMobileRobotController (controller2 y goalPoints goalRadius)), tVec, initPose);[tDiffDrive, diffDrivePose] =数值(@ (t, y)导数(diffDrive y exampleHelperMobileRobotController (controller3 y goalPoints goalRadius)), tVec, initPose);
在ODE求解器的结果可以在单个情节使用容易地观察plotTransforms
可视化所有的轨迹上的结果。
姿势输出必须先被转换为翻译和四元数的索引矩阵。
unicycleTranslations = [unicyclePose(:,1:2)零(长度(unicyclePose),1)];unicycleRot = axang2quat([repmat([0 0 1],长度(unicyclePose),1)unicyclePose(:,3)]);bicycleTranslations = [bicyclePose(:,1:2)零(长度(bicyclePose),1)];bicycleRot = axang2quat([repmat([0 0 1],长度(bicyclePose),1)bicyclePose(:,3)]);diffDriveTranslations = [diffDrivePose(:,1:2)零(长度(diffDrivePose),1)];diffDriveRot = axang2quat([repmat([0 0 1],长度(diffDrivePose),1)diffDrivePose(:,3)]);
接着,将组中的所有变换可以绘制和从顶部看。独轮车,自行车,和差分驱动机器人的路径分别为红色,蓝色和绿色。为了简化图,只显示每十输出。
图图(航点(:,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)