Webots教程(根据官网教程)

Webots教程

  • 1.上手
    • 创建新世界
    • 添加节点
    • 添加电子冰球机器人
    • 创建一个新的控制器
    • 总结
  • 2.修改环境
    • 实体节点
    • 创建一个球
    • DEF-USE Mechanism(定义机制)
    • 添加墙
    • 总结
  • 3.外观
    • Light(灯光)
    • 修改墙的外观
    • 向球添加纹理
    • Rendering Options(渲染选项)
    • 总结
  • 4.有关控制器的更多信息
    • 了解电子冰球模型
    • 编程控制器
  • 5.Compound Solid and Physics Attributes(复合固体和物理属性)
    • 物理属性
    • 旋转场
    • basicTimeStep,ERP和CFM
    • 结论
  • 6.四轮机器人
    • Separating the Robot in Solid Nodes
    • HingeJoint
    • 感测器
    • Controller
    • 动起来啦!!!

1.上手

创建新世界

一个世界是包含像对象是一个信息的文件,他们的样子,它们如何相互影响,天空是什么,如何定义重力,摩擦力,物体的质量,等它定义的颜色模拟的初始状态。不同的对象称为“ 节点(Node)”,并在“ 场景树”中进行分层组织。因此,一个节点可能包含子节点。世界存储在具有.wbt扩展名的文件中。文件格式源自VRML97语言,并且易于阅读。世界文件必须直接存储在名为的目录中worlds。

可以文件-新世界或者是向导(Wizard)-新项目目录
两个建新世界的不同处在于:前一个的啥都没有,右边的基础的比如光线啥的已经给你配置好了。以右边的为例,建完后有如下节点自动建成:
Webots教程(根据官网教程)_第1张图片
WorldInfo:包含模拟的全局参数,一般不修改。
Viewpoint:定义主要视点相机参数。
TexturedBackground:定义场景的背景(如果稍微旋转视点,您应该看到远处的山脉)
TexturedBackroundLight:定义与上述背景关联的光。

添加节点

点击加号(若加号为灰色,先点击3D窗口或者把所有的Node全部折叠,不要展开),此处选择RectangleArena。
在这里插入图片描述
每个节点都有一些可定制的属性,称为Fields,双击RectangleArena或点击前面的箭头即可打开,可以在此更改一些参数。
Webots教程(根据官网教程)_第2张图片

注:可以Ctrl-C,Ctrl-V复制Node,具体什么能复制还在摸索,反正这个RectangleArena不行,而box之类的是可以的。
可以按住Shift并单击来拖动新框(平移),也可以使用旋转手柄移动对象(坐标轴)
Shift+鼠标中间键:铅直移动物体
Shift+鼠标右键:沿xyz轴旋转物体,连续按下shift键,旋转轴会在XYZ依次轮换。
Alt+鼠标左键:添加一个力(仿真运行时才有反应)
Alt+鼠标右键:添加一个力矩(仿真运行时才有反应)

添加电子冰球机器人

e-puck是一款小型机器人,带有差速轮,10个LED和几个传感器,其中包括8个DistanceSensors和一个Camera。在本教程中,我们仅对使用其轮子感兴趣。在接下来的教程中,我们将学习如何使用其他功能。

现在,我们将向世界添加一个电子冰球模型。确保模拟已暂停并且虚拟时间为0。如果不是这种情况,请使用Reset按钮(rewind)重置模拟。
当修改Webots世界以进行保存时,首先要暂停模拟并将其重新加载到其初始状态,即从根本上讲,即主工具栏上的虚拟时间计数器应显示0:00:00:000。否则,每次保存时,每个3D对象的位置都会累积错误。因此,对世界的任何修改都应按以下顺序执行:暂停,重置,修改和保存仿真
同上,导入E-puck节点,保存模拟并按下Run real-time按钮,机器人应移动,LED闪烁并避免障碍物。这是因为它具有具有该行为的默认控制器。您可能已经注意到3D视图的左上角出现了一个黑色的小窗口。它显示了电子冰球机器人的相机拍摄的图像。该图像将保持黑色,直到由机器人的控制器明确启用相机为止。可以通过拖动来移动此小图像窗口。也可以通过拖动右下角来调整其大小。最后,可以通过单击右上角的“ x”将其关闭。您可以通过在“ 叠加设备”菜单中的“ 相机设备”子菜单中将其选中,使其再次可见(Overlays- Camera Devices)。因为我们不需要它,所以您实际上可以将其关闭。
按下Alt +左​​键单击+拖动,向wodenbox施加力。无法对节点施加力,因为默认情况下,它们没有质量并且被视为粘在地板上。要在节点上启用物理,应将其质量(mass)设置为某个值(例如0.2 kg)。完成此操作后,也应该能够对它们施加力。
现在,我们将修改世界并减少物理模拟的步骤:这将提高模拟的准确性和稳定性(但会降低最大模拟速度)。

