当前位置: 首页 > news >正文

Webots控制器编程

本文主要内容是如何编写Webots控制器,使用语言为Python。

文章目录

      • 1. 新增控制器
      • 2. Hello World Example
      • 3. 读取传感器
      • 4. 使用执行器
      • 5. 理解step和robot.step函数
      • 6. 同时使用传感器和执行器
      • 7. 控制器参数

1. 新增控制器

对机器人Robot新增控制器的方式:

Wizards -> New Robot Controller

默认的Python代码模版是:

# You may need to import some classes of the controller module. Ex:
#  from controller import Robot, Motor, DistanceSensor
# 1. 导入相关控制器类
from controller import Robot# create the Robot instance.
# 2. 实例化控制器类得到控制的对象
robot = Robot()# get the time step of the current world.
# 3. 获取环境仿真时间步
timestep = int(robot.getBasicTimeStep())# You should insert a getDevice-like function in order to get the
# instance of a device of the robot. Something like:
# 4. 获取要操控的设备并设置仿真时间步
#  motor = robot.getDevice('motorname')
#  ds = robot.getDevice('dsname')
#  ds.enable(timestep)# Main loop:
# - perform simulation steps until Webots is stopping the controller
# 5. 主循环中按照时间步进行仿真
while robot.step(timestep) != -1:# Read the sensors:# Enter here functions to read sensor data, like:#  val = ds.getValue()# Process sensor data here.# Enter here functions to send actuator commands, like:#  motor.setPosition(10.0)pass# Enter here exit cleanup code.

可以看到一般控制器程序的代码可以分为五部分:

  1. 导入相关控制器类
  2. 实例化控制器类得到控制的对象
  3. 获取环境仿真时间步
  4. 获取要操控的设备并设置仿真时间步
  5. 主循环中按照时间步进行仿真

2. Hello World Example

from controller import Robotrobot = Robot()while robot.step(32) != -1:print("Hello World!")

在主循环中每隔32ms会进行执行一次,执行的内容可能需要1ms也可能需要1min的时间完成这次仿真的推进,具体的时间需要看执行内容的复杂程度。

3. 读取传感器

from controller import Robot, DistanceSensorTIME_STEP = 32robot = Robot()# my_distance_sensor这个需要根据你命名的传感器名称进行定义
sensor = robot.getDevice("my_distance_sensor")
# 传感器需要先启用才能使用,TIME_STEP传感器的两次数据更新的时间间隔
# 一般设置TIME_STEP和仿真时间步相同
sensor.enable(TIME_STEP)while robot.step(TIME_STEP) != -1:value = sensor.getValue()print("Sensor value is: ", value)

需要注意的是有些传感器返回的值不是标量而是向量,如下代码所示:

GPS.getValues()
Accelerometer.getValues()
Gyro.getValues()# return the sensor measurement as an array of 3 floating point numbers: `[x, y, z]`.
values = gps.getValues()# OK, to read the values they should never be explicitly deleted by the controller code
print("MY_ROBOT is at position: %g %g %g" % (values[0], values[1], values[2]))# there is no need to copy these values

4. 使用执行器

下面的示例显示了如何使用 2 Hz 正弦信号使旋转电机振荡。

from controller import Robot, Motor
from math import pi, sinTIME_STEP = 32robot = Robot()
# 获取机器人上名为"my_motor"的电机设备
motor = robot.getDevice("my_motor")# 设置频率F为2 Hz,用于控制电机的周期性运动,使电机每秒进行两个完整周期的运动。
F = 2.0   # frequency 2 Hz
t = 0.0   # elapsed simulation timewhile robot.step(TIME_STEP) != -1:position = sin(t * 2.0 * pi * F)motor.setPosition(position)t += TIME_STEP / 1000.0

与传感器不同,执行器不需要明确启用。为了控制运动,通常有用的是将运动分解为与控制步骤相对应的离散步骤。和以前一样,这里使用无限循环:在每次迭代时,根据正弦方程计算新的目标位置。

需要注意的是,motor.setPosition 函数存储新位置,但它不会立即启动电机。有效驱动调用 robot.step 函数开始。

