ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

机器人仿真笔记[2]-基于Webots的两轮机器人

2022-09-15 01:02:32  阅读:196  来源: 互联网

标签:仿真 right 机器人 robot Robot motor Webots ds left


使用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/]

  1. 添加光源
    (不然你添加其他东西也是一片漆黑,还以为软件有问题)
    添加TexturedBackgroundLight

  2. 添加地板
    (不然模型受重力影响会一直往下掉)
    添加RectangleArena"rectangle arena"

  3. 添加其他小物件
    添加Table,size:[0.1,0.1,0.1]

创建两轮机器人

  1. 添加Robot节点
    Base nodes->Robot
  2. 添加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

  1. RobotWindow机器人窗口验证模型工作
    开始仿真,然后鼠标双击机器人

    拖动小滑块可让机器人轮子旋转
  2. 添加传感器

在世界文件(.wbt)的描述代码中各个Solid节点是并列存在的,而在ball_3 Solid中,它的某些特征是呈嵌套形式出现的,由此我们可以大胆猜测一个机器人实体必然也是通过多个节点嵌套组成的,而机器人实体与环境中的其他物体在世界文件中平行存在。实际上webots的世界文件(.wbt)与gazebo的世界文件(*.world)结构是类似的,区别只在于前者使用VRML语言描述,而后者使用XML语言描述。

添加两轮机器人的控制器

这里笔者直接使用了现成的世界[https://github.com/XuelongSun/WebotsTutorialBilibili]

  1. 向导(Wizard)新建机器人控制器

  2. 代码
    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.

  1. 将机器人控制器属性设置为如上代码
  2. 开始仿真

超级控制器Supervisor

用途:代码操控场景树中的任一节点的任一属性值

  1. 将Robot节点的Supervisor属性变成True
  2. 新建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.
  1. 将机器人控制器设置为如上代码
  2. 开始仿真

标签:仿真,right,机器人,robot,Robot,motor,Webots,ds,left
来源: https://www.cnblogs.com/qsbye/p/16691598.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有