暂停仿真并还原它。在“场景树”视图中,展开WorldInfo节点(第一个节点)。将其basicTimeStep字段设置为16。然后保存模拟。

创建一个新的控制器

现在,我们将编程一个简单的控制器,该控制器将使机器人向前移动。
控制器是一个程序,限定了机器人的行为。Webots控制器可以用以下编程语言编写:C,C ++,Java,Python,MATLAB,ROS等。C,C ++和Java控制器必须先进行编译,然后才能作为机器人控制器运行。Python和MATLAB控制器是解释性语言,因此它们无需编译即可运行。在本教程中,我们将使用Python作为参考语言,但是所有代码段也都可以在C ++,Java,C和MATLAB中获得(其他详见官网)。
节点的controller字段Robot指定当前与机器人关联的控制器。请注意,同一台控制器可以由多个机器人使用,但一个机器人一次只能使用一个控制器。 每个控制器在通常由Webots产生的单独的子进程中执行。因为它们是独立的进程,所以控制器不共享相同的地址空间,并且可以在不同的处理器内核上运行。

1.使用菜单创建一个新的Python(或其他语言)控制器e-puck_go_forward(对于C ++和Java则称为EPuckGoForward),点击Wizards / New Robot Controller…。这将在中创建一个新e-puck_go_forward(或EPuckGoForward)目录my_first_simulation/controllers。选择提供您在文本编辑器中打开源文件的选项。
2.在场景树视图中,选择节点的controller字段E-puck,然后使用“场景树”视图底部的字段编辑器:按Select…按钮,然后e-puck_go_forward在列表中选择。一旦控制器与机器人关联,就可以拯救世界。通过获取电机设备(leftMotor = robot.getMotor(‘left wheel motor’))和应用电机命令(leftMotor.setPosition(10.0))来修改程序:
3.保存修改后的源代码(File / Save Text File),重置并运行仿真。

from controller import Robot, Motor

TIME_STEP = 64

MAX_SPEED = 6.28

# create the Robot instance.
robot = Robot()

# get a handler to the motors and set target position to infinity (speed control)
leftMotor = robot.getMotor('left wheel motor')
rightMotor = robot.getMotor('right wheel motor')
leftMotor.setPosition(float('inf'))
rightMotor.setPosition(float('inf'))

# set up the motor speeds at 10% of the MAX_SPEED.
leftMotor.setVelocity(0.1 * MAX_SPEED)
rightMotor.setVelocity(0.1 * MAX_SPEED)

while robot.step(TIME_STEP) != -1:
   pass

现在,机器人将移动(轮子将以每秒1弧度的速度旋转)并且永不停止。如果没有任何反应,请不要忘记选择Build / Build菜单项或单击代码区域上方的齿轮图标来编译代码。编译错误在控制台中以红色显示。如果有,请修复它们并重试编译。然后,重新加载世界。

总结

  1. 世界由以树形结构组织的节点组成。
  2. 世界保存在.wbtWebots项目中存储的文件中。
  3. 该项目还包含定义机器人行为的机器人控制器程序。
  4. 控制器可以用C或其他语言编写。
  5. 必须先显式编译C,C ++和Java控制器,然后才能执行它们。
  6. 控制器通过节点的controller字段与机器人相关联Robot。

2.修改环境

