主要内容

ackermannKinematics

汽车式转向车辆模型

描述

ackermannKinematics创建一个类似汽车的车辆模型,使用Ackermann转向。这个模型代表了一辆车,两个车轴之间有距离,轴距.车辆状态定义为四元矢量,[X y,全球xy-位置,单位为米。的xy-position位于后桥中间。标题,θ,和转向角度,ψ以弧度表示。车辆头被定义在后轴的中心。角度是以弧度为单位的。要计算模型的时间导数状态,使用导数功能与输入转向命令和当前的机器人状态。

创建

描述

例子

kinematicModel= ackermannKinematics创建具有默认属性值的Ackermann运动学模型对象。

kinematicModel= ackermannKinematics(名称,值)将附加属性设置为指定值。您可以以任何顺序指定多个属性。

属性

全部展开

轮距是指前后轴之间的距离,以米为单位。

车辆速度范围是一个二元向量,它提供了最小和最大的车辆速度,[MinSpeed MaxSpeed,单位为米每秒。

对象的功能

导数 车辆状态的时间导数

例子

全部折叠

这个例子展示了如何在一个环境中建立不同的机器人运动学模型并进行比较。

定义带有运动学约束的移动机器人

建立移动机器人运动学模型的方法有很多种。所有这些都说明了车轮速度与机器人状态之间的关系:(x yθ),因为xy -坐标和机器人的航向,θ在弧度。

独轮车运动模型

描述移动机器人车辆运动学最简单的方法是使用独轮车模型,它的车轮速度由绕中心轴旋转设定,并且可以绕其z轴旋转。在不考虑其他约束条件的情况下,差速驱动和自行车运动学模型均可简化为独轮车运动学模型。

独轮车= unicycleKinematics (“VehicleInputs”“VehicleSpeedHeadingRate”);

差动传动运动学模型

差动驱动模型使用一个后桥来控制车辆速度和头部速度。驱动桥上的轮子可以双向旋转。由于大多数移动机器人都有一些接口的低级车轮命令,该模型将再次使用车辆速度和头率作为输入,以简化车辆控制。

diffDrive = differentialDriveKinematics (“VehicleInputs”“VehicleSpeedHeadingRate”);

为了区别于独轮车模型的行为,在差动驱动运动学模型中添加一个车轮速度约束

diffDrive。WheelSpeedRange = [-10 10]*2*pi;

自行车运动模型

自行车模型将机器人视为带有两个轴的汽车模型:一个后驱桥和一个绕z轴旋转的前桥。自行车模型的工作前提是,每个轴上的车轮可以建模为一个单一的、居中的车轮,并且前轮头可以像自行车一样直接设置。

自行车= bicycleKinematics (“VehicleInputs”“VehicleSpeedHeadingRate”“MaxSteeringAngle”π/ 8);

其他模型

Ackermann运动学模型是一种假设Ackermann转向的改进型汽车模型。在大多数类似汽车的车辆中,前轮不是绕着同一轴转动,而是绕着稍微不同的轴转动,以确保它们围绕车辆转弯的中心处于同心圆上。这种转弯角度的差异被称为阿克曼转向,通常是由实际车辆中的机械装置强制执行的。从车辆和车轮运动学的角度来看,它可以通过将转向角度作为速率输入来实现。

汽车式样= 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控制器跟随一组路标。给定一组路点、机器人当前状态和其他一些参数,控制器输出车速和航向率。

%定义控制器。每个机器人都需要自己的控制器管理员一= controllerPurePursuit (“锚点”锚点,“DesiredLinearVelocity”3,“MaxAngularVelocity”, 3 *π);controller2 = controllerPurePursuit (“锚点”锚点,“DesiredLinearVelocity”3,“MaxAngularVelocity”, 3 *π);controller3 = controllerPurePursuit (“锚点”锚点,“DesiredLinearVelocity”3,“MaxAngularVelocity”, 3 *π);

使用ODE求解器模拟模型

模型采用导数命令,更新状态。这个例子使用一个常微分方程(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) zeros(length(unicyclePose),1)];unicycleRot = axang2quat([repmat([0 0 1],length(unicyclePose),1) unicyclePose(:,3)]);bicycleTranslations = [bicyclePose(:,1:2) 0 (length(bicyclePose),1)];双环自行车= axang2quat([repmat([0 0 1],length(bicyclePose),1) bicyclePose(:,3)]);diffDriveTranslations = [diffDrivePose(:,1:2) 0 (length(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)

图中包含一个轴对象。axis对象包含493个类型为patch, line的对象。

模拟一个使用Ackermann转向的移动机器人模型,并对其转向角度进行约束。在仿真过程中,模型在达到转向极限后仍保持最大转向角。为了观察转向饱和的效果,您可以比较两个机器人的轨迹,一个有转向角度约束,另一个没有任何转向约束。

定义模型

定义Ackermann运动学模型。在这种类似汽车的模型中,前轮之间的距离是给定的。为了确保它们是同心圆,车轮有不同的转向角度。当转向时,前轮以转向角度变化率接收转向输入。

汽车式样= ackermannKinematics;

设置仿真参数

设定移动机器人遵循恒定的线速度,接收恒定的转向速率作为输入。对受约束的机器人进行长时间仿真,以验证转向饱和。

velo = 5;等线速度psidot = 1;恒定左转向速率定义总时间和采样率sampleTime = 0.05;%采样时间[s]timeEnd1 = 1.5;%无约束机器人仿真结束时间timeEnd2 = 10;%受限机器人仿真结束时间tVec1 = 0: sampleTime: timeEnd1;%无约束机器人时间数组tVec2 = 0: sampleTime: timeEnd2;%受限机器人时间数组initPose = (0, 0, 0, 0);初始姿态(x y)

为ODE求解器创建选项结构

在这个例子中,你传递一个选项结构作为ODE求解器的参数。的选项结构包含有关转向角度限制的信息。创建选项结构,使用事件选择odeset创建的事件函数,detectSteeringSaturationdetectSteeringSaturation设置最大转向角度为45度。

,以说明如何定义detectSteeringSaturation,请参阅定义事件函数在这个例子的最后。

选择= odeset (“事件”, @detectSteeringSaturation);

用ODE求解器模拟模型

接下来,使用导数函数和ODE求解器,数值,求解模型并生成解。

%模拟无约束机器人[t1,pose1] = ode45(@(t,y)derivative(carLike,y,[velo psidot]),tVec1,initPose); / /初始化%模拟受限机器人[t2,pose2,te,ye,ie] = ode45(@(t,y)derivative(carLike,y,[velo psidot]),tVec2,initPose,options);

检测转向饱和

当模型达到转向极限时,它注册事件的时间戳。达到极限所花费的时间被存储在te

如果te < timeEnd2 str1 =“转向角度极限达到”;str2 =“秒”;Comp = str1 + te + str2;disp (comp)结束
转向角极限达到0.785秒

用新的初始条件模拟约束机器人

现在以积分结束前受约束机器人的状态作为第二次仿真的初始条件。修改输入向量以表示转向饱和度,即设置转向速率为零。

saturatedPsiDot = 0;饱和后转向率%cds = [velo饱和psidot];%命令向量tVec3 = te: sampleTime: timeEnd2;%的时间向量pose3 = pose2(长度(pose2):);[t3,pose3,te3,ye3,ie3] = ode45(@(t,y)derivative(carLike,y,cmds), tVec3,pose3, options);

阴谋的结果

绘制机器人使用的轨迹情节和存储的数据姿势。

图(1)情节(pose1 (: 1), pose1 (:, 2),“——r”“线宽”2);持有;情节([pose2 (: 1);pose3(: 1)]、[pose2 (:, 2); pose3 (:, 2)),‘g’);标题(“轨迹x - y”)包含(“X”) ylabel (“Y”)传说(“无约束的机器人”“限制机器人”“位置”“西北”)轴平等的

图中包含一个轴对象。标题为轨迹X-Y的轴对象包含两个类型为line的对象。这些对象分别代表无约束机器人和受约束机器人。

达到转向极限后,无约束机器人沿曲率半径减小的螺旋轨迹运动,约束机器人沿曲率半径恒定的圆形轨迹运动。

定义事件函数

设置事件函数,使积分在第4状态theta等于最大转向角度时终止。

函数[state, isterterminal,direction] = detectSteeringSaturation(t,y) maxSteerAngle = 0.785;%最大转向角(pi/4弧度)state(4) = (y(4) - maxSteerAngle);当第4状态theta等于最大转向角度时,%发生饱和事件isterminal (4) = 1;事件发生时,集成终止方向(4)= 0;%双向终止结束

参考文献

林奇、凯文·M和弗兰克·c·帕克。现代机器人技术:机械、计划和控制第1版,马萨诸塞州剑桥:剑桥大学出版社,2017。

扩展功能

C / c++代码生成
使用MATLAB®Coder™生成C和c++代码。

介绍了R2019b