CoppeliaSim软件下载:https://www.coppeliarobotics.com/downloads
CoppeliaSim用户手册:https://www.coppeliarobotics.com/helpFiles/index.html
BubbleRob Tutorial:https://www.coppeliarobotics.com/helpFiles/en/bubbleRobTutorial.htm

目录)
一、概括
二、建立模型
2.1 创建小球
2.2 设置距离传感器
2.3 创建轮子
2.4 创建后轮
三、设置物理属性
四、设置环境障碍
五、添加视觉传感器
六、完善BubbleRob模型
一、概括
这个教程将要设计一个简单的移动机器人BubbleRob,在这个过程中将要介绍CoppeliaSim的一些功能。由于该软件默认安装在C盘下,所以CoppeliaSim的场景文件通常在该目录下:C:\Program Files\CoppeliaRobotics\CoppeliaSimEdu\scenes;该教程BubbleRob的教程在该目录下:C:\Program Files\CoppeliaRobotics\CoppeliaSimEdu\scenes\tutorials\BubbleRob。

下图为我们需要建立的仿真场景。
在这里插入图片描述

二、建立模型
2.1 创建小球
添加一个直径为0.2的球。菜单栏:Add — Primitive shape — Sphere。设置X-size为0.2,点击OK。

可见层(visibility layer)默认为1,layers的默认设置为1-8,所以此小球为可见状态。
dynamic和respondable默认为enable,这意味着小球可以掉落或是与其他respondable的物体发生碰撞。
选中小球通过Ctrl+C和Ctrl+V进行复制,启动仿真后,两个小球将会被弹开。仿真完成后,删掉刚刚复制的小球。
在这里插入图片描述

同样,在仿真过程中,通过复制粘贴也可观察到该现象。仿真结束后复制的小球将被移除,可在工具栏的Simulation dialog界面中进行设置是否在仿真结束后移除创建的对象。

在这里插入图片描述

2.2 设置距离传感器

设置BubbleRobk使用计算模块(例如,计算距离),需要在模型的通用属性中使能Collidable, Measurable, Renderable 和 Detectable。

在这里插入图片描述

打开位置对话框,选择Translation栏,相对于的坐标系选择World,Along Z设置为0.02,最后点击Translate selection。

在这里插入图片描述

这会使所有选中的物体在Z轴上抬高2cm。

在scene hierachy中,双击sphere进行重命名,将其改为bubbleRob。

在这里插入图片描述

接下来,我们为其添加距离传感器(Proximity sensors)。其中有超声波、红外等距离传感器。

在这里插入图片描述

菜单栏中:Add — Proximity sensor — Cone Type。

在这里插入图片描述

打开方向对话框(orientation dialog)中的Rotation选项卡,设置Around Y 和 Around Z为90,点击Rotate selection。

在这里插入图片描述

打开位置对话框(position dialog)中的Position选项卡,设置X-coord为0.1,Z-coord为0.12。

在这里插入图片描述

在scene hierarchy中,双击距离传感器(proximity sensor)的图标打开属性窗口(scene Object Properties),点击Show volume parameters打开Detection Volume Properties对话框,设置Offset为0.005,Angle为30,Range为0.15。
在这里插入图片描述

接下来,在属性窗口(scene Object Properties),点击Show Detection parameters打开Detection Parameters对话框,取消Don't allow detections if distance smaller than选项。

在这里插入图片描述

在scene hierarchy中双击proximity sensor的名字重命名为bubbleRob_sensingNose。

造scene hierarchy中选择bubbleRob_sensingNose,在通过Ctrl+鼠标左键选择bubbleRob,在菜单栏中点击Edit — Make last selected object parent,将传感器装在机器人上。
在这里插入图片描述

2.3 创建轮子
步骤1 新建一个场景:菜单栏 File — new scene

步骤2 建立一个圆柱体:菜单栏Add — Primitive Shape — Cylinder,设置其属性为 (0.08,0.08,0.02)并确定

步骤3 打开object common properties使能 Collidable, Measurable, Renderable 和 Detectable。

步骤4 设置位置坐标为 (0.05,0.1,0.04) ,旋转为 (-90,0,0),并重命名为bubbleRob_leftWheel,复制并粘贴该圆柱体并设置Y轴坐标为-0.1,重命名bubbleRob_rightWheel。
在这里插入图片描述

步骤5 选择刚刚建立好的两个圆柱体复制到之前的场景中。