即将学习如何在环境中创建简单对象。第一步将是创建一个与环境互动的球。我们将处理与节点有关的几个概念:它们的含义,如何创建它们,如何将它们关联在一起等等。此外,我们还将了解如何设置物理学。

实体节点

默认的RectangleArenaPROTO定义固定在静态环境上的简单地板,即没有Physics节点,并被墙壁包围。Webots对象库中提供了其他预建楼层。现在,我们将删除该RectangleArena节点,并添加一个简单的地板(floor(solid)),在本教程后面的部分中,我们将使用墙壁对其进行手动包围。

Solid节点代表一个刚体,即在其中变形可以忽略不计的主体。刚体上任意两个给定点之间的距离在时间上保持恒定,而不管施加在其上的外力如何。例如,桌子,机械手指骨或轮子是刚体。软体和关节物体不是刚体。例如,绳索,轮胎,海绵或关节式机械臂不是刚性体。但是,可以将铰接的实体分解为多个刚体。
Webots的物理引擎仅设计用于模拟刚体。设计仿真时,重要的一步是将各种实体分解为单独的刚体。
要定义刚体,必须创建一个实体节点。在此节点内,可以根据刚体的特性设置不同的子节点。下图描绘了刚体及其子节点。实体节点的图形表示由填充其列表的Shape节点定义children。碰撞范围在其boundingObject字段中定义。图形表示和碰撞形状通常但不一定相同。最后,该physics字段定义对象是属于动态环境还是属于静态环境。所有这些子节点都是可选的,但是该physics字段需要boundingObject定义。
Webots教程(根据官网教程)_第3张图片

创建一个球

添加节点-Base Nodes-Solid。在场景树视图中,展开“ 实体”节点并右键其children字段,新增一个Base Nodes-Shape节点。选择“ Shape”节点的appearance Null,然后右键新增一个节点PBRAppearance。
Webots教程(根据官网教程)_第4张图片

  1. Solid-children-右键新增一个shape
  2. Solid-children-Shape-appearance NULL-右键新增一个PBRAppearance
  3. 展开该PBRAppearance节点,并将其metalness字段更改为0,并将其roughness字段更改为1。
  4. Solid-children-Shape-geometey NULL-右键新增一个Sphere
  5. Solid-boundingObject NUll-右键新增一个Sphere
  6. Solid-physics NULL-右键新增一个physics
  7. 通过修改实体节点的translation字段,改变球体位置。

当模拟开始时,球击中地板。可以通过向球施加力来移动球(Ctrl + Alt +左​​键单击+拖动)。通过启用View / Optional Rendering / Show Contact Points菜单项,可以将球和地板之间的接触点显示为青色线。

为了定义球,我们在两个不同的上下文中使用了Sphere节点:用于图形表示(children)和定义物理边界(boundingObject)。所有Geometry节点(例如Sphere节点)都可以在图形上下文中使用。但是,它们的子集只能在物理环境中使用。

现在,我们将通过增加用于表示球体的三角形的数量来减小球体的大小并提高其图形质量。
对于每一个球体限定球节点,其设置radius于场0.05和它的subdivision字段2

该subdivision字段控制渲染球体的面数。如果该ico字段为TRUE并且该subdivision字段为0,则将球体渲染为具有20个面的二十面体。如果该subdivision字段为1(默认值),则将二十面体的每个面细分为4个面,从而产生80面的二十面体。将细分字段设置为2时,将渲染320个面,从而使球非常光滑。此细分字段允许使用最大值5(对应于20480个面),以避免非常长的渲染过程。如果该ico字段为FALSE,则将球体渲染为UV球体,并且该subdivision值必须在[3,32]范围内。在这种情况下,该subdivision字段指定将球体细分的环和线段的数量。如果subdivision字段设置为3,则球体将具有3个环和3个线段,形成9个面。将subdivision字段设置为32时,面为1024。

DEF-USE Mechanism(定义机制)

DEF-USE机制允许在一个地方定义一个节点,并在场景树在其他地方重复使用的定义。这对于避免在世界文件中重复相同的节点很有用。此外,它还允许用户同时修改多个对象。它是这样工作的:首先用DEF字符串标记节点。然后,可以使用USE关键字在其他地方重用此节点的副本。只能编辑DEF节点的字段,USE的字段从DEF节点继承,并且不能更改。此机制取决于world文件中节点的顺序。应在任何相应的USE节点之前定义DEF节点。

