【机器人仿真Webots教程】-控制器编程指南

news2025/2/26 18:48:06

Webots controller编程指南

文章目录

  • Webots controller编程指南
    • 1. controller程序设计流程
      • 1.1 controller与场景树节点
      • 1.2 进程角度分析
      • 1.3 仿真时间步长与控制器程序更新延时步长
    • 2. 例解控制器编程
      • 2.1 Hello world 实例
      • 2.2 传感器读取实例
      • 2.3 执行器的使用
      • 2.4 传感器与执行器综合例程
      • 2.5 控制器读入参数、程序终止
      • 2.6 控制台
      • 2.7 共享库&环境变量

1. controller程序设计流程

1.1 controller与场景树节点

在Webots中,场景树节点(Scene Tree Nodes)是Webots仿真环境中的各种对象,包括机器人模型、传感器、环境物体等。每个节点都有其在场景树中的位置,节点之间可以形成层次结构,以便组织和管理模拟环境。

控制器程序(Controller Program)是用于控制机器人在仿真环境中执行动作和决策的代码。它可以是任何支持Webots API的编程语言,例如C、C++、Python等。控制器程序可以访问和操纵场景树中的节点,以实现机器人的行为。

在这里插入图片描述

关联场景树节点和控制器程序的过程通常如下:

  1. 创建或导入机器人模型和其他物体,这些将成为场景树节点的一部分。
  2. 在Webots中创建一个控制器程序文件,并将其与一个或多个场景树节点关联。关联可以通过以下方式之一完成:
    • 使用Webots图形用户界面(GUI):选择一个或多个节点,然后在GUI中设置它们的控制器程序路径。
    • 使用Webots API:在控制器程序中使用适当的API函数来获取对场景树节点的引用,并将其与控制器程序关联起来。
  3. 编写控制器程序,使用适当的API函数来操作和控制场景树节点。这包括读取传感器数据、发送控制命令、更新节点状态等。
  4. 在Webots中运行仿真,控制器程序将与场景树节点进行交互,实现机器人的控制和行为。

通过这种方式,控制器程序可以与场景树节点进行关联,并利用节点的属性和功能来控制仿真环境中的机器人行为。

在这里插入图片描述

1.2 进程角度分析

从进程的角度观察,每个控制器进程都是webots进程的子进程,同时每个控制器进程和webots进程并不共享内存(除Camera外)

在这里插入图片描述

1.3 仿真时间步长与控制器程序更新延时步长

step指的是仿真步长,这个步长是整个仿真环境(具体来说是场景树)中更新计算的时间间隔,在场景树中指定WorldInfo.basicTimeStep

wb_robot_step是controller程序的更新间隔,一个wb_robot_step包含若干step(simulation step)

例如仿真步长为16ms,那么wb_robot_step可以是16、32、64、128ms,单击界面中的step按钮,即走一个simulation step,如果wb_robot_step包含多个simulation step,那么会打断wb_robot_step的执行。

在这里插入图片描述

2. 例解控制器编程

2.1 Hello world 实例

wb_robot_init 为C Api在函数调用之前调用的初始化函数,初始化controller和webots lib的通信,在C API中特有,其他编程语言中并不存在

wb_robot_cleanup 做善后工作,在C API中特有,其他编程语言中并不存在。

wb_robot_step 在每个controller中都有,定期调用,因此通常放在主循环中,参数代表毫秒数,,为控制步骤的持续时间,函数根据设定的毫秒数进行仿真返回计算值,仿真时间量并不是真实的时间,在实际中可能是1毫秒或者一分钟的时间。注意,webots终止时返回wb_robot_step -1。只要仿真进行,那么控制回路就会运行

Hello world入门实例如下:

#include <webots/robot.h>
#include <stdio.h>

int main() {
  wb_robot_init();

  while(wb_robot_step(32) != -1)
    printf("Hello World!\n");

  wb_robot_cleanup();
  return 0;
}

2.2 传感器读取实例

#include <webots/robot.h>
#include <webots/distance_sensor.h>
#include <stdio.h>

#define TIME_STEP 32