步骤6 添加关节:菜单栏 Add — Joint — Revolute

步骤7 Ctrl+鼠标左键选中bubbleRob_leftWheel,在position对话框的position选项卡中点击Apply to selection,在orientation对话框的orientation选项卡中点击Apply to selection。

步骤8 重命名该关节为bubbleRob_leftMotor。

步骤9 双击该关节的图标,按一下步骤进行设置。
在这里插入图片描述

步骤10 重复步骤6-9对右边的轮子进行设置。

步骤11 将两个小轮连接在机器人的主体上。

在这里插入图片描述

2.4 创建后轮
此时进行仿真的话,机器人的身体将会向后跑,因为机器人与地面之间缺少第三个连接。所以在后面为其添加一个小轮(slider或是caster)。

步骤1: 创建一个新的场景,添加pure primitive sphere,设置直径为0.05(也就是X-size为0.05),并且使能 Collidable, Measurable, Renderable 和 Detectable。并重命名为bubbleRob_slider。

步骤2 :在shape dynamic properties中按照如下进行设置。
在这里插入图片描述

步骤3:添加force snsor object,菜单栏:Add — Force sensor,并重命名为bubbleRob_connection.

步骤4:将其Z轴的坐标设置为0.05.

步骤5:将两个部件一起复制到最初的场景中,并将它们的x轴坐标设为-0.07。

在这里插入图片描述

此时运行仿真的话,还是可以看见后轮有轻微的运动,这是因为bubbleRob_slider与bubbleRob互相发生碰撞,为了防止仿真过程中出现这一奇怪的现象,我们需要告诉CoppeliaSIm这两个部件不需要相互碰撞。

步骤6:在shape dynamics properties界面中,设置bubbleRob_slider的local respondable mask为00001111,设置bubbleRob的local respondable mask 为 11110000。

此时进行仿真,机器人内部部件不会互相干扰。

三、设置物理属性
当我们运行仿真时,可发现即使我们锁住了电机,BubbleRob仍在缓慢的移动。当使用不同的物理引擎时会出现不同的结果。

动态仿真的稳定性取决于非静态物体的质量和惯性,所以要保证物体的质量不要太小,且物体之间的质量差距不要太大。

选中两个轮子和一个后轮,打开shape dynamics对话框,点击M=M*2 (for selection)三次,这会使它们的质量变为原来的8倍。对惯性(inertias)进行同样的设置。
在这里插入图片描述

此时进行仿真,发现稳定性提高了很多。

对两个电机进行设置,设置速度为50。

在这里插入图片描述

此时进行仿真,bubbleRob将不断前进直至掉下平台。将其速度重新设置为0。

四、设置环境障碍
添加尺寸为(0.1, 0.1, 0.2)的圆柱体(pure primitive cylinder)。

因为我们希望圆柱体为静态的(忽略重力和碰撞),但是还希望它能够与其他的非静态物体(non-static respondable)发生碰撞。因此,在shape dynamics properties栏内关掉Body is dynamic选项,并且在 object common properties内选上 Collidable, Measurable, Renderable 和 Detectable。

设置好后,我们可以通过工具栏的Object/item shift工具拖拽物体。拖拽过程中,Z轴将保持不变。
在这里插入图片描述

通过复制和粘贴,我们可以得到很多这样的圆柱体,并将其摆在BubbleRob的周围上。

在拖拽过程中,按住shift键拖拽的精度会变小.

五、添加视觉传感器
添加视觉传感器(vision sensor),菜单栏:Add — Vision sensor — Perspective type,将视觉传感器与距离传感器连接起来,并且设置视觉传感器和位置和旋转属性与距离传感器相同。

打开视觉传感器属性栏,设置Resolution x 和 Resolution y 均为256。
在这里插入图片描述

右键点击屏幕,View— floating view;选择视觉传感器,右键点击该悬浮窗,View — Associate view with selected vision sensor。

此时进行仿真,悬浮窗的画面为视觉传感器内的画面。

为视觉传感器添加脚本,菜单栏:Add — Asscoicated child script — Non threaded。在scene hierarchy中双击视觉传感器的脚本图标,并将以下代码复制其中。
在这里插入图片描述

function sysCall_vision(inData)
    simVision.sensorImgToWorkImg(inData.handle) -- copy the vision sensor image to the work image
    simVision.edgeDetectionOnWorkImg(inData.handle,0.2) -- perform edge detection on the work image
    simVision.workImgToSensorImg(inData.handle) -- copy the work image to the vision sensor image buffer