我们之前用来定义球的两个Sphere定义是多余的。现在,我们将使用DEF-USE机制将这两个Sphere合并为一次。
Webots教程(根据官网教程)_第5张图片

  1. 在场景树视图中选择第一个Sphere节点(Shape的子级)。
  2. 输入BALL_GEOMETRY
  3. 选择boundingObject字段(包含第二个Sphere节点),然后通过右键单击选择Reset to default value来将其清空。
  4. 选择boundingObject字段并单击Add按钮,然后选择USE- BALL_GEOMETRY。

现在,更改第一个Sphere节点的radius字段也会修改boundingObject。结构图变为下图:
Webots教程(根据官网教程)_第6张图片

添加墙

为了验证您的进度,请自己实施四堵墙以包围环境。墙壁必须相对于环境静态定义。要了解静态和动态之间的区别,让我们将定义的对象(球)放在地面上方。如果Physics节点为NULL,则在仿真过程中它将保持冻结状态(静态情况)。如果该physics字段包含“ 物理”节点,则它将属于重力作用(动态情况)。

在Shape级别而不是Geometry级别,尽可能使用DEF-USE机制。实际上,在实体节点的字段中添加中间Shape节点更为方便。实现墙的最佳几何原语是Box节点。所有墙壁仅需定义一个形状。完成如下,剩下三面墙的children右键新增后都选择USE-WALL_SHAPE。
Webots教程(根据官网教程)_第7张图片
Webots教程(根据官网教程)_第8张图片

总结

已经熟悉了Solid,Physics,Shape,Sphere和Box节点。您还看到了DEF-USE机制,该机制可减少场景树的节点冗余。

3.外观

本教程的目的是使您熟悉一些与图形渲染有关的节点。当这些节点得到充分使用时,可以非常快速地创建美观的仿真。良好的图形质量不仅可以增强用户的体验,而且对于机器人感知其环境的模拟(相机图像处理,行跟踪等)也至关重要。

Light(灯光)

世界的照明是通过确定灯节点和背景。共有三种类型的光源节点:DirectionalLight,PointLight和SpotLight。甲DirectionalLight的模拟光,其是无限远(例如:太阳),一个点光源会模拟光从一个点(例如:一个灯泡)发射,并且一个射灯模拟锥形光(例如:一个手电筒)。 此图显示了它们之间的比较。每种类型的光节点都可以投射阴影。您可以在参考手册中找到它们的完整文档。
就性能而言,灯光成本很高,并且会降低模拟速度(尤其是当它们投射阴影时)
A PointLight is more efficient than a SpotLight, but less than a DirectionalLight.

在此模拟中,Light节点在场景树中不可见,因为它包含在TexturedBackgroundLight PROTO节点中。它由DirectionalLight组成,其强度和方向是根据场景的背景自动计算的。

修改墙的外观

Shape节点的Appearance和PBRAppearance节点确定对象的图形外观。这些节点尤其负责对象的颜色和纹理。

  1. 在以图形方式表示第一面墙的Shape节点中,向该appearance字段添加一个PBRAppearance节点。
  2. baseColor使用颜色选择器将其设置为蓝色。
  3. metalness使用字段编辑器将其字段设置为0。
  4. 最后,roughness使用字段编辑器将其字段设置为0.5。
  5. 如果正确地实现了上一教程的DEF-USE机制,则所有墙都应变为蓝色。

向球添加纹理

  1. 类似地,将PBRAppearance节点添加到球中
  2. 和以前一样,将metalness字段设置为0并将roughness字段设置为1。
  3. 将一个ImageTexture节点添加到PBRAppearance节点的baseColorMap字段中。
  4. 使用按钮将一项添加到ImageTexture的url字段中Add。
  5. 然后双击url使用“选择”按钮设置图片纹理。在默认项目目录中,您将找到适用于每个世界的纹理。

Rendering Options(渲染选项)

使用View / Wireframe Rendering菜单项以线框模式查看仿真。然后恢复纯渲染模式:View / Plain Rendering