int main() {
  wb_robot_init();

  WbDeviceTag sensor = wb_robot_get_device("my_distance_sensor");
  wb_distance_sensor_enable(sensor, TIME_STEP);

  while (wb_robot_step(TIME_STEP) != -1) {
    const double value = wb_distance_sensor_get_value(sensor);
    printf("Sensor value is %f\n", value);
  }

  wb_robot_cleanup();
  return 0;
}

使用设备需要获取设备的标签,类型为WbDeviceTag,获取方式为wb_robot_get_device,参数为机器人描述文件(.wbt或者.proto文件)中的设备名称,获取失败返回0

传感器设备在使用之前需要调用wb_*_enable进行使能,参数为获取的WbDeviceTag类型的变量(指定使能的设备)以及传感器数据两次更新之间的延时时间(TIME_STEP),一般的此处设置的延时时间与wb_robot_step的参数有关,一般为倍数关系,例如延时时间设置为控制步长的两倍,那么传感器每两次wb_robot_step调用更新一次,如果设置的延时时间比控制步长还要短是没有意义的,可以理解wb_robot_step的控制步长为一个最小单位时间。

wb_*_disable禁用设备,这样有可能会提高仿真的速度。wb_distance_sensor_get_value函数可以获取距离传感器的最新值,那么,类似的,还有很多获取传感器值的API,但是有可能这些设备返回的是个数组,例如加速度计、GPS、陀螺仪等等,接收数据如下:

API原型

const double *wb_gps_get_values(WbDeviceTag tag);
const double *wb_accelerometer_get_values(WbDeviceTag tag);
const double *wb_gyro_get_values(WbDeviceTag tag);

获取

const double *values = wb_gps_get_values(gps);

// OK, to read the values they should never be explicitly deleted by the controller code
printf("MY_ROBOT is at position: %g %g %g\n", values[0], values[1], values[2]);

// OK, to copy the values
double x, y, z;
x = values[0];
y = values[1];
z = values[2];

2.3 执行器的使用

controller也需要WbDeviceTag类型的变量作为入参指定设备,其不需要使能设备

电机控制实例

#include <webots/robot.h>
#include <webots/motor.h>
#include <math.h>

#define TIME_STEP 32

int main() {
  wb_robot_init();

  WbDeviceTag motor = wb_robot_get_device("my_motor");

  const double F = 2.0;   // frequency 2 Hz
  double t = 0.0;         // elapsed simulation time

  while (wb_robot_step(TIME_STEP) != -1) {
    const double position = sin(t * 2.0 * M_PI * F);
    wb_motor_set_position(motor, position);
    t += (double)TIME_STEP / 1000.0;
  }

  wb_robot_cleanup();
  return 0;
}

功能说明:使旋转电机以2Hz正弦信号震荡.

API解释

函数名函数功能参数
wb_motor_set_position设置旋转电机位置设备描述符,位置量

wb_motor_set_position设置位置之后并不会立即启动电机,而是等待wb_robot_step的驱动,将驱动命令发送到RationalMotor中,在指定的控制步长的时间(单位毫秒)内仿真电机的运动,一个控制步长的时间并不一定可以完成整个运动的过程。

#include <webots/robot.h>
#include <webots/motor.h>
#include <math.h>

#define TIME_STEP 32

int main() {
  wb_robot_init();

  WbDeviceTag motor = wb_robot_get_device("my_motor");

  const double F = 2.0;   // frequency 2 Hz
  double t = 0.0;         // elapsed simulation time

  while (wb_robot_step(TIME_STEP) != -1) {
    const double position = sin(t * 2.0 * M_PI * F);
    wb_motor_set_position(motor, position);
    t += (double)TIME_STEP / 1000.0;
  }

  wb_robot_cleanup();
  return 0;
}

一般情况下为控制运动的行进建模,将整个运动分解为离散的组合步骤,一般这个离散步骤的单位就是wb_robot_step的参数。

2.4 传感器与执行器综合例程

功能描述:机器人使用的是差动转向。它使用两个距离传感器 ( DistanceSensor) 来检测障碍物。

#include <webots/robot.h>
#include <webots/motor.h>
#include <webots/distance_sensor.h>

#define TIME_STEP 32