robot.step 函数返回时,电机已移动一定的(线性或旋转)量,该量取决于目标位置、控制步骤的持续时间(使用 robot.step 函数参数指定)、速度、加速度、力等电机“.wbt”描述中指定的参数。例如,如果指定非常小的控制步长或较低的电机速度,则当 robot.step 函数返回时,电机不会移动太多。在这种情况下,旋转电机需要几个控制步骤才能到达目标位置。如果指定更长的持续时间或更高的速度,则当 robot.step 函数返回时,电机可能已完全完成运动。

请注意,motor.setPosition 函数仅指定所需的目标位置。就像真实的机器人一样,旋转电机有可能无法到达该位置(仅在基于物理的模拟中),因为它被障碍物阻挡或因为电机的扭矩(最大力)不足以抵抗重力等。

如果要同时控制多个旋转电机的运动,则需要使用motor.setPosition 函数分别为每个旋转电机指定所需的位置。然后您需要调用一次 robot.step 函数来同时驱动所有旋转电机。

5. 理解step和robot.step函数

Webots 使用两种不同的时间步长:

  • The simulation step(在场景树中指定:WorldInfo.basicTimeStep
  • The control step(指定为每个机器人的 robot.step 函数的参数)

The simulation step(模拟步长)是 WorldInfo.basicTimeStep 中指定的值(以毫秒为单位)。它表示一步模拟的持续时间,即两次计算每个模拟对象的位置、速度、碰撞等的时间间隔。如果模拟使用physics (vs. kinematics),则模拟步骤还指定需要应用于模拟刚体的力和扭矩的两次计算之间的间隔。

The control step(控制步长)是控制循环迭代的持续时间。它与传递给 robot.step 函数的参数相对应。robot.step 函数将指定持续时间的控制器时间提前。同时,它还会根据控制器时间将传感器和执行器数据与模拟器同步。

每个控制器都需要定期调用 robot.step 函数。如果控制器不调用 robot.step 函数,则传感器和执行器将不会更新,并且模拟器将阻塞(仅在同步模式下)。因为需要定期调用,所以 robot.step 函数调用通常放在控制器的主循环中。

a simulation step的执行是一个原子操作:它不能被中断。因此,传感器测量或电机驱动只能在两个simulation step之间进行。因此,每个 robot.step 函数调用指定的The control step必须是simulation step的倍数。因此,例如,如果simulation step为 16 ms,则传递给 robot.step 函数的控制步参数可以是 16、32、64、128 等。

如果模拟以逐步模式运行,即通过单击Step按钮,则执行具有模拟步骤持续时间的单个步骤。下图详细描述了仿真状态、控制器状态和Step点击之间的同步。

6. 同时使用传感器和执行器

Webots 和每个机器人控制器在不同的进程中执行。例如,如果模拟涉及两个机器人,则总共会有三个进程:一个是 Webots 进程,两个是两个机器人进程。在调用 robot.step 函数时,每个机器人控制器进程都会与 Webots 进程交换传感器和执行器数据。例如,my_leg.setPosition 函数不会立即将数据发送给 Webots。相反,它会在本地存储数据,并在调用 robot.step 函数时有效发送数据。

因此,下面的代码片段是一个糟糕的示例。显然,第一次调用 my_leg.setPosition 函数时指定的值将被第二次调用覆盖:

my_leg.setPosition(0.34) # BAD: ignored
my_leg.setPosition(0.56)
robot.step(40) # BAD: we don't test the return value of this function

同样,这段代码也没有什么意义:

while robot.step(40) != -1:d1 = sensor.getValue()d2 = sensor.getValue()if d2 > d1: # WRONG: d2 will always equal d1 hereavoidCollision()

由于在两次传感器读数之间没有调用 robot.step 函数,因此传感器返回的值不可能在此期间发生变化。一个正确的版本如下:

while robot.step(40) != -1:d1 = sensor.getValue()if robot.step(40) == -1:breakd2 = sensor.getValue()if d2 > d1:avoidCollision()

然而,通常推荐的方法是在主控制循环中调用一个 robot.step 函数,并使用它同时更新所有传感器和执行器,如下所示:

while robot.step(40) != -1:readSensors()actuateMotors()

请注意,在循环开始时调用 robot.step函数非常重要,以确保传感器在进入 readSensors 函数之前已经具有有效值。

这是一起使用传感器和执行器的完整示例。这里使用的机器人使用差速转向。它使用两个距离传感器(DistanceSensor)来检测障碍物。

from controller import Robot, Motor, DistanceSensorTIME_STEP = 32robot = Robot()left_sensor = robot.getDevice("left_sensor")
right_sensor = robot.getDevice("right_sensor")
left_sensor.enable(TIME_STEP)
right_sensor.enable(TIME_STEP)left_motor = robot.getDevice("left_motor")
right_motor = robot.getDevice("right_motor")
left_motor.setPosition(float('inf'))
right_motor.setPosition(float('inf'))
left_motor.setVelocity(0.0)
right_motor.setVelocity(0.0)while robot.step(TIME_STEP) != -1:# read sensorsleft_dist = left_sensor.getValue()right_dist = right_sensor.getValue()# compute behavior (user functions)left = compute_left_speed(left_dist, right_dist)right = compute_right_speed(left_dist, right_dist)# actuate wheel motorsleft_motor.setVelocity(left)right_motor.setVelocity(right)

在Webots仿真环境中,控制电机的方式主要有两种:位置控制和速度控制。而在这段代码中,通过将电机的位置设置为“无限”float('inf'),就可以使电机进入速度控制模式 。

  • 位置控制模式:通常情况下,如果给电机设置一个固定的目标位置(例如一个角度或距离),电机会尝试旋转到该位置并停在那里,这就是“位置控制”。
  • 速度控制模式:通过将电机位置设为“无限”float('inf'),Webots将认为电机的目标位置是无限远的,这种情况下,电机会进入“速度控制模式”,即不再关注目标位置,而是只根据设定的速度值进行旋转或移动。

7. 控制器参数

.wbt 文件中,可以指定控制器启动时传递的参数。这些参数在机器人节点的 controllerArgs 字段中指定,并作为主函数的参数传递。例如,这可用于指定每个机器人控制器的不同参数。请注意,使用 MATLAB 时不支持控制器参数检索。

比如:

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

如果控制器的名称是 “demo”,那么就会出现这段示例控制器代码

from controller import Robot
import sysrobot = Robot()for i in range(0, len(sys.argv)):print("argv[%i]=%s" % (i, sys.argv[i]))
argv[0]=demo
argv[1]=one
argv[2]=two
argv[3]=three

相关文章:

Webots控制器编程

本文主要内容是如何编写Webots控制器,使用语言为Python。 文章目录 1. 新增控制器2. Hello World Example3. 读取传感器4. 使用执行器5. 理解step和robot.step函数6. 同时使用传感器和执行器7. 控制器参数 1. 新增控制器 对机器人Robot新增控制器的方式&#xff1…...

舷外机,高效动力的选择,可靠性能的保障_鼎跃安全

舷外机是现代船只动力系统中的核心设备,广泛应用于娱乐船、渔船、巡逻船、救援船等多种场景。它不仅提供船只的动力支持,还因其结构简便、操作灵活和维护方便,成为水上作业的重要组成部分。 一、舷外机的功能作用 1. 强劲动力源 舷外机是船…...

计算机新手练级攻略——如何搜索问题

目录 计算机学生新手练级攻略——如何搜索问题1.明确搜索意图2.使用精确关键词3.使用专业引擎搜索4.利用好技术社区1. Stack Overflow2. GitHub3. IEEE Xplore4. DBLP 5.使用代码搜索工具1. GitHub 代码搜索2. Stack Overflow 代码搜索3. Papers with Code4. IEEE Xplore 6.查阅…...

echarts-gl 3D柱状图配置

1. 源码 此demo可以直接在echarts的编辑器中运行 option {title: {text: 产量图,textStyle: {color: rgba(255, 255, 255, 1),fontSize: 17},left: center},tooltip: {},legend: {show: false,orient: vertical,x: left,top: 0,right: 20,textStyle: {fontSize: 12}},visualM…...

设计模式之模版方法模式(Template)

一、模版方法模式介绍 1、模版方法模式定义: 模板方法模式(template method pattern)原始定义是:在操作中定义算法的框架,将一些 步骤推迟到子类中。模板方法让子类在不改变算法结构的情况下重新定义算法的某些步骤。 模板方法中的算法可以理…...

背包九讲——背包问题求具体方案

目录 背包问题求具体方案 1. 01 背包问题 题目:12. 背包问题求具体方案 - AcWing题库 算法思路: 代码实现: 2. 多重背包问题 算法思路: 3. 完全背包问题 算法思路: 代码实现: 背包问题第九讲—…...

Python http打印(http打印body)flask demo(http调试demo、http demo、http printer)

文章目录 代码解释 代码 # flask_http_printer.pyfrom flask import Flask, request, jsonify import jsonapp Flask(__name__)app.route(/printinfo, methods[POST]) def print_info():# 分隔符separator "-" * 60# 获取请求头headers request.headers# 获取 JS…...

JSF HTML标签教程一口气讲完!(下)

JSF OutputScript示例 JSF教程 - JSF OutputScript示例 h:outputScript标记渲染类型为“script"的HTML元素&#xff0c;类型为“text/javascript"。 此标记将外部JavaScript文件添加到JSF页面。 以下JSF标记 <h:outputScript library"js" name"…...

cmake报错The link interface of target “gRPC::grpc“ contains: OpenSSL::SSL 解决

系统环境&#xff1a;麒麟V10 报错描述&#xff1a; The link interface of target "gRPC::grpc" contains: OpenSSL::SSL but the target was not found. Possible reasons include: * There is a typo in the target name. * A find_package call is missing fo…...

C语言PythonBash:空白(空格、水平制表符、换行符)与转义字符

C语言 空白 C语言中的空白&#xff08;空格、水平制表符、换行符&#xff09;被用于分隔Token&#xff0c;因此Token间可以有任意多个空白。 // 例1 printf("Hello, World!"); 例1中存在5个Token&#xff0c;分别是&#xff1a; printf("Hello, World! \n&qu…...

【Python】轻松解析JSON与XML:Python标准库的json与xml模块

轻松解析JSON与XML&#xff1a;Python标准库的json与xml模块 在现代数据处理与交换中&#xff0c;JSON&#xff08;JavaScript Object Notation&#xff09;和XML&#xff08;eXtensible Markup Language&#xff09;是最常用的两种数据格式。它们广泛应用于API数据传输、配置…...

物联网对商业领域的影响

互联网彻底改变了通信方式&#xff0c;并跨越了因地理障碍造成的人与人之间的鸿沟。然而&#xff0c;物联网&#xff08;IoT&#xff09;的引入通过使设备能够连接到互联网&#xff0c;改变了设备的功能。想象一下&#xff0c;你的闹钟连接到互联网&#xff0c;并且能够用你的声…...

第16章 SELECT 底层执行原理

一、SELECT查询的完整结构 1.1 方式一&#xff08;SQL 92语法&#xff09; SELECT ..., ..., ... FROM ..., ..., ... WHERE 多表的连接条件 AND 不包含组函数的过滤条件 GROUP BY ..., ... HAVING 包含组函数的过滤条件 ORDER BY ... ASC/DESC LIMIT ..., ... 1.2 方式二&a…...

python查询日志,并组装sql,修复缺失的数据

前言 由于mysql链接超时波动&#xff0c;导致数据缺失&#xff0c;需要根据日志填补数据 流程 获取确实数据的订单列表 搜索日志&#xff0c;获取请求日志 根据请求日志拼装sql 打印sql供修复数据 代码 因为我们日志打印的有问题&#xff0c;所以这里用字符串截取获取入…...

RecyclerView进阶知识讲解

在 Android 开发中&#xff0c;RecyclerView 是一种高效的列表和网格布局控件&#xff0c;用于显示大规模数据。尽管基本使用方法简单&#xff0c;但深入理解并掌握其高级进阶用法能大幅提升用户体验和应用性能。下面&#xff0c;我将从布局管理、动画和手势、自定义缓存、优化…...

C语言 函数

时间&#xff1a;2024.11.10-11.11 一、学习内容 1、什么是函数 函数&#xff1a;程序中独立的功能。将反复书写的代码&#xff0c;又不确定什么时候回用到的代码打包起来。 2、函数的基本格式 函数的定义格式&#xff08;写在main函数外&#xff09; void 函数名() { 函数…...

windows中docker安装redis和redisinsight记录

创建一个Redis运行容器&#xff0c;命令如下 docker run -it -d --name redis -p 6379:6379 redis --bind 0.0.0.0 --protected-mode no -d 代表Redis容器后台运行 --name redis 给创建好的容器起名叫redis -p 6379:6379 将容器的6379端口映射到宿主机的6379端口&#xff0c;注…...

itextpdf打印A5的问题

使用A5打印的时候&#xff0c;再生成pdf是没有问题的。下面做了一个测试&#xff0c;在打印机中&#xff0c;使用A5的纸张横向放入&#xff0c;因为是家用打印机&#xff0c;A5与A4是同一个口&#xff0c;因此只能这么放。 使用itextpdf生成pdf&#xff0c;在浏览器中预览pdf是…...

qt QUndoView详解

1、概述 QUndoView 是 Qt 框架中用于显示 QUndoStack&#xff08;撤销堆栈&#xff09;内容的视图类。它通常与 QUndoStack 一起使用&#xff0c;为用户提供了一个可视化的界面来查看和操作撤销/重做历史。QUndoView 可以显示堆栈中的每个命令&#xff0c;并允许用户通过界面进…...

python+智谱AI-实现钉钉消息自动回复

python智谱AI-实现钉钉消息自动回复 实现了电脑窗口切换&#xff0c;截图识别未读消息&#xff0c;与语言模型交互后&#xff0c;将答案带入到钉钉窗口中。偷个懒&#xff0c;直接贴代码了&#xff0c;后续不断完善注释&#xff0c;如果遇到读不懂的地方&#xff0c;欢迎交流。…...

[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?

&#x1f9e0; 智能合约中的数据是如何在区块链中保持一致的&#xff1f; 为什么所有区块链节点都能得出相同结果&#xff1f;合约调用这么复杂&#xff0c;状态真能保持一致吗&#xff1f;本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里&#xf…...

脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)

一、数据处理与分析实战 &#xff08;一&#xff09;实时滤波与参数调整 基础滤波操作 60Hz 工频滤波&#xff1a;勾选界面右侧 “60Hz” 复选框&#xff0c;可有效抑制电网干扰&#xff08;适用于北美地区&#xff0c;欧洲用户可调整为 50Hz&#xff09;。 平滑处理&…...

连锁超市冷库节能解决方案:如何实现超市降本增效

在连锁超市冷库运营中&#xff0c;高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术&#xff0c;实现年省电费15%-60%&#xff0c;且不改动原有装备、安装快捷、…...

dedecms 织梦自定义表单留言增加ajax验证码功能

增加ajax功能模块&#xff0c;用户不点击提交按钮&#xff0c;只要输入框失去焦点&#xff0c;就会提前提示验证码是否正确。 一&#xff0c;模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...

c++ 面试题(1)-----深度优先搜索(DFS)实现

操作系统&#xff1a;ubuntu22.04 IDE:Visual Studio Code 编程语言&#xff1a;C11 题目描述 地上有一个 m 行 n 列的方格&#xff0c;从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子&#xff0c;但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...

如何为服务器生成TLS证书

TLS&#xff08;Transport Layer Security&#xff09;证书是确保网络通信安全的重要手段&#xff0c;它通过加密技术保护传输的数据不被窃听和篡改。在服务器上配置TLS证书&#xff0c;可以使用户通过HTTPS协议安全地访问您的网站。本文将详细介绍如何在服务器上生成一个TLS证…...

python如何将word的doc另存为docx

将 DOCX 文件另存为 DOCX 格式&#xff08;Python 实现&#xff09; 在 Python 中&#xff0c;你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是&#xff0c;.doc 是旧的 Word 格式&#xff0c;而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...

Axios请求超时重发机制

Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式&#xff1a; 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...

css3笔记 (1) 自用

outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size&#xff1a;0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格&#xff…...

Mobile ALOHA全身模仿学习

一、题目 Mobile ALOHA&#xff1a;通过低成本全身远程操作学习双手移动操作 传统模仿学习&#xff08;Imitation Learning&#xff09;缺点&#xff1a;聚焦与桌面操作&#xff0c;缺乏通用任务所需的移动性和灵活性 本论文优点&#xff1a;&#xff08;1&#xff09;在ALOHA…...