其他渲染功能可能会有所帮助:
查看坐标系统:View / Optional Rendering / Show Coordinates System (Ctrl + F1)。
查看距离传感器的光线:View / Optional Rendering / Show DistanceSensor Rays (Ctrl + F10)。

总结

在本教程中,您学习了如何使用PBRAppearance节点和light节点设置美观的环境。

4.有关控制器的更多信息

现在我们开始解决与编程机器人控制器有关的主题。我们将设计一个简单的控制器,避免前面教程中创建的障碍。

本教程将向您介绍Webots中机器人编程的基础。在本章的最后,您应该了解场景树节点和控制器API之间的链接是什么,如何初始化和清理机器人控制器,如何初始化机器人设备,如何获取传感器值,如何命令执行器,以及如何编写简单的反馈回路。

本教程仅解决Webots函数的正确用法。机器人算法的研究超出了本教程的目标,因此此处不再赘述。处理本章需要一些基本的编程知识(任何C教程都应该是足够的介绍)。在本章的最后,给出了到进一步的机器人算法的链接。

了解电子冰球模型

控制器编程需要一些与e-puck模型有关的信息。为了创建避免碰撞算法,我们需要读取位于其转塔周围的8个红外距离传感器的值,并需要致动其两个车轮。在下图中显示了距离传感器围绕转塔和e-puck方向分布的方式。
Webots教程(根据官网教程)_第9张图片
距离传感器由机器人层次结构中的8个DistanceSensor节点建模。这些节点由其name字段(从ps0到ps7)引用。稍后我们将解释如何定义这些节点。现在,仅需注意,可以通过Webots API的相关模块(通过包含文件)访问DistanceSensor节点webots/distance_sensor.h。距离传感器返回的值在0到4096之间缩放(逐段线性变化到距离)。4096表示测量到大量的光(障碍物很近),0表示没有测量到的光(没有障碍物)。
该控制器API是编程接口,让你进入机器人的模拟传感器和执行器。例如,包含webots/distance_sensor.h文件允许使用这些wb_distance_sensor_*功能,并且使用这些功能,您可以查询DistanceSensor节点的值。有关API函数的文档以及每个节点的说明,请参见《参考手册》。
Webots教程(根据官网教程)_第10张图片

编程控制器

我们想编写一个非常简单的避免碰撞行为。您将对机器人进行编程,直到前部距离传感器检测到障碍物,然后再朝无障碍物方向转向。为了做到这一点,我们将使用该图中的UML状态机中描述的简单反馈回路。

#添加与Robot,DistanceSensor和Motor节点相对应的import指令,以便能够使用相应的API
from controller import Robot, DistanceSensor, Motor

# time in [ms] of a simulation step
#定义一个变量,该变量定义每个物理步骤的持续时间。该宏将用作该Robot::step函数的参数,还将用于启用设备。此持续时间以毫秒为单位指定,并且必须是WorldInfo节点basicTimeStep字段中值的倍数。
TIME_STEP = 64

MAX_SPEED = 6.28

# create the Robot instance.
robot = Robot()

# initialize devices获取并启用距离传感器
ps = []
psNames = [
    'ps0', 'ps1', 'ps2', 'ps3',
    'ps4', 'ps5', 'ps6', 'ps7'
]

for i in range(8):
    ps.append(robot.getDistanceSensor(psNames[i]))
    ps[i].enable(TIME_STEP)

#初始化设备后初始化电机
leftMotor = robot.getMotor('left wheel motor')
rightMotor = robot.getMotor('right wheel motor')
leftMotor.setPosition(float('inf'))
rightMotor.setPosition(float('inf'))
leftMotor.setVelocity(0.0)
rightMotor.setVelocity(0.0)