int main() {
  wb_robot_init();

  WbDeviceTag left_sensor = wb_robot_get_device("left_sensor");
  WbDeviceTag right_sensor = wb_robot_get_device("right_sensor");
  wb_distance_sensor_enable(left_sensor, TIME_STEP);
  wb_distance_sensor_enable(right_sensor, TIME_STEP);

  WbDeviceTag left_motor = wb_robot_get_device("left_motor");
  WbDeviceTag right_motor = wb_robot_get_device("right_motor");
  wb_motor_set_position(left_motor, INFINITY);
  wb_motor_set_position(right_motor, INFINITY);
  wb_motor_set_velocity(left_motor, 0.0);
  wb_motor_set_velocity(right_motor, 0.0);

  while (wb_robot_step(TIME_STEP) != -1) {

    // read sensors
    const double left_dist = wb_distance_sensor_get_value(left_sensor);
    const double right_dist = wb_distance_sensor_get_value(right_sensor);

    // compute behavior (user functions)
    const double left = compute_left_speed(left_dist, right_dist);
    const double right = compute_right_speed(left_dist, right_dist);

    // actuate wheel motors
    wb_motor_set_velocity(left_motor, left);
    wb_motor_set_velocity(right_motor, right);
  }

  wb_robot_cleanup();
  return 0;
}

注意,更新传感器状态一定要通过wb_robot_step,因为在wb_robot_step之前,API仅仅做了预备工作,并不会直接对仿真的进程进行推进(也即设备状态不会立即得到响应),只有调用了wb_robot_step才会推进仿真进程的响应。

2.5 控制器读入参数、程序终止

对于控制器的参数,通过控制器的main函数入口的argv接收,指定方式为机器人的controllerArgs节点字段

例:

参数:

Robot {
  ...
  controllerArgs "one two three"
  ...
}

控制器(名为demo)程序:

#include <webots/robot.h>
#include <stdio.h>

int main(int argc, const char *argv[]) {
  wb_robot_init();

  int i;
  for (i = 0; i < argc; i++)
    printf("argv[%i]=%s\n", i, argv[i]);

  wb_robot_cleanup();
  return 0;
}

输出:

argv[0]=demo
argv[1]=one
argv[2]=two
argv[3]=three

一般控制器的主程序程序是一个大循环,控制器的终止也是循环的终止。导致控制器发生终止的事件一般有:

  • Webots退出
  • 仿真重置
  • world重新加载
  • 加载新的仿真
  • 控制器名称修改

当上述事件发生时wb_robot_step返回-1,控制器进程不再与webots进程通信,在实际时间的1s后,如果控制器程序没有主动终止,Webots进行将发送SIGKILL信号杀死控制器进程,并给控制器程序足够的时间完成数据的转储和文件关闭。

示例:

功能描述:控制器程序终止之前保存数据。

#include <webots/robot.h>
#include <webots/distance_sensor.h>
#include <stdio.h>

#define TIME_STEP 32

int main() {
  wb_robot_init();

  WbDeviceTag sensor = wb_robot_get_device("my_distance_sensor");
  wb_distance_sensor_enable(sensor, TIME_STEP);

  while (wb_robot_step(TIME_STEP) != -1) {
    const double value = wb_distance_sensor_get_value();
    printf("sensor value is %f\n", value);
  }

  // Webots triggered termination detected!
  // Past this point, new printf statements will no longer be
  // displayed in the Webots console

  saveExperimentData();  // this shouldn't last longer than one second

  wb_robot_cleanup();
  return 0;
}

在某些情况下,由控制器做出终止模拟的决定。例如在搜索和优化算法的情况下:搜索可能会在找到解决方案时或在固定次数的迭代(或生成)之后终止。

在这种情况下,控制器应该只保存实验结果并通过从函数返回main或调用exit函数退出。这将终止控制器进程并在当前仿真步骤冻结仿真。物理仿真和仿真中涉及的每个机器人都将停止。

2.6 控制台

控制器程序支持stdout、stderr,并被程序重定向到了webots的控制台,webots不支持stdin(即标准输入),仅支持一些ANSI转义码进行文本样式的设置和清除,支持类型有以下所示:

  • 3 位色彩(前景和背景)
  • Blob 风格
  • 下划线 风格
  • clear清屏
  • 重置(颜色和样式)

示例程序:

world文件:

WEBOTS_HOME/projects/samples/howto/console/worlds/console.wbt

控制器文件:

WEBOTS_HOME/projects/samples/howto/console/controllers/console/console.c

ANSI头文件:

WEBOTS_HOME/include/controller/c/webots/utils/ansi_codes.h

#include <webots/utils/ansi_codes.h>

printf("This is %sred%s!\n", ANSI_RED_FOREGROUND, ANSI_RESET);

2.7 共享库&环境变量

共享库对于控制器程序和插件之间的代码共享非常有用

  • 可以将共享库放入libraries子目录中

  • WEBOTS_HOME/resources/Makefile.include,手动修改链接共享库
    示例: WEBOTS_HOME/resources/projects/libraries/qt_utils

  • 将共享库添加到环境变量[[DY]LD_LIBRARY_]PATH

每个控制器程序目录下支持一个配置文件的方式自动在运行前加载环境变量到当前环境下,该配置文件名为"runtime.ini",runtime.ini以键值对的形式设置,包括以下7个字段:

  • [environment variables with paths]

    此部分应仅包含具有相对或绝对路径的环境变量。路径必须使用冒号“:”分隔,目录组件必须使用斜杠符号“/”分隔。本节中声明的变量将添加到每个平台上。在 Windows 上,根据 Windows 语法,冒号将替换为分号,斜线将替换为反斜线。

  • [environment variables]

    本节中定义的环境变量也将添加到每个平台的环境中,但它们将直接写入而不更改语法。对于不包含任何路径的变量来说,这是一个很好的位置。

  • [environment variables for Windows]

    如果控制器在 Windows 平台上运行,则此部分中定义的变量将仅添加到环境中。如果你想在这个部分声明路径,值应该写在双引号符号之间。

  • [environment variables for macOS]

    此处定义的变量只会在 macOS 上添加,在其他平台上会被忽略。

  • [environment variables for Linux]

    此处定义的变量将添加到所有 Linux 平台上,但不会添加到 Mac 或 Windows 上。

  • [environment variables for Linux 32]

    仅当 Linux 平台为 32 位时才会添加这些变量。

  • [environment variables for Linux 64]

    仅当 Linux 平台为 64 位时才会添加这些变量。

示例:

; typical runtime.ini

[environment variables with paths]
WEBOTS_LIBRARY_PATH = lib:$(WEBOTS_LIBRARY_PATH):../../library

[environment variables]
ROS_MASTER_URI = http://localhost:11311

[environment variables for Windows]
NAOQI_LIBRARY_FOLDER = "bin;C:\Users\My Documents\Naoqi\bin"

[environment variables for macOS]
NAOQI_LIBRARY_FOLDER = lib

[environment variables for Linux]
NAOQI_LIBRARY_FOLDER = lib

同时runtime.ini中还有关于编程语言的特定配置项,字段分别有

  • [java]
  • [python]
  • [matlab]

每个字段又包含两个键COMMANDOPTIONS,分别代表命令和选项

示例:

; runtime.ini for a Python controller on macOS

[python]
COMMAND = /opt/local/bin/python3.8
OPTIONS = -m package.name.given

上述配置等同于

/opt/local/bin/python3.8 -m package.name.given my_controller.py

示例:

; runtime.ini for a Java controller on Windows

[environment variables with paths]
CLASSPATH = ../lib/MyLibrary.jar
JAVA_LIBRARY_PATH = ../lib

[java]
COMMAND = javaw.exe
OPTIONS = -Xms6144k

注意:Java -classpath(或 - cp)选项是从CLASSPATH环境变量自动生成的。因此,您不应将其添加到OPTIONS密钥中,而应将其添加到“runtime.ini”文件中的标准环境变量中。在上面的示例中,-classpath传递给 Java 虚拟机的最终选项包括“$(WEBOTS_HOME)/lib/Controller.jar”,当前目录(“.”)或控制器 jar 文件(如果存在)(“MyController.jar”)。 jar”),最后是“…/lib/MyLibrary.jar”。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/501120.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

距离保护整定计算中分支系数公式理解