end

function sysCall_init()
end

六、完善BubbleRob模型

打开BubbleRob的object common properties,选择Object is model base 和 Object/model can transfer or accept DNA。

在这里插入图片描述

选择两个轮子(两个joint)、距离传感器和graph,打开object common properties对话框,使能Ignored by model bounding box,并点击Apply to selection,。

选择两个轮子和Force sensor,打开object common properties对话框,按照如下设置可见层。并选上Select base of model instead。
在这里插入图片描述

选择Select base of model instead表示,当我们点击整个模型的一部分时,会自动选中父元素。我们可以在scene hierarchy中点击不同部件进行操作。

为BubbleRob添加脚本,点击bubbleRob,菜单栏:Add — Associated child script — Non threaded,在scene hierarchy中bubbleRob的脚本图标,并将以下代码复制其中。

function speedChange_callback(ui,id,newVal)
    speed=minMaxSpeed[1]+(minMaxSpeed[2]-minMaxSpeed[1])*newVal/100
end

function sysCall_init()
    -- This is executed exactly once, the first time this script is executed
    bubbleRobBase=sim.getObjectAssociatedWithScript(sim.handle_self) -- this is bubbleRob's handle
    leftMotor=sim.getObjectHandle("bubbleRob_leftMotor") -- Handle of the left motor
    rightMotor=sim.getObjectHandle("bubbleRob_rightMotor") -- Handle of the right motor
    noseSensor=sim.getObjectHandle("bubbleRob_sensingNose") -- Handle of the proximity sensor
    minMaxSpeed={50*math.pi/180,300*math.pi/180} -- Min and max speeds for each motor
    backUntilTime=-1 -- Tells whether bubbleRob is in forward or backward mode
    robotCollection=sim.createCollection(0)
    sim.addItemToCollection(robotCollection,sim.handle_tree,bubbleRobBase,0)
    distanceSegment=sim.addDrawingObject(sim.drawing_lines,4,0,-1,1,{0,1,0})
    robotTrace=sim.addDrawingObject(sim.drawing_linestrip+sim.drawing_cyclic,2,0,-1,200,{1,1,0},nil,nil,{1,1,0})
    graph=sim.getObjectHandle('bubbleRob_graph')
    distStream=sim.addGraphStream(graph,'bubbleRob clearance','m',0,{1,0,0})
    -- Create the custom UI:
        xml = '<ui title="'..sim.getObjectName(bubbleRobBase)..' speed" closeable="false" resizeable="false" activate="false">'..[[
        <hslider minimum="0" maximum="100" οnchange="speedChange_callback" id="1"/>
        <label text="" style="* {margin-left: 300px;}"/>
        </ui>
        ]]
    ui=simUI.create(xml)
    speed=(minMaxSpeed[1]+minMaxSpeed[2])*0.5
    simUI.setSliderValue(ui,1,100*(speed-minMaxSpeed[1])/(minMaxSpeed[2]-minMaxSpeed[1]))
end

function sysCall_sensing()
    local result,distData=sim.checkDistance(robotCollection,sim.handle_all)
    if result>0 then
        sim.addDrawingObjectItem(distanceSegment,nil)
        sim.addDrawingObjectItem(distanceSegment,distData)
        sim.setGraphStreamValue(graph,distStream,distData[7])
    end
    local p=sim.getObjectPosition(bubbleRobBase,-1)
    sim.addDrawingObjectItem(robotTrace,p)
end

function sysCall_actuation()
    result=sim.readProximitySensor(noseSensor) -- Read the proximity sensor
    -- If we detected something, we set the backward mode:
    if (result>0) then backUntilTime=sim.getSimulationTime()+4 end 

    if (backUntilTime<sim.getSimulationTime()) then
        -- When in forward mode, we simply move forward at the desired speed
        sim.setJointTargetVelocity(leftMotor,speed)
        sim.setJointTargetVelocity(rightMotor,speed)
    else
        -- When in backward mode, we simply backup in a curve at reduced speed
        sim.setJointTargetVelocity(leftMotor,-speed/2)
        sim.setJointTargetVelocity(rightMotor,-speed/8)
    end
end

function sysCall_cleanup()
	simUI.destroy(ui)
end

现在可以开始运行仿真了,在仿真过程中可以修改BubbleRob的速度。