# feedback loop: step simulation until receiving an exit event
while robot.step(TIME_STEP) != -1:
    # read sensors outputs读取距离传感器
    psValues = []
    for i in range(8):
        psValues.append(ps[i].getValue())

    # detect obstacles检测是否发生碰撞,即距离传感器返回的值是否大于阈值
    right_obstacle = psValues[0] > 70.0 or psValues[1] > 70.0 or psValues[2] > 70.0
    left_obstacle = psValues[5] > 70.0 or psValues[6] > 70.0 or psValues[7] > 70.0

    # initialize motor speeds at 50% of MAX_SPEED.
    leftSpeed  = 0.5 * MAX_SPEED
    rightSpeed = 0.5 * MAX_SPEED
    # modify speeds according to obstacles
    if left_obstacle:
        # turn right
        leftSpeed  += 0.5 * MAX_SPEED
        rightSpeed -= 0.5 * MAX_SPEED
    elif right_obstacle:
        # turn left
        leftSpeed  -= 0.5 * MAX_SPEED
        rightSpeed += 0.5 * MAX_SPEED
    # write actuators inputs
    leftMotor.setVelocity(leftSpeed)
    rightMotor.setVelocity(rightSpeed)

注:6.1节讲解了更多机器人编程。

5.Compound Solid and Physics Attributes(复合固体和物理属性)

compound_solid.wbt
本教程的目的是通过创建具有多个边界对象的实体来更详细地探索物理模拟:一个由两个球体和一个圆柱体组成的哑铃。

通过聚合Shape节点,可以构建比以前更复杂的Solid节点。实际上,物理和一个的图形属性固体可以由几个的形状的节点。此外,可以将每个Shape节点放置在Transform节点中,以更改其相对位置和方向。 组节点也可以用于对几个子节点进行分组。
我们要实现一个由手柄(Cylinder)和位于手柄两端的两个重物(Sphere)制成的哑铃。该图描述了实现哑铃所需的实体节点及其子节点。
Webots教程(根据官网教程)_第11张图片
Transform相当于使整个group再做了次坐标变换。

  1. 手柄的长度应为0.1 m,半径应为0.01 m。重物的半径应为0.03 m,细分(subdivision)为2。
  2. 修改两个Sphere的坐标使之在Cylinder的两边(哑铃形状)

物理属性

本小节的目的是学习如何为实体节点设置一些简单的物理属性。的物理节点包含与当前刚体(的物理字段的固体)。
固体节点的质量通过其给定density或mass字段来赋值。一次只能指定这两个字段之一(另一个应设置为-1)。当mass指定时,它定义固体的总质量([千克])。当density指定时,其值([千克/立方米])由包围物体的体积相乘,并将结果赋给固体的总质量。密度1000 [kg / m ^ 3]对应于水的密度(默认值)。
将哑铃的质量设置为2 [kg]。不使用密度,应将其设置为-1。

一个固体节点的重心被设定在其原点。可以使用centerOfMass“ 物理”节点的字段修改质心。重心是相对于Solid的原点指定的。
假设其中一个权重比另一个更重。沿y轴移动0.01[m] 的哑铃的质心。
请注意,当选择实体时,质心在3D视图中由比表示实体中心的坐标系统更暗的坐标系表示。

旋转场

“ Transform”节点的rotation字段使用欧拉轴和角度表示来确定此节点(及其子节点)的旋转。欧拉轴及角度旋转由四个部件限定。前三个分量是定义旋转轴的单位向量。第四个分量定义绕轴的旋转角度(以[rad]为单位)。旋转按照右手法则规定的意义发生。
修改哑铃的Solid节点的旋转,以使手柄的轴(y轴)平行于地面。单位轴(1, 0, 0)和π/ 2(〜1.5708)的角度是可能的解决方案。

basicTimeStep,ERP和CFM

用于物理模拟的最关键参数被存储在basicTimeStep,ERP与CFM所述的字段WorldInfo节点。

该basicTimeStep字段确定物理步骤的持续时间(以[ms]为单位)。该值越大,模拟越快,模拟越不精确。对于Webots的常规使用,我们建议使用介于8和16之间的值。

解释ERP和 CFM字段的行为更加困难。这些值由物理引擎直接用于确定如何解决约束。默认值已为常规使用Webots定义好。我们建议您阅读参考手册和ODE(Webots中使用的物理引擎)的文档,以全面了解其目的。

结论

