机器人仿真笔记[2]-基于Webots的两轮机器人
作者:互联网
使用docker镜像
docker pull dorowu/ubuntu-desktop-lxde-vnc:latest
docker run -it -p 8070:8070 -v /Users/workspace/Downloads/hello:/tmp --privileged=true dorowu/ubuntu-desktop-lxde-vnc:latest /bin/bash
这个镜像可以通过浏览器访问桌面
创建自己的机器人概述
[https://www.ncnynl.com/archives/202203/5095.html]
[https://cyberbotics.com/doc/guide/tutorial-1-your-first-simulation-in-webots?tab-language=c++]
大致过程:创建世界->创建机器人形体->创建机器人控制器
- 世界:机器人所处的环境,可以是地板
- 形体:机器人外形,可从3d建模软件导入
- 控制器:机器人运动控制
创建一个环境world
构建过程中请保持连接github.com通畅,不然会不停Warning
[https://www.guyuehome.com/6039]
[https://www.bilibili.com/video/BV1MF411F7oF/]
-
添加光源
(不然你添加其他东西也是一片漆黑,还以为软件有问题)
添加TexturedBackgroundLight -
添加地板
(不然模型受重力影响会一直往下掉)
添加RectangleArena"rectangle arena" -
添加其他小物件
添加Table,size:[0.1,0.1,0.1]
创建两轮机器人
- 添加Robot节点
Base nodes->Robot - 添加Solid
Solid有几个重要属性:
- Children
- Physics物理特性
- boundingObject边界
节点:Robot->Solid
3. 添加形状
圆柱体-主体
Robot->children->Solid->children->Shape->geometry Cylinder
属性:height:0.4,radius:0.02,其他默认
圆柱体-轮子(复制一个出来)
Robot->children->(新的)Solid->children->Shape->geometry Cylinder
属性:height:0.01,radius:0.02,其他默认
设置外观,(没有设置很难分辨物体),轮子appearance:GenericTireAppearance,车身appearance:BakelitePlastic
然后调整相对位置,摆出一个双轮机器人的造型
轮子rotation:[-1,0,0,1.57],车身默认
4. 添加运动结构
Robot->children->HingeJoint
HingeJoint有几个参数:
- JointParameters
- endPoint
- device
将轮子1和轮子2的Solid分别分别剪切到Robot->children->HingeJoint->endPoint以实现运动结构的绑定
jointParameters HingeJointParameters的anchor要设置为轮子旋转轴
HingeJoint的device添加RotationalMotor旋转电机
电机改一下名字以区分
endPoint Solid中设置physics Physics和boundingObject PipeBoundingObject
圆柱体-主体也要添加physics Physics和boundingObject PipeBoundingObject
- RobotWindow机器人窗口验证模型工作
开始仿真,然后鼠标双击机器人
拖动小滑块可让机器人轮子旋转
- 添加传感器
在世界文件(.wbt)的描述代码中各个Solid节点是并列存在的,而在ball_3 Solid中,它的某些特征是呈嵌套形式出现的,由此我们可以大胆猜测一个机器人实体必然也是通过多个节点嵌套组成的,而机器人实体与环境中的其他物体在世界文件中平行存在。实际上webots的世界文件(.wbt)与gazebo的世界文件(*.world)结构是类似的,区别只在于前者使用VRML语言描述,而后者使用XML语言描述。
添加两轮机器人的控制器
这里笔者直接使用了现成的世界[https://github.com/XuelongSun/WebotsTutorialBilibili]
-
向导(Wizard)新建机器人控制器
-
代码
my_robot.py
'''
原作:Sun博士
'''
"""my_robot controller."""
# You may need to import some classes of the controller module. Ex:
# from controller import Robot, Motor, DistanceSensor
from controller import Robot
# create the Robot instance.
robot = Robot()
# get the time step of the current world.
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:
right_motor = robot.getDevice('MotorRight')
left_motor = robot.getDevice('MotorLeft')
right_motor.setPosition(float('inf'))
left_motor.setPosition(float('inf'))
led = robot.getDevice('led')
right_motor.setVelocity(1.0)
left_motor.setVelocity(1.0)
# motor = robot.getMotor('motorname')
# ds = robot.getDistanceSensor('dsname')
# ds.enable(timestep)
ds_front = robot.getDevice('DisSensFront')
ds_front.enable(timestep)
ds_left = robot.getDevice('DisSensLeft')
ds_left.enable(timestep)
ds_right = robot.getDevice('DisSensRight')
ds_right.enable(timestep)
camera_left = robot.getDevice('CameraLeft')
camera_left.enable(timestep)
camera_right = robot.getDevice('CameraRight')
camera_right.enable(timestep)
# Main loop:
# - perform simulation steps until Webots is stopping the controller
loop_counter = 0
robot_state = 'run'
while robot.step(timestep) != -1:
ds_front_value = ds_front.getValue()
ds_right_value = ds_right.getValue()
ds_left_value = ds_left.getValue()
if ds_front_value < 850:
right_motor.setVelocity(0.0)
left_motor.setVelocity(0.0)
led.set(1)
if robot_state == 'run':
camera_left.saveImage('left_img.png', quality=50)
camera_right.saveImage('right_img.png', quality=50)
robot_state = 'stop'
else:
robot_state = 'run'
if loop_counter % 10 == 0:
led_value = 1 if led.get() == 0 else 0
led.set(led_value)
if (ds_right_value - ds_left_value) > 5:
right_motor.setVelocity(0.0)
left_motor.setVelocity(0.5)
elif (ds_right_value - ds_left_value) < -5:
right_motor.setVelocity(0.5)
left_motor.setVelocity(0.0)
else:
right_motor.setVelocity(1.0)
left_motor.setVelocity(1.0)
# Read the sensors:
# Enter here functions to read sensor data, like:
# val = ds.getValue()
# print('ds_front={}, ds_left={}, ds_right={}'.format(ds_front.getValue(), ds_left.getValue(), ds_right.getValue()))
# Process sensor data here.
# Enter here functions to send actuator commands, like:
# motor.setPosition(10.0)
loop_counter += 1
pass
# Enter here exit cleanup code.
- 将机器人控制器属性设置为如上代码
- 开始仿真
超级控制器Supervisor
用途:代码操控场景树中的任一节点的任一属性值
- 将Robot节点的Supervisor属性变成True
- 新建Supervisor控制器代码
my_supervisor.py
'''
原作:Sun博士
'''
"""my_supervisor controller."""
# You may need to import some classes of the controller module. Ex:
# from controller import Robot, Motor, DistanceSensor
from controller import Robot, Supervisor
# create the Robot instance.
# robot = Robot()
supervisor = Supervisor()
# get the time step of the current world.
timestep = int(supervisor.getBasicTimeStep())
# a node
obstacle = supervisor.getFromDef("Obstacle")
# a field
obstacle_pos = obstacle.getField("translation")
obs_centre_pos = [-2.68744, 0.199608, -0.831638]
obs_en_router = [-2.719, 0.152944, 0.397579]
# light node
light = supervisor.getFromDef("light")
light_intensity = light.getField("pointLightIntensity")
# keyboard
keyboard = supervisor.getKeyboard()
keyboard.enable(timestep)
# You should insert a getDevice-like function in order to get the
# instance of a device of the robot. Something like:
# motor = robot.getMotor('motorname')
# ds = robot.getDistanceSensor('dsname')
# ds.enable(timestep)
obstacle_pos.setSFVec3f(obs_centre_pos)
loop_counter = 0
# Main loop:
# - perform simulation steps until Webots is stopping the controller
while supervisor.step(timestep) != -1:
# Read the sensors:
# Enter here functions to read sensor data, like:
# val = ds.getValue()
key = keyboard.getKey()
if key == keyboard.UP:
# 调亮灯光
intensity = light_intensity.getSFFloat()
light_intensity.setSFFloat(intensity + 0.1)
elif key == keyboard.DOWN:
# 调暗灯光
intensity = light_intensity.getSFFloat()
light_intensity.setSFFloat(intensity - 0.1)
else:
pass
# Process sensor data here.
supervisor.setLabel(1, 'Key {}'.format(key), 0.8, 0.2, 0.1, 0x00ffff, 0.4)
supervisor.setLabel(2, 'Frame: {}th'.format(loop_counter),
0.8,0.1,0.1,0xff0000, 0.2)
# Enter here functions to send actuator commands, like:
# motor.setPosition(10.0)
loop_counter += 1
if loop_counter == 300:
obstacle_pos.setSFVec3f(obs_en_router)
# Enter here exit cleanup code.
- 将机器人控制器设置为如上代码
- 开始仿真
标签:仿真,right,机器人,robot,Robot,motor,Webots,ds,left 来源: https://www.cnblogs.com/qsbye/p/16691598.html