在一般的距离保护II段和III段的整定计算中&#xff0c;分支系数的计算是必须要的&#xff0c;本文选自电力系统继电保护&#xff08;第二版&#xff09;&#xff08;张保会老师主编&#xff09;P94-P97页的例题&#xff0c;分析其中分支系数的计算公式。 我们在前面的章节中知道…

springboot+jsp影院管理系统9ufid电影票预订管理系统

项目介绍开发语言&#xff1a;Java 框架&#xff1a;springboot 技术&#xff1a;JSP JDK版本&#xff1a;JDK1.8 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven3.3.9 浏览器&#xff1a;谷歌浏览器 功能介绍 主要对…

HTB靶机08-Nineveh-WP

008-nineveh 靶机IP&#xff1a; 10.10.10.43 scan Nmap 扫描 ┌──(xavier㉿kali)-[~] └─$ sudo nmap -sSV -T4 10.10.10.43 -p- Starting Nmap 7.93 ( https://nmap.org ) at 2023-04-07 17:40 CST Nmap scan report for nineveh.htb (10.10.10.43) Host is up (0.34s …

linux系统安装nginx 支持ssl

目录 1. 开放80端口和443端口 2. 安装nginx的基础环境 -> 2.1 安装gcc-c编译器 -> 2.2 安装pcre包 -> 2.3 安装zlib包(可能安装过) 3. 安装nginx -> 3.1 创建文件夹 -> 3.2 在官网下载nginx包到服务器内 -> 3.3 解压tar.gz,并进入nginx-1.19.9 -&g…

[数据库系统] 二、表的基本操作(educoder)

目录 第一关&#xff1a;修改表名 一、知识点 ①查看所有表&#xff1a;show tables; ②查看表基本结构&#xff1a;DESCRIBE 表名&#xff1b; 或 简写为 desc 表名; ③查看创建表的语句&#xff1a;SHOW CREATE TABLE 二、educoder 第二关&#xff1a; 修改表结构-1 一、…

面对AI“龙卷风”破坏力 白宫“软着陆”欧盟“硬防御”

ChatGPT的风靡与风险将OpenAI的CEO山姆奥特曼&#xff08;Sam Altman&#xff09;送进白宫&#xff0c;他被蹲守在美国总统府邸的记者们围追&#xff0c;面对5月4日白宫发起的AI风险治理会议&#xff0c;奥特曼很官方地给出“重要也很及时”的回应&#xff0c;自信的反复强调“…

【TCP三次握手】

文章目录 TCP基本认识TCP头部格式为什么需要 TCP 协议&#xff1f; TCP 工作在哪一层&#xff1f;什么是 TCP &#xff1f;如何唯一确定一个 TCPUDP 和 TCP 有什么区别呢&#xff1f;分别的应用场景是&#xff1f;TCP 和 UDP 可以使用同一个端口吗&#xff1f; TCP连接建立TCP三…

“SCSA-T学习导图+”系列:深入浅出理解OSPF链路状态信息

本期引言 本文是基于读者对OSPF有一定了解的基础上&#xff0c;重点理解OSPF收集链路状态的过程。我们都知道在OSPF的工作原理中&#xff0c;主要是通过泛洪不同种类的LSA来进行LSDB的同步&#xff0c;最后通过SPF算法来计算路由&#xff0c;达到全网互通的目的。所以我们研究…

camunda流程变量如何使用

Camunda是一个流程引擎&#xff0c;它支持在流程执行期间存储和操作流程变量。流程变量是一个值或对象&#xff0c;可以与Camunda中的流程实例、任务或执行相关联。 流程变量在Camunda中有很多用途。以下是一些常见的用途&#xff1a; 1、传递数据&#xff1a;流程变量可以用于…

通讯录备份的方法你知道几个?分享iPhone通讯录3个备份技巧!

案例&#xff1a;苹果通讯录的备份方法 【我想把 iPhone 8重置一下&#xff0c;把里边乱七八糟的东西清一清&#xff0c;软件什么的重新下了就好了&#xff0c;设置什么的也不需要备份&#xff0c;只想重置完了能恢复一下通讯录&#xff0c;求解答&#xff01;】 在如今的移动…

Scrum敏捷开发工具-单团队敏捷开发管理