您可以构建各种实体,包括由多个刚体组成的实体。您知道,如果Geometry Node包含在“ Transform”节点中,则可以移动和旋转它。您了解所有物理参数,可以设计可靠的模拟。下一步将是创建自己的机器人。

6.四轮机器人

4_wheels_robot.wbt
本教程的目的是从头开始创建您的第一个机器人。该机器人将由一个身体,四个轮子和两个距离传感器组成。

Separating the Robot in Solid Nodes

在给出创建机器人模型的规则之前,需要一些定义。

包含实体节点及其所有派生节点的集合称为实体节点。类似的定义适用于Device,Robot,Joint和Motor节点。您可以在节点图表中获得有关节点层次结构的更多信息。大多数传感器和执行器同时是实体节点和设备节点。

Robot模型的主要结构是链接在一起的实体节点树。该树的根节点应为机械手节点。实体通过关节节点链接在一起。一个设备节点应该是一个直接子机器人节点,实心节点或联合节点。

一个联合节点(Joint Node)用于在其parent和child之间添加自由的一个(或两个)度(Degree of Freedom)。 The direct parent and child of a Joint node are both Solid nodes.

从关节派生的节点允许在链接的实体节点之间创建不同种类的约束。机器人技术中使用最多的一种是HingeJoint,它可以对包括轮子在内的旋转电动机进行建模。

联合节点可以通过分别添加PositionSensor Node被监视或驱动,或在其device field下加一个 motor node。

牢记这些规则,我们可以开始设计用于对机器人建模的节点层次结构。第一步是确定应将机器人的哪个部分建模为实体节点。在我们的示例中,此操作非常明显。机器人具有与车轮电机相对应的4个自由度。它可以分为五个实体节点:车身和四个轮子。

根据机器人模型的预期应用,**在建模时减少自由度的数量对于获得有效的仿真可能很重要。**例如,在对脚轮建模时,现实的方法意味着对2 DOF进行建模。但是,如果这种精度对仿真无用,则可以找到一种更有效的方法。例如,将脚轮建模为与地面的摩擦系数为零的Sphere。

第二步是确定哪个实体节点是机械手节点(根节点)。这个选择是任意的,但是解决方案通常更容易实现。例如,在类人机器人的情况下,机器人节点通常是机器人的胸部,因为机器人的对称性有利于关节参数的计算。在我们的案例中,车身箱显然是更好的选择。下图描绘了机器人的实体节点层次结构。
Webots教程(根据官网教程)_第12张图片

At the end of the scene tree, add a Robot node having four HingeJoint nodes having a Solid node as endPoint. Please refer to this figure. 在Robot node下增加一个Shape node ,Shape里面再来一个 Box geometry . 将Shape 的颜色设置成红色. 用Shape来定义boundingObject field. The dimension of the box is (0.1, 0.05, 0.2). 在Robot下增加一个Physics node. The figure represents all the nodes defining the robot. So far only the direct children nodes of the root Robot node are implemented.

HingeJoint

Wheel的初始位置由实体节点的平移和旋转字段定义。而旋转原点(anchor)和旋转轴(axis)由HingeJoint节点的可选HingeJointParameters子级定义。

结构图如下:
Webots教程(根据官网教程)_第13张图片

Webots教程(根据官网教程)_第14张图片
对于每个HingeJoint**(4个)**,需要在三个字段中添加节点。
jointParameters:添加一个HingeJointParameters并配置锚点(0.06 0 -0.05)和轴字段(1 0 0)。这些值必须根据车轮的位置进行修改。比如锚点就是轮子的旋转中心是哪。
设备:添加RotationalMotor,以便能够驱动车轮。改变他们name从wheel1到wheel4。这些标签将用于引用控制器上的车轮。
endPoint(铰链的另一端连的啥):添加一个Solid节点,然后在Solid的字段中添加一个Shape节点,最后,在Shape节点的geometry字段中添加一个Cylinder。The Cylinder should have a radius of 0.04 and a height of 0.02. 将车轮的颜色设置为绿色。Rotate the Transform node by an Euler axis and angle of (0, 0, 1, Pi/2) in order to inverse the x-axis and the y-axis.

