9、教程-1在Webots中的第一个仿真
第一个教程的目的是熟悉用户界面和Webot的基本概念。您将创建包含一个简单环境的第一个模拟:一个有地板和墙壁的竞技场、几个盒子、一个电子吸盘机器人和一个使机器人移动的控制器程序。
1、创建一个新的世界
“世界”是一个文件,包含对象在哪里、它们看起来像什么、它们如何相互作用、天空的颜色、如何定义对象的重力、摩擦力、质量等信息。它定义了模拟的初始状态。不同的对象称为“节点”,并在“场景树”中按层次组织。因此,一个节点可能包含子节点。世界存储在一个扩展名为.wbt的文件中。该文件格式源自VRML97语言,并且是人类可读的。世界文件必须直接存储在名为worlds的目录中。
选择Wizards->New Project Directory
将目录名取为my_first_simulation,以及世界文件名也一样,选择所有选项;
Webots显示它刚刚创建的目录和文件的列表。这与Webots项目的标准文件层次结构相对应。单击Finish(Windows、Linux)或Done(macOS)按钮关闭此窗口。
祝贺你,你刚刚创建了你的第一个Webots世界!三维视图应该显示一个方格地板的方形竞技场。可以使用鼠标在三维视图中移动视点:左键、右键和轮子。
存储在世界文件中的Webots节点以称为场景树的树结构进行组织。场景树可以在主窗口的两个子窗口中查看:3D视图(位于主窗口的中心)是场景树的3D表示,场景树视图(位于左侧)是场景树木的层次表示。场景树视图是可以修改节点和字段的位置。它当前应列出以下节点:
WorldInfo:包含模拟的全局参数。
Viewpoint:定义主视点摄影机参数。
TexturedBackground:定义场景的背景(如果稍微旋转一点视点,应该可以看到远处的山脉)
TexturedBackgroundLight:定义与上述背景关联的灯光。
RectangleArena:定义到目前为止在该场景中看到的唯一对象。
每个节点都有一些可自定义的属性,称为字段。让我们修改这些字段以更改矩形竞技场:
双击场景树中的RectangleArena节点。这将打开节点并显示其字段。
1.选择“floorTileSize”字段,并将其值设置为0.25 0.25,而不是0.5 0.5。您应该立即在三维视图中看到效果。
2.选择wallHeight字段,并将其值更改为0.05而不是0.1。竞技场的墙现在应该更低了。
在场景树视图中,如果字段与默认值不同,则字段将显示为不同的颜色(取决于主题)。现在,我们想添加一些对象:
双击场景树中的RectangleArena将其关闭并选中。单击场景树顶部的Add+按钮。在打开的对话框中,选择PROTO节点(Webots项目)/objects/factory/containers/WoodenBox(实体)。竞技场中央应该出现一个大盒子。在场景树中双击它以打开它的字段。
- 将其大小更改为0.1 0.1 0.1,而不是0.6 0.6 0.6
- 将其平移更改为0 0 0.05,而不是0 0 0.3。或者,可以使用三维视图中显示的蓝色箭头来调整其translation.z字段
- 现在,按住shift键,在三维视图中单击并拖动长方体,然后将其移动到竞技场的某个角落。
-
选择该框,然后按ctrl-C、ctrl-V(Windows、Linux)或command-C、command-V(macOS)复制并粘贴。按住Shift键,单击并拖动新框,将其移动到不同的位置。以这种方式创建第三个长方体.
- 移动箱子,这样竞技场中心就不会有箱子了。也可以使用蓝色旋转箭头沿垂直轴旋转框。这也可以通过用鼠标右键按住shift键并拖动来完成。或者,可以更改场景树中WoodenBox节点的旋转场的角度。
- 一旦您对结果感到满意,请使用保存按钮保存世界。
使用平移和旋转hangles来移动对象:https://www.cyberbotics.com/doc/guide/the-3d-window?tab-os=linux&tab-language=c++#axis-aligned-handles
添加一个e-puck机器人
电子吸盘是一个小型机器人,有差速器轮、10个LED和几个传感器,包括8个距离传感器和一个摄像头。在本教程中,我们只对使用它的轮子感兴趣。我们将在接下来的教程中学习如何使用其他功能。
现在,我们将向世界添加一个电子吸盘模型。请确保模拟已暂停,并且经过的虚拟时间为0。如果不是这种情况,请使用“重置”按钮重置模拟。
当修改Webots世界以保存时,首先暂停模拟并重新加载到其初始状态是至关重要的,即主工具栏上的虚拟时间计数器应显示0:00:00:000。否则,每次保存时,每个三维对象的位置都可能累积错误。因此,对世界的任何修改都应按以下顺序执行:暂停、重置、修改和保存模拟。
我们不需要从头开始创建电子吸盘机器人,我们只需要导入一个电子吸盘节点。这个节点实际上是一个PROTO节点,就像我们之前介绍的RectangleArena或WoodenBox。原型设计允许您创建自定义对象并重用它们。
选择场景树视图的最后一个节点WoodenBox。单击场景树视图顶部的“添加”按钮。在对话框中,选择PROTO节点(Webots项目)/arobots/gctronic/e-puck/e-puck(Robot)。电子冰球机器人应该出现在场地中央。移动和旋转这个机器人,就像你处理盒子一样。保存模拟并按下“实时运行”按钮。
机器人应该移动、闪烁LED并避开障碍物。这是因为它有一个具有该行为的默认控制器。您可能已经注意到一个黑色的小窗口出现在三维视图的左上角。它显示了电子吸盘机器人的摄像头拍摄的图像。该图像将保持黑色,直到机器人的控制器明确启用相机。这个小图像窗口可以通过拖动来移动,也可以通过拖动右下角来调整大小。最后,单击右上角的“x”可以关闭它。通过在“相机设备”子菜单中选择“套印格式”菜单,可以使其再次可见。因为我们不需要它,所以你实际上可以关闭它。
现在,在模拟运行的同时,让我们玩物理游戏:
在Linux上,除了alt+左键单击+拖动之外,还应该按下ctrl键。无法对WoodenBox节点施加力,因为默认情况下,它们没有质量,并且被视为粘在地板上。若要在WoodenBox节点上启用物理,应将其质量场设置为某个值(例如0.2 kg)。一旦完成,就应该能够对它们施加力。
现在我们要修改世界,减少物理模拟的步骤:这将提高模拟的准确性和稳定性(但会降低最大模拟速度)。
暂停模拟并将其还原。在“场景树”视图中,展开“世界信息”节点(第一个节点)。将其basicTimeStep字段设置为16。然后保存模拟。
创建一个新的控制器
我们现在将对一个简单的控制器进行编程,使机器人向前移动。
控制器是一个定义机器人行为的程序。Webots控制器可以用以下编程语言编写:C、C++、Java、Python、MATLAB、ROS等。C、C++和Java控制器需要经过编译才能作为机器人控制器运行。Python和MATLAB控制器是解释语言,因此它们将在不编译的情况下运行。在本教程中,我们将使用C作为参考语言,但所有代码片段也可以在C++、Java、Python和MATLAB中使用。请参阅语言章节,使用不同的编程语言设置控制器。
机器人节点的控制器字段指定当前与机器人关联的控制器。请注意,同一个控制器可以由多个机器人使用,但一个机器人一次只能使用一个控制器。每个控制器都在一个单独的子进程中执行,通常由Webots派生。因为它们是独立的进程,所以控制器不共享相同的地址空间,并且可能在不同的处理器内核上运行。
使用Wizards/new Robot controller创建一个名为epuck_go_forward的新C(或任何其他语言)控制器(对于C++和Java,请改为EPuckGoForward)。。。菜单项。这将在my_first_simulation/controllers中创建一个新的epuck_go_forward(或EPuckGoForward)目录。选择可在文本编辑器中打开源文件的选项。
现在,我们将把新的epuck_go_forward(或EPuckGoForward)控制器关联到E-puck节点。
在场景树视图中,选择E-puck节点的控制器字段,然后使用场景树视图底部的字段编辑器:按select。。。按钮,然后在列表中选择epuck_go_forward。一旦控制器与机器人相关联,保存世界。通过插入include语句(#include<webots/motor.h>)修改程序,获取电机设备(WbDeviceTag motor=wb_robot_get_device(“motor_name”);),并且通过应用电动机命令(wb_motor_set_position(电动机,10);):
#include <webots/robot.h> // Added a new include file #include <webots/motor.h> #define TIME_STEP 64 int main(int argc, char **argv) { wb_robot_init(); // get the motor devices WbDeviceTag left_motor = wb_robot_get_device("left wheel motor"); WbDeviceTag right_motor = wb_robot_get_device("right wheel motor"); // set the target position of the motors wb_motor_set_position(left_motor, 10.0); wb_motor_set_position(right_motor, 10.0); while (wb_robot_step(TIME_STEP) != -1); wb_robot_cleanup(); return 0; }
保存修改后的源代码(文件/保存文本文件),并对其进行编译(构建/构建)。如有必要,修复任何编译错误。当Webots建议重置或重新加载世界时,请选择“重置”并运行模拟。
如果一切正常,你的机器人应该向前移动。机器人将使用其最大速度移动一段时间,然后在车轮旋转10弧度后停止。
在项目的controllers目录中,已经创建了一个包含epuck_go_forward(或EPuckGoForward)控制器的目录。epuck_go_forward(或EPuckGoForward)目录包含一个在编译控制器后生成的epuck_go_forward)二进制文件(在Windows上,此文件的扩展名为.exe)。控制器目录名称应与二进制名称匹配。
扩展控制器到速度控制
机器人的轮子通常是用速度来控制的,而不是像前面的例子那样用位置来控制。为了控制车轮的电机速度,您需要将目标位置设置为无穷远,并设置所需速度:
#include <webots/robot.h> // Added a new include file #include <webots/motor.h> #define TIME_STEP 64 #define MAX_SPEED 6.28 int main(int argc, char **argv) { wb_robot_init(); // get a handler to the motors and set target position to infinity (speed control) WbDeviceTag left_motor = wb_robot_get_device("left wheel motor"); WbDeviceTag right_motor = wb_robot_get_device("right wheel motor"); wb_motor_set_position(left_motor, INFINITY); wb_motor_set_position(right_motor, INFINITY); // set up the motor speeds at 10% of the MAX_SPEED. wb_motor_set_velocity(left_motor, 0.1 * MAX_SPEED); wb_motor_set_velocity(right_motor, 0.1 * MAX_SPEED); while (wb_robot_step(TIME_STEP) != -1) { } wb_robot_cleanup(); return 0; }
结论
- 世界是由以树状结构组织的节点组成的。
- 世界保存在Webots项目中存储的.wbt文件中。
- 该项目还包含定义机器人行为的机器人控制器程序。
- 控制器可以用C语言或其他语言编写。
- C、 C++和Java控制器必须经过显式编译才能执行。
- 控制器通过Robot节点的控制器字段与Robot相关联。