Scrum是全球运用最广泛的敏捷管理框架&#xff0c;Leangoo基于Scrum框架提供了一系列的流程和模板&#xff0c;可以帮助敏捷团队快速启动Scrum敏捷开发。 这里可以介绍一下在scrum中单团队敏捷开发如何管理&#xff0c;单团队敏捷开发主要是针对10-15人以下&#xff0c;只有一…

PHP+MYSQL+Thinkphp——仓库管理系统

一、功能 前台功能&#xff1a; 1、企业介绍、企业消息推送 2、用户注册、用户登录、重置密码、退出登录 3、用户个人信息修改、材料申购、审批查看 4、材料管理&#xff1a;公司已有材料查看、材料借用、材料归还、借用记录 后台功能&#xff1a; 1、后台登录、修改管理员密…

【Java EE】-Servlet(二) Servlet API 详解

作者&#xff1a;学Java的冬瓜 博客主页&#xff1a;☀冬瓜的主页&#x1f319; 专栏&#xff1a;【JavaEE】 分享:寂寞会发慌&#xff0c;孤独是饱满的。——史铁生《命若琴弦》 主要内容&#xff1a;HttpServlet的方法&#xff0c;init,service,destroy,doGet/doPost/doPut/…

MySQL之从一条记录说起 【InnoDB 记录结构上篇】

前言 本文章收录在MySQL性能优化原理实战专栏&#xff0c;点击此处查看开篇介绍。 本文摘录自 ▪ 小孩子4919《MySQL是怎样运行的&#xff1a;从根儿上理解MySQL》 到现在为⽌&#xff0c;MySQL对于我们来说还是⼀个⿊盒&#xff0c;我们只负责使⽤客户端发送请求并等待服务…

【Go编程语言】 Go语言基础语法

Go语言基础语法 文章目录 Go语言基础语法一、注释1.单行注释2.多行注释 二、变量1.变量的定义2.变量的初始化3.理解变量&#xff08;内存地址&#xff09;4.变量交换5.匿名变量6.变量的作用域 三、常量1.常量的定义&#xff1a; const2.iota&#xff08;特殊常量&#xff09; 四…

HLS直播与延迟时长的来源与超低延迟直播

1.HLS直播延迟时长&#xff08;HTTP Live Streaming&#xff09; HTTP Live Streaming&#xff08;简称 HLS&#xff09;是一个基于 HTTP 的视频流协议&#xff0c;由 Apple 公司实现&#xff0c;Mac OS 上的 QuickTime、Safari 以及 iOS 上的 Safari 都能很好的支持 HLS&…

Kmeans++ 算法对随机数据样本聚类

一、算法简介 K-means算法是一种常见的无监督学习聚类算法&#xff0c;其基本思想是将n个样本划分为k个簇&#xff0c;每个簇内的样本之间的相似度要尽可能的大&#xff0c;而不同簇之间的相似度要尽可能的小&#xff0c;通过最小化各个簇内点与该簇中心点的距离和来实现。 二…

API接口对程序员的帮助有哪些,参考值简要说明

API接口对程序员的帮助有哪些 提高开发效率&#xff1a;通过API接口&#xff0c;程序员能够在不用重复编写代码的情况下&#xff0c;直接获取其他应用程序提供的服务或数据&#xff0c;极大地提高了开发效率。 减少错误率&#xff1a;使用API接口可以避免手动输入数据容易出现…

(LDR6020)双USBType-C口快充头适配器方案(PD快充 支持功率动态分配,只需要一颗芯片完成所需功能)

6月7日&#xff0c;欧盟公布了“在欧盟境内统一使用USB Type-C接口用于移动设备充电”的法规。在同一天&#xff0c;苹果公司发布了自己的35W双USB Type-C口充电器。可以看到&#xff0c;多USB Type-C口&#xff08;下文简称:C口&#xff09;快充充电器将成为市场趋势。LDR6020…

thinkphp+vue+html高校固定资产管理系统维修 租借4h80u

本高校资产管理系统采用的数据库是Mysql&#xff0c;使用thinkphp框架开发。在设计过程中&#xff0c;充分保证了系统代码的良好可读性、实用性、易扩展性、通用性、便于后期维护、操作方便以及页面简洁等特点。运行环境:phpstudy/wamp/xammp等 开发语言&#xff1a;php 后端框…