对于第一个车轮,应定义Solid translation(0.06, 0, 0.05)以定义车身和车轮之间的相对间隙。所述HingeJointParameters anchor也应定义为(0.06, 0, 0.05)以限定所述旋转原点(相对于所述主体)。最后,HingeJointParameters axis应定义旋转轴。在我们的例子中,它沿着x轴(所以(1, 0, 0))。

现在,我们要实现车轮的圆柱形状。由于圆柱体节点的定义是沿着y轴,一个Transform节点应该封装Shape,使圆柱体沿着x轴旋转。

感测器

机器人建模的最后一部分是将两个距离传感器添加到机器人。这可以通过添加两个DistanceSensor节点作为Robot节点的children节点来完成。注意,距离传感器沿+ x轴获取其数据。因此,旋转距离传感器以使其x轴指向机器人外部是必要的。

如何知道距离传感器的方向?
可以使用快捷方式(Ctrl + F10)或观看距离传感器射线View / Optional Rendering / Show DistanceSensor Rays

如上所述,添加两个距离传感器。距离传感器与机器人前向矢量(robot front vector)的角度为0.3 [rad]。将type field设置为sonar。将其图形和物理形状(graphicial and physical)设置为边缘为0.01[m] 的立方体(未经变换)。【children中添加一个solid固件-solid固件的children中添加shape节点】将其颜色设置为蓝色。name根据该图的标签设置其字段。

如何精确定位距离传感器?”
在DistanceSensor节点中,旋转字段具有4个参数。如果将angle参数设置为0,则可以使用鼠标滚轮以0.1309 rad(=7.5度)的步长递增/递减。

这里需要注意一点,距离传感器的X方向(红色箭头的方向应该指向前方)

Controller

在先前的教程中,您已经学习了如何设置反馈回路以及如何读取距离传感器值。但是,激活RotationalMotor节点是新的内容。要对旋转电机进行编程,第一步是包括与RotationalMotor节点相对应的API模块:

from controller import Robot

TIME_STEP = 64
robot = Robot()
ds = []
dsNames = ['ds_right', 'ds_left']
for i in range(2):
    ds.append(robot.getDistanceSensor(dsNames[i]))
    ds[i].enable(TIME_STEP)
wheels = []
wheelsNames = ['wheel1', 'wheel2', 'wheel3', 'wheel4']
for i in range(4):
    wheels.append(robot.getMotor(wheelsNames[i]))
    #电机可以通过设置它的位置,它的速度,它的加速度或其力被致动。在这里,我们设置其速度。这可以通过将其位置设置为无穷大并限制其速度来实现:
    wheels[i].setPosition(float('inf'))
    wheels[i].setVelocity(0.0)
avoidObstacleCounter = 0
while robot.step(TIME_STEP) != -1:
    leftSpeed = 1.0
    rightSpeed = 1.0
    if avoidObstacleCounter > 0:
        avoidObstacleCounter -= 1
        leftSpeed = 1.0
        rightSpeed = -1.0
    else:  # read sensors
        for i in range(2):
            if ds[i].getValue() < 950.0:
                avoidObstacleCounter = 100
    wheels[0].setVelocity(leftSpeed)
    wheels[1].setVelocity(rightSpeed)
    wheels[2].setVelocity(leftSpeed)
    wheels[3].setVelocity(rightSpeed)

请注意,DistanceSensor节点的lookupTable字段指示传感器返回哪些值。为了帮助调试传感器,可以在机械手窗口中实时查看传感器的值。要打开机器人窗口,请双击机器人主体,它将在左侧弹出一个菜单,其中包含DistanceSensor和RotationalMotor图。运行模拟以查看演变。

不要忘记设置“ 机器人”节点的controller字段来指示您的新控制器。

动起来啦!!!

发现的上面几个没有说清楚的问题:

  1. 电机按顺序依次命名为wheel1-wheel4
    Webots教程(根据官网教程)_第15张图片
  2. 代码中的ds_right和ds_left是距离传感器,也要在他们的name标签里依次命名
  3. 每个轮子的anchor要依次按照他们自己的旋转中心设定,否则就会出现轮子乱飞的情况
    Webots教程(根据官网教程)_第16张图片

你可能感兴趣的